X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/e5d9ca18eb7ce993806e3c0752baf813ff3ddf23..e8c4b8b2904e0c9241aa8538654837ed6fa619d6:/src/match.c diff --git a/src/match.c b/src/match.c index ee77aeb..44de328 100644 --- a/src/match.c +++ b/src/match.c @@ -16,14 +16,14 @@ * 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" #include "config.h" #include "client.h" #include "ircd.h" -#include "irc_string.h" +#include "match.h" /* * Compare if a given string (name) matches the given @@ -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 @@ -234,7 +307,7 @@ int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask iaddr = &((struct sockaddr_in *)addr)->sin_addr; idest = &((struct sockaddr_in *)dest)->sin_addr; } -#ifdef IPV6 +#ifdef RB_IPV6 else { iaddr = &((struct sockaddr_in6 *)addr)->sin6_addr; @@ -253,7 +326,7 @@ int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask */ int match_ips(const char *s1, const char *s2) { - struct irc_sockaddr_storage ipaddr, maskaddr; + struct rb_sockaddr_storage ipaddr, maskaddr; char mask[BUFSIZE]; char address[HOSTLEN + 1]; char *len; @@ -273,7 +346,7 @@ int match_ips(const char *s1, const char *s2) if (cidrlen == 0) return 0; -#ifdef IPV6 +#ifdef RB_IPV6 if (strchr(mask, ':') && strchr(address, ':')) { aftype = AF_INET6; @@ -291,8 +364,8 @@ int match_ips(const char *s1, const char *s2) else return 0; - inetpton(aftype, address, ipptr); - inetpton(aftype, mask, maskptr); + rb_inet_pton(aftype, address, ipptr); + rb_inet_pton(aftype, mask, maskptr); if (comp_with_mask(ipptr, maskptr, cidrlen)) return 1; else @@ -307,7 +380,7 @@ int match_ips(const char *s1, const char *s2) int match_cidr(const char *s1, const char *s2) { - struct irc_sockaddr_storage ipaddr, maskaddr; + struct rb_sockaddr_storage ipaddr, maskaddr; char mask[BUFSIZE]; char address[NICKLEN + USERLEN + HOSTLEN + 6]; char *ipmask; @@ -341,7 +414,7 @@ int match_cidr(const char *s1, const char *s2) if (cidrlen == 0) return 0; -#ifdef IPV6 +#ifdef RB_IPV6 if (strchr(ip, ':') && strchr(ipmask, ':')) { aftype = AF_INET6; @@ -359,8 +432,8 @@ int match_cidr(const char *s1, const char *s2) else return 0; - inetpton(aftype, ip, ipptr); - inetpton(aftype, ipmask, maskptr); + rb_inet_pton(aftype, ip, ipptr); + rb_inet_pton(aftype, ipmask, maskptr); if (comp_with_mask(ipptr, maskptr, cidrlen) && match(mask, address)) return 1; else