]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/wildcard.cpp
Rename lowermap to rfc_case_insensitive_map, add case_sensitive_map.. adjust files...
[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  *      Iteration 5)
32  *   peavey: Fix glob scan similar to 1.1, but scan ahead on glob in inner loop to retain speedup
33  *   this fixes another case which we forgot to test. Add early return for obvious fail condition.
34  */
35 static bool match_internal(const unsigned char *string, const unsigned char *wild, unsigned const char *map)
36 {
37         const unsigned char *s, *m; m = wild;
38
39         if (*string && !*wild)
40                 return false;
41
42         if (!map)
43                 map = rfc_case_insensitive_map;
44
45         while (*string)
46         {
47                 if (*wild == '*')
48                 {
49                         while (*wild && *wild == '*')
50                                 wild++;
51
52                         m = wild;
53
54                         if (!*wild)
55                                 return true;
56                         else if (*wild != '?')
57                         {
58                                 s = string;
59                                 while (*s)
60                                 {
61                                         if ((map[*wild] == map[*s]))
62                                         {
63                                                 string = s;
64                                                 if (*(wild+1) || !*(s+1))
65                                                         wild++;
66                                                 break;
67                                         }
68                                         s++;
69                                 }
70                         }
71                 }
72                 else if ( (map[*wild] == map[*string]) || (*wild == '?') )
73                         wild++;
74                 else
75                         wild = m;
76
77                 string++;
78         }
79
80         while (*wild && *wild == '*')
81                 wild++;
82
83         return !*wild;
84 }
85
86 /********************************************************************
87  * Below here is all wrappers around match_internal
88  ********************************************************************/
89
90 CoreExport bool InspIRCd::Match(const std::string &str, const std::string &mask, unsigned const char *map)
91 {
92         return match_internal((const unsigned char *)str.c_str(), (const unsigned char *)mask.c_str(), map);
93 }
94
95 CoreExport bool InspIRCd::Match(const  char *str, const char *mask, unsigned const char *map)
96 {
97         return match_internal((const unsigned char *)str, (const unsigned char *)mask, map);
98 }
99
100 CoreExport bool InspIRCd::MatchCIDR(const std::string &str, const std::string &mask, unsigned const char *map)
101 {
102         if (irc::sockets::MatchCIDR(str, mask, true))
103                 return true;
104
105         // Fall back to regular match
106         return InspIRCd::Match(str, mask, NULL);
107 }
108
109 CoreExport bool InspIRCd::MatchCIDR(const  char *str, const char *mask, unsigned const char *map)
110 {
111         if (irc::sockets::MatchCIDR(str, mask, true))
112                 return true;
113
114         // Fall back to regular match
115         return InspIRCd::Match(str, mask, NULL);
116 }
117