ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/opercmd.c
Revision: 6148
Committed: Sun Jun 14 17:29:37 2015 UTC (11 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 7925 byte(s)
Log Message:
- Style corrections

File Contents

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

Properties

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