]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_channames.cpp
Fix the cloaking module on C++98 compilers.
[user/henk/code/inspircd.git] / src / modules / m_channames.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013, 2017 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2013 Daniel Vassdal <shutter@canternet.org>
6  *   Copyright (C) 2012-2014 Attila Molnar <attilamolnar@hush.com>
7  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
8  *   Copyright (C) 2010 Craig Edwards <brain@inspircd.org>
9  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
10  *
11  * This file is part of InspIRCd.  InspIRCd is free software: you can
12  * redistribute it and/or modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24
25 #include "inspircd.h"
26
27 static std::bitset<256> allowedmap;
28
29 class NewIsChannelHandler
30 {
31  public:
32         static bool Call(const std::string&);
33 };
34
35 bool NewIsChannelHandler::Call(const std::string& channame)
36 {
37         if (channame.empty() || channame.length() > ServerInstance->Config->Limits.ChanMax || channame[0] != '#')
38                 return false;
39
40         for (std::string::const_iterator c = channame.begin(); c != channame.end(); ++c)
41         {
42                 unsigned int i = *c & 0xFF;
43                 if (!allowedmap[i])
44                         return false;
45         }
46
47         return true;
48 }
49
50 class ModuleChannelNames : public Module
51 {
52         TR1NS::function<bool(const std::string&)> rememberer;
53         bool badchan;
54         ChanModeReference permchannelmode;
55
56  public:
57         ModuleChannelNames()
58                 : rememberer(ServerInstance->IsChannel)
59                 , badchan(false)
60                 , permchannelmode(this, "permanent")
61         {
62         }
63
64         void init() CXX11_OVERRIDE
65         {
66                 ServerInstance->IsChannel = NewIsChannelHandler::Call;
67         }
68
69         void ValidateChans()
70         {
71                 Modes::ChangeList removepermchan;
72
73                 badchan = true;
74                 const chan_hash& chans = ServerInstance->GetChans();
75                 for (chan_hash::const_iterator i = chans.begin(); i != chans.end(); )
76                 {
77                         Channel* c = i->second;
78                         // Move iterator before we begin kicking
79                         ++i;
80                         if (ServerInstance->IsChannel(c->name))
81                                 continue; // The name of this channel is still valid
82
83                         if (c->IsModeSet(permchannelmode) && c->GetUserCounter())
84                         {
85                                 removepermchan.clear();
86                                 removepermchan.push_remove(*permchannelmode);
87                                 ServerInstance->Modes->Process(ServerInstance->FakeClient, c, NULL, removepermchan);
88                         }
89
90                         Channel::MemberMap& users = c->userlist;
91                         for (Channel::MemberMap::iterator j = users.begin(); j != users.end(); )
92                         {
93                                 if (IS_LOCAL(j->first))
94                                 {
95                                         // KickUser invalidates the iterator
96                                         Channel::MemberMap::iterator it = j++;
97                                         c->KickUser(ServerInstance->FakeClient, it, "Channel name no longer valid");
98                                 }
99                                 else
100                                         ++j;
101                         }
102                 }
103                 badchan = false;
104         }
105
106         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
107         {
108                 ConfigTag* tag = ServerInstance->Config->ConfValue("channames");
109                 std::string denyToken = tag->getString("denyrange");
110                 std::string allowToken = tag->getString("allowrange");
111
112                 if (!denyToken.compare(0, 2, "0-"))
113                         denyToken[0] = '1';
114                 if (!allowToken.compare(0, 2, "0-"))
115                         allowToken[0] = '1';
116
117                 allowedmap.set();
118
119                 irc::portparser denyrange(denyToken, false);
120                 int denyno = -1;
121                 while (0 != (denyno = denyrange.GetToken()))
122                         allowedmap[denyno & 0xFF] = false;
123
124                 irc::portparser allowrange(allowToken, false);
125                 int allowno = -1;
126                 while (0 != (allowno = allowrange.GetToken()))
127                         allowedmap[allowno & 0xFF] = true;
128
129                 allowedmap[0x07] = false; // BEL
130                 allowedmap[0x20] = false; // ' '
131                 allowedmap[0x2C] = false; // ','
132
133                 ValidateChans();
134         }
135
136         void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list) CXX11_OVERRIDE
137         {
138                 if (badchan)
139                 {
140                         const Channel::MemberMap& users = memb->chan->GetUsers();
141                         for (Channel::MemberMap::const_iterator i = users.begin(); i != users.end(); ++i)
142                                 if (i->first != memb->user)
143                                         except_list.insert(i->first);
144                 }
145         }
146
147         CullResult cull() CXX11_OVERRIDE
148         {
149                 ServerInstance->IsChannel = rememberer;
150                 ValidateChans();
151                 return Module::cull();
152         }
153
154         Version GetVersion() CXX11_OVERRIDE
155         {
156                 return Version("Allows the server administrator to define what characters are allowed in channel names.", VF_VENDOR);
157         }
158 };
159
160 MODULE_INIT(ModuleChannelNames)