ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/opercmd.c
Revision: 5207
Committed: Mon Dec 29 19:38:22 2014 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 8059 byte(s)
Log Message:
- Removed AC_HEADER_STDC configure test

File Contents

# User Rev Content
1 michael 5052 /*
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 michael 5207 #include <string.h>
26     #include <stdlib.h>
27 michael 5052 #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 michael 5202 #include "main.h"
35 michael 5052 #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 michael 5114 list_t *COMMANDS = NULL; /* List of active commands */
45 michael 5052
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 michael 5114 {
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 michael 5052
64    
65     /* command_init
66     *
67     * Do command initialization
68     *
69     * Parameters: NONE
70     * Return: NONE
71     *
72     */
73 michael 5114 void
74     command_init(void)
75 michael 5052 {
76 michael 5114 if (COMMANDS == NULL)
77     COMMANDS = list_create();
78 michael 5052 }
79    
80     /* command_timer
81     *
82     * Perform ~1 second actions.
83     *
84     * Parameters: NONE
85     *
86     * Return: NONE
87     *
88     */
89 michael 5114 void
90     command_timer(void)
91 michael 5052 {
92 michael 5114 static unsigned short interval;
93     node_t *node, *next;
94     struct Command *cs;
95     time_t present;
96 michael 5052
97 michael 5114 /* Only perform command removal every COMMANDINTERVAL seconds */
98     if (interval++ < COMMANDINTERVAL)
99     return;
100     else
101     interval = 0;
102 michael 5052
103 michael 5114 time(&present);
104 michael 5052
105 michael 5114 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 michael 5052 return;
117 michael 5114 }
118 michael 5052 }
119    
120     /* command_parse
121     *
122 michael 5069 * Parse a command to hopm (sent to a channel hopm is on). The command is parsed
123 michael 5052 * 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 michael 5114 void
135     command_parse(char *command, char *msg, struct ChannelConf *target,
136     struct UserInfo *source_p)
137 michael 5052 {
138 michael 5114 char *param; /* Parsed parameters */
139     struct Command *cs;
140     node_t *node;
141 michael 5052
142 michael 5114 if (OPT_DEBUG)
143     log_printf("COMMAND -> Parsing command (%s) from %s [%s]", command,
144     source_p->irc_nick, target->name);
145 michael 5052
146 michael 5114 /* Only allow COMMANDMAX commands in the queue */
147     if (LIST_SIZE(COMMANDS) >= COMMANDMAX)
148     return;
149 michael 5052
150 michael 5114 /*
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 michael 5052 */
157    
158 michael 5114 /* Skip past the botname/!all */
159     command = strchr(command, ' ');
160 michael 5052
161 michael 5114 /* 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 michael 5052
169 michael 5114 /* Find the parameters */
170     param = strchr(command, ' ');
171 michael 5052
172 michael 5114 if (param)
173     {
174     *param = '\0';
175     param++;
176     }
177     else
178     param = "";
179 michael 5052
180 michael 5114 log_printf("COMMAND -> parsed [%s] [%s]", command, param);
181 michael 5052
182 michael 5114 /* 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 michael 5052
194 michael 5114 irc_send("USERHOST %s", source_p->irc_nick);
195 michael 5052 }
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 michael 5114 static struct Command *
211     command_create(unsigned short type, char *param, char *irc_nick, struct ChannelConf *target)
212 michael 5052 {
213 michael 5114 struct Command *ret = MyMalloc(sizeof *ret);
214 michael 5052
215 michael 5114 ret->type = type;
216 michael 5052
217 michael 5114 if (param)
218     ret->param = xstrdup(param);
219     else
220     ret->param = NULL;
221 michael 5052
222 michael 5114 ret->irc_nick = xstrdup(irc_nick);
223     ret->target = target; /* FIXME: This needs fixed if rehash is implemented */
224 michael 5052
225 michael 5114 time(&(ret->added));
226 michael 5052
227 michael 5114 return ret;
228 michael 5052 }
229    
230     /* command_free
231     *
232     * Free a command struct
233     *
234     * Parameters:
235     * command: Command struct to free
236     *
237     * Return: NONE
238     */
239 michael 5114 static void
240     command_free(struct Command *command)
241     {
242     if (command->param)
243     MyFree(command->param);
244 michael 5052
245 michael 5114 MyFree(command->irc_nick);
246     MyFree(command);
247 michael 5052 }
248    
249     /* command_userhost
250     *
251     * A 302 reply was received. The reply is parsed to check if the
252 michael 5114 * user was an operator. If so any commands they had queued are
253 michael 5052 * executed.
254     *
255     * Parameters:
256     * reply: Reply to USERHOST (ex: :grifferz*=+goats@pc-62-30-219-54-pb.blueyonder.co.uk)
257     *
258     * Return: NONE
259     *
260     */
261 michael 5114 void
262     command_userhost(char *reply)
263 michael 5052 {
264 michael 5114 node_t *node, *next;
265     char *tmp;
266     int oper = 0;
267 michael 5052
268 michael 5114 tmp = strchr(reply, '=');
269 michael 5052
270 michael 5114 /* They quit, ignore it */
271     if (tmp == NULL)
272     return;
273 michael 5052
274 michael 5114 /* Operators have a * flag in a USERHOST reply */
275     if (*(tmp - 1) == '*')
276     oper = 1;
277 michael 5052
278 michael 5114 /* Null terminate it so tmp = the oper's nick */
279     if (oper)
280     *(--tmp) = '\0';
281 michael 5052 else
282 michael 5114 *(tmp) = '\0';
283 michael 5052
284 michael 5114 /* Find any queued commands that match this user */
285     LIST_FOREACH_SAFE(node, next, COMMANDS->head)
286     {
287     struct Command *cs = node->data;
288 michael 5052
289 michael 5114 if (strcmp(cs->irc_nick, reply) == 0)
290     {
291     if (oper)
292     COMMAND_TABLE[cs->type].handler(cs->param, cs->irc_nick, cs->target);
293 michael 5052
294 michael 5114 /* Cleanup the command */
295     command_free(cs);
296     list_remove(COMMANDS, node);
297     node_free(node);
298     }
299     }
300 michael 5052 }
301    
302     /* cmd_check
303     *
304 michael 5069 * Start a manual scan on given IP. Parameter MUST be an IP. HOPM should not
305 michael 5052 * have to waste any time resolving a hostname.
306     *
307     * Parameters:
308     * param: Parameters of the command
309     * source: irc_nick of user who requested the command
310     * target: channel command was sent to
311     *
312     */
313 michael 5114 static void
314     cmd_check(char *param, char *source, struct ChannelConf *target)
315 michael 5052 {
316 michael 5084 scan_manual(param, target);
317 michael 5052 }
318    
319     /* cmd_stat
320     *
321     * Send output of stats to channel.
322     *
323     * Parameters:
324     * param: Parameters of the command
325     * source: irc_nick of user who requested the command
326     * target: channel command was sent to
327     */
328 michael 5114 static void
329     cmd_stat(char *param, char *source, struct ChannelConf *target)
330 michael 5052 {
331 michael 5084 stats_output(target->name);
332 michael 5052 }
333    
334     /* cmd_fdstat
335     *
336     * Send output of stats to channel.
337     *
338     * Parameters:
339     * param: Parameters of the command
340     * source: irc_nick of user who requested the command
341     * target: channel command was sent to
342     */
343 michael 5114 static void
344     cmd_fdstat(char *param, char *source, struct ChannelConf *target)
345 michael 5052 {
346 michael 5084 fdstats_output(target->name);
347 michael 5052 }

Properties

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