]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - src/match.c
Unref privset of quitting oper.
[irc/rqf/shadowircd.git] / src / match.c
index 6b13f8293f6b875180e438dee638d3ce1e5f2464..44de3286fecea80d3f67a4be2dc3838f2d2de9fa 100644 (file)
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: match.c 708 2006-02-05 22:44:03Z 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
@@ -599,7 +672,7 @@ const unsigned int CharAttrs[] = {
 /* ' */ PRINT_C | CHAN_C | NONEOS_C,
 /* ( */ PRINT_C | CHAN_C | NONEOS_C,
 /* ) */ PRINT_C | CHAN_C | NONEOS_C,
-/* * */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C | SERV_C,
+/* * */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
 /* + */ PRINT_C | CHAN_C | NONEOS_C,
 /* , */ PRINT_C | NONEOS_C,
 /* - */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,