src/match.c File Reference

#include "main.h"
Include dependency graph for match.c:

Go to the source code of this file.

Defines

#define QUOTE   '\\'
#define WILDS   '*'
#define WILDP   '%'
#define WILDQ   '?'
#define WILDT   '~'
#define NOMATCH   0
#define MATCH   (match+sofar)
#define PERMATCH   (match+saved+sofar)

Functions

int casecharcmp (unsigned char a, unsigned char b)
int charcmp (unsigned char a, unsigned char b)
int _wild_match_per (register unsigned char *m, register unsigned char *n, int(*cmp1)(unsigned char, unsigned char), int(*cmp2)(unsigned char, unsigned char), unsigned char *chgpoint)
int _wild_match (register unsigned char *m, register unsigned char *n)
int addr_match (char *m, char *n, int user, int cmp)
int mask_match (char *m, char *n)
int cidr_match (char *m, char *n, int count)
int cron_matchfld (char *mask, int match)
int cron_match (const char *mask, const char *match)

Variables

int cidr_support = 0

Define Documentation

#define MATCH   (match+sofar)

Definition at line 36 of file match.c.

Referenced by _wild_match().

#define NOMATCH   0

Definition at line 35 of file match.c.

Referenced by _wild_match(), _wild_match_per(), addr_match(), and cidr_match().

#define PERMATCH   (match+saved+sofar)

Definition at line 37 of file match.c.

Referenced by _wild_match_per().

#define QUOTE   '\\'

Definition at line 29 of file match.c.

Referenced by _wild_match_per().

#define WILDP   '%'

Definition at line 31 of file match.c.

Referenced by _wild_match_per().

#define WILDQ   '?'

Definition at line 32 of file match.c.

Referenced by _wild_match(), and _wild_match_per().

#define WILDS   '*'

Definition at line 30 of file match.c.

Referenced by _wild_match(), and _wild_match_per().

#define WILDT   '~'

Definition at line 33 of file match.c.

Referenced by _wild_match_per().


Function Documentation

int _wild_match ( register unsigned char *  m,
register unsigned char *  n 
)

Definition at line 157 of file match.c.

References MATCH, NOMATCH, WILDQ, and WILDS.

00158 {
00159   unsigned char *ma = m, *na = n, *lsm = 0, *lsn = 0;
00160   int match = 1;
00161   register int sofar = 0;
00162 
00163   /* null strings should never match */
00164   if ((ma == 0) || (na == 0) || (!*ma) || (!*na))
00165     return NOMATCH;
00166   /* find the end of each string */
00167   while (*(++m));
00168   m--;
00169   while (*(++n));
00170   n--;
00171 
00172   while (n >= na) {
00173     /* If the mask runs out of chars before the string, fall back on
00174      * a wildcard or fail. */
00175     if (m < ma) {
00176       if (lsm) {
00177         n = --lsn;
00178         m = lsm;
00179         if (n < na)
00180           lsm = 0;
00181         sofar = 0;
00182       }
00183       else
00184         return NOMATCH;
00185     }
00186 
00187     switch (*m) {
00188     case WILDS:                /* Matches anything */
00189       do
00190         m--;                    /* Zap redundant wilds */
00191       while ((m >= ma) && (*m == WILDS));
00192       lsm = m;
00193       lsn = n;
00194       match += sofar;
00195       sofar = 0;                /* Update fallback pos */
00196       if (m < ma)
00197         return MATCH;
00198       continue;                 /* Next char, please */
00199     case WILDQ:
00200       m--;
00201       n--;
00202       continue;                 /* '?' always matches */
00203     }
00204     if (toupper(*m) == toupper(*n)) {   /* If matching char */
00205       m--;
00206       n--;
00207       sofar++;                  /* Tally the match */
00208       continue;                 /* Next char, please */
00209     }
00210     if (lsm) {                  /* To to fallback on '*' */
00211       n = --lsn;
00212       m = lsm;
00213       if (n < na)
00214         lsm = 0;                /* Rewind to saved pos */
00215       sofar = 0;
00216       continue;                 /* Next char, please */
00217     }
00218     return NOMATCH;             /* No fallback=No match */
00219   }
00220   while ((m >= ma) && (*m == WILDS))
00221     m--;                        /* Zap leftover %s & *s */
00222   return (m >= ma) ? NOMATCH : MATCH;   /* Start of both = match */
00223 }

int _wild_match_per ( register unsigned char *  m,
register unsigned char *  n,
int(*)(unsigned char, unsigned char)  cmp1,
int(*)(unsigned char, unsigned char)  cmp2,
unsigned char *  chgpoint 
)

Definition at line 54 of file match.c.

References NOMATCH, NULL, PERMATCH, QUOTE, WILDP, WILDQ, WILDS, and WILDT.

00058 {
00059   unsigned char *ma = m, *lsm = 0, *lsn = 0, *lpm = 0, *lpn = 0;
00060   int match = 1, saved = 0, space;
00061   register unsigned int sofar = 0;
00062 
00063   /* null strings should never match */
00064   if ((m == 0) || (n == 0) || (!*n) || (!cmp1))
00065     return NOMATCH;
00066 
00067   if (!cmp2)                    /* Don't change cmpfunc if it's not valid */
00068     chgpoint = NULL;
00069 
00070   while (*n) {
00071     if (*m == WILDT) {          /* Match >=1 space */
00072       space = 0;                /* Don't need any spaces */
00073       do {
00074         m++;
00075         space++;
00076       }                         /* Tally 1 more space ... */
00077       while ((*m == WILDT) || (*m == ' '));     /*  for each space or ~ */
00078       sofar += space;           /* Each counts as exact */
00079       while (*n == ' ') {
00080         n++;
00081         space--;
00082       }                         /* Do we have enough? */
00083       if (space <= 0)
00084         continue;               /* Had enough spaces! */
00085     }
00086     /* Do the fallback       */
00087     else {
00088       switch (*m) {
00089       case 0:
00090         do
00091           m--;                  /* Search backwards */
00092         while ((m > ma) && (*m == '?'));        /* For first non-? char */
00093         if ((m > ma) ? ((*m == '*') && (m[-1] != QUOTE)) : (*m == '*'))
00094           return PERMATCH;      /* nonquoted * = match */
00095         break;
00096       case WILDP:
00097         while (*(++m) == WILDP);        /* Zap redundant %s */
00098         if (*m != WILDS) {      /* Don't both if next=* */
00099           if (*n != ' ') {      /* WILDS can't match ' ' */
00100             lpm = m;
00101             lpn = n;            /* Save '%' fallback spot */
00102             saved += sofar;
00103             sofar = 0;          /* And save tally count */
00104           }
00105           continue;             /* Done with '%' */
00106         }
00107         /* FALL THROUGH */
00108       case WILDS:
00109         do
00110           m++;                  /* Zap redundant wilds */
00111         while ((*m == WILDS) || (*m == WILDP));
00112         lsm = m;
00113         lsn = n;
00114         lpm = 0;                /* Save '*' fallback spot */
00115         match += (saved + sofar);       /* Save tally count */
00116         saved = sofar = 0;
00117         continue;               /* Done with '*' */
00118       case WILDQ:
00119         m++;
00120         n++;
00121         continue;               /* Match one char */
00122       case QUOTE:
00123         m++;                    /* Handle quoting */
00124       }
00125       if (((!chgpoint || n < chgpoint) && !(*cmp1)(*m, *n)) ||
00126           (chgpoint && n >= chgpoint && !(*cmp2)(*m, *n))) { /* If matching */
00127         m++;
00128         n++;
00129         sofar++;
00130         continue;               /* Tally the match */
00131       }
00132 #ifdef WILDT
00133     }
00134 #endif
00135     if (lpm) {                  /* Try to fallback on '%' */
00136       n = ++lpn;
00137       m = lpm;
00138       sofar = 0;                /* Restore position */
00139       if ((*n | 32) == 32)
00140         lpm = 0;                /* Can't match 0 or ' ' */
00141       continue;                 /* Next char, please */
00142     }
00143     if (lsm) {                  /* Try to fallback on '*' */
00144       n = ++lsn;
00145       m = lsm;                  /* Restore position */
00146       saved = sofar = 0;
00147       continue;                 /* Next char, please */
00148     }
00149     return NOMATCH;             /* No fallbacks=No match */
00150   }
00151   while ((*m == WILDS) || (*m == WILDP))
00152     m++;                        /* Zap leftover %s & *s */
00153   return (*m) ? NOMATCH : PERMATCH;     /* End of both = match */
00154 }

int addr_match ( char *  m,
char *  n,
int  user,
int  cmp 
)

Definition at line 234 of file match.c.

References cidr_match(), cidr_support, NOMATCH, rfc_toupper, str_isdigit, UHOSTLEN, and wild_match.

00235 {
00236   char *p, *q, *r = 0, *s = 0;
00237   char mu[UHOSTLEN], nu[UHOSTLEN];
00238 
00239   /* copy the strings into our own buffers
00240      and convert to rfc uppercase */
00241   for (p = mu; *m && (p - mu < UHOSTLEN - 1); m++) {
00242     if (*m == '@')
00243       r = p;
00244     *p++ = rfc_toupper(*m);
00245   }
00246   for (q = nu; *n && (q - nu < UHOSTLEN - 1); n++) {
00247     if (*n == '@')
00248       s = q;
00249     *q++ = rfc_toupper(*n);
00250   }
00251   *p = *q = 0;
00252   if ((!user && !cidr_support) || !r || !s)
00253     return wild_match(mu, nu) ? 1 : NOMATCH;
00254 
00255   *r++ = *s++ = 0;
00256   if (!wild_match(mu, nu))
00257     return NOMATCH; /* nick!ident parts don't match */
00258   if (!*r && !*s)
00259     return 1; /* end of nonempty strings */
00260 
00261   /* check for CIDR notation and perform
00262      generic string matching if not found */
00263   if (!(p = strrchr(r, '/')) || !str_isdigit(p + 1))
00264     return wild_match(r, s) ? 1 : NOMATCH;
00265   /* if the two strings are both cidr masks,
00266      use the broader prefix */
00267   if (cmp && (q = strrchr(s, '/')) && str_isdigit(q + 1)) {
00268     if (atoi(p + 1) > atoi(q + 1))
00269       return NOMATCH;
00270     *q = 0;
00271   }
00272   *p = 0;
00273   /* looks like a cidr mask */
00274   return cidr_match(r, s, atoi(p + 1));
00275 }

Here is the call graph for this function:

int casecharcmp ( unsigned char  a,
unsigned char  b 
)

Definition at line 41 of file match.c.

References rfc_toupper.

00042 {
00043   return (rfc_toupper(a) - rfc_toupper(b));
00044 }

int charcmp ( unsigned char  a,
unsigned char  b 
)

Definition at line 46 of file match.c.

00047 {
00048   return (a - b);
00049 }

int cidr_match ( char *  m,
char *  n,
int  count 
)

Definition at line 328 of file match.c.

References NOMATCH.

Referenced by addr_match(), mask_match(), and tcl_matchcidr().

00329 {
00330 #ifdef IPV6
00331   int c, af = AF_INET;
00332   u_8bit_t block[16], addr[16];
00333 
00334   if (count < 1)
00335     return NOMATCH;
00336   if (strchr(m, ':') || strchr(n, ':')) {
00337     af = AF_INET6;
00338     if (count > 128)
00339       return NOMATCH;
00340   } else if (count > 32)
00341       return NOMATCH;
00342   if (inet_pton(af, m, &block) != 1 ||
00343       inet_pton(af, n, &addr) != 1)
00344     return NOMATCH;
00345   for (c = 0; c < (count / 8); c++)
00346     if (block[c] != addr[c])
00347       return NOMATCH;
00348   if (!(count % 8))
00349     return 1;
00350   count = 8 - (count % 8);
00351   return ((block[c] >> count) == (addr[c] >> count));
00352 
00353 #else
00354   IP block, addr;
00355 
00356   if (count < 1 || count > 32)
00357     return NOMATCH;
00358   block = ntohl(inet_addr(m));
00359   addr = ntohl(inet_addr(n));
00360   if (block == INADDR_NONE || addr == INADDR_NONE)
00361     return NOMATCH;
00362   count = 32 - count;
00363   return ((block >> count) == (addr >> count));
00364 #endif
00365 }

Here is the caller graph for this function:

int cron_match ( const char *  mask,
const char *  match 
)

Definition at line 420 of file match.c.

References cron_matchfld(), newsplit, nfree, and nmalloc.

00421 {
00422   int d = 0, i, m = 1, t[5];
00423   char *p, *q, *buf;
00424 
00425   if (!mask[0])
00426     return 0;
00427   if (sscanf(match, "%d %d %d %d %d",
00428              &t[0], &t[1], &t[2], &t[3], &t[4]) < 5)
00429     return 0;
00430   buf = nmalloc(strlen(mask) + 1);
00431   strcpy(buf, mask);
00432   for (p = buf, i = 0; *p && i < 5; i++) {
00433     q = newsplit(&p);
00434     if (!strcmp(q, "*"))
00435       continue;
00436     m = (cron_matchfld(q, t[i]) ||
00437         (i == 4 && !t[i] && cron_matchfld(q, 7)));
00438     if (i == 2)
00439       d = m;
00440     else if (!m || (i == 3 && d))
00441       break;
00442   }
00443   nfree(buf);
00444   return m;
00445 }

Here is the call graph for this function:

int cron_matchfld ( char *  mask,
int  match 
) [inline]

Definition at line 370 of file match.c.

Referenced by cron_match().

00371 {
00372   int skip = 0, f, t;
00373   char *p, *q;
00374 
00375   for (p = mask; mask && *mask; mask = p) {
00376     /* loop through a list of values, if such is given */
00377     if ((p = strchr(mask, ',')))
00378       *p++ = 0;
00379     /* check for the step operator */
00380     if ((q = strchr(mask, '/'))) {
00381       if (q == mask)
00382         continue;
00383       *q++ = 0;
00384       skip = atoi(q);
00385     }
00386     if (!strcmp(mask, "*") && (!skip || !(match % skip)))
00387       return 1;
00388     /* ranges, e.g 10-20 */
00389     if (strchr(mask, '-')) {
00390       if (sscanf(mask, "%d-%d", &f, &t) != 2)
00391         continue;
00392       if (t < f) {
00393         if (match <= t)
00394           match += 60;
00395         t += 60;
00396       }
00397       if ((match >= f && match <= t) &&
00398           (!skip || !((match - f) % skip)))
00399         return 1;
00400     }
00401     /* no operator found, should be exact match */
00402     f = strtol(mask, &q, 10);
00403     if ((q > mask) &&
00404         (skip ? !((match - f) % skip) : (match == f)))
00405       return 1;
00406   }
00407   return 0;
00408 }

Here is the caller graph for this function:

int mask_match ( char *  m,
char *  n 
)

Definition at line 280 of file match.c.

References cidr_match(), cidr_support, rfc_toupper, str_isdigit, UHOSTLEN, and wild_match.

00281 {
00282   int prefix;
00283   char *p, *q, *r = 0, *s = 0;
00284   char mu[UHOSTLEN], nu[UHOSTLEN];
00285 
00286   for (p = mu; *m && (p - mu < UHOSTLEN - 1); m++) {
00287     if (*m == '@')
00288       r = p;
00289     *p++ = rfc_toupper(*m);
00290   }
00291   for (q = nu; *n && (q - nu < UHOSTLEN - 1); n++) {
00292     if (*n == '@')
00293       s = q;
00294     *q++ = rfc_toupper(*n);
00295   }
00296   *p = *q = 0;
00297   if (!cidr_support || !r || !s)
00298     return (wild_match(mu, nu) || wild_match(nu, mu));
00299 
00300   *r++ = *s++ = 0;
00301   if (!wild_match(mu, nu) && !wild_match(nu, mu))
00302     return 0;
00303 
00304   if (!*r && !*s)
00305     return 1;
00306   p = strrchr(r, '/');
00307   q = strrchr(s, '/');
00308   if ((!p || !str_isdigit(p + 1)) && (!q || !str_isdigit(q + 1)))
00309     return (wild_match(r, s) || wild_match(s, r));
00310 
00311   if (p) {
00312     *p = 0;
00313     prefix = atoi(p + 1);
00314   } else
00315     prefix = (strchr(r, ':') ? 128 : 32);
00316   if (q) {
00317     *q = 0;
00318     if (atoi(q + 1) < prefix)
00319       prefix = atoi(q + 1);
00320   }
00321   return cidr_match(r, s, prefix);
00322 }

Here is the call graph for this function:


Variable Documentation

int cidr_support = 0

Definition at line 39 of file match.c.

Referenced by addr_match(), and mask_match().


Generated on 7 Sep 2016 for Eggdrop by  doxygen 1.6.1