From 63860dd1a7e06f181cf037101490270ae89e7ad1 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 4e734d7..6a10c56 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 e1c5c9f..1aff1c9 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 3d82b71..090c793 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);