00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "main.h"
00028
00029 #define QUOTE '\\'
00030 #define WILDS '*'
00031 #define WILDP '%'
00032 #define WILDQ '?'
00033 #define WILDT '~'
00034
00035 #define NOMATCH 0
00036 #define MATCH (match+sofar)
00037 #define PERMATCH (match+saved+sofar)
00038
00039 int cidr_support = 0;
00040
00041 int casecharcmp(unsigned char a, unsigned char b)
00042 {
00043 return (rfc_toupper(a) - rfc_toupper(b));
00044 }
00045
00046 int charcmp(unsigned char a, unsigned char b)
00047 {
00048 return (a - b);
00049 }
00050
00051
00052
00053
00054 int _wild_match_per(register unsigned char *m, register unsigned char *n,
00055 int (*cmp1)(unsigned char, unsigned char),
00056 int (*cmp2)(unsigned char, unsigned char),
00057 unsigned char *chgpoint)
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
00064 if ((m == 0) || (n == 0) || (!*n) || (!cmp1))
00065 return NOMATCH;
00066
00067 if (!cmp2)
00068 chgpoint = NULL;
00069
00070 while (*n) {
00071 if (*m == WILDT) {
00072 space = 0;
00073 do {
00074 m++;
00075 space++;
00076 }
00077 while ((*m == WILDT) || (*m == ' '));
00078 sofar += space;
00079 while (*n == ' ') {
00080 n++;
00081 space--;
00082 }
00083 if (space <= 0)
00084 continue;
00085 }
00086
00087 else {
00088 switch (*m) {
00089 case 0:
00090 do
00091 m--;
00092 while ((m > ma) && (*m == '?'));
00093 if ((m > ma) ? ((*m == '*') && (m[-1] != QUOTE)) : (*m == '*'))
00094 return PERMATCH;
00095 break;
00096 case WILDP:
00097 while (*(++m) == WILDP);
00098 if (*m != WILDS) {
00099 if (*n != ' ') {
00100 lpm = m;
00101 lpn = n;
00102 saved += sofar;
00103 sofar = 0;
00104 }
00105 continue;
00106 }
00107
00108 case WILDS:
00109 do
00110 m++;
00111 while ((*m == WILDS) || (*m == WILDP));
00112 lsm = m;
00113 lsn = n;
00114 lpm = 0;
00115 match += (saved + sofar);
00116 saved = sofar = 0;
00117 continue;
00118 case WILDQ:
00119 m++;
00120 n++;
00121 continue;
00122 case QUOTE:
00123 m++;
00124 }
00125 if (((!chgpoint || n < chgpoint) && !(*cmp1)(*m, *n)) ||
00126 (chgpoint && n >= chgpoint && !(*cmp2)(*m, *n))) {
00127 m++;
00128 n++;
00129 sofar++;
00130 continue;
00131 }
00132 #ifdef WILDT
00133 }
00134 #endif
00135 if (lpm) {
00136 n = ++lpn;
00137 m = lpm;
00138 sofar = 0;
00139 if ((*n | 32) == 32)
00140 lpm = 0;
00141 continue;
00142 }
00143 if (lsm) {
00144 n = ++lsn;
00145 m = lsm;
00146 saved = sofar = 0;
00147 continue;
00148 }
00149 return NOMATCH;
00150 }
00151 while ((*m == WILDS) || (*m == WILDP))
00152 m++;
00153 return (*m) ? NOMATCH : PERMATCH;
00154 }
00155
00156
00157 int _wild_match(register unsigned char *m, register unsigned char *n)
00158 {
00159 unsigned char *ma = m, *na = n, *lsm = 0, *lsn = 0;
00160 int match = 1;
00161 register int sofar = 0;
00162
00163
00164 if ((ma == 0) || (na == 0) || (!*ma) || (!*na))
00165 return NOMATCH;
00166
00167 while (*(++m));
00168 m--;
00169 while (*(++n));
00170 n--;
00171
00172 while (n >= na) {
00173
00174
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:
00189 do
00190 m--;
00191 while ((m >= ma) && (*m == WILDS));
00192 lsm = m;
00193 lsn = n;
00194 match += sofar;
00195 sofar = 0;
00196 if (m < ma)
00197 return MATCH;
00198 continue;
00199 case WILDQ:
00200 m--;
00201 n--;
00202 continue;
00203 }
00204 if (toupper(*m) == toupper(*n)) {
00205 m--;
00206 n--;
00207 sofar++;
00208 continue;
00209 }
00210 if (lsm) {
00211 n = --lsn;
00212 m = lsm;
00213 if (n < na)
00214 lsm = 0;
00215 sofar = 0;
00216 continue;
00217 }
00218 return NOMATCH;
00219 }
00220 while ((m >= ma) && (*m == WILDS))
00221 m--;
00222 return (m >= ma) ? NOMATCH : MATCH;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 int addr_match(char *m, char *n, int user, int cmp)
00235 {
00236 char *p, *q, *r = 0, *s = 0;
00237 char mu[UHOSTLEN], nu[UHOSTLEN];
00238
00239
00240
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;
00258 if (!*r && !*s)
00259 return 1;
00260
00261
00262
00263 if (!(p = strrchr(r, '/')) || !str_isdigit(p + 1))
00264 return wild_match(r, s) ? 1 : NOMATCH;
00265
00266
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
00274 return cidr_match(r, s, atoi(p + 1));
00275 }
00276
00277
00278
00279
00280 int mask_match(char *m, char *n)
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 }
00323
00324
00325
00326
00327
00328 int cidr_match(char *m, char *n, int count)
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 }
00366
00367
00368
00369
00370 inline int cron_matchfld(char *mask, int match)
00371 {
00372 int skip = 0, f, t;
00373 char *p, *q;
00374
00375 for (p = mask; mask && *mask; mask = p) {
00376
00377 if ((p = strchr(mask, ',')))
00378 *p++ = 0;
00379
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
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
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 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 int cron_match(const char *mask, const char *match)
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 }