ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_set.c
Revision: 1230
Committed: Thu Sep 22 19:41:19 2011 UTC (12 years, 6 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_set.c
File size: 17874 byte(s)
Log Message:
- cleanup module loader. Make module api more flexible

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

Properties

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