ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.1.x/src/opercmd.c
Revision: 6228
Committed: Thu Jul 2 13:10:18 2015 UTC (11 years ago) by michael
Content type: text/x-csrc
File size: 7701 byte(s)
Log Message:
- Create 1.1.x branch

File Contents

# Content
1 /*
2 * Copyright (c) 2002 Erik Fears
3 * Copyright (c) 2014-2015 ircd-hybrid development team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18 * USA
19 */
20
21 #include "setup.h"
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <time.h>
27
28 #include "options.h"
29 #include "irc.h"
30 #include "log.h"
31 #include "main.h"
32 #include "config.h"
33 #include "opercmd.h"
34 #include "scan.h"
35 #include "memory.h"
36 #include "list.h"
37 #include "stats.h"
38
39
40 static list_t COMMANDS; /* List of active commands */
41
42
43 /* cmd_check
44 *
45 * Start a manual scan on given IP address/hostname.
46 *
47 * Parameters:
48 * param: Parameters of the command
49 * target: channel command was sent to
50 *
51 */
52 static void
53 cmd_check(char *param, const struct ChannelConf *target)
54 {
55 scan_manual(param, target);
56 }
57
58 /* cmd_stat
59 *
60 * Send output of stats to channel.
61 *
62 * Parameters:
63 * param: Parameters of the command
64 * target: channel command was sent to
65 */
66 static void
67 cmd_stats(char *param, const struct ChannelConf *target)
68 {
69 stats_output(target->name);
70 }
71
72 /* cmd_fdstat
73 *
74 * Send output of stats to channel.
75 *
76 * Parameters:
77 * param: Parameters of the command
78 * target: channel command was sent to
79 */
80 static void
81 cmd_fdstat(char *param, const struct ChannelConf *target)
82 {
83 fdstats_output(target->name);
84 }
85
86 static void
87 cmd_protocols(char *param, const struct ChannelConf *target)
88 {
89 node_t *node, *node2;
90
91 LIST_FOREACH(node, ScannerItemList->head)
92 {
93 const struct ScannerConf *sc = node->data;
94 irc_send("PRIVMSG %s :Scanner: '%s'", target->name, sc->name);
95
96 LIST_FOREACH(node2, sc->protocols->head)
97 {
98 const struct ProtocolConf *proto = node2->data;
99 irc_send("PRIVMSG %s : %s:%d", target->name, scan_gettype(proto->type), proto->port);
100 }
101 }
102 }
103
104 /* command_create
105 *
106 * Create a Command struct.
107 *
108 * Parameters:
109 * type: Index in COMMAND_TABLE
110 * param: Parameters to the command (NULL if there are not any)
111 * irc_nick: Nickname of user that initiated the command
112 * target: Target channel (target is ALWAYS a channel)
113 *
114 * Return:
115 * Pointer to new Command
116 */
117 static struct Command *
118 command_create(const struct OperCommandHash *tab, const char *param, const char *irc_nick,
119 const struct ChannelConf *target)
120 {
121 struct Command *command = xcalloc(sizeof(*command));
122
123 if (param)
124 command->param = xstrdup(param);
125
126 command->tab = tab;
127 command->irc_nick = xstrdup(irc_nick);
128 command->target = target;
129
130 time(&command->added);
131
132 return command;
133 }
134
135 /* command_free
136 *
137 * Free a command struct
138 *
139 * Parameters:
140 * command: Command struct to free
141 *
142 * Return: NONE
143 */
144 static void
145 command_free(struct Command *command)
146 {
147 if (command->param)
148 xfree(command->param);
149
150 xfree(command->irc_nick);
151 xfree(command);
152 }
153
154 /* command_parse
155 *
156 * Parse a command to hopm (sent to a channel hopm is on). The command is parsed
157 * from the parameters, and if it is a known command it is stored in a queue. A
158 * userhost is performed on the user to check if they are an IRC operator. When
159 * a reply is returned (command_userhost), the command will be executed.
160 *
161 * Parameters:
162 * command: Command sent (including parameters)
163 * target: Channel command was sent to (we only got this far if there was only one recipient)
164 * source_p: Operator (hopefully) that sent the command.
165 *
166 */
167 void
168 command_parse(const char *command, const struct ChannelConf *target, const char *source_p)
169 {
170 char *param; /* Parsed parameters */
171 static const struct OperCommandHash COMMAND_TABLE[] =
172 {
173 { "CHECK", cmd_check },
174 { "SCAN", cmd_check },
175 { "STATS", cmd_stats },
176 { "FDSTAT", cmd_fdstat },
177 { "PROTOCOLS", cmd_protocols },
178 { NULL, NULL }
179 };
180
181 if (OPT_DEBUG)
182 log_printf("COMMAND -> Parsing command (%s) from %s [%s]", command,
183 source_p, target->name);
184
185 /* Only allow COMMANDMAX commands in the queue */
186 if (LIST_SIZE(&COMMANDS) >= COMMANDMAX)
187 return;
188
189 /*
190 * Parameter is the first character in command after the first space.
191 * param will be NULL if:
192 * 1. There was no space
193 * 2. There was a space but it was the last character in command, in which case
194 * param = '\0'
195 */
196
197 /* Skip past the botname/!all */
198 command = strchr(command, ' ');
199
200 /* TBD: skip leading spaces if there's more than one */
201 /*
202 * There is no command OR there is at least nothing
203 * past that first space.
204 */
205 if (command == NULL || *++command == '\0')
206 return;
207
208 /* Find the parameters */
209 param = strchr(command, ' ');
210
211 if (param)
212 {
213 *param = '\0';
214 param++;
215 }
216
217 log_printf("COMMAND -> parsed [%s] [%s]", command, param ? param : "");
218
219 /* Lookup the command in the table */
220 for (const struct OperCommandHash *tab = COMMAND_TABLE; tab->command; ++tab)
221 {
222 if (strcasecmp(command, tab->command) == 0)
223 {
224 /* Queue this command */
225 struct Command *cmd = command_create(tab, param, source_p, target);
226
227 list_add(&COMMANDS, node_create(cmd));
228 break;
229 }
230 }
231
232 irc_send("USERHOST %s", source_p);
233 }
234
235 /* command_timer
236 *
237 * Perform ~1 second actions.
238 *
239 * Parameters: NONE
240 *
241 * Return: NONE
242 *
243 */
244 void
245 command_timer(void)
246 {
247 static unsigned int interval;
248 node_t *node, *node_next;
249 time_t present;
250
251 /* Only perform command removal every COMMANDINTERVAL seconds */
252 if (interval++ < COMMANDINTERVAL)
253 return;
254 else
255 interval = 0;
256
257 time(&present);
258
259 LIST_FOREACH_SAFE(node, node_next, COMMANDS.head)
260 {
261 struct Command *command = node->data;
262
263 if ((present - command->added) > COMMANDTIMEOUT)
264 {
265 command_free(command);
266 list_remove(&COMMANDS, node);
267 node_free(node);
268 }
269 else /* Since the queue is in order, it's also ordered by time, no nodes after this will be timed out */
270 return;
271 }
272 }
273
274 /* command_userhost
275 *
276 * A 302 reply was received. The reply is parsed to check if the
277 * user was an operator. If so any commands they had queued are
278 * executed.
279 *
280 * Parameters:
281 * reply: Reply to USERHOST (ex: :grifferz*=+goats@pc-62-30-219-54-pb.blueyonder.co.uk)
282 *
283 * Return: NONE
284 *
285 */
286 void
287 command_userhost(const char *reply)
288 {
289 node_t *node, *node_next;
290 char *tmp;
291 int oper = 0;
292
293 tmp = strchr(reply, '=');
294
295 /* They quit, ignore it */
296 if (tmp == NULL)
297 return;
298
299 /* Operators have a * flag in a USERHOST reply */
300 if (*(tmp - 1) == '*')
301 oper = 1;
302
303 /* Null terminate it so tmp = the oper's nick */
304 if (oper)
305 *(--tmp) = '\0';
306 else
307 *(tmp) = '\0';
308
309 /* Find any queued commands that match this user */
310 LIST_FOREACH_SAFE(node, node_next, COMMANDS.head)
311 {
312 struct Command *command = node->data;
313
314 if (strcmp(command->irc_nick, reply) == 0)
315 {
316 if (oper)
317 command->tab->handler(command->param, command->target);
318
319 /* Cleanup the command */
320 command_free(command);
321 list_remove(&COMMANDS, node);
322 node_free(node);
323 }
324 }
325 }

Properties

Name Value
svn:eol-style native
svn:keywords Id