ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/opercmd.c
Revision: 5280
Committed: Fri Jan 2 20:31:46 2015 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 8020 byte(s)
Log Message:
- Use 'const' and 'unsigned' whenever possible
- Removed pointless 0 assignments

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

Properties

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