]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/wildcard.cpp
Actually, we did manage to make a faster match than znc, when casemapping is taken...
[user/henk/code/inspircd.git] / src / wildcard.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 /* $Core */
15
16 #include "inspircd.h"
17 #include "hashcomp.h"
18 #include "inspstring.h"
19
20 /*
21  * Wildcard matching!
22  *
23  *  Iteration 1)
24  *   Slow, horrible, etc.
25  *      Iteration 2)
26  *   The vastly available 'public domain' one
27  *      Iteration 3)
28  *   ZNC's, thought to be faster than ours, but it turned out that we could do better ;-)
29  *      Iteration 4)
30  *   Largely from work by peavey and myself (w00t) :)
31  *
32  */
33 static bool match_internal(const unsigned char *string, const unsigned char *wild, unsigned const char *map)
34 {
35         const unsigned char* s;
36
37         if (!map)
38                 map = lowermap;
39
40         while (*string)
41         {
42                 if (*wild == '*')
43                 {
44                         while (*wild && *wild == '*')
45                                 wild++;
46
47                         if (!*wild)
48                                 return true;
49                         else if (*wild != '?')
50                         {
51                                 s = string;
52                                 while (*s)
53                                 {
54                                         if ((map[*wild] == map[*s]))
55                                         {
56                                                 string = s;
57                                                 if (*(wild+1) || !*(s+1))
58                                                 {
59                                                         wild++;
60                                                         break;
61                                                 }
62                                         }
63                                         s++;
64                                 }
65                         }
66                 }
67                 else if ( (map[*wild] != map[*string]) && (*wild != '?') )
68                 {
69                         return false;
70                 }
71                 else
72                         wild++;
73
74                 string++;
75         }
76
77         while (*wild && *wild == '*')
78                 wild++;
79
80         return !*wild;
81 }
82
83 /********************************************************************
84  * Below here is all wrappers around match_internal
85  ********************************************************************/
86
87 CoreExport bool InspIRCd::Match(const std::string &str, const std::string &mask, unsigned const char *map)
88 {
89         return match_internal((const unsigned char *)str.c_str(), (const unsigned char *)mask.c_str(), map);
90 }
91
92 CoreExport bool InspIRCd::Match(const  char *str, const char *mask, unsigned const char *map)
93 {
94         return match_internal((const unsigned char *)str, (const unsigned char *)mask, map);
95 }
96
97
98 CoreExport bool InspIRCd::MatchCIDR(const std::string &str, const std::string &mask, unsigned const char *map)
99 {
100         if (irc::sockets::MatchCIDR(str, mask, true))
101                 return true;
102
103         // Fall back to regular match
104         return InspIRCd::Match(str, mask, NULL);
105 }
106
107 CoreExport bool InspIRCd::MatchCIDR(const  char *str, const char *mask, unsigned const char *map)
108 {
109         if (irc::sockets::MatchCIDR(str, mask, true))
110                 return true;
111
112         // Fall back to regular match
113         return InspIRCd::Match(str, mask, NULL);
114 }
115