/* This is a C function (and error checking wrapper) for comparing IRC hostmasks. This program is Copyright 2002 by Hardcore Software, and its distribution is protected by the GNU General Public License. See www.gnu.org for more information. Use the function ircmasktest(char *mask, char *test) for comparisons. It will return 1 for a positive match, 0 for a non-match, -1 for an invalid mask, -2 for an invalid test. Some examples: ircmasktest("*!*@*", "jimmy!~jim@blah.somehost.com") -> 1 ircmasktest("jimmy!*@*", "jimmy!~jim@blah.somehost.com") -> 1 ircmasktest("*!*@*.somehost.com", "jimmy!~jim@blah.somehost.com") -> 1 ircmasktest("*!~*@*", "jimmy!~jim@blah.somehost.com") -> 1 ircmasktest("???!*@*", "jimmy!~jim@blah.somehost.com") -> 0 (Only matches 3 letter long nicks.) ircmasktest("*!*@*.somehost.*", "jimmy!~jim@blah.somehost.com") -> 1 ircmasktest("", "") -> -1 ircmasktest("*!*@*", "") -> -2 ircmasktest("*!*@*", "blah !blah@blah.somehost.com") -> -2 If you know for certain that your masks and tests are valid, you can get a (marginal) performace increase by skipping right to wildtest(). */ #include int wildtest(char *wild, char *test) { int i; while(*wild != '\0' || *test != '\0') { if (*wild == '*') { /* --- Deal with multiple asterisks. --- */ while (wild[1] == '*') wild++; /* --- Deal with terminating asterisks. --- */ if (wild[1] == '\0') return 1; for(i=0; test[i]!='\0'; i++) if ((wild[1] == test[i] || wild[1] == '?') && wildtest(wild+1, test+i) == 1) return 1; return 0; } /* --- '?' can't match '\0'. --- */ if (*wild == '?' && *test == '\0') return 0; if (*wild != '?' && *wild != *test) return 0; wild++; test++; } if (*wild == *test) return 1; return 0; } int ircmasktest(char *mask, char *test) { int i, bang, at; for(at=bang=0,i=strlen(mask)-1; i>=0; i--) { if (mask[i] == ' ') return -1; else if (mask[i] == '!') bang++; else if (mask[i] == '@') at++; } if(bang!=1 || at!=1) return -1; for(at=bang=0,i=strlen(test)-1; i>=0; i--) { if (test[i] == ' ') return -2; else if (test[i] == '!') bang++; else if (test[i] == '@') at++; } if(bang!=1 || at!=1) return -2; return wildtest(mask, test); }