ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/releases/1.0.4/src/opercmd.c
Revision: 5717
Committed: Tue Mar 17 19:12:28 2015 UTC (9 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 8389 byte(s)
Log Message:
RELEASE TAG 1.0.4

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 = NULL; /* List of active commands */
41
42
43 static struct Command *command_create(const struct OperCommandHash *, char *param, char *irc_nick, const struct ChannelConf *target);
44 static void command_free(struct Command *);
45
46 static void cmd_check(char *, const struct ChannelConf *);
47 static void cmd_stat(char *, const struct ChannelConf *);
48 static void cmd_fdstat(char *, const struct ChannelConf *);
49 static void cmd_protocols(char *, const struct ChannelConf *);
50
51 static const struct OperCommandHash COMMAND_TABLE[] =
52 {
53 { "CHECK", cmd_check },
54 { "SCAN", cmd_check },
55 { "STAT", cmd_stat },
56 { "STATS", cmd_stat },
57 { "STATUS", cmd_stat },
58 { "FDSTAT", cmd_fdstat },
59 { "PROTOCOLS", cmd_protocols },
60 { NULL, NULL }
61 };
62
63
64 /* command_init
65 *
66 * Do command initialization
67 *
68 * Parameters: NONE
69 * Return: NONE
70 *
71 */
72 void
73 command_init(void)
74 {
75 if (COMMANDS == NULL)
76 COMMANDS = list_create();
77 }
78
79 /* command_timer
80 *
81 * Perform ~1 second actions.
82 *
83 * Parameters: NONE
84 *
85 * Return: NONE
86 *
87 */
88 void
89 command_timer(void)
90 {
91 static unsigned int interval;
92 node_t *node, *node_next;
93 time_t present;
94
95 /* Only perform command removal every COMMANDINTERVAL seconds */
96 if (interval++ < COMMANDINTERVAL)
97 return;
98 else
99 interval = 0;
100
101 time(&present);
102
103 LIST_FOREACH_SAFE(node, node_next, COMMANDS->head)
104 {
105 struct Command *cs = node->data;
106
107 if ((present - cs->added) > COMMANDTIMEOUT)
108 {
109 command_free(cs);
110 list_remove(COMMANDS, node);
111 node_free(node);
112 }
113 else /* Since the queue is in order, it's also ordered by time, no nodes after this will be timed out */
114 return;
115 }
116 }
117
118 /* command_parse
119 *
120 * Parse a command to hopm (sent to a channel hopm is on). The command is parsed
121 * from the parameters, and if it is a known command it is stored in a queue. A
122 * userhost is performed on the user to check if they are an IRC operator. When
123 * a reply is returned (command_userhost), the command will be executed.
124 *
125 * Parameters:
126 * command: Command sent (including parameters)
127 * target: Channel command was sent to (we only got this far if there was only one recipient)
128 * source_p: Operator (hopefully) that sent the command.
129 *
130 */
131 void
132 command_parse(char *command, const struct ChannelConf *target,
133 const struct UserInfo *source_p)
134 {
135 char *param; /* Parsed parameters */
136
137 if (OPT_DEBUG)
138 log_printf("COMMAND -> Parsing command (%s) from %s [%s]", command,
139 source_p->irc_nick, target->name);
140
141 /* Only allow COMMANDMAX commands in the queue */
142 if (LIST_SIZE(COMMANDS) >= COMMANDMAX)
143 return;
144
145 /*
146 * Parameter is the first character in command after the first space.
147 * param will be NULL if:
148 * 1. There was no space
149 * 2. There was a space but it was the last character in command, in which case
150 * param = '\0'
151 */
152
153 /* Skip past the botname/!all */
154 command = strchr(command, ' ');
155
156 /* TBD: skip leading spaces if there's more than one */
157 /*
158 * There is no command OR there is at least nothing
159 * past that first space.
160 */
161 if (command == NULL || *++command == '\0')
162 return;
163
164 /* Find the parameters */
165 param = strchr(command, ' ');
166
167 if (param)
168 {
169 *param = '\0';
170 param++;
171 }
172
173 log_printf("COMMAND -> parsed [%s] [%s]", command, param ? param : "");
174
175 /* Lookup the command in the table */
176 for (const struct OperCommandHash *tab = COMMAND_TABLE; tab->command; ++tab)
177 {
178 if (strcasecmp(command, tab->command) == 0)
179 {
180 /* Queue this command */
181 struct Command *cs = command_create(tab, param, source_p->irc_nick, target);
182
183 list_add(COMMANDS, node_create(cs));
184 break;
185 }
186 }
187
188 irc_send("USERHOST %s", source_p->irc_nick);
189 }
190
191 /* command_create
192 *
193 * Create a Command struct.
194 *
195 * Parameters:
196 * type: Index in COMMAND_TABLE
197 * param: Parameters to the command (NULL if there are not any)
198 * irc_nick: Nickname of user that initiated the command
199 * target: Target channel (target is ALWAYS a channel)
200 *
201 * Return:
202 * Pointer to new Command
203 */
204 static struct Command *
205 command_create(const struct OperCommandHash *tab, char *param, char *irc_nick,
206 const struct ChannelConf *target)
207 {
208 struct Command *const ret = xcalloc(sizeof *ret);
209
210 if (param)
211 ret->param = xstrdup(param);
212
213 ret->tab = tab;
214 ret->irc_nick = xstrdup(irc_nick);
215 ret->target = target; /* FIXME: This needs fixed if rehash is implemented */
216
217 time(&ret->added);
218
219 return ret;
220 }
221
222 /* command_free
223 *
224 * Free a command struct
225 *
226 * Parameters:
227 * command: Command struct to free
228 *
229 * Return: NONE
230 */
231 static void
232 command_free(struct Command *command)
233 {
234 if (command->param)
235 xfree(command->param);
236
237 xfree(command->irc_nick);
238 xfree(command);
239 }
240
241 /* command_userhost
242 *
243 * A 302 reply was received. The reply is parsed to check if the
244 * user was an operator. If so any commands they had queued are
245 * executed.
246 *
247 * Parameters:
248 * reply: Reply to USERHOST (ex: :grifferz*=+goats@pc-62-30-219-54-pb.blueyonder.co.uk)
249 *
250 * Return: NONE
251 *
252 */
253 void
254 command_userhost(const char *reply)
255 {
256 node_t *node, *node_next;
257 char *tmp;
258 int oper = 0;
259
260 tmp = strchr(reply, '=');
261
262 /* They quit, ignore it */
263 if (tmp == NULL)
264 return;
265
266 /* Operators have a * flag in a USERHOST reply */
267 if (*(tmp - 1) == '*')
268 oper = 1;
269
270 /* Null terminate it so tmp = the oper's nick */
271 if (oper)
272 *(--tmp) = '\0';
273 else
274 *(tmp) = '\0';
275
276 /* Find any queued commands that match this user */
277 LIST_FOREACH_SAFE(node, node_next, COMMANDS->head)
278 {
279 struct Command *cs = node->data;
280
281 if (strcmp(cs->irc_nick, reply) == 0)
282 {
283 if (oper)
284 cs->tab->handler(cs->param, cs->target);
285
286 /* Cleanup the command */
287 command_free(cs);
288 list_remove(COMMANDS, node);
289 node_free(node);
290 }
291 }
292 }
293
294 /* cmd_check
295 *
296 * Start a manual scan on given IP address/hostname.
297 *
298 * Parameters:
299 * param: Parameters of the command
300 * target: channel command was sent to
301 *
302 */
303 static void
304 cmd_check(char *param, const struct ChannelConf *target)
305 {
306 scan_manual(param, target);
307 }
308
309 /* cmd_stat
310 *
311 * Send output of stats to channel.
312 *
313 * Parameters:
314 * param: Parameters of the command
315 * target: channel command was sent to
316 */
317 static void
318 cmd_stat(char *param, const struct ChannelConf *target)
319 {
320 stats_output(target->name);
321 }
322
323 /* cmd_fdstat
324 *
325 * Send output of stats to channel.
326 *
327 * Parameters:
328 * param: Parameters of the command
329 * target: channel command was sent to
330 */
331 static void
332 cmd_fdstat(char *param, const struct ChannelConf *target)
333 {
334 fdstats_output(target->name);
335 }
336
337 static void
338 cmd_protocols(char *param, const struct ChannelConf *target)
339 {
340 node_t *node, *node2;
341
342 LIST_FOREACH(node, ScannerItemList->head)
343 {
344 const struct ScannerConf *sc = node->data;
345 irc_send("PRIVMSG %s :Scanner: '%s'", target->name, sc->name);
346
347 LIST_FOREACH(node2, sc->protocols->head)
348 {
349 const struct ProtocolConf *proto = node2->data;
350 irc_send("PRIVMSG %s : %s:%d", target->name, scan_gettype(proto->type), proto->port);
351 }
352 }
353 }

Properties

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