#include "main.h"
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 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().
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 }
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 | |||
) |
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 }
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 }
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 }
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 }
int cidr_support = 0 |
Definition at line 39 of file match.c.
Referenced by addr_match(), and mask_match().