From 97c9dd8a265b504b6804725341519d6f9930dad6 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 8 May 2009 00:21:14 +0200 Subject: [PATCH] Change xlines to store spaces as \s. Spaces in xline.conf files are changed to \s in memory and recognized on unxline, but are not changed in the file. New xlines are added to xline.conf files with \s. xline.conf written by this commit or newer will not work properly with charybdis older than 1124:131254925f32 (which introduced \s support in match_esc()). --- include/s_conf.h | 1 + modules/m_xline.c | 58 +++++++++++++---------------------------------- src/kdparse.c | 41 ++++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 43 deletions(-) diff --git a/include/s_conf.h b/include/s_conf.h index 4e734d79..6a10c56a 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -368,6 +368,7 @@ extern void parse_d_file(FILE * fb); extern void parse_x_file(FILE * fb); extern void parse_resv_file(FILE *); extern char *getfield(char *newline); +extern char *xline_encode_spaces(const char *); extern char *get_oper_name(struct Client *client_p); diff --git a/modules/m_xline.c b/modules/m_xline.c index e1c5c9f5..1aff1c9b 100644 --- a/modules/m_xline.c +++ b/modules/m_xline.c @@ -280,41 +280,7 @@ apply_xline(struct Client *source_p, const char *name, const char *reason, aconf = make_conf(); aconf->status = CONF_XLINE; - if(strstr(name, "\\s")) - { - char *tmp = LOCAL_COPY(name); - char *orig = tmp; - char *new = tmp; - - while(*orig) - { - if(*orig == '\\' && *(orig + 1) != '\0') - { - if(*(orig + 1) == 's') - { - *new++ = ' '; - orig += 2; - } - /* otherwise skip that and the escaped - * character after it, so we dont mistake - * \\s as \s --fl - */ - else - { - *new++ = *orig++; - *new++ = *orig++; - } - } - else - *new++ = *orig++; - } - - *new = '\0'; - aconf->name = rb_strdup(tmp); - } - else - aconf->name = rb_strdup(name); - + aconf->name = rb_strdup(name); aconf->passwd = rb_strdup(reason); collapse(aconf->name); @@ -532,38 +498,43 @@ remove_xline(struct Client *source_p, const char *name) { struct ConfItem *aconf; rb_dlink_node *ptr; + char *encoded; + + encoded = xline_encode_spaces(name); RB_DLINK_FOREACH(ptr, xline_conf_list.head) { aconf = ptr->data; - if(!irccmp(aconf->name, name)) + if(!irccmp(aconf->name, encoded)) { if (!aconf->hold) { - if (!remove_xline_from_file(source_p, name)) + if (!remove_xline_from_file(source_p, encoded)) return; } else { sendto_one_notice(source_p, ":X-Line for [%s] is removed", - name); + encoded); sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has removed the temporary X-Line for: [%s]", - get_oper_name(source_p), name); + get_oper_name(source_p), encoded); ilog(L_KLINE, "UX %s %s", - get_oper_name(source_p), name); + get_oper_name(source_p), encoded); } remove_reject_mask(aconf->name, NULL); free_conf(aconf); rb_dlinkDestroy(ptr, &xline_conf_list); + rb_free(encoded); return; } } - sendto_one_notice(source_p, ":No X-Line for %s", name); + sendto_one_notice(source_p, ":No X-Line for %s", encoded); + rb_free(encoded); return; } @@ -586,6 +557,7 @@ remove_xline_from_file(struct Client *source_p, const char *huntgecos) const char *gecos; mode_t oldumask; char *p; + char *encoded; int error_on_write = 0; int found_xline = 0; @@ -639,10 +611,12 @@ remove_xline_from_file(struct Client *source_p, const char *huntgecos) } /* matching.. */ - if(irccmp(gecos, huntgecos) == 0) + encoded = xline_encode_spaces(gecos); + if(irccmp(encoded, huntgecos) == 0) found_xline++; else error_on_write = (fputs(buf, out) < 0) ? YES : NO; + rb_free(encoded); } fclose(in); diff --git a/src/kdparse.c b/src/kdparse.c index 3d82b718..090c7933 100644 --- a/src/kdparse.c +++ b/src/kdparse.c @@ -158,6 +158,37 @@ parse_d_file(FILE * file) } } +char * +xline_encode_spaces(const char *mask) +{ + int i, j; + int spaces = 0; + int backslash = 0; + char *encoded; + + for (i = 0; mask[i] != '\0'; i++) + if (mask[i] == ' ') + spaces++; + encoded = rb_malloc(i + spaces + 1); + for (i = 0, j = 0; mask[i] != '\0'; i++) + { + if (mask[i] == '\\') + backslash = !backslash; + else if (mask[i] == ' ') + { + if (!backslash) + encoded[j++] = '\\'; + encoded[j++] = 's'; + backslash = 0; + continue; + } + else + backslash = 0; + encoded[j++] = mask[i]; + } + return encoded; +} + void parse_x_file(FILE * file) { @@ -166,6 +197,7 @@ parse_x_file(FILE * file) char *reason_field = NULL; char line[BUFSIZE]; char *p; + char *encoded; while (fgets(line, sizeof(line), file)) { @@ -191,10 +223,17 @@ parse_x_file(FILE * file) (strchr(reason_field, ':') != NULL)) continue; + encoded = xline_encode_spaces(gecos_field); + if (find_xline_mask(encoded) != NULL) + { + rb_free(encoded); + continue; + } + aconf = make_conf(); aconf->status = CONF_XLINE; - aconf->name = rb_strdup(gecos_field); + aconf->name = encoded; aconf->passwd = rb_strdup(reason_field); rb_dlinkAddAlloc(aconf, &xline_conf_list);