ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/opercmd.c
Revision: 5876
Committed: Wed Apr 29 11:25:48 2015 UTC (10 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 8321 byte(s)
Log Message:
- Removed trailing whitespaces

File Contents

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

Properties

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