ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/opercmd.c
Revision: 6147
Committed: Sun Jun 14 16:36:55 2015 UTC (8 years, 10 months ago) by michael
Content type: text/x-csrc
File size: 7869 byte(s)
Log Message:
- opercmd.c: renamed cmd_stat() to cmd_stats()

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; /* List of active commands */
41
42
43 /* 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
58 /* 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 cmd_stats(char *param, const struct ChannelConf *target)
68 {
69 stats_output(target->name);
70 }
71
72 /* 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 {
83 fdstats_output(target->name);
84 }
85
86 static void
87 cmd_protocols(char *param, const struct ChannelConf *target)
88 {
89 node_t *node, *node2;
90
91 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 /* command_init
105 *
106 * Do command initialization
107 *
108 * Parameters: NONE
109 * Return: NONE
110 *
111 */
112 void
113 command_init(void)
114 {
115 if (COMMANDS == NULL)
116 COMMANDS = list_create();
117 }
118
119 /* command_create
120 *
121 * Create a Command struct.
122 *
123 * 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 *
129 * Return:
130 * Pointer to new Command
131 */
132 static struct Command *
133 command_create(const struct OperCommandHash *tab, char *param, char *irc_nick,
134 const struct ChannelConf *target)
135 {
136 struct Command *command = xcalloc(sizeof *command);
137
138 if (param)
139 command->param = xstrdup(param);
140
141 command->tab = tab;
142 command->irc_nick = xstrdup(irc_nick);
143 command->target = target;
144
145 time(&command->added);
146
147 return command;
148 }
149
150 /* 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 /* command_parse
170 *
171 * Parse a command to hopm (sent to a channel hopm is on). The command is parsed
172 * 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 void
183 command_parse(char *command, const struct ChannelConf *target,
184 const struct UserInfo *source_p)
185 {
186 char *param; /* Parsed parameters */
187 static const struct OperCommandHash COMMAND_TABLE[] =
188 {
189 { "CHECK", cmd_check },
190 { "SCAN", cmd_check },
191 { "STATS", cmd_stats },
192 { "FDSTAT", cmd_fdstat },
193 { "PROTOCOLS", cmd_protocols },
194 { NULL, NULL }
195 };
196
197 if (OPT_DEBUG)
198 log_printf("COMMAND -> Parsing command (%s) from %s [%s]", command,
199 source_p->irc_nick, target->name);
200
201 /* Only allow COMMANDMAX commands in the queue */
202 if (LIST_SIZE(COMMANDS) >= COMMANDMAX)
203 return;
204
205 /*
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 */
212
213 /* Skip past the botname/!all */
214 command = strchr(command, ' ');
215
216 /* 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
224 /* Find the parameters */
225 param = strchr(command, ' ');
226
227 if (param)
228 {
229 *param = '\0';
230 param++;
231 }
232
233 log_printf("COMMAND -> parsed [%s] [%s]", command, param ? param : "");
234
235 /* Lookup the command in the table */
236 for (const struct OperCommandHash *tab = COMMAND_TABLE; tab->command; ++tab)
237 {
238 if (strcasecmp(command, tab->command) == 0)
239 {
240 /* Queue this command */
241 struct Command *cs = command_create(tab, param, source_p->irc_nick, target);
242
243 list_add(COMMANDS, node_create(cs));
244 break;
245 }
246 }
247
248 irc_send("USERHOST %s", source_p->irc_nick);
249 }
250
251 /* command_timer
252 *
253 * Perform ~1 second actions.
254 *
255 * Parameters: NONE
256 *
257 * Return: NONE
258 *
259 */
260 void
261 command_timer(void)
262 {
263 static unsigned int interval;
264 node_t *node, *node_next;
265 time_t present;
266
267 /* Only perform command removal every COMMANDINTERVAL seconds */
268 if (interval++ < COMMANDINTERVAL)
269 return;
270 else
271 interval = 0;
272
273 time(&present);
274
275 LIST_FOREACH_SAFE(node, node_next, COMMANDS->head)
276 {
277 struct Command *cs = node->data;
278
279 if ((present - cs->added) > COMMANDTIMEOUT)
280 {
281 command_free(cs);
282 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 }
289
290 /* command_userhost
291 *
292 * A 302 reply was received. The reply is parsed to check if the
293 * user was an operator. If so any commands they had queued are
294 * executed.
295 *
296 * Parameters:
297 * reply: Reply to USERHOST (ex: :grifferz*=+goats@pc-62-30-219-54-pb.blueyonder.co.uk)
298 *
299 * Return: NONE
300 *
301 */
302 void
303 command_userhost(const char *reply)
304 {
305 node_t *node, *node_next;
306 char *tmp;
307 int oper = 0;
308
309 tmp = strchr(reply, '=');
310
311 /* They quit, ignore it */
312 if (tmp == NULL)
313 return;
314
315 /* Operators have a * flag in a USERHOST reply */
316 if (*(tmp - 1) == '*')
317 oper = 1;
318
319 /* Null terminate it so tmp = the oper's nick */
320 if (oper)
321 *(--tmp) = '\0';
322 else
323 *(tmp) = '\0';
324
325 /* Find any queued commands that match this user */
326 LIST_FOREACH_SAFE(node, node_next, COMMANDS->head)
327 {
328 struct Command *cs = node->data;
329
330 if (strcmp(cs->irc_nick, reply) == 0)
331 {
332 if (oper)
333 cs->tab->handler(cs->param, cs->target);
334
335 /* Cleanup the command */
336 command_free(cs);
337 list_remove(COMMANDS, node);
338 node_free(node);
339 }
340 }
341 }

Properties

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