ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/opercmd.c
Revision: 5135
Committed: Thu Dec 25 18:51:51 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 8091 byte(s)
Log Message:
- propset svn:eol-style native

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

Properties

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