ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/opercmd.c
Revision: 5354
Committed: Sun Jan 11 17:15:43 2015 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 7890 byte(s)
Log Message:
- command_parse(): removed 'msg' parameter. We actually only need this for
  m_notice() as proof for reporting insecure proxies to a dnsbl provider.

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 <netinet/in.h>
27     #include <time.h>
28    
29     #include "options.h"
30     #include "irc.h"
31     #include "log.h"
32 michael 5202 #include "main.h"
33 michael 5052 #include "misc.h"
34     #include "opercmd.h"
35     #include "scan.h"
36     #include "config.h"
37 michael 5333 #include "memory.h"
38 michael 5052 #include "list.h"
39     #include "stats.h"
40    
41    
42 michael 5287 static list_t *COMMANDS = NULL; /* List of active commands */
43 michael 5052
44    
45 michael 5338 static struct Command *command_create(const struct OperCommandHash *, char *param, char *irc_nick, const struct ChannelConf *target);
46 michael 5052 static void command_free(struct Command *);
47    
48 michael 5338 static void cmd_check(char *, const struct ChannelConf *);
49     static void cmd_stat(char *, const struct ChannelConf *);
50     static void cmd_fdstat(char *, const struct ChannelConf *);
51 michael 5052
52 michael 5338 static const struct OperCommandHash COMMAND_TABLE[] =
53 michael 5114 {
54 michael 5287 { "CHECK", cmd_check },
55     { "SCAN", cmd_check },
56     { "STAT", cmd_stat },
57     { "STATS", cmd_stat },
58     { "STATUS", cmd_stat },
59     { "FDSTAT", cmd_fdstat },
60     { NULL, NULL }
61 michael 5114 };
62 michael 5052
63    
64     /* command_init
65     *
66     * 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     *
85     * Return: NONE
86     *
87     */
88 michael 5114 void
89     command_timer(void)
90 michael 5052 {
91 michael 5279 static unsigned int interval;
92 michael 5114 node_t *node, *next;
93     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 5114 LIST_FOREACH_SAFE(node, next, COMMANDS->head)
104     {
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     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     else
173     param = "";
174 michael 5052
175 michael 5114 log_printf("COMMAND -> parsed [%s] [%s]", command, param);
176 michael 5052
177 michael 5114 /* Lookup the command in the table */
178 michael 5287 for (const struct OperCommandHash *tab = COMMAND_TABLE; tab->command; ++tab)
179 michael 5114 {
180 michael 5287 if (strcasecmp(command, tab->command) == 0)
181 michael 5114 {
182     /* Queue this command */
183 michael 5287 struct Command *cs = command_create(tab, param, source_p->irc_nick, target);
184    
185     list_add(COMMANDS, node_create(cs));
186 michael 5339 break;
187 michael 5114 }
188     }
189 michael 5052
190 michael 5114 irc_send("USERHOST %s", source_p->irc_nick);
191 michael 5052 }
192    
193     /* command_create
194     *
195     * Create a Command struct.
196     *
197     * Parameters:
198     * type: Index in COMMAND_TABLE
199     * param: Parameters to the command (NULL if there are not any)
200     * irc_nick: Nickname of user that initiated the command
201     * target: Target channel (target is ALWAYS a channel)
202     *
203     * Return:
204     * Pointer to new Command
205     */
206 michael 5114 static struct Command *
207 michael 5338 command_create(const struct OperCommandHash *tab, char *param, char *irc_nick,
208     const struct ChannelConf *target)
209 michael 5052 {
210 michael 5338 struct Command *const ret = xcalloc(sizeof *ret);
211 michael 5052
212 michael 5114 if (param)
213     ret->param = xstrdup(param);
214 michael 5052
215 michael 5287 ret->tab = tab;
216 michael 5114 ret->irc_nick = xstrdup(irc_nick);
217     ret->target = target; /* FIXME: This needs fixed if rehash is implemented */
218 michael 5052
219 michael 5114 time(&(ret->added));
220 michael 5052
221 michael 5114 return ret;
222 michael 5052 }
223    
224     /* command_free
225     *
226     * Free a command struct
227     *
228     * Parameters:
229     * command: Command struct to free
230     *
231     * Return: NONE
232     */
233 michael 5114 static void
234     command_free(struct Command *command)
235     {
236     if (command->param)
237     MyFree(command->param);
238 michael 5052
239 michael 5114 MyFree(command->irc_nick);
240     MyFree(command);
241 michael 5052 }
242    
243     /* command_userhost
244     *
245     * A 302 reply was received. The reply is parsed to check if the
246 michael 5114 * user was an operator. If so any commands they had queued are
247 michael 5052 * executed.
248     *
249     * Parameters:
250     * reply: Reply to USERHOST (ex: :grifferz*=+goats@pc-62-30-219-54-pb.blueyonder.co.uk)
251     *
252     * Return: NONE
253     *
254     */
255 michael 5114 void
256 michael 5291 command_userhost(const char *reply)
257 michael 5052 {
258 michael 5114 node_t *node, *next;
259     char *tmp;
260     int oper = 0;
261 michael 5052
262 michael 5114 tmp = strchr(reply, '=');
263 michael 5052
264 michael 5114 /* They quit, ignore it */
265     if (tmp == NULL)
266     return;
267 michael 5052
268 michael 5114 /* Operators have a * flag in a USERHOST reply */
269     if (*(tmp - 1) == '*')
270     oper = 1;
271 michael 5052
272 michael 5114 /* Null terminate it so tmp = the oper's nick */
273     if (oper)
274     *(--tmp) = '\0';
275 michael 5052 else
276 michael 5114 *(tmp) = '\0';
277 michael 5052
278 michael 5114 /* Find any queued commands that match this user */
279     LIST_FOREACH_SAFE(node, next, COMMANDS->head)
280     {
281     struct Command *cs = node->data;
282 michael 5052
283 michael 5114 if (strcmp(cs->irc_nick, reply) == 0)
284     {
285     if (oper)
286 michael 5291 cs->tab->handler(cs->param, cs->target);
287 michael 5052
288 michael 5114 /* Cleanup the command */
289     command_free(cs);
290     list_remove(COMMANDS, node);
291     node_free(node);
292     }
293     }
294 michael 5052 }
295    
296     /* cmd_check
297     *
298 michael 5069 * Start a manual scan on given IP. Parameter MUST be an IP. HOPM should not
299 michael 5052 * have to waste any time resolving a hostname.
300     *
301     * Parameters:
302     * param: Parameters of the command
303     * target: channel command was sent to
304     *
305     */
306 michael 5114 static void
307 michael 5338 cmd_check(char *param, const struct ChannelConf *target)
308 michael 5052 {
309 michael 5084 scan_manual(param, target);
310 michael 5052 }
311    
312     /* cmd_stat
313     *
314     * Send output of stats to channel.
315     *
316     * Parameters:
317     * param: Parameters of the command
318     * target: channel command was sent to
319     */
320 michael 5114 static void
321 michael 5338 cmd_stat(char *param, const struct ChannelConf *target)
322 michael 5052 {
323 michael 5084 stats_output(target->name);
324 michael 5052 }
325    
326     /* cmd_fdstat
327     *
328     * Send output of stats to channel.
329     *
330     * Parameters:
331     * param: Parameters of the command
332     * target: channel command was sent to
333     */
334 michael 5114 static void
335 michael 5338 cmd_fdstat(char *param, const struct ChannelConf *target)
336 michael 5052 {
337 michael 5084 fdstats_output(target->name);
338 michael 5052 }

Properties

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