/[svn]/hopm/trunk/src/opercmd.c
ViewVC logotype

Contents of /hopm/trunk/src/opercmd.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9865 - (show annotations)
Sat Jan 2 18:42:37 2021 UTC (22 months, 4 weeks ago) by michael
File MIME type: text/x-chdr
File size: 7205 byte(s)
- Bump copyright years

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

Properties

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28