Apply minor fixes from patches@, SF tracker, and others.
[ircu2.10.12-pk.git] / ircd / match.c
1 /*
2  * IRC - Internet Relay Chat, common/match.c
3  * Copyright (C) 1990 Jarkko Oikarinen
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 1, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  * $Id$
20  */
21 #include "config.h"
22
23 #include "match.h"
24 #include "ircd_chattr.h"
25 /*
26  * mmatch()
27  *
28  * Written by Run (carlo@runaway.xs4all.nl), 25-10-96
29  *
30  *
31  * From: Carlo Wood <carlo@runaway.xs4all.nl>
32  * Message-Id: <199609021026.MAA02393@runaway.xs4all.nl>
33  * Subject: [C-Com] Analysis for `mmatch' (was: gline4 problem)
34  * To: coder-com@mail.undernet.org (coder committee)
35  * Date: Mon, 2 Sep 1996 12:26:01 +0200 (MET DST)
36  *
37  * We need a new function `mmatch(const char *old_mask, const char *new_mask)'
38  * which returns `true' likewise the current `match' (start with copying it),
39  * but which treats '*' and '?' in `new_mask' differently (not "\*" and "\?" !)
40  * as follows:  a '*' in `new_mask' does not match a '?' in `old_mask' and
41  * a '?' in `new_mask' does not match a '\?' in `old_mask'.
42  * And ofcourse... a '*' in `new_mask' does not match a '\*' in `old_mask'...
43  * And last but not least, '\?' and '\*' in `new_mask' now become one character.
44  */
45
46 int mmatch(const char *old_mask, const char *new_mask)
47 {
48   const char *m = old_mask;
49   const char *n = new_mask;
50   const char *ma = m;
51   const char *na = n;
52   int wild = 0;
53   int mq = 0, nq = 0;
54
55   while (1)
56   {
57     if (*m == '*')
58     {
59       while (*m == '*')
60         m++;
61       wild = 1;
62       ma = m;
63       na = n;
64     }
65
66     if (!*m)
67     {
68       if (!*n)
69         return 0;
70       for (m--; (m > old_mask) && (*m == '?'); m--)
71         ;
72       if ((*m == '*') && (m > old_mask) && (m[-1] != '\\'))
73         return 0;
74       if (!wild)
75         return 1;
76       m = ma;
77
78       /* Added to `mmatch' : Because '\?' and '\*' now is one character: */
79       if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?')))
80         ++na;
81
82       n = ++na;
83     }
84     else if (!*n)
85     {
86       while (*m == '*')
87         m++;
88       return (*m != 0);
89     }
90     if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
91     {
92       m++;
93       mq = 1;
94     }
95     else
96       mq = 0;
97
98     /* Added to `mmatch' : Because '\?' and '\*' now is one character: */
99     if ((*n == '\\') && ((n[1] == '*') || (n[1] == '?')))
100     {
101       n++;
102       nq = 1;
103     }
104     else
105       nq = 0;
106
107 /*
108  * This `if' has been changed compared to match() to do the following:
109  * Match when:
110  *   old (m)         new (n)         boolean expression
111  *    *               any             (*m == '*' && !mq) ||
112  *    ?               any except '*'  (*m == '?' && !mq && (*n != '*' || nq)) ||
113  * any except * or ?  same as m       (!((*m == '*' || *m == '?') && !mq) &&
114  *                                      ToLower(*m) == ToLower(*n) &&
115  *                                        !((mq && !nq) || (!mq && nq)))
116  *
117  * Here `any' also includes \* and \? !
118  *
119  * After reworking the boolean expressions, we get:
120  * (Optimized to use boolean shortcircuits, with most frequently occuring
121  *  cases upfront (which took 2 hours!)).
122  */
123     if ((*m == '*' && !mq) ||
124         ((!mq || nq) && ToLower(*m) == ToLower(*n)) ||
125         (*m == '?' && !mq && (*n != '*' || nq)))
126     {
127       if (*m)
128         m++;
129       if (*n)
130         n++;
131     }
132     else
133     {
134       if (!wild)
135         return 1;
136       m = ma;
137
138       /* Added to `mmatch' : Because '\?' and '\*' now is one character: */
139       if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?')))
140         ++na;
141
142       n = ++na;
143     }
144   }
145 }
146
147 /*
148  * Compare if a given string (name) matches the given
149  * mask (which can contain wild cards: '*' - match any
150  * number of chars, '?' - match any single character.
151  *
152  * return  0, if match
153  *         1, if no match
154  *
155  *  Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
156  *  Rewritten by Timothy Vogelsang (netski), net@astrolink.org
157  */
158
159 int match(const char *mask, const char *name)
160 {
161   const char *m = mask, *n = name;
162   const char *m_tmp = mask, *n_tmp = name;
163   int wild = 0;
164
165   for (;;)
166   {
167     if (*m == '*') {
168       while (*m == '*')  /* clean up any additional wildcards */
169         m++;
170
171       m_tmp = m;
172       n_tmp = n;
173       wild = 1;
174     }
175     if (*m == '\\')  /* next wildcard is disregarded */
176       m++;
177
178     if (!*m) {
179       if (!*n)
180         return 0;  /* match */
181
182       for (m--; (m > mask) && (*m == '?'); m--);
183         ;
184
185       if (*m == '*' && (m > mask))
186         return 0;  /* match */
187
188       if (!wild)
189         return 1;
190
191       m = m_tmp;
192       n = ++n_tmp;
193     }
194     else if (!*n) {
195       while (*m == '*')  /* clean up any additional wildcards */
196         m++;
197
198       return (*m != 0);
199     }
200     if (ToLower(*m) != ToLower(*n) && *m != '?') {
201       if (!wild)
202         return 1;  /* failure! */
203
204       m = m_tmp;
205       n = ++n_tmp;
206     }
207     else {
208       if (*m)
209         m++;
210       if (*n)
211         n++;
212     }
213   }
214
215   return 1;  /* no match! */
216 }
217
218 /*
219  * collapse()
220  * Collapse a pattern string into minimal components.
221  * This particular version is "in place", so that it changes the pattern
222  * which is to be reduced to a "minimal" size.
223  *
224  * (C) Carlo Wood - 6 Oct 1998
225  * Speedup rewrite by Andrea Cocito, December 1998.
226  * Note that this new optimized alghoritm can *only* work in place.
227  */
228
229 char *collapse(char *mask)
230 {
231   int star = 0;
232   char *m = mask;
233   char *b;
234
235   if (m)
236   {
237     do
238     {
239       if ((*m == '*') && ((m[1] == '*') || (m[1] == '?')))
240       {
241         b = m;
242         do
243         {
244           if (*m == '*')
245             star = 1;
246           else
247           {
248             if (star && (*m != '?'))
249             {
250               *b++ = '*';
251               star = 0;
252             };
253             *b++ = *m;
254             if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
255               *b++ = *++m;
256           };
257         }
258         while (*m++);
259         break;
260       }
261       else
262       {
263         if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
264           m++;
265       };
266     }
267     while (*m++);
268   };
269   return mask;
270 }
271
272 /*
273  ***************** Nemesi's matchcomp() / matchexec() **************
274  */
275
276 /* These functions allow the use of "compiled" masks, you compile a mask
277  * by means of matchcomp() that gets the plain text mask as input and writes
278  * its result in the memory locations addressed by the 3 parameters:
279  * - *cmask will contain the text of the compiled mask
280  * - *minlen will contain the lenght of the shortest string that can match 
281  *   the mask
282  * - *charset will contain the minimal set of chars needed to match the mask
283  * You can pass NULL as *charset and it will be simply not returned, but you
284  * MUST pass valid pointers for *minlen and *cmask (wich must be big enough 
285  * to contain the compiled mask text that is in the worst case as long as the 
286  * text of the mask itself in plaintext format) and the return value of 
287  * matchcomp() will be the number of chars actually written there (excluded 
288  * the trailing zero). cmask can be == mask, matchcomp() can work in place.
289  * The {cmask, minlen} couple of values make the real compiled mask and
290  * need to be passed to the functions that use the compiled mask, if you pass
291  * the wrong minlen or something wrong in cmask to one of these expect a
292  * coredump. This means that when you record a compiled mask you must store
293  * *both* these values.
294  * Once compiled the mask can be used to match a string by means of 
295  * matchexec(), it can be printed back to human-readable format by means
296  * of sprintmatch() or it can be compared to another compiled mask by means
297  * of mmexec() that will tell if it completely overrides that mask (a lot like
298  * what mmatch() does for plain text masks).
299  * You can gain a lot of speed in many situations avoiding to matchexec() when:
300  * - The maximum lenght of the field you are about to match() the mask to is
301  *   shorter than minlen, in example when matching abc*def*ghil with a nick:
302  *   It just cannot match since a nick is at most 9 chars long and the mask
303  *   needs at least 10 chars (10 will be the value returned in minlen).
304  * - The charset allowed for the field you are about to match to doesn't
305  *   "contain" the charset returned by matchcomp(), in example when you
306  *   have *.* as mask it makes no sense to try to match it against a nick
307  *   because, again, a nick can't contain a '.', you can check this with
308  *   a simple (charset & NTL_IRCNK) in this case.
309  * - As a special case, since compiled masks are forced to lowercase,
310  *   it would make no sense to use the NTL_LOWER and NTL_UPPER on a compiled
311  *   mask, thus they are reused as follows: if the NTL_LOWER bit of charset
312  *   is set it means that the mask contains only non-wilds chars (i.e. you can
313  *   use strCasecmp() to match it or a direct hash lookup), if the NTL_UPPER
314  *   bit is set it means that it contains only wild chars (and you can
315  *   match it with strlen(field)>=minlen).
316  * Do these optimizations ONLY when the data you are about to pass to
317  * matchexec() are *known* to be invalid in advance, using strChattr() 
318  * or strlen() on the text would be slower than calling matchexec() directly
319  * and let it fail.
320  * Internally a compiled mask contain in the *cmask area the text of
321  * the plain text form of the mask itself with applied the following hacks:
322  * - All characters are forced to lowercase (so that uppercase letters and
323  *   specifically the symbols 'A' and 'Z' are reserved for special use)
324  * - All non-escaped stars '*' are replaced by the letter 'Z'
325  * - All non-escaped question marks '?' are replaced by the letter 'A' 
326  * - All escape characters are removed, the wilds escaped by them are
327  *   then passed by without the escape since they don't collide anymore
328  *   with the real wilds (encoded as A/Z) 
329  * - Finally the part of the mask that follows the last asterisk is
330  *   reversed (byte order mirroring) and moved right after the first
331  *   asterisk.
332  * After all this a mask like:   Head*CHUNK1*chu\*nK2*ch??k3*TaIl 
333  *               .... becomes:   headZliatZchunk1Zchu*nk2ZchAAk3
334  * This can still be printed on a console, more or less understood by an
335  * human and handled with the usual str*() library functions.
336  * When you store somewhere the compiled mask you can avoid storing the
337  * textform of it since it can be "decompiled" by means of sprintmatch(),
338  * but at that time the following things are changed in the mask:
339  * - All chars have been forced to lowercase.
340  * - The mask is collapsed.
341  * The balance point of using compiled masks in terms of CPU is when you expect
342  * to use matchexec() instead of match() at least 20 times on the same mask
343  * or when you expect to use mmexec() instead of mmatch() 3 times.
344  */
345
346  /* 
347     * matchcomp()
348     *
349     * Compiles a mask into a form suitable for using in matchexec().
350   */
351
352 int matchcomp(char *cmask, int *minlen, int *charset, const char *mask)
353 {
354   const char *m = mask;
355   char *b = cmask;
356   char *fs = 0;
357   char *ls = 0;
358   char *x1, *x2;
359   int l1, l2, lmin, loop, sign;
360   int star = 0;
361   int cnt = 0;
362   char ch;
363   int chset = ~0;
364   int chset2 = (NTL_LOWER | NTL_UPPER);
365
366   if (m)
367     while ((ch = *m++))
368       switch (ch)
369       {
370         case '*':
371           star = 1;
372           break;
373         case '?':
374           cnt++;
375           *b++ = 'A';
376           chset2 &= ~NTL_LOWER;
377           break;
378         case '\\':
379           if ((*m == '?') || (*m == '*'))
380             ch = *m++;
381         default:
382           if (star)
383           {
384             ls = b;
385             fs = fs ? fs : b;
386             *b++ = 'Z';
387             chset2 &= ~NTL_LOWER;
388             star = 0;
389           };
390           cnt++;
391           *b = ToLower(ch);
392           chset &= IRCD_CharAttrTab[*b++ - CHAR_MIN];
393           chset2 &= ~NTL_UPPER;
394       };
395
396   if (charset)
397     *charset = (chset | chset2);
398
399   if (star)
400   {
401     ls = b;
402     fs = (fs ? fs : b);
403     *b++ = 'Z';
404   };
405
406   if (ls)
407   {
408     for (x1 = ls + 1, x2 = (b - 1); x1 < x2; x1++, x2--)
409     {
410       ch = *x1;
411       *x1 = *x2;
412       *x2 = ch;
413     };
414     l1 = (ls - fs);
415     l2 = (b - ls);
416     x1 = fs;
417     while ((lmin = (l1 < l2) ? l1 : l2))
418     {
419       x2 = x1 + l1;
420       for (loop = 0; loop < lmin; loop++)
421       {
422         ch = x1[loop];
423         x1[loop] = x2[loop];
424         x2[loop] = ch;
425       };
426       x1 += lmin;
427       sign = l1 - l2;
428       l1 -= (sign < 0) ? 0 : lmin;
429       l2 -= (sign > 0) ? 0 : lmin;
430     };
431   };
432
433   *b = '\0';
434   *minlen = cnt;
435   return (b - cmask);
436
437 }
438
439 /*
440  * matchexec()
441  *
442  * Executes a match with a mask previosuly compiled with matchcomp()
443  * Note 1: If the mask isn't correctly produced by matchcomp() I will core
444  * Note 2: 'min' MUST be the value returned by matchcomp on that mask,
445  *         or.... I will core even faster :-)
446  * Note 3: This piece of code is not intended to be nice but efficient.
447  */
448
449 int matchexec(const char *string, const char *cmask, int minlen)
450 {
451   const char *s = string - 1;
452   const char *b = cmask - 1;
453   int trash;
454   const char *bb, *bs;
455   char ch;
456
457 tryhead:
458   while ((ToLower(*++s) == *++b) && *s);
459   if (!*s)
460     return ((*b != '\0') && ((*b++ != 'Z') || (*b != '\0')));
461   if (*b != 'Z')
462   {
463     if (*b == 'A')
464       goto tryhead;
465     return 1;
466   };
467
468   bs = s;
469   while (*++s);
470
471   if ((trash = (s - string - minlen)) < 0)
472     return 2;
473
474 trytail:
475   while ((ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b
476       && (ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b);
477   if (*b != 'Z')
478   {
479     if (*b == 'A')
480       goto trytail;
481     return (*b != '\0');
482   };
483
484   s = --bs;
485   bb = b;
486
487   while ((ch = *++b))
488   {
489     while ((ToLower(*++s) != ch))
490       if (--trash < 0)
491         return 4;
492     bs = s;
493
494 trychunk:
495     while ((ToLower(*++s) == *++b) && *b);
496     if (!*b)
497       return 0;
498     if (*b == 'Z')
499     {
500       bs = --s;
501       bb = b;
502       continue;
503     };
504     if (*b == 'A')
505       goto trychunk;
506
507     b = bb;
508     s = bs;
509     if (--trash < 0)
510       return 5;
511   };
512
513   return 0;
514 }
515
516 /*
517  * matchdecomp()
518  * Prints the human readable version of *cmask into *mask, (decompiles
519  * cmask).
520  * The area pointed by *mask MUST be big enough (the mask might be up to
521  * twice the size of its compiled form if it's made all of \? or \*, and
522  * this function can NOT work in place since it might enflate the mask)
523  * The printed mask is not identical to the one that was compiled to cmask,
524  * infact it is 1) forced to all lowercase, 2) collapsed, both things
525  * are supposed to NOT change it's meaning.
526  * It returns the number of chars actually written to *mask;
527  */
528
529 int matchdecomp(char *mask, const char *cmask)
530 {
531   char *rtb = mask;
532   const char *rcm = cmask;
533   const char *begtail, *endtail;
534
535   if (rtb ==0)
536     return (-1);
537
538   if (rcm == 0)
539     return (-2);
540
541   for (; (*rcm != 'Z'); rcm++, rtb++)
542   {
543     if ((*rcm == '?') || (*rcm == '*'))
544       *rtb++ = '\\';
545     if (!((*rtb = ((*rcm == 'A') ? '?' : *rcm))))
546       return (rtb - mask);
547   };
548
549   begtail = rcm++;
550   *rtb++ = '*';
551
552   while (*rcm && (*rcm != 'Z'))
553     rcm++;
554
555   endtail = rcm;
556
557   if (*rcm)
558   {
559     while (*++rcm)
560       switch (*rcm)
561       {
562         case 'A':
563           *rtb++ = '?';
564           break;
565         case 'Z':
566           *rtb++ = '*';
567           break;
568         case '*':
569         case '?':
570           *rtb++ = '\\';
571         default:
572           *rtb++ = *rcm;
573       };
574     *rtb++ = '*';
575   };
576
577   for (rcm = endtail; (--rcm) > begtail; *rtb++ = ((*rcm == 'A') ? '?' : *rcm))
578     if ((*rcm == '?') || (*rcm == '*'))
579       *rtb++ = '\\';
580
581   *rtb = '\0';
582   return (rtb - mask);
583 }
584
585 /*
586  * mmexec()
587  * Checks if a wider compiled mask (wcm/wminlen) completely overrides
588  * a more restrict one (rcm/rminlen), basically what mmatch() does for
589  * non-compiled masks, returns 0 if the override is true (like mmatch()).
590  * "the wider overrides the restrict" means that any string that matches
591  * the restrict one _will_ also match the wider one, always. 
592  * In this we behave differently from mmatch() because in example we return 
593  * true for " a?*cd overrides a*bcd " for wich the override happens for how 
594  * we literally defined it, here mmatch() would have returned false.
595  * The original concepts and the base alghoritm are copied from mmatch() 
596  * written by Run (Carlo Wood), this function is written by
597  * Nemesi (Andrea Cocito)
598  */
599
600 int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen)
601 {
602   const char *w, *r, *br, *bw, *rx, *rz;
603   int eat, trash;
604
605   /* First of all rm must have enough non-stars to 'contain' wm */
606   if ((trash = rminlen - wminlen) < 0)
607     return 1;
608   w = wcm;
609   r = rcm;
610   eat = 0;
611
612   /* Let's start the game, remember that '*' is mapped to 'Z', '?'
613      is mapped to 'A' and that head?*??*?chunk*???*tail becomes
614      headAAAAZliatAAAZchunk for compiled masks */
615
616   /* Match the head of wm with the head of rm */
617   for (; (*r) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); r++, w++);
618   if (*r == 'Z')
619     while (*w == 'A')           /* Eat extra '?' before '*' in wm if got '*' in rm */
620       w++, eat++;
621   if (*w != 'Z')                /* head1<any>.. can't match head2<any>.. */
622     return ((*w) || (*r)) ? 1 : 0;      /* and head<nul> matches only head<nul> */
623   if (!*++w)
624     return 0;                   /* headZ<nul> matches head<anything>    */
625
626   /* Does rm have any stars in it ? let's check */
627   for (rx = r; *r && (*r != 'Z'); r++);
628   if (!*r)
629   {
630     /* rm has no stars and thus isn't a mask but it's just a flat
631        string: special handling occurs here, note that eat must be 0 here */
632
633     /* match the tail */
634     if (*w != 'Z')
635     {
636       for (; r--, (*w) && ((*w == *r) || (*w == 'A')); w++);
637       if (*w != 'Z')            /* headZliat1<any> fails on head<any>2tail  */
638         return (*w) ? 1 : 0;    /* but headZliat<nul> matches head<any>tail */
639     }
640
641     /* match the chunks */
642     while (1)
643     {                           /* This loop can't break but only return   */
644
645       for (bw = w++; (*w != *rx); rx++) /* Seek the 1st char of the chunk */
646         if (--trash < 0)        /* See if we can trash one more char of rm */
647           return 1;             /* If not we can only fail of course       */
648       for (r = ++rx, w++; (*w) && ((*w == *r) || (*w == 'A')); r++, w++);
649       if (!*w)                  /* Did last loop match the rest of chunk ? */
650         return 0;               /* ... Yes, end of wm, matched !           */
651       if (*w != 'Z')
652       {                         /* ... No, hitted non-star                 */
653         w = bw;                 /* Rollback at beginning of chunk          */
654         if (--trash < 0)        /* Trashed the char where this try started */
655           return 1;             /* if we can't trash more chars fail       */
656       }
657       else
658       {
659         rx = r;                 /* Successfully matched a chunk, move rx   */
660       }                 /* and go on with the next one             */
661     }
662   }
663
664   /* rm has at least one '*' and thus is a 'real' mask */
665   rz = r++;                     /* rx = unused of head, rz = beg-tail */
666
667   /* Match the tail of wm (if any) against the tail of rm */
668   if (*w != 'Z')
669   {
670     for (; (*w) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); w++, r++);
671     if (*r == 'Z')              /* extra '?' before tail are fluff, just flush 'em */
672       while (*w == 'A')
673         w++;
674     if (*w != 'Z')              /* We aren't matching a chunk, can't rollback      */
675       return (*w) ? 1 : 0;
676   }
677
678   /* Match the chunks of wm against what remains of the head of rm */
679   while (1)
680   {
681     bw = w;
682     for (bw++; (rx < rz) && (*bw != *rx); rx++) /* Seek the first           */
683       if (--trash < 0)          /* waste some trash reserve */
684         return 1;
685     if (!(rx < rz))             /* head finished            */
686       break;
687     for (bw++, (br = ++rx);
688         (br < rz) && (*bw) && ((*bw == *br) || (*bw == 'A')); br++, bw++);
689     if (!(br < rz))             /* Note that we didn't use any 'eat' char yet, if  */
690       while (*bw == 'A')        /* there were eat-en chars the head would be over  */
691         bw++, eat++;            /* Happens only at end of head, and eat is still 0 */
692     if (!*bw)
693       return 0;
694     if (*bw != 'Z')
695     {
696       eat = 0;
697       if (!(br < rz))
698       {                         /* If we failed because we got the end of head */
699         trash -= (br - rx);     /* it makes no sense to rollback, just trash   */
700         if (--trash < 0)        /* all the rest of the head wich isn't long    */
701           return 1;             /* enough for this chunk and go out of this    */
702         break;                  /* loop, then we try with the chunks of rm     */
703       };
704       if (--trash < 0)
705         return 1;
706     }
707     else
708     {
709       w = bw;
710       rx = br;
711     }
712   }
713
714   /* Match the unused chunks of wm against the chunks of rm */
715   rx = r;
716   for (; *r && (*r != 'Z'); r++);
717   rz = r;
718   if (*r++)
719   {
720     while (*r)
721     {
722       bw = w;
723       while (eat && *r)         /* the '?' we had eated make us skip as many chars */
724         if (*r++ != 'Z')        /* here, but can't skip stars or trailing zero     */
725           eat--;
726       for (bw++; (*r) && (*bw != *r); r++)
727         if ((*r != 'Z') && (--trash < 0))
728           return 1;
729       if (!*r)
730         break;
731       for ((br = ++r), bw++;
732           (*br) && (*br != 'Z') && ((*bw == *br) || (*bw == 'A')); br++, bw++);
733       if (*br == 'Z')
734         while (*bw == 'A')
735           bw++, eat++;
736       if (!*bw)
737         return 0;
738       if (*bw != 'Z')
739       {
740         eat = 0;
741         if ((!*br) || (*r == 'Z'))
742         {                       /* If we hit the end of rm or a star in it */
743           trash -= (br - r);    /* makes no sense to rollback within this  */
744           if (trash < 0)        /* same chunk of br, skip it all and then  */
745             return 1;           /* either rollback or break this loop if   */
746           if (!*br)             /* it was the end of rm                    */
747             break;
748           r = br;
749         }
750         if (--trash < 0)
751           return 1;
752       }
753       else
754       {
755         r = br;
756         w = bw;
757       }
758     }
759   }
760
761   /* match the remaining chunks of wm against what remains of the tail of rm */
762   r = rz - eat - 1;             /* can't have <nul> or 'Z'within the tail, so just move r */
763   while (r >= rx)
764   {
765     bw = w;
766     for (bw++; (*bw != *r); r--)
767       if (--trash < 0)
768         return 1;
769     if (!(r >= rx))
770       return 1;
771     for ((br = --r), bw++;
772         (*bw) && (br >= rx) && ((*bw == *br) || (*bw == 'A')); br--, bw++);
773     if (!*bw)
774       return 0;
775     if (!(br >= rx))
776       return 1;
777     if (*bw != 'Z')
778     {
779       if (--trash < 0)
780         return 1;
781     }
782     else
783     {
784       r = br;
785       w = bw;
786     }
787   }
788   return 1;                     /* Auch... something left out ? Fail */
789 }
790
791 /*
792  * matchcompIP()
793  * Compiles an IP mask into an in_mask structure
794  * The given <mask> can either be:
795  * - An usual irc type mask, containing * and or ?
796  * - An ip number plus a /bitnumber part, that will only consider
797  *   the first "bitnumber" bits of the IP (bitnumber must be in 0-31 range)
798  * - An ip numer plus a /ip.bit.mask.values that will consider
799  *   only the bits marked as 1 in the ip.bit.mask.values
800  * In the last two cases both the ip number and the bitmask can specify
801  * less than 4 bytes, the missing bytes then default to zero, note that
802  * this is *different* from the way inet_aton() does and that this does
803  * NOT happen for normal IPmasks (not containing '/')
804  * If the returned value is zero the produced in_mask might match some IP,
805  * if it's nonzero it will never match anything (and the imask struct is
806  * set so that always fails).
807  *
808  * The returned structure contains 3 fields whose meaning is the following:
809  * im.mask = The bits considered significative in the IP
810  * im.bits = What these bits should look like to have a match
811  * im.fall = If zero means that the above information used as 
812  *           ((IP & im.mask) == im.bits) is enough to tell if the compiled
813  *           mask matches the given IP, nonzero means that it is needed,
814  *           in case they did match, to call also the usual text match
815  *           functions, because the mask wasn't "completely compiled"
816  *
817  * They should be used like:
818  * matchcompIP(&im, mask);
819  * if ( ((IP & im.mask)!=im.bits)) || (im.fall&&match(mask,inet_ntoa(IP))) )
820  *    { handle_non_match } else { handle_match };
821  * instead of:
822  * if ( match(mask, inet_ntoa(IP)) )
823  *    { handle_non_match } else { handle_match };
824  * 
825  * Note: This function could be smarter when dealing with complex masks,
826  *       this implementation is quite lazy and understands only very simple
827  *       cases, whatever contains a ? anywhere or contains a '*' that isn't
828  *       part of a trailing '.*' will fallback to text-match, this could be 
829  *       avoided for masks like 12?3.5.6 12.*.3.4 1.*.*.2 72?72?72?72 and
830  *       so on that "could" be completely compiled to IP masks.
831  *       If you try to improve this be aware of the fact that ? and *
832  *       could match both dots and digits and we _must_ always reject
833  *       what doesn't match in textform (like leading zeros and so on),
834  *       so it's a LOT more tricky than it might seem. By now most common
835  *       cases are optimized.
836  */
837
838 int matchcompIP(struct in_mask *imask, const char *mask)
839 {
840   const char *m = mask;
841   unsigned int bits = 0;
842   unsigned int filt = 0;
843   int unco = 0;
844   int digits = 0;
845   int shift = 24;
846   int tmp = 0;
847
848   do
849   {
850     switch (*m)
851     {
852       case '\\':
853         if ((m[1] == '\\') || (m[1] == '*') || (m[1] == '?')
854             || (m[1] == '\0'))
855           break;
856         continue;
857       case '0':
858       case '1':
859       case '2':
860       case '3':
861       case '4':
862       case '5':
863       case '6':
864       case '7':
865       case '8':
866       case '9':
867         if (digits && !tmp)     /* Leading zeros */
868           break;
869         digits++;
870         tmp *= 10;
871         tmp += (*m - '0');      /* Can't overflow, INT_MAX > 2559 */
872         if (tmp > 255)
873           break;
874         continue;
875       case '\0':
876         filt = 0xFFFFFFFF;
877         /* Intentional fallthrough */
878       case '.':
879         if ((!shift) != (!*m))
880           break;
881         /* Intentional fallthrough */
882       case '/':
883         bits |= (tmp << shift);
884         shift -= 8;
885         digits = 0;
886         tmp = 0;
887         if (*m != '/')
888           continue;
889         shift = 24;
890         do
891         {
892           m++;
893           if (IsDigit(*m))
894           {
895             if (digits && !tmp) /* Leading zeros */
896               break;
897             digits++;
898             tmp *= 10;
899             tmp += (*m - '0');  /* Can't overflow, INT_MAX > 2559 */
900             if (tmp > 255)
901               break;
902           }
903           else
904           {
905             switch (*m)
906             {
907               case '.':
908               case '\0':
909                 if ((!shift) && (*m))
910                   break;
911                 filt |= (tmp << shift);
912                 shift -= 8;
913                 tmp = 0;
914                 digits = 0;
915                 continue;
916               default:
917                 break;
918             }
919             break;
920           }
921         }
922         while (*m);
923         if (*m)
924           break;
925         if (filt && (!(shift < 16)) && (!(filt & 0xE0FFFFFF)))
926           filt = 0xFFFFFFFF << (32 - ((filt >> 24)));
927         bits &= filt;
928         continue;
929       case '?':
930         unco = 1;
931         /* Intentional fallthrough */
932       case '*':
933         if (digits)
934           unco = 1;
935         filt = (0xFFFFFFFF << (shift)) << 8;
936         while (*++m)
937         {
938           if (IsDigit(*m))
939             unco = 1;
940           else
941           {
942             switch (*m)
943             {
944               case '.':
945                 if (m[1] != '*')
946                   unco = 1;
947                 if (!shift)
948                   break;
949                 shift -= 8;
950                 continue;
951               case '?':
952                 unco = 1;
953               case '*':
954                 continue;
955               default:
956                 break;
957             }
958             break;
959           }
960         }
961         if (*m)
962           break;
963         continue;
964       default:
965         break;
966     }
967
968     /* If we get here there is some error and this can't ever match */
969     filt = 0;
970     bits = ~0;
971     unco = 0;
972     break;                      /* This time break the loop :) */
973
974   }
975   while (*m++);
976
977   imask->bits.s_addr = htonl(bits);
978   imask->mask.s_addr = htonl(filt);
979   imask->fall = unco;
980   return ((bits & ~filt) ? -1 : 0);
981
982 }