ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/opercmd.c
Revision: 5274
Committed: Thu Jan 1 20:00:33 2015 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 8028 byte(s)
Log Message:
- Renamed MyMalloc() to xcalloc()

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

Properties

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