]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/wildcard.cpp
Clean up wildcard code.
[user/henk/code/inspircd.git] / src / wildcard.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
5  *   Copyright (C) 2003, 2006-2008 Craig Edwards <craigedwards@brainbox.cc>
6  *   Copyright (C) 2007-2008 Dennis Friis <peavey@inspircd.org>
7  *
8  * This file is part of InspIRCd.  InspIRCd is free software: you can
9  * redistribute it and/or modify it under the terms of the GNU General Public
10  * License as published by the Free Software Foundation, version 2.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21
22 #include "inspircd.h"
23 #include "hashcomp.h"
24 #include "inspstring.h"
25
26 static bool MatchInternal(const unsigned char* str, const unsigned char* mask, unsigned const char* map)
27 {
28         unsigned char* cp = NULL;
29         unsigned char* mp = NULL;
30         unsigned char* string = (unsigned char*)str;
31         unsigned char* wild = (unsigned char*)mask;
32
33         while ((*string) && (*wild != '*'))
34         {
35                 if ((map[*wild] != map[*string]) && (*wild != '?'))
36                 {
37                         return 0;
38                 }
39                 wild++;
40                 string++;
41         }
42
43         while (*string)
44         {
45                 if (*wild == '*')
46                 {
47                         if (!*++wild)
48                         {
49                                 return 1;
50                         }
51                         mp = wild;
52                         cp = string+1;
53                 }
54                 else
55                         if ((map[*wild] == map[*string]) || (*wild == '?'))
56                         {
57                                 wild++;
58                                 string++;
59                         }
60                         else
61                         {
62                                 wild = mp;
63                                 string = cp++;
64                         }
65
66         }
67
68         while (*wild == '*')
69         {
70                 wild++;
71         }
72
73         return !*wild;
74 }
75
76 // Below here is all wrappers around MatchInternal
77
78 bool InspIRCd::Match(const std::string& str, const std::string& mask, unsigned const char* map)
79 {
80         if (!map)
81                 map = national_case_insensitive_map;
82
83         return MatchInternal((const unsigned char*)str.c_str(), (const unsigned char*)mask.c_str(), map);
84 }
85
86 bool InspIRCd::Match(const char* str, const char* mask, unsigned const char* map)
87 {
88         if (!map)
89                 map = national_case_insensitive_map;
90
91         return MatchInternal((const unsigned char*)str, (const unsigned char*)mask, map);
92 }
93
94 bool InspIRCd::MatchCIDR(const std::string& str, const std::string& mask, unsigned const char* map)
95 {
96         if (irc::sockets::MatchCIDR(str, mask, true))
97                 return true;
98
99         // Fall back to regular match
100         return InspIRCd::Match(str, mask, map);
101 }
102
103 bool InspIRCd::MatchCIDR(const char* str, const char* mask, unsigned const char* map)
104 {
105         if (irc::sockets::MatchCIDR(str, mask, true))
106                 return true;
107
108         // Fall back to regular match
109         return InspIRCd::Match(str, mask, map);
110 }
111
112 bool InspIRCd::MatchMask(const std::string& masks, const std::string& hostname, const std::string& ipaddr)
113 {
114         std::stringstream masklist(masks);
115         std::string mask;
116         while (masklist >> mask)
117         {
118                 if (InspIRCd::Match(hostname, mask, ascii_case_insensitive_map) ||
119                         InspIRCd::MatchCIDR(ipaddr, mask, ascii_case_insensitive_map))
120                 {
121                         return true;
122                 }
123         }
124         return false;
125 }