diff options
-rw-r--r-- | contrib/m_operspy.c | 4 | ||||
-rw-r--r-- | include/irc_string.h | 10 | ||||
-rw-r--r-- | modules/m_module.c | 2 | ||||
-rw-r--r-- | src/conf.c | 2 | ||||
-rw-r--r-- | src/hash.c | 4 | ||||
-rw-r--r-- | src/match.c | 210 | ||||
-rw-r--r-- | src/resv.c | 2 |
7 files changed, 76 insertions, 158 deletions
diff --git a/contrib/m_operspy.c b/contrib/m_operspy.c index 1d2d050..f893bb7 100644 --- a/contrib/m_operspy.c +++ b/contrib/m_operspy.c @@ -191,12 +191,10 @@ operspy_list(struct Client *client_p, int parc, char *parv[]) { const struct Channel *chptr_list = ptr->data; - if (match_chan(parv[2], chptr_list->chname)) - { + if (!match(parv[2], chptr_list->chname)) sendto_one(client_p, form_str(RPL_LIST), me.name, client_p->name, chptr_list->chname, dlink_list_length(&chptr_list->members), chptr_list->topic); - } } sendto_one(client_p, form_str(RPL_LISTEND), diff --git a/include/irc_string.h b/include/irc_string.h index dee67df..3043e9e 100644 --- a/include/irc_string.h +++ b/include/irc_string.h @@ -31,17 +31,7 @@ extern int has_wildcards(const char *); extern int ircd_pcre_exec(const void *, const char *); extern void *ircd_pcre_compile(const char *, const char **); - -/* - * match - compare name with mask, mask may contain * and ? as wildcards - * match - returns 1 on successful match, 0 otherwise - * - * match_esc - compare with support for escaping chars - * match_chan - like match_esc with first character auto-escaped - */ extern int match(const char *, const char *); -extern int match_esc(const char *, const char *); -extern int match_chan(const char *, const char *); /* * collapse - collapse a string in place, converts multiple adjacent *'s diff --git a/modules/m_module.c b/modules/m_module.c index 02a8567..b8ec8dd 100644 --- a/modules/m_module.c +++ b/modules/m_module.c @@ -217,7 +217,7 @@ mo_module(struct Client *client_p, struct Client *source_p, { modp = ptr->data; - if (!EmpyString(parv[2]) && match(parv[2], modp->name)) + if (!EmptyString(parv[2]) && match(parv[2], modp->name)) continue; sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name, @@ -1105,7 +1105,7 @@ find_matching_name_conf(enum maskitem_type type, const char *name, const char *u if (EmptyString(conf->name)) continue; - if ((name != NULL) && match_esc(conf->name, name)) + if ((name != NULL) && !match(conf->name, name)) { if ((user == NULL && (host == NULL))) return conf; @@ -815,11 +815,11 @@ list_allow_channel(const char *chname, struct ListTask *lt) dlink_node *dl = NULL; DLINK_FOREACH(dl, lt->show_mask.head) - if (!match_chan(dl->data, chname)) + if (match(dl->data, chname) != 0) return 0; DLINK_FOREACH(dl, lt->hide_mask.head) - if (match_chan(dl->data, chname)) + if (match(dl->data, chname) == 0) return 0; return 1; diff --git a/src/match.c b/src/match.c index 714809b..3a5b78c 100644 --- a/src/match.c +++ b/src/match.c @@ -25,163 +25,93 @@ #include "client.h" #include "ircd.h" -/* Fix "statement not reached" warnings on Sun WorkShop C */ -#ifdef __SUNPRO_C -# pragma error_messages(off, E_STATEMENT_NOT_REACHED) -#endif -/* match() - * - * Compare if a given string (name) matches the given - * mask (which can contain wild cards: '*' - match any - * number of chars, '?' - match any single character. - * - * return 1, if match - * 0, if no match - * - * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu) +/*! \brief Check a string against a mask. + * This test checks using traditional IRC wildcards only: '*' means + * match zero or more characters of any type; '?' means match exactly + * one character of any type. A backslash escapes the next character + * so that a wildcard may be matched exactly. + * param mask Wildcard-containing mask. + * param name String to check against \a mask. + * return Zero if \a mask matches \a name, non-zero if no match. */ int match(const char *mask, const char *name) { - const unsigned char *m = (const unsigned char *)mask; - const unsigned char *n = (const unsigned char *)name; - const unsigned char *ma = NULL; - const unsigned char *na = (const unsigned char *)name; - - assert(mask != NULL); - assert(name != NULL); - - while (1) - { - if (*m == '*') - { - while (*m == '*') - m++; - ma = m; - na = n; - } - - if (!*m) - { - if (!*n) - return 0; - if (!ma) - return 1; - for (m--; (m > (const unsigned char *)mask) && (*m == '?'); m--) - ; - if (*m == '*') - return 0; - m = ma; - n = ++na; - } - else if (!*n) - { - while (*m == '*') - m++; - return *m != '\0'; - } - - if (ToLower(*m) != ToLower(*n) && *m != '?' && (*m != '#' || !IsDigit(*n))) - { - if (!ma) - return 1; - m = ma; - n = ++na; - } - else - m++, n++; - } - - return 1; -} - -/* match_esc() - * - * The match() function with support for escaping characters such - * as '*' and '?' - */ -int -match_esc(const char *mask, const char *name) -{ - const unsigned char *m = (const unsigned char *)mask; - const unsigned char *n = (const unsigned char *)name; - const unsigned char *ma = NULL; - const unsigned char *na = (const unsigned char *)name; - - assert(mask != NULL); - assert(name != NULL); + const char *m = mask, *n = name; + const char *m_tmp = mask, *n_tmp = name; + int star = 0; while (1) { - if (*m == '*') + switch (*m) { - while (*m == '*') + case '\0': + if (!*n) + return 0; + backtrack: + if (m_tmp == mask) + return 1; + m = m_tmp; + n = ++n_tmp; + if (*n == '\0') + return 1; + break; + case '\\': m++; - ma = m; - na = n; - } + /* allow escaping to force capitalization */ + if (*m++ != *n++) + goto backtrack; + break; + case '*': + case '?': + for (star = 0; ; m++) + { + if (*m == '*') + star = 1; + else if (*m == '?') + { + if (!*n++) + goto backtrack; + } + else + break; + } - if (!*m) - { - if (!*n) - return 0; - if (!ma) - return 1; - for (m--; (m > (const unsigned char *)mask) && (*m == '?'); m--) - ; - if (*m == '*') - return 0; - m = ma; - n = ++na; - } - else if (!*n) - { - while (*m == '*') + if (star) + { + if (!*m) + return 0; + else if (*m == '\\') + { + m_tmp = ++m; + if (!*m) + return 1; + for (n_tmp = n; *n && *n != *m; n++) + ; + } + else + { + m_tmp = m; + for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++) + ; + } + } + /* and fall through */ + default: + if (!*n) + return *m != '\0'; + if (ToLower(*m) != ToLower(*n)) + goto backtrack; m++; - return *m != '\0'; - } - - if (*m != '?' && (*m != '#' || IsDigit(*n))) - { - if (*m == '\\') - if (!*++m) - return 1; - if (ToLower(*m) != ToLower(*n)) - { - if (!ma) - return 1; - m = ma; - n = ++na; - } - else - m++, n++; + n++; + break; } - else - m++, n++; } return 1; } -/* match_chan() - * - * The match_esc() function doing channel prefix auto-escape, - * ie. mask: #blah*blah is seen like \#blah*blah - */ -int -match_chan(const char *mask, const char *name) -{ - if (*mask == '#') - { - if (*name != '#') - return 0; - ++name, ++mask; - } - - return match_esc(mask, name) == 0; -} - /* * collapse() * Collapse a pattern string into minimal components. @@ -401,7 +331,7 @@ const unsigned int CharAttrs[] = { /* SP */ PRINT_C|SPACE_C, /* ! */ PRINT_C|KWILD_C|CHAN_C|VCHAN_C|NONEOS_C, /* " */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, -/* # */ PRINT_C|KWILD_C|MWILD_C|CHANPFX_C|CHAN_C|VCHAN_C|NONEOS_C, +/* # */ PRINT_C|KWILD_C|CHANPFX_C|CHAN_C|VCHAN_C|NONEOS_C, /* $ */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, /* % */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, /* & */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, @@ -150,7 +150,7 @@ match_find_resv(const char *name) { struct MaskItem *conf = ptr->data; - if (match_chan(name, conf->name)) + if (!match(name, conf->name)) return conf; } |