ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_set.c
Revision: 1832
Committed: Fri Apr 19 19:16:09 2013 UTC (12 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 16353 byte(s)
Log Message:
- Made all numeric defines use the actual string instead of the numeric value
  which allows to use gcc's printf format attribute
- Remove current message locale implementation

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_set.c: Sets a server parameter.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 /* rewritten by jdc */
26
27 #include "stdinc.h"
28 #include "client.h"
29 #include "event.h"
30 #include "irc_string.h"
31 #include "ircd.h"
32 #include "numeric.h"
33 #include "fdlist.h"
34 #include "s_bsd.h"
35 #include "s_serv.h"
36 #include "send.h"
37 #include "channel.h"
38 #include "conf.h"
39 #include "parse.h"
40 #include "modules.h"
41 #include "s_user.h"
42 #include "s_misc.h"
43
44
45 /* Structure used for the SET table itself */
46 struct SetStruct
47 {
48 const char *name;
49 void (*handler)();
50 const int wants_char; /* 1 if it expects (char *, [int]) */
51 const int wants_int; /* 1 if it expects ([char *], int) */
52 /* eg: 0, 1 == only an int arg
53 * eg: 1, 1 == char and int args */
54 };
55
56 static void quote_autoconn(struct Client *, const char *, int);
57 static void quote_autoconnall(struct Client *, int);
58 static void quote_floodcount(struct Client *, int);
59 static void quote_identtimeout(struct Client *, int);
60 static void quote_max(struct Client *, int);
61 static void quote_spamnum(struct Client *, int);
62 static void quote_spamtime(struct Client *, int);
63 static void quote_splitmode(struct Client *, char *);
64 static void quote_splitnum(struct Client *, int);
65 static void quote_splitusers(struct Client *, int);
66 static void list_quote_commands(struct Client *);
67 static void quote_jfloodtime(struct Client *, int);
68 static void quote_jfloodcount(struct Client *, int);
69
70 /*
71 * If this ever needs to be expanded to more than one arg of each
72 * type, want_char/want_int could be the count of the arguments,
73 * instead of just a boolean flag...
74 *
75 * -davidt
76 */
77
78 static const struct SetStruct set_cmd_table[] =
79 {
80 /* name function string arg int arg */
81 /* -------------------------------------------------------- */
82 { "AUTOCONN", quote_autoconn, 1, 1 },
83 { "AUTOCONNALL", quote_autoconnall, 0, 1 },
84 { "FLOODCOUNT", quote_floodcount, 0, 1 },
85 { "IDENTTIMEOUT", quote_identtimeout, 0, 1 },
86 { "MAX", quote_max, 0, 1 },
87 { "SPAMNUM", quote_spamnum, 0, 1 },
88 { "SPAMTIME", quote_spamtime, 0, 1 },
89 { "SPLITMODE", quote_splitmode, 1, 0 },
90 { "SPLITNUM", quote_splitnum, 0, 1 },
91 { "SPLITUSERS", quote_splitusers, 0, 1 },
92 { "JFLOODTIME", quote_jfloodtime, 0, 1 },
93 { "JFLOODCOUNT", quote_jfloodcount, 0, 1 },
94 /* -------------------------------------------------------- */
95 { NULL, NULL, 0, 0 }
96 };
97
98 /*
99 * list_quote_commands() sends the client all the available commands.
100 * Four to a line for now.
101 */
102 static void
103 list_quote_commands(struct Client *source_p)
104 {
105 int j = 0;
106 const struct SetStruct *tab = set_cmd_table;
107 const char *names[4] = { "", "", "", "" };
108
109 sendto_one(source_p, ":%s NOTICE %s :Available QUOTE SET commands:",
110 me.name, source_p->name);
111
112 for (; tab->handler; ++tab)
113 {
114 names[j++] = tab->name;
115
116 if (j > 3)
117 {
118 sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
119 me.name, source_p->name,
120 names[0], names[1],
121 names[2], names[3]);
122 j = 0;
123 names[0] = names[1] = names[2] = names[3] = "";
124 }
125
126 }
127
128 if (j)
129 sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
130 me.name, source_p->name,
131 names[0], names[1],
132 names[2], names[3]);
133 }
134
135 /* SET AUTOCONN */
136 static void
137 quote_autoconn(struct Client *source_p, const char *arg, int newval)
138 {
139 if (arg != NULL)
140 {
141 struct MaskItem *conf = find_exact_name_conf(CONF_SERVER, NULL, arg, NULL, NULL);
142
143 if (conf != NULL)
144 {
145 if (newval)
146 SetConfAllowAutoConn(conf);
147 else
148 ClearConfAllowAutoConn(conf);
149
150 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
151 "%s has changed AUTOCONN for %s to %i",
152 get_oper_name(source_p), arg, newval);
153 sendto_one(source_p,
154 ":%s NOTICE %s :AUTOCONN for %s is now set to %i",
155 me.name, source_p->name, arg, newval);
156 }
157 else
158 {
159 sendto_one(source_p, ":%s NOTICE %s :Can't find %s",
160 me.name, source_p->name, arg);
161 }
162 }
163 else
164 {
165 sendto_one(source_p, ":%s NOTICE %s :Please specify a server name!",
166 me.name, source_p->name);
167 }
168 }
169
170 /* SET AUTOCONNALL */
171 static void
172 quote_autoconnall(struct Client *source_p, int newval)
173 {
174 if (newval >= 0)
175 {
176 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
177 "%s has changed AUTOCONNALL to %i",
178 get_oper_name(source_p), newval);
179
180 GlobalSetOptions.autoconn = newval;
181 }
182 else
183 sendto_one(source_p, ":%s NOTICE %s :AUTOCONNALL is currently %i",
184 me.name, source_p->name, GlobalSetOptions.autoconn);
185 }
186
187 /* SET FLOODCOUNT */
188 static void
189 quote_floodcount(struct Client *source_p, int newval)
190 {
191 if (newval >= 0)
192 {
193 GlobalSetOptions.floodcount = newval;
194 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
195 "%s has changed FLOODCOUNT to %i",
196 get_oper_name(source_p), GlobalSetOptions.floodcount);
197 }
198 else
199 sendto_one(source_p, ":%s NOTICE %s :FLOODCOUNT is currently %i",
200 me.name, source_p->name, GlobalSetOptions.floodcount);
201 }
202
203 /* SET IDENTTIMEOUT */
204 static void
205 quote_identtimeout(struct Client *source_p, int newval)
206 {
207 if (!HasUMode(source_p, UMODE_ADMIN))
208 {
209 sendto_one(source_p, ERR_NOPRIVS,
210 me.name, source_p->name, "set");
211 return;
212 }
213
214 if (newval > 0)
215 {
216 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
217 "%s has changed IDENTTIMEOUT to %d",
218 get_oper_name(source_p), newval);
219 GlobalSetOptions.ident_timeout = newval;
220 }
221 else
222 sendto_one(source_p, ":%s NOTICE %s :IDENTTIMEOUT is currently %d",
223 me.name, source_p->name, GlobalSetOptions.ident_timeout);
224 }
225
226 /* SET MAX */
227 static void
228 quote_max(struct Client *source_p, int newval)
229 {
230 if (newval > 0)
231 {
232 if (newval > MAXCLIENTS_MAX)
233 {
234 sendto_one(source_p,
235 ":%s NOTICE %s :You cannot set MAXCLIENTS to > %d, restoring to %d",
236 me.name, source_p->name, MAXCLIENTS_MAX, ServerInfo.max_clients);
237 return;
238 }
239
240 if (newval < MAXCLIENTS_MIN)
241 {
242 sendto_one(source_p,
243 ":%s NOTICE %s :You cannot set MAXCLIENTS to < %d, restoring to %d",
244 me.name, source_p->name, MAXCLIENTS_MIN, ServerInfo.max_clients);
245 return;
246 }
247
248 ServerInfo.max_clients = newval;
249
250 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
251 "%s set new MAXCLIENTS to %d (%d current)",
252 get_oper_name(source_p), ServerInfo.max_clients, Count.local);
253 }
254 else
255 sendto_one(source_p, ":%s NOTICE %s :Current MAXCLIENTS = %d (%d)",
256 me.name, source_p->name, ServerInfo.max_clients, Count.local);
257 }
258
259 /* SET SPAMNUM */
260 static void
261 quote_spamnum(struct Client *source_p, int newval)
262 {
263 if (newval >= 0)
264 {
265 if (newval == 0)
266 {
267 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
268 "%s has disabled ANTI_SPAMBOT", source_p->name);
269 GlobalSetOptions.spam_num = newval;
270 return;
271 }
272
273 GlobalSetOptions.spam_num = IRCD_MAX(newval, MIN_SPAM_NUM);
274 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
275 "%s has changed SPAMNUM to %i",
276 get_oper_name(source_p), GlobalSetOptions.spam_num);
277 }
278 else
279 sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i",
280 me.name, source_p->name, GlobalSetOptions.spam_num);
281 }
282
283 /* SET SPAMTIME */
284 static void
285 quote_spamtime(struct Client *source_p, int newval)
286 {
287 if (newval > 0)
288 {
289 GlobalSetOptions.spam_time = IRCD_MAX(newval, MIN_SPAM_TIME);
290 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
291 "%s has changed SPAMTIME to %i",
292 get_oper_name(source_p), GlobalSetOptions.spam_time);
293 }
294 else
295 sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i",
296 me.name, source_p->name, GlobalSetOptions.spam_time);
297 }
298
299 /* this table is what splitmode may be set to */
300 static const char *splitmode_values[] =
301 {
302 "OFF",
303 "ON",
304 "AUTO",
305 NULL
306 };
307
308 /* this table is what splitmode may be */
309 static const char *splitmode_status[] =
310 {
311 "OFF",
312 "AUTO (OFF)",
313 "ON",
314 "AUTO (ON)",
315 NULL
316 };
317
318 /* SET SPLITMODE */
319 static void
320 quote_splitmode(struct Client *source_p, char *charval)
321 {
322 if (charval)
323 {
324 int newval;
325
326 for (newval = 0; splitmode_values[newval]; ++newval)
327 if (irccmp(splitmode_values[newval], charval) == 0)
328 break;
329
330 /* OFF */
331 if (newval == 0)
332 {
333 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
334 "%s is disabling splitmode",
335 get_oper_name(source_p));
336
337 splitmode = 0;
338 splitchecking = 0;
339
340 eventDelete(check_splitmode, NULL);
341 }
342 /* ON */
343 else if (newval == 1)
344 {
345 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
346 "%s is enabling and activating splitmode",
347 get_oper_name(source_p));
348
349 splitmode = 1;
350 splitchecking = 0;
351
352 /* we might be deactivating an automatic splitmode, so pull the event */
353 eventDelete(check_splitmode, NULL);
354 }
355 /* AUTO */
356 else if (newval == 2)
357 {
358 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
359 "%s is enabling automatic splitmode",
360 get_oper_name(source_p));
361
362 splitchecking = 1;
363 check_splitmode(NULL);
364 }
365 }
366 else
367 /* if we add splitchecking to splitmode*2 we get a unique table to
368 * pull values back out of, splitmode can be four states - but you can
369 * only set to three, which means we cant use the same table --fl_
370 */
371 sendto_one(source_p, ":%s NOTICE %s :SPLITMODE is currently %s",
372 me.name, source_p->name,
373 splitmode_status[(splitchecking + (splitmode * 2))]);
374 }
375
376 /* SET SPLITNUM */
377 static void
378 quote_splitnum(struct Client *source_p, int newval)
379 {
380 if (newval >= 0)
381 {
382 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
383 "%s has changed SPLITNUM to %i",
384 get_oper_name(source_p), newval);
385 split_servers = newval;
386
387 if (splitchecking)
388 check_splitmode(NULL);
389 }
390 else
391 sendto_one(source_p, ":%s NOTICE %s :SPLITNUM is currently %i",
392 me.name, source_p->name, split_servers);
393 }
394
395 /* SET SPLITUSERS */
396 static void
397 quote_splitusers(struct Client *source_p, int newval)
398 {
399 if (newval >= 0)
400 {
401 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
402 "%s has changed SPLITUSERS to %i",
403 get_oper_name(source_p), newval);
404 split_users = newval;
405
406 if (splitchecking)
407 check_splitmode(NULL);
408 }
409 else
410 sendto_one(source_p, ":%s NOTICE %s :SPLITUSERS is currently %i",
411 me.name, source_p->name, split_users);
412 }
413
414 /* SET JFLOODTIME */
415 static void
416 quote_jfloodtime(struct Client *source_p, int newval)
417 {
418 if (newval >= 0)
419 {
420 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
421 "%s has changed JFLOODTIME to %i",
422 get_oper_name(source_p), newval);
423 GlobalSetOptions.joinfloodtime = newval;
424 }
425 else
426 sendto_one(source_p, ":%s NOTICE %s :JFLOODTIME is currently %i",
427 me.name, source_p->name, GlobalSetOptions.joinfloodtime);
428 }
429
430 /* SET JFLOODCOUNT */
431 static void
432 quote_jfloodcount(struct Client *source_p, int newval)
433 {
434 if (newval >= 0)
435 {
436 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
437 "%s has changed JFLOODCOUNT to %i",
438 get_oper_name(source_p), newval);
439 GlobalSetOptions.joinfloodcount = newval;
440 }
441 else
442 sendto_one(source_p, ":%s NOTICE %s :JFLOODCOUNT is currently %i",
443 me.name, source_p->name, GlobalSetOptions.joinfloodcount);
444 }
445
446 /*
447 * mo_set - SET command handler
448 * set options while running
449 */
450 static void
451 mo_set(struct Client *client_p, struct Client *source_p,
452 int parc, char *parv[])
453 {
454 int n;
455 int newval;
456 const char *arg = NULL;
457 const char *intarg = NULL;
458 const struct SetStruct *tab = set_cmd_table;
459
460 if (!HasOFlag(source_p, OPER_FLAG_SET))
461 {
462 sendto_one(source_p, ERR_NOPRIVS,
463 me.name, source_p->name, "set");
464 return;
465 }
466
467 if (parc > 1)
468 {
469 /*
470 * Go through all the commands in set_cmd_table, until one is
471 * matched.
472 */
473 for (; tab->handler; ++tab)
474 {
475 if (!irccmp(tab->name, parv[1]))
476 {
477 /*
478 * Command found; now execute the code
479 */
480 n = 2;
481
482 if (tab->wants_char)
483 arg = parv[n++];
484
485 if (tab->wants_int)
486 intarg = parv[n++];
487
488 if ((n - 1) > parc)
489 {
490 if (parc > 2)
491 sendto_one(source_p,
492 ":%s NOTICE %s :SET %s expects (\"%s%s\") args",
493 me.name, source_p->name, tab->name,
494 (tab->wants_char ? "string, " : ""),
495 (tab->wants_char ? "int" : ""));
496 }
497
498 if (parc <= 2)
499 {
500 arg = NULL;
501 intarg = NULL;
502 }
503
504 if (!strcmp(tab->name, "AUTOCONN") && (parc < 4))
505 {
506 sendto_one(source_p, ERR_NEEDMOREPARAMS,
507 me.name, source_p->name, "SET");
508 return;
509 }
510
511 if (tab->wants_int && (parc > 2))
512 {
513 if (intarg)
514 {
515 if (irccmp(intarg, "yes") == 0 || irccmp(intarg, "on") == 0)
516 newval = 1;
517 else if (irccmp(intarg, "no") == 0|| irccmp(intarg, "off") == 0)
518 newval = 0;
519 else
520 newval = atoi(intarg);
521 }
522 else
523 newval = -1;
524
525 if (newval < 0)
526 {
527 sendto_one(source_p,
528 ":%s NOTICE %s :Value less than 0 illegal for %s",
529 me.name, source_p->name,
530 tab->name);
531
532 return;
533 }
534 }
535 else
536 newval = -1;
537
538 if (tab->wants_char)
539 {
540 if (tab->wants_int)
541 tab->handler(source_p, arg, newval);
542 else
543 tab->handler(source_p, arg);
544 return;
545 }
546 else
547 {
548 if (tab->wants_int)
549 tab->handler(source_p, newval);
550 else
551 /* Just in case someone actually wants a
552 * set function that takes no args.. *shrug* */
553 tab->handler(source_p);
554 return;
555 }
556 }
557 }
558
559 /*
560 * Code here will be executed when a /QUOTE SET command is not
561 * found within set_cmd_table.
562 */
563 sendto_one(source_p, ":%s NOTICE %s :Variable not found.",
564 me.name, source_p->name);
565 return;
566 }
567
568 list_quote_commands(source_p);
569 }
570
571 static struct Message set_msgtab = {
572 "SET", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
573 {m_unregistered, m_not_oper, rfc1459_command_send_error, m_ignore, mo_set, m_ignore}
574 };
575
576 static void
577 module_init(void)
578 {
579 mod_add_cmd(&set_msgtab);
580 }
581
582 static void
583 module_exit(void)
584 {
585 mod_del_cmd(&set_msgtab);
586 }
587
588 struct module module_entry = {
589 .node = { NULL, NULL, NULL },
590 .name = NULL,
591 .version = "$Revision$",
592 .handle = NULL,
593 .modinit = module_init,
594 .modexit = module_exit,
595 .flags = 0
596 };

Properties

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