]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_jumpserver.cpp
Merge pull request #514 from SaberUK/master+virtual-cleanup
[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->WriteNotice("*** Disabled jumpserver (previously set to '" + redirect_to + ":" + ConvToStr(port) + "')");
57                         else
58                                 user->WriteNotice("*** Jumpserver was not enabled.");
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->WriteNotice("*** Invalid JUMPSERVER flag: " + ConvToStr(*n));
88                                                 return CMD_FAILURE;
89                                         break;
90                                 }
91                         }
92
93                         if (!atoi(parameters[1].c_str()))
94                         {
95                                 user->WriteNotice("*** Invalid port number");
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 (!t->IsOper())
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->WriteNotice("*** Set jumpserver to server '" + parameters[0] + "' port '" + parameters[1] + "', flags '+" +
125                                 (redirect_all_immediately ? "a" : "") + (redirect_new_users ? "n'" : "'") +
126                                 (n_done ? " (" + n_done_s + "user(s) redirected): " : ": ") + reason);
127                 }
128
129                 return CMD_SUCCESS;
130         }
131 };
132
133 class ModuleJumpServer : public Module
134 {
135         CommandJumpserver js;
136  public:
137         ModuleJumpServer() : js(this)
138         {
139         }
140
141         void init() CXX11_OVERRIDE
142         {
143                 ServerInstance->Modules->AddService(js);
144                 Implementation eventlist[] = { I_OnUserRegister, I_OnRehash };
145                 ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
146         }
147
148         ModResult OnUserRegister(LocalUser* user) CXX11_OVERRIDE
149         {
150                 if (js.port && js.redirect_new_users)
151                 {
152                         user->WriteNumeric(10, "%s %s %d :Please use this Server/Port instead",
153                                 user->nick.c_str(), js.redirect_to.c_str(), js.port);
154                         ServerInstance->Users->QuitUser(user, js.reason);
155                         return MOD_RES_PASSTHRU;
156                 }
157                 return MOD_RES_PASSTHRU;
158         }
159
160         void OnRehash(User* user) CXX11_OVERRIDE
161         {
162                 // Emergency way to unlock
163                 if (!user) js.redirect_new_users = false;
164         }
165
166         Version GetVersion() CXX11_OVERRIDE
167         {
168                 return Version("Provides support for the RPL_REDIR numeric and the /JUMPSERVER command.", VF_VENDOR);
169         }
170 };
171
172 MODULE_INIT(ModuleJumpServer)