diff --git a/ChangeLog b/ChangeLog index eb34f9f..e8025be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +jilles 2007/07/14 12:20:48 UTC (20070714-3530) + Log: + add_id() for local client: do not collapse() the ban mask. + The code calling this already collapses the mask, and if + not, doing it here would cause a desync. + + + Changes: Modified: + +0 -2 trunk/src/chmode.c (File Modified) + + nenolod 2007/07/07 08:08:23 UTC (20070707-3528) Log: - fix dereference problems with not widely used polling engines diff --git a/include/irc_string.h b/include/irc_string.h index d2bd104..bfb6942 100644 --- a/include/irc_string.h +++ b/include/irc_string.h @@ -21,7 +21,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: irc_string.h 678 2006-02-03 20:25:01Z jilles $ + * $Id: irc_string.h 3532 2007-07-14 13:32:18Z jilles $ */ #ifndef INCLUDED_irc_string_h @@ -34,11 +34,13 @@ * match - compare name with mask, mask may contain * and ? as wildcards * match - returns 1 on successful match, 0 otherwise * + * mask_match - compare one mask to another * match_esc - compare with support for escaping chars * match_cidr - compares u!h@addr with u!h@addr/cidr * match_ips - compares addr with addr/cidr in ascii form */ extern int match(const char *mask, const char *name); +extern int mask_match(const char *oldmask, const char *newmask); extern int match_esc(const char *mask, const char *name); extern int match_cidr(const char *mask, const char *name); extern int match_ips(const char *mask, const char *name); diff --git a/include/serno.h b/include/serno.h index 8d7003b..fc6dd76 100644 --- a/include/serno.h +++ b/include/serno.h @@ -1 +1 @@ -#define SERNO "20070707-3528" +#define SERNO "20070714-3530" diff --git a/src/match.c b/src/match.c index ee77aeb..7a9ad94 100644 --- a/src/match.c +++ b/src/match.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: match.c 3175 2007-02-01 00:02:35Z jilles $ + * $Id: match.c 3532 2007-07-14 13:32:18Z jilles $ * */ #include "stdinc.h" @@ -105,6 +105,79 @@ int match(const char *mask, const char *name) } } +/** Check a mask 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. + * The difference between mask_match() and match() is that in mask_match() + * a '?' in mask does not match a '*' in name. + * + * @param[in] mask Existing wildcard-containing mask. + * @param[in] name New wildcard-containing mask. + * @return 1 if \a name is equal to or more specific than \a mask, 0 otherwise. + */ +int mask_match(const char *mask, const char *name) +{ + const char *m = mask, *n = name; + const char *m_tmp = mask, *n_tmp = name; + int star_p; + + s_assert(mask != NULL); + s_assert(name != NULL); + + for (;;) + { + switch (*m) + { + case '\0': + if (!*n) + return 1; + backtrack: + if (m_tmp == mask) + return 0; + m = m_tmp; + n = ++n_tmp; + break; + case '*': + case '?': + for (star_p = 0;; m++) + { + if (*m == '*') + star_p = 1; + else if (*m == '?') + { + /* changed for mask_match() */ + if (*n == '*' || !*n) + goto backtrack; + n++; + } + else + break; + } + if (star_p) + { + if (!*m) + return 1; + else + { + m_tmp = m; + for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++); + } + } + /* and fall through */ + default: + if (!*n) + return (*m != '\0' ? 0 : 1); + if (ToLower(*m) != ToLower(*n)) + goto backtrack; + m++; + n++; + break; + } + } +} + + /** 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