]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_svshold.cpp
Fix a bunch of weird indentation and spacing issues.
[user/henk/code/inspircd.git] / src / modules / m_svshold.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2019-2020 Matt Schatz <genius3000@g3k.solutions>
5  *   Copyright (C) 2018 linuxdaemon <linuxdaemon.irc@gmail.com>
6  *   Copyright (C) 2013, 2017-2018, 2020 Sadie Powell <sadie@witchery.services>
7  *   Copyright (C) 2012, 2019 Robby <robby@chatbelgie.be>
8  *   Copyright (C) 2012, 2014, 2016 Attila Molnar <attilamolnar@hush.com>
9  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
10  *   Copyright (C) 2007-2008 Dennis Friis <peavey@inspircd.org>
11  *   Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net>
12  *   Copyright (C) 2006 Craig Edwards <brain@inspircd.org>
13  *
14  * This file is part of InspIRCd.  InspIRCd is free software: you can
15  * redistribute it and/or modify it under the terms of the GNU General Public
16  * License as published by the Free Software Foundation, version 2.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
21  * details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  */
26
27
28 #include "inspircd.h"
29 #include "xline.h"
30 #include "modules/stats.h"
31
32 namespace
33 {
34         bool silent;
35 }
36
37 /** Holds a SVSHold item
38  */
39 class SVSHold : public XLine
40 {
41 public:
42         std::string nickname;
43
44         SVSHold(time_t s_time, unsigned long d, const std::string& src, const std::string& re, const std::string& nick)
45                 : XLine(s_time, d, src, re, "SVSHOLD")
46         {
47                 this->nickname = nick;
48         }
49
50         bool Matches(User* u) CXX11_OVERRIDE
51         {
52                 if (u->nick == nickname)
53                         return true;
54                 return false;
55         }
56
57         bool Matches(const std::string& s) CXX11_OVERRIDE
58         {
59                 return InspIRCd::Match(s, nickname);
60         }
61
62         void DisplayExpiry() CXX11_OVERRIDE
63         {
64                 if (!silent)
65                 {
66                         ServerInstance->SNO->WriteToSnoMask('x', "Removing expired SVSHOLD %s (set by %s %s ago): %s",
67                                 nickname.c_str(), source.c_str(), InspIRCd::DurationString(ServerInstance->Time() - set_time).c_str(), reason.c_str());
68                 }
69         }
70
71         const std::string& Displayable() CXX11_OVERRIDE
72         {
73                 return nickname;
74         }
75 };
76
77 /** An XLineFactory specialized to generate SVSHOLD pointers
78  */
79 class SVSHoldFactory : public XLineFactory
80 {
81  public:
82         SVSHoldFactory() : XLineFactory("SVSHOLD") { }
83
84         /** Generate an SVSHOLD
85         */
86         XLine* Generate(time_t set_time, unsigned long duration, const std::string& source, const std::string& reason, const std::string& xline_specific_mask) CXX11_OVERRIDE
87         {
88                 return new SVSHold(set_time, duration, source, reason, xline_specific_mask);
89         }
90
91         bool AutoApplyToUserList(XLine* x) CXX11_OVERRIDE
92         {
93                 return false;
94         }
95 };
96
97 /** Handle /SVSHold
98  */
99 class CommandSvshold : public Command
100 {
101  public:
102         CommandSvshold(Module* Creator) : Command(Creator, "SVSHOLD", 1)
103         {
104                 flags_needed = 'o'; this->syntax = "<nick> [<duration> :<reason>]";
105         }
106
107         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
108         {
109                 /* syntax: svshold nickname time :reason goes here */
110                 /* 'time' is a human-readable timestring, like 2d3h2s. */
111
112                 if (!user->server->IsULine())
113                 {
114                         /* don't allow SVSHOLD from non-ulined clients */
115                         return CMD_FAILURE;
116                 }
117
118                 if (parameters.size() == 1)
119                 {
120                         std::string reason;
121
122                         if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "SVSHOLD", reason, user))
123                         {
124                                 if (!silent)
125                                         ServerInstance->SNO->WriteToSnoMask('x', "%s removed SVSHOLD on %s: %s", user->nick.c_str(), parameters[0].c_str(), reason.c_str());
126                         }
127                         else
128                         {
129                                 user->WriteNotice("*** SVSHOLD " + parameters[0] + " not found on the list.");
130                         }
131                 }
132                 else
133                 {
134                         if (parameters.size() < 3)
135                                 return CMD_FAILURE;
136
137                         unsigned long duration;
138                         if (!InspIRCd::Duration(parameters[1], duration))
139                         {
140                                 user->WriteNotice("*** Invalid duration for SVSHOLD.");
141                                 return CMD_FAILURE;
142                         }
143                         SVSHold* r = new SVSHold(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
144
145                         if (ServerInstance->XLines->AddLine(r, user))
146                         {
147                                 if (silent)
148                                         return CMD_SUCCESS;
149
150                                 if (!duration)
151                                 {
152                                         ServerInstance->SNO->WriteToSnoMask('x', "%s added permanent SVSHOLD for %s: %s", user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
153                                 }
154                                 else
155                                 {
156                                         ServerInstance->SNO->WriteToSnoMask('x', "%s added timed SVSHOLD for %s, expires in %s (on %s): %s",
157                                                 user->nick.c_str(), parameters[0].c_str(), InspIRCd::DurationString(duration).c_str(),
158                                                 InspIRCd::TimeString(ServerInstance->Time() + duration).c_str(), parameters[2].c_str());
159                                 }
160                         }
161                         else
162                         {
163                                 delete r;
164                                 return CMD_FAILURE;
165                         }
166                 }
167
168                 return CMD_SUCCESS;
169         }
170
171         RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE
172         {
173                 return ROUTE_BROADCAST;
174         }
175 };
176
177 class ModuleSVSHold : public Module, public Stats::EventListener
178 {
179         CommandSvshold cmd;
180         SVSHoldFactory s;
181
182
183  public:
184         ModuleSVSHold()
185                 : Stats::EventListener(this)
186                 , cmd(this)
187         {
188         }
189
190         void init() CXX11_OVERRIDE
191         {
192                 ServerInstance->XLines->RegisterFactory(&s);
193         }
194
195         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
196         {
197                 ConfigTag* tag = ServerInstance->Config->ConfValue("svshold");
198                 silent = tag->getBool("silent", true);
199         }
200
201         ModResult OnStats(Stats::Context& stats) CXX11_OVERRIDE
202         {
203                 if (stats.GetSymbol() != 'S')
204                         return MOD_RES_PASSTHRU;
205
206                 ServerInstance->XLines->InvokeStats("SVSHOLD", stats);
207                 return MOD_RES_DENY;
208         }
209
210         ModResult OnUserPreNick(LocalUser* user, const std::string& newnick) CXX11_OVERRIDE
211         {
212                 XLine *rl = ServerInstance->XLines->MatchesLine("SVSHOLD", newnick);
213
214                 if (rl)
215                 {
216                         user->WriteNumeric(ERR_ERRONEUSNICKNAME, newnick, InspIRCd::Format("Services reserved nickname: %s", rl->reason.c_str()));
217                         return MOD_RES_DENY;
218                 }
219
220                 return MOD_RES_PASSTHRU;
221         }
222
223         ~ModuleSVSHold()
224         {
225                 ServerInstance->XLines->DelAll("SVSHOLD");
226                 ServerInstance->XLines->UnregisterFactory(&s);
227         }
228
229         Version GetVersion() CXX11_OVERRIDE
230         {
231                 return Version("Adds the /SVSHOLD command which allows services to reserve nicknames.", VF_COMMON | VF_VENDOR);
232         }
233 };
234
235 MODULE_INIT(ModuleSVSHold)