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);