00001 #ifndef USE_PCH
00002 #include "sys.h"
00003 #endif
00004
00005 #include "match.h"
00006 #include "ircd_chattr.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 int mmatch(char const* old_mask, char const* new_mask)
00031 {
00032 register char const* m = old_mask;
00033 register char const* n = new_mask;
00034 char const* ma = m;
00035 char const* na = n;
00036 int wild = 0;
00037 int mq = 0, nq = 0;
00038
00039 while (1)
00040 {
00041 if (*m == '*')
00042 {
00043 while (*m == '*')
00044 m++;
00045 wild = 1;
00046 ma = m;
00047 na = n;
00048 }
00049
00050 if (!*m)
00051 {
00052 if (!*n)
00053 return 0;
00054 for (m--; (m > old_mask) && (*m == '?'); m--)
00055 ;
00056 if ((*m == '*') && (m > old_mask) && (m[-1] != '\\'))
00057 return 0;
00058 if (!wild)
00059 return 1;
00060 m = ma;
00061
00062
00063 if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?')))
00064 ++na;
00065
00066 n = ++na;
00067 }
00068 else if (!*n)
00069 {
00070 while (*m == '*')
00071 m++;
00072 return (*m != 0);
00073 }
00074 if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
00075 {
00076 m++;
00077 mq = 1;
00078 }
00079 else
00080 mq = 0;
00081
00082
00083 if ((*n == '\\') && ((n[1] == '*') || (n[1] == '?')))
00084 {
00085 n++;
00086 nq = 1;
00087 }
00088 else
00089 nq = 0;
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 if ((*m == '*' && !mq) ||
00108 ((!mq || nq) && ToLower(*m) == ToLower(*n)) ||
00109 (*m == '?' && !mq && (*n != '*' || nq)))
00110 {
00111 if (*m)
00112 m++;
00113 if (*n)
00114 n++;
00115 }
00116 else
00117 {
00118 if (!wild)
00119 return 1;
00120 m = ma;
00121
00122
00123 if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?')))
00124 ++na;
00125
00126 n = ++na;
00127 }
00128 }
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 int match(char const* mask, char const* string)
00150 {
00151 register char const* m = mask, *s = string;
00152 register char ch;
00153 char const* bm, *bs;
00154
00155
00156 while ((ch = *m++) && (ch != '*'))
00157 switch (ch)
00158 {
00159 case '\\':
00160 if (*m == '?' || *m == '*')
00161 ch = *m++;
00162 default:
00163 if (ToLower(*s) != ToLower(ch))
00164 return 1;
00165 case '?':
00166 if (!*s++)
00167 return 1;
00168 };
00169 if (!ch)
00170 return *s;
00171
00172
00173 got_star:
00174 bm = m;
00175 while ((ch = *m++))
00176 switch (ch)
00177 {
00178 case '?':
00179 if (!*s++)
00180 return 1;
00181 case '*':
00182 bm = m;
00183 continue;
00184 case '\\':
00185 if (*m == '?' || *m == '*')
00186 ch = *m++;
00187 default:
00188 goto break_while;
00189 };
00190 break_while:
00191 if (!ch)
00192 return 0;
00193 ch = ToLower(ch);
00194 while (ToLower(*s++) != ch)
00195 if (!*s)
00196 return 1;
00197 bs = s;
00198
00199
00200 while ((ch = *m++))
00201 {
00202 switch (ch)
00203 {
00204 case '*':
00205 goto got_star;
00206 case '\\':
00207 if (*m == '?' || *m == '*')
00208 ch = *m++;
00209 default:
00210 if (ToLower(*s) != ToLower(ch))
00211 {
00212 m = bm;
00213 s = bs;
00214 goto got_star;
00215 };
00216 case '?':
00217 if (!*s++)
00218 return 1;
00219 };
00220 };
00221 if (*s)
00222 {
00223 m = bm;
00224 s = bs;
00225 goto got_star;
00226 };
00227 return 0;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 char* collapse(char* mask)
00242 {
00243 register int star = 0;
00244 register char* m = mask;
00245 register char* b;
00246
00247 if (m)
00248 {
00249 do
00250 {
00251 if ((*m == '*') && ((m[1] == '*') || (m[1] == '?')))
00252 {
00253 b = m;
00254 do
00255 {
00256 if (*m == '*')
00257 star = 1;
00258 else
00259 {
00260 if (star && (*m != '?'))
00261 {
00262 *b++ = '*';
00263 star = 0;
00264 };
00265 *b++ = *m;
00266 if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
00267 *b++ = *++m;
00268 };
00269 }
00270 while (*m++);
00271 break;
00272 }
00273 else
00274 {
00275 if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
00276 m++;
00277 };
00278 }
00279 while (*m++);
00280 };
00281 return mask;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 int matchcomp(char* cmask, int* minlen, int* charset, char const* mask)
00365 {
00366 char const* m = mask;
00367 char* b = cmask;
00368 char* fs = NULL;
00369 char* ls = NULL;
00370 char* x1, *x2;
00371 int l1, l2, lmin, loop, sign;
00372 int star = 0;
00373 int cnt = 0;
00374 char ch;
00375 int chset = ~0;
00376 int chset2 = (NTL_LOWER | NTL_UPPER);
00377
00378 if (m)
00379 while ((ch = *m++))
00380 switch (ch)
00381 {
00382 case '*':
00383 star = 1;
00384 break;
00385 case '?':
00386 cnt++;
00387 *b++ = 'A';
00388 chset2 &= ~NTL_LOWER;
00389 break;
00390 case '\\':
00391 if ((*m == '?') || (*m == '*'))
00392 ch = *m++;
00393 default:
00394 if (star)
00395 {
00396 ls = b;
00397 fs = fs ? fs : b;
00398 *b++ = 'Z';
00399 chset2 &= ~NTL_LOWER;
00400 star = 0;
00401 };
00402 cnt++;
00403 chset &= IRCD_CharAttrTab[((*b++ = ToLower(ch))) - std::numeric_limits<char>::min()];
00404 chset2 &= ~NTL_UPPER;
00405 };
00406
00407 if (charset)
00408 *charset = (chset | chset2);
00409
00410 if (star)
00411 {
00412 ls = b;
00413 fs = (fs ? fs : b);
00414 *b++ = 'Z';
00415 };
00416
00417 if (ls)
00418 {
00419 for (x1 = ls + 1, x2 = (b - 1); x1 < x2; x1++, x2--)
00420 {
00421 ch = *x1;
00422 *x1 = *x2;
00423 *x2 = ch;
00424 };
00425 l1 = (ls - fs);
00426 l2 = (b - ls);
00427 x1 = fs;
00428 while ((lmin = (l1 < l2) ? l1 : l2))
00429 {
00430 x2 = x1 + l1;
00431 for (loop = 0; loop < lmin; loop++)
00432 {
00433 ch = x1[loop];
00434 x1[loop] = x2[loop];
00435 x2[loop] = ch;
00436 };
00437 x1 += lmin;
00438 sign = l1 - l2;
00439 l1 -= (sign < 0) ? 0 : lmin;
00440 l2 -= (sign > 0) ? 0 : lmin;
00441 };
00442 };
00443
00444 *b = '\000';
00445 *minlen = cnt;
00446 return (b - cmask);
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 int matchexec(char const* string, size_t len, char const* cmask, int minlen)
00465 {
00466 char const* bs = string - 1;
00467 char const* s = string + len;
00468 char const* b = cmask - 1;
00469 int trash;
00470 char const* bb;
00471 char ch;
00472
00473 tryhead:
00474 while ((ToLower(*++bs) == *++b) && bs != s);
00475 if (bs == s)
00476 return ((*b != '\000') && ((*b++ != 'Z') || (*b != '\000')));
00477 if (*b != 'Z')
00478 {
00479 if (*b == 'A')
00480 goto tryhead;
00481 return 1;
00482 };
00483
00484 if ((trash = (len - minlen)) < 0)
00485 return 2;
00486
00487 trytail:
00488 while ((ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b
00489 && (ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b);
00490 if (*b != 'Z')
00491 {
00492 if (*b == 'A')
00493 goto trytail;
00494 return (*b != '\000');
00495 };
00496
00497 s = --bs;
00498 bb = b;
00499
00500 while ((ch = *++b))
00501 {
00502 while ((ToLower(*++s) != ch))
00503 if (--trash < 0)
00504 return 4;
00505 bs = s;
00506
00507 trychunk:
00508 while ((ToLower(*++s) == *++b) && *b);
00509 if (!*b)
00510 return 0;
00511 if (*b == 'Z')
00512 {
00513 bs = --s;
00514 bb = b;
00515 continue;
00516 };
00517 if (*b == 'A')
00518 goto trychunk;
00519
00520 b = bb;
00521 s = bs;
00522 if (--trash < 0)
00523 return 5;
00524 };
00525
00526 return 0;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 int matchdecomp(char* mask, char const* cmask)
00543 {
00544 register char* rtb = mask;
00545 register char const* rcm = cmask;
00546 register char const* begtail, *endtail;
00547
00548 if (rtb == NULL)
00549 return (-1);
00550
00551 if (rcm == NULL)
00552 return (-2);
00553
00554 for (; (*rcm != 'Z'); rcm++, rtb++)
00555 {
00556 if ((*rcm == '?') || (*rcm == '*'))
00557 *rtb++ = '\\';
00558 if (!((*rtb = ((*rcm == 'A') ? '?' : *rcm))))
00559 return (rtb - mask);
00560 };
00561
00562 begtail = rcm++;
00563 *rtb++ = '*';
00564
00565 while (*rcm && (*rcm != 'Z'))
00566 rcm++;
00567
00568 endtail = rcm;
00569
00570 if (*rcm)
00571 {
00572 while (*++rcm)
00573 switch (*rcm)
00574 {
00575 case 'A':
00576 *rtb++ = '?';
00577 break;
00578 case 'Z':
00579 *rtb++ = '*';
00580 break;
00581 case '*':
00582 case '?':
00583 *rtb++ = '\\';
00584 default:
00585 *rtb++ = *rcm;
00586 };
00587 *rtb++ = '*';
00588 };
00589
00590 for (rcm = endtail; (--rcm) > begtail; *rtb++ = ((*rcm == 'A') ? '?' : *rcm))
00591 if ((*rcm == '?') || (*rcm == '*'))
00592 *rtb++ = '\\';
00593
00594 *rtb = '\000';
00595 return (rtb - mask);
00596 }
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 int mmexec(char const* wcm, int wminlen, char const* rcm, int rminlen)
00614 {
00615 register char const* w, *r, *br, *bw, *rx, *rz;
00616 register int eat, trash;
00617
00618
00619 if ((trash = rminlen - wminlen) < 0)
00620 return 1;
00621 w = wcm;
00622 r = rcm;
00623 eat = 0;
00624
00625
00626
00627
00628
00629
00630 for (; (*r) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); r++, w++);
00631 if (*r == 'Z')
00632 while (*w == 'A')
00633 w++, eat++;
00634 if (*w != 'Z')
00635 return ((*w) || (*r)) ? 1 : 0;
00636 if (!*++w)
00637 return 0;
00638
00639
00640 for (rx = r; *r && (*r != 'Z'); r++);
00641 if (!*r)
00642 {
00643
00644
00645
00646
00647 if (*w != 'Z')
00648 {
00649 for (; r--, (*w) && ((*w == *r) || (*w == 'A')); w++);
00650 if (*w != 'Z')
00651 return (*w) ? 1 : 0;
00652 };
00653
00654
00655 while (1)
00656 {
00657
00658 for (bw = w++; (*w != *rx); rx++)
00659 if (--trash < 0)
00660 return 1;
00661 for (r = ++rx, w++; (*w) && ((*w == *r) || (*w == 'A')); r++, w++);
00662 if (!*w)
00663 return 0;
00664 if (*w != 'Z')
00665 {
00666 w = bw;
00667 if (--trash < 0)
00668 return 1;
00669 }
00670 else
00671 {
00672 rx = r;
00673 };
00674 };
00675 };
00676
00677
00678 rz = r++;
00679
00680
00681 if (*w != 'Z')
00682 {
00683 for (; (*w) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); w++, r++);
00684 if (*r == 'Z')
00685 while (*w == 'A')
00686 w++;
00687 if (*w != 'Z')
00688 return (*w) ? 1 : 0;
00689 };
00690
00691
00692 while (1)
00693 {
00694 bw = w;
00695 for (bw++; (rx < rz) && (*bw != *rx); rx++)
00696 if (--trash < 0)
00697 return 1;
00698 if (!(rx < rz))
00699 break;
00700 for (bw++, (br = ++rx);
00701 (br < rz) && (*bw) && ((*bw == *br) || (*bw == 'A')); br++, bw++);
00702 if (!(br < rz))
00703 while (*bw == 'A')
00704 bw++, eat++;
00705 if (!*bw)
00706 return 0;
00707 if (*bw != 'Z')
00708 {
00709 eat = 0;
00710 if (!(br < rz))
00711 {
00712 trash -= (br - rx);
00713 if (--trash < 0)
00714 return 1;
00715 break;
00716 };
00717 if (--trash < 0)
00718 return 1;
00719 }
00720 else
00721 {
00722 w = bw;
00723 rx = br;
00724 };
00725 };
00726
00727
00728 rx = r;
00729 for (; *r && (*r != 'Z'); r++);
00730 rz = r;
00731 if (*r++)
00732 {
00733 while (*r)
00734 {
00735 bw = w;
00736 while (eat && *r)
00737 if (*r++ != 'Z')
00738 eat--;
00739 for (bw++; (*r) && (*bw != *r); r++)
00740 if ((*r != 'Z') && (--trash < 0))
00741 return 1;
00742 if (!*r)
00743 break;
00744 for ((br = ++r), bw++;
00745 (*br) && (*br != 'Z') && ((*bw == *br) || (*bw == 'A')); br++, bw++);
00746 if (*br == 'Z')
00747 while (*bw == 'A')
00748 bw++, eat++;
00749 if (!*bw)
00750 return 0;
00751 if (*bw != 'Z')
00752 {
00753 eat = 0;
00754 if ((!*br) || (*r == 'Z'))
00755 {
00756 trash -= (br - r);
00757 if (trash < 0)
00758 return 1;
00759 if (!*br)
00760 break;
00761 r = br;
00762 };
00763 if (--trash < 0)
00764 return 1;
00765 }
00766 else
00767 {
00768 r = br;
00769 w = bw;
00770 };
00771 };
00772 };
00773
00774
00775 r = rz - eat - 1;
00776 while (r >= rx)
00777 {
00778 bw = w;
00779 for (bw++; (*bw != *r); r--)
00780 if (--trash < 0)
00781 return 1;
00782 if (!(r >= rx))
00783 return 1;
00784 for ((br = --r), bw++;
00785 (*bw) && (br >= rx) && ((*bw == *br) || (*bw == 'A')); br--, bw++);
00786 if (!*bw)
00787 return 0;
00788 if (!(br >= rx))
00789 return 1;
00790 if (*bw != 'Z')
00791 {
00792 if (--trash < 0)
00793 return 1;
00794 }
00795 else
00796 {
00797 r = br;
00798 w = bw;
00799 };
00800 };
00801 return 1;
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 int matchcompIP(in_mask* imask, char const* mask)
00852 {
00853 register char const* m = mask;
00854 register unsigned int bits = 0;
00855 register unsigned int filt = 0;
00856 register int unco = 0;
00857 register int digits = 0;
00858 register int shift = 24;
00859 register int tmp = 0;
00860
00861 do
00862 {
00863 switch (*m)
00864 {
00865 case '\\':
00866 if ((m[1] == '\\') || (m[1] == '*') || (m[1] == '?')
00867 || (m[1] == '\000'))
00868 break;
00869 continue;
00870 case '0':
00871 case '1':
00872 case '2':
00873 case '3':
00874 case '4':
00875 case '5':
00876 case '6':
00877 case '7':
00878 case '8':
00879 case '9':
00880 if (digits && !tmp)
00881 break;
00882 digits++;
00883 tmp *= 10;
00884 tmp += (*m - '0');
00885 if (tmp > 255)
00886 break;
00887 continue;
00888 case '\000':
00889 filt = 0xFFFFFFFF;
00890
00891 case '.':
00892 if ((!shift) != (!*m))
00893 break;
00894
00895 case '/':
00896 bits |= (tmp << shift);
00897 shift -= 8;
00898 digits = 0;
00899 tmp = 0;
00900 if (*m != '/')
00901 continue;
00902 shift = 24;
00903 do
00904 {
00905 m++;
00906 if (IsDigit(*m))
00907 {
00908 if (digits && !tmp)
00909 break;
00910 digits++;
00911 tmp *= 10;
00912 tmp += (*m - '0');
00913 if (tmp > 255)
00914 break;
00915 }
00916 else
00917 {
00918 switch (*m)
00919 {
00920 case '.':
00921 case '\000':
00922 if ((!shift) && (*m))
00923 break;
00924 filt |= (tmp << shift);
00925 shift -= 8;
00926 tmp = 0;
00927 digits = 0;
00928 continue;
00929 default:
00930 break;
00931 }
00932 break;
00933 }
00934 }
00935 while (*m);
00936 if (*m)
00937 break;
00938 if (filt && (!(shift < 16)) && (!(filt & 0xE0FFFFFF)))
00939 filt = 0xFFFFFFFF << (32 - ((filt >> 24)));
00940 bits &= filt;
00941 continue;
00942 case '?':
00943 unco = 1;
00944
00945 case '*':
00946 if (digits)
00947 unco = 1;
00948 filt = (0xFFFFFFFF << (shift)) << 8;
00949 while (*++m)
00950 {
00951 if (IsDigit(*m))
00952 unco = 1;
00953 else
00954 {
00955 switch (*m)
00956 {
00957 case '.':
00958 if (m[1] != '*')
00959 unco = 1;
00960 if (!shift)
00961 break;
00962 shift -= 8;
00963 continue;
00964 case '?':
00965 unco = 1;
00966 case '*':
00967 continue;
00968 default:
00969 break;
00970 }
00971 break;
00972 }
00973 }
00974 if (*m)
00975 break;
00976 continue;
00977 default:
00978 break;
00979 }
00980
00981
00982 filt = 0;
00983 bits = ~0;
00984 unco = 0;
00985 break;
00986
00987 }
00988 while (*m++);
00989
00990 imask->bits.s_addr = htonl(bits);
00991 imask->mask.s_addr = htonl(filt);
00992 imask->fall = unco;
00993 return ((bits & ~filt) ? -1 : 0);
00994 }