ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/opercmd.c
Revision: 5426
Committed: Wed Jan 28 13:49:38 2015 UTC (10 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 7770 byte(s)
Log Message:
- memory.c:MyFree(): removed extraneous pointer test; renamed MyFree to xfree

File Contents

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

Properties

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