The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

wildcard.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 /* $Core */
00015 
00016 #include "inspircd.h"
00017 #include "hashcomp.h"
00018 #include "inspstring.h"
00019 
00020 /*
00021  * Wildcard matching!
00022  *
00023  *  Iteration 1)
00024  *   Slow, horrible, etc.
00025  *      Iteration 2)
00026  *   The vastly available 'public domain' one
00027  *      Iteration 3)
00028  *   ZNC's, thought to be faster than ours, but it turned out that we could do better ;-)
00029  *      Iteration 4)
00030  *   Largely from work by peavey and myself (w00t) :)
00031  *      Iteration 5)
00032  *   peavey: Fix glob scan similar to 1.1, but scan ahead on glob in inner loop to retain speedup
00033  *   this fixes another case which we forgot to test. Add early return for obvious fail condition.
00034  */
00035 static bool match_internal(const unsigned char *string, const unsigned char *wild, unsigned const char *map)
00036 {
00037         const unsigned char *s, *m; m = wild;
00038 
00039         if (*string && !*wild)
00040                 return false;
00041 
00042         if (!map)
00043                 map = rfc_case_insensitive_map;
00044 
00045         while (*string)
00046         {
00047                 if (*wild == '*')
00048                 {
00049                         while (*wild && *wild == '*')
00050                                 wild++;
00051 
00052                         m = wild;
00053 
00054                         if (!*wild)
00055                                 return true;
00056                         else if (*wild != '?')
00057                         {
00058                                 s = string;
00059                                 while (*s)
00060                                 {
00061                                         if ((map[*wild] == map[*s]))
00062                                         {
00063                                                 string = s;
00064                                                 if (*(wild+1) || !*(s+1))
00065                                                         wild++;
00066                                                 break;
00067                                         }
00068                                         s++;
00069                                 }
00070                         }
00071                 }
00072                 else if ( (map[*wild] == map[*string]) || (*wild == '?') )
00073                         wild++;
00074                 else
00075                         wild = m;
00076 
00077                 string++;
00078         }
00079 
00080         while (*wild && *wild == '*')
00081                 wild++;
00082 
00083         return !*wild;
00084 }
00085 
00086 /********************************************************************
00087  * Below here is all wrappers around match_internal
00088  ********************************************************************/
00089 
00090 CoreExport bool InspIRCd::Match(const std::string &str, const std::string &mask, unsigned const char *map)
00091 {
00092         return match_internal((const unsigned char *)str.c_str(), (const unsigned char *)mask.c_str(), map);
00093 }
00094 
00095 CoreExport bool InspIRCd::Match(const  char *str, const char *mask, unsigned const char *map)
00096 {
00097         return match_internal((const unsigned char *)str, (const unsigned char *)mask, map);
00098 }
00099 
00100 CoreExport bool InspIRCd::MatchCIDR(const std::string &str, const std::string &mask, unsigned const char *map)
00101 {
00102         if (irc::sockets::MatchCIDR(str, mask, true))
00103                 return true;
00104 
00105         // Fall back to regular match
00106         return InspIRCd::Match(str, mask, NULL);
00107 }
00108 
00109 CoreExport bool InspIRCd::MatchCIDR(const  char *str, const char *mask, unsigned const char *map)
00110 {
00111         if (irc::sockets::MatchCIDR(str, mask, true))
00112                 return true;
00113 
00114         // Fall back to regular match
00115         return InspIRCd::Match(str, mask, NULL);
00116 }
00117