ircproxy The Ultimate Cyborg |
Definition in file match.h.
#include <netinet/in.h>
Go to the source code of this file.
Classes | |
struct | in_mask |
An IP mask used for matchcompIP. More... | |
Functions | |
int | mmatch (char const *old_mask, char const *new_mask) |
Mask match. | |
int | match (char const *mask, char const *string) |
Wildcard match. | |
char * | collapse (char *mask) |
Collapse mask. | |
int | matchcomp (char *cmask, int *minlen, int *charset, char const *mask) |
Match compile function. | |
int | matchexec (char const *string, size_t len, char const *cmask, int minlen) |
Match execute function. | |
int | matchdecomp (char *mask, char const *cmask) |
Match decompile function. | |
int | mmexec (char const *wcm, int wminlen, char const *rcm, int rminlen) |
Match execute function. | |
int | matchcompIP (in_mask *imask, char const *mask) |
Match compile function. |
int mmatch | ( | char const * | old_mask, | |
char const * | new_mask | |||
) |
Mask match.
Definition at line 30 of file match.cc.
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 /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ 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 /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ 00083 if ((*n == '\\') && ((n[1] == '*') || (n[1] == '?'))) 00084 { 00085 n++; 00086 nq = 1; 00087 } 00088 else 00089 nq = 0; 00090 00091 /* 00092 * This `if' has been changed compared to match() to do the following: 00093 * Match when: 00094 * old (m) new (n) boolean expression 00095 * * any (*m == '*' && !mq) || 00096 * ? any except '*' (*m == '?' && !mq && (*n != '*' || nq)) || 00097 * any except * or ? same as m (!((*m == '*' || *m == '?') && !mq) && 00098 * ToLower(*m) == ToLower(*n) && 00099 * !((mq && !nq) || (!mq && nq))) 00100 * 00101 * Here `any' also includes \* and \? ! 00102 * 00103 * After reworking the boolean expressions, we get: 00104 * (Optimized to use boolean shortcircuits, with most frequently occuring 00105 * cases upfront (which took 2 hours!)). 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 /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ 00123 if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?'))) 00124 ++na; 00125 00126 n = ++na; 00127 } 00128 } 00129 }
int match | ( | char const * | mask, | |
char const * | string | |||
) |
Wildcard match.
Definition at line 149 of file match.cc.
00150 { 00151 register char const* m = mask, *s = string; 00152 register char ch; 00153 char const* bm, *bs; /* Will be reg anyway on a decent CPU/compiler */ 00154 00155 /* Process the "head" of the mask, if any */ 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 /* We got a star: quickly find if/where we match the next char */ 00173 got_star: 00174 bm = m; /* Next try rollback here */ 00175 while ((ch = *m++)) 00176 switch (ch) 00177 { 00178 case '?': 00179 if (!*s++) 00180 return 1; 00181 case '*': 00182 bm = m; 00183 continue; /* while */ 00184 case '\\': 00185 if (*m == '?' || *m == '*') 00186 ch = *m++; 00187 default: 00188 goto break_while; /* C is structured ? */ 00189 }; 00190 break_while: 00191 if (!ch) 00192 return 0; /* mask ends with '*', we got it */ 00193 ch = ToLower(ch); 00194 while (ToLower(*s++) != ch) 00195 if (!*s) 00196 return 1; 00197 bs = s; /* Next try start from here */ 00198 00199 /* Check the rest of the "chunk" */ 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 }
char* collapse | ( | char * | mask | ) |
Collapse mask.
Definition at line 241 of file match.cc.
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 }
int matchcomp | ( | char * | cmask, | |
int * | minlen, | |||
int * | charset, | |||
char const * | mask | |||
) |
Match compile function.
Definition at line 364 of file match.cc.
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 }
int matchexec | ( | char const * | string, | |
size_t | len, | |||
char const * | cmask, | |||
int | minlen | |||
) |
Match execute function.
Definition at line 464 of file match.cc.
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 }
int matchdecomp | ( | char * | mask, | |
char const * | cmask | |||
) |
Match decompile function.
Definition at line 542 of file match.cc.
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 }
int mmexec | ( | char const * | wcm, | |
int | wminlen, | |||
char const * | rcm, | |||
int | rminlen | |||
) |
Match execute function.
Definition at line 613 of file match.cc.
00614 { 00615 register char const* w, *r, *br, *bw, *rx, *rz; 00616 register int eat, trash; 00617 00618 /* First of all rm must have enough non-stars to 'contain' wm */ 00619 if ((trash = rminlen - wminlen) < 0) 00620 return 1; 00621 w = wcm; 00622 r = rcm; 00623 eat = 0; 00624 00625 /* Let's start the game, remember that '*' is mapped to 'Z', '?' 00626 is mapped to 'A' and that head?*??*?chunk*???*tail becomes 00627 headAAAAZliatAAAZchunk for compiled masks */ 00628 00629 /* Match the head of wm with the head of rm */ 00630 for (; (*r) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); r++, w++); 00631 if (*r == 'Z') 00632 while (*w == 'A') /* Eat extra '?' before '*' in wm if got '*' in rm */ 00633 w++, eat++; 00634 if (*w != 'Z') /* head1<any>.. can't match head2<any>.. */ 00635 return ((*w) || (*r)) ? 1 : 0; /* and head<nul> matches only head<nul> */ 00636 if (!*++w) 00637 return 0; /* headZ<nul> matches head<anything> */ 00638 00639 /* Does rm have any stars in it ? let's check */ 00640 for (rx = r; *r && (*r != 'Z'); r++); 00641 if (!*r) 00642 { 00643 /* rm has no stars and thus isn't a mask but it's just a flat 00644 string: special handling occurs here, note that eat must be 0 here */ 00645 00646 /* match the tail */ 00647 if (*w != 'Z') 00648 { 00649 for (; r--, (*w) && ((*w == *r) || (*w == 'A')); w++); 00650 if (*w != 'Z') /* headZliat1<any> fails on head<any>2tail */ 00651 return (*w) ? 1 : 0; /* but headZliat<nul> matches head<any>tail */ 00652 }; 00653 00654 /* match the chunks */ 00655 while (1) 00656 { /* This loop can't break but only return */ 00657 00658 for (bw = w++; (*w != *rx); rx++) /* Seek the 1st char of the chunk */ 00659 if (--trash < 0) /* See if we can trash one more char of rm */ 00660 return 1; /* If not we can only fail of course */ 00661 for (r = ++rx, w++; (*w) && ((*w == *r) || (*w == 'A')); r++, w++); 00662 if (!*w) /* Did last loop match the rest of chunk ? */ 00663 return 0; /* ... Yes, end of wm, matched ! */ 00664 if (*w != 'Z') 00665 { /* ... No, hitted non-star */ 00666 w = bw; /* Rollback at beginning of chunk */ 00667 if (--trash < 0) /* Trashed the char where this try started */ 00668 return 1; /* if we can't trash more chars fail */ 00669 } 00670 else 00671 { 00672 rx = r; /* Successfully matched a chunk, move rx */ 00673 }; /* and go on with the next one */ 00674 }; 00675 }; 00676 00677 /* rm has at least one '*' and thus is a 'real' mask */ 00678 rz = r++; /* rx = unused of head, rz = beg-tail */ 00679 00680 /* Match the tail of wm (if any) against the tail of rm */ 00681 if (*w != 'Z') 00682 { 00683 for (; (*w) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); w++, r++); 00684 if (*r == 'Z') /* extra '?' before tail are fluff, just flush 'em */ 00685 while (*w == 'A') 00686 w++; 00687 if (*w != 'Z') /* We aren't matching a chunk, can't rollback */ 00688 return (*w) ? 1 : 0; 00689 }; 00690 00691 /* Match the chunks of wm against what remains of the head of rm */ 00692 while (1) 00693 { 00694 bw = w; 00695 for (bw++; (rx < rz) && (*bw != *rx); rx++) /* Seek the first */ 00696 if (--trash < 0) /* waste some trash reserve */ 00697 return 1; 00698 if (!(rx < rz)) /* head finished */ 00699 break; 00700 for (bw++, (br = ++rx); 00701 (br < rz) && (*bw) && ((*bw == *br) || (*bw == 'A')); br++, bw++); 00702 if (!(br < rz)) /* Note that we didn't use any 'eat' char yet, if */ 00703 while (*bw == 'A') /* there were eat-en chars the head would be over */ 00704 bw++, eat++; /* Happens only at end of head, and eat is still 0 */ 00705 if (!*bw) 00706 return 0; 00707 if (*bw != 'Z') 00708 { 00709 eat = 0; 00710 if (!(br < rz)) 00711 { /* If we failed because we got the end of head */ 00712 trash -= (br - rx); /* it makes no sense to rollback, just trash */ 00713 if (--trash < 0) /* all the rest of the head wich isn't long */ 00714 return 1; /* enough for this chunk and go out of this */ 00715 break; /* loop, then we try with the chunks of rm */ 00716 }; 00717 if (--trash < 0) 00718 return 1; 00719 } 00720 else 00721 { 00722 w = bw; 00723 rx = br; 00724 }; 00725 }; 00726 00727 /* Match the unused chunks of wm against the chunks of rm */ 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) /* the '?' we had eated make us skip as many chars */ 00737 if (*r++ != 'Z') /* here, but can't skip stars or trailing zero */ 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 { /* If we hit the end of rm or a star in it */ 00756 trash -= (br - r); /* makes no sense to rollback within this */ 00757 if (trash < 0) /* same chunk of br, skip it all and then */ 00758 return 1; /* either rollback or break this loop if */ 00759 if (!*br) /* it was the end of rm */ 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 /* match the remaining chunks of wm against what remains of the tail of rm */ 00775 r = rz - eat - 1; /* can't have <nul> or 'Z'within the tail, so just move r */ 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; /* Auch... something left out ? Fail */ 00802 }
int matchcompIP | ( | in_mask * | imask, | |
char const * | mask | |||
) |
Match compile function.
Definition at line 851 of file match.cc.
References in_mask::bits, in_mask::fall, and in_mask::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) /* Leading zeros */ 00881 break; 00882 digits++; 00883 tmp *= 10; 00884 tmp += (*m - '0'); /* Can't overflow, INT_MAX > 2559 */ 00885 if (tmp > 255) 00886 break; 00887 continue; 00888 case '\000': 00889 filt = 0xFFFFFFFF; 00890 /* Intentional fallthrough */ 00891 case '.': 00892 if ((!shift) != (!*m)) 00893 break; 00894 /* Intentional fallthrough */ 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) /* Leading zeros */ 00909 break; 00910 digits++; 00911 tmp *= 10; 00912 tmp += (*m - '0'); /* Can't overflow, INT_MAX > 2559 */ 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 /* Intentional fallthrough */ 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 /* If we get here there is some error and this can't ever match */ 00982 filt = 0; 00983 bits = ~0; 00984 unco = 0; 00985 break; /* This time break the loop :) */ 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 }
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|