ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/opercmd.c
Revision: 5084
Committed: Mon Dec 22 19:57:43 2014 UTC (11 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 8321 byte(s)
Log Message:
- Removed USE_VAR cruft

File Contents

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