ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_set.c
Revision: 513
Committed: Sun Mar 5 08:28:01 2006 UTC (18 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 19185 byte(s)
Log Message:
- Moved m_error to core modules and made remaining command handlers use
  m_ignore instead of m_error

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

Properties

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