/[svn]/ircd-hybrid-7.2/modules/m_set.c
ViewVC logotype

Contents of /ircd-hybrid-7.2/modules/m_set.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 946 - (show annotations)
Mon Jul 20 23:18:04 2009 UTC (12 years, 2 months ago) by michael
File MIME type: text/x-chdr
File size: 18839 byte(s)
- move m_error.c to modules/


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

Properties

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

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