]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_jumpserver.cpp
m_jumpserver Prevent OnUserRegister from running in other modules for users we quit
[user/henk/code/inspircd.git] / src / modules / m_jumpserver.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
5  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
6  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
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
24 /* $ModDesc: Provides support for the RPL_REDIR numeric and the /JUMPSERVER command. */
25
26 /** Handle /JUMPSERVER
27  */
28 class CommandJumpserver : public Command
29 {
30  public:
31         bool redirect_new_users;
32         std::string redirect_to;
33         std::string reason;
34         int port;
35
36         CommandJumpserver(Module* Creator) : Command(Creator, "JUMPSERVER", 0, 4)
37         {
38                 flags_needed = 'o'; syntax = "[<server> <port> <+/-an> <reason>]";
39                 port = 0;
40                 redirect_new_users = false;
41         }
42
43         CmdResult Handle (const std::vector<std::string> &parameters, User *user)
44         {
45                 int n_done = 0;
46                 reason = (parameters.size() < 4) ? "Please use this server/port instead" : parameters[3];
47                 bool redirect_all_immediately = false;
48                 redirect_new_users = true;
49                 bool direction = true;
50                 std::string n_done_s;
51
52                 /* No parameters: jumpserver disabled */
53                 if (!parameters.size())
54                 {
55                         if (port)
56                                 user->WriteServ("NOTICE %s :*** Disabled jumpserver (previously set to '%s:%d')", user->nick.c_str(), redirect_to.c_str(), port);
57                         else
58                                 user->WriteServ("NOTICE %s :*** Jumpserver was not enabled.", user->nick.c_str());
59
60                         port = 0;
61                         redirect_to.clear();
62                         return CMD_SUCCESS;
63                 }
64
65                 port = 0;
66                 redirect_to.clear();
67
68                 if (parameters.size() >= 3)
69                 {
70                         for (std::string::const_iterator n = parameters[2].begin(); n != parameters[2].end(); ++n)
71                         {
72                                 switch (*n)
73                                 {
74                                         case '+':
75                                                 direction = true;
76                                         break;
77                                         case '-':
78                                                 direction = false;
79                                         break;
80                                         case 'a':
81                                                 redirect_all_immediately = direction;
82                                         break;
83                                         case 'n':
84                                                 redirect_new_users = direction;
85                                         break;
86                                         default:
87                                                 user->WriteServ("NOTICE %s :*** Invalid JUMPSERVER flag: %c", user->nick.c_str(), *n);
88                                                 return CMD_FAILURE;
89                                         break;
90                                 }
91                         }
92
93                         if (!atoi(parameters[1].c_str()))
94                         {
95                                 user->WriteServ("NOTICE %s :*** Invalid port number", user->nick.c_str());
96                                 return CMD_FAILURE;
97                         }
98
99                         if (redirect_all_immediately)
100                         {
101                                 /* Redirect everyone but the oper sending the command */
102                                 for (LocalUserList::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); ++i)
103                                 {
104                                         User* t = *i;
105                                         if (!IS_OPER(t))
106                                         {
107                                                 t->WriteNumeric(10, "%s %s %s :Please use this Server/Port instead", t->nick.c_str(), parameters[0].c_str(), parameters[1].c_str());
108                                                 ServerInstance->Users->QuitUser(t, reason);
109                                                 n_done++;
110                                         }
111                                 }
112                                 if (n_done)
113                                 {
114                                         n_done_s = ConvToStr(n_done);
115                                 }
116                         }
117
118                         if (redirect_new_users)
119                         {
120                                 redirect_to = parameters[0];
121                                 port = atoi(parameters[1].c_str());
122                         }
123
124                         user->WriteServ("NOTICE %s :*** Set jumpserver to server '%s' port '%s', flags '+%s%s'%s%s%s: %s", user->nick.c_str(), parameters[0].c_str(), parameters[1].c_str(),
125                                         redirect_all_immediately ? "a" : "",
126                                         redirect_new_users ? "n" : "",
127                                         n_done ? " (" : "",
128                                         n_done ? n_done_s.c_str() : "",
129                                         n_done ? " user(s) redirected)" : "",
130                                         reason.c_str());
131                 }
132
133                 return CMD_SUCCESS;
134         }
135 };
136
137
138 class ModuleJumpServer : public Module
139 {
140         CommandJumpserver js;
141  public:
142         ModuleJumpServer() : js(this)
143         {
144         }
145
146         void init()
147         {
148                 ServerInstance->Modules->AddService(js);
149                 Implementation eventlist[] = { I_OnUserRegister, I_OnRehash };
150                 ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
151         }
152
153         virtual ~ModuleJumpServer()
154         {
155         }
156
157         virtual ModResult OnUserRegister(LocalUser* user)
158         {
159                 if (js.port && js.redirect_new_users)
160                 {
161                         user->WriteNumeric(10, "%s %s %d :Please use this Server/Port instead",
162                                 user->nick.c_str(), js.redirect_to.c_str(), js.port);
163                         ServerInstance->Users->QuitUser(user, js.reason);
164                         return MOD_RES_DENY;
165                 }
166                 return MOD_RES_PASSTHRU;
167         }
168
169         virtual void OnRehash(User* user)
170         {
171                 // Emergency way to unlock
172                 if (!user) js.redirect_new_users = false;
173         }
174
175         virtual Version GetVersion()
176         {
177                 return Version("Provides support for the RPL_REDIR numeric and the /JUMPSERVER command.", VF_VENDOR);
178         }
179
180 };
181
182 MODULE_INIT(ModuleJumpServer)