ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/m_set.c
Revision: 1029
Committed: Sun Nov 8 13:10:50 2009 UTC (14 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 18481 byte(s)
Log Message:
- branch off trunk to create 7.3 branch

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 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 const int wants_char; /* 1 if it expects (char *, [int]) */
77 const 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 const 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 j = 0;
140 const struct SetStruct *tab = set_cmd_table;
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 (; tab->handler; ++tab)
147 {
148 names[j++] = tab->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 if (newval >= 0)
295 {
296 if (newval < L_WARN)
297 {
298 sendto_one(source_p, ":%s NOTICE %s :LOG must be > %d (L_WARN)",
299 me.name, source_p->name, L_WARN);
300 return;
301 }
302
303 if (newval > L_DEBUG)
304 newval = L_DEBUG;
305
306 set_log_level(newval);
307 sendto_realops_flags(UMODE_ALL, L_ALL,"%s has changed LOG level to %i (%s)",
308 source_p->name, get_log_level(),
309 get_log_level_as_string(get_log_level()));
310 }
311 else
312 sendto_one(source_p, ":%s NOTICE %s :LOG level is currently %i (%s)",
313 me.name, source_p->name, get_log_level(),
314 get_log_level_as_string(get_log_level()));
315 }
316
317 /* SET MAX */
318 static void
319 quote_max(struct Client *source_p, int newval)
320 {
321 if (newval > 0)
322 {
323 recalc_fdlimit(NULL);
324
325 if (newval > MAXCLIENTS_MAX)
326 {
327 sendto_one(source_p,
328 ":%s NOTICE %s :You cannot set MAXCLIENTS to > %d, restoring to %d",
329 me.name, source_p->name, MAXCLIENTS_MAX);
330 return;
331 }
332
333 if (newval < MAXCLIENTS_MIN)
334 {
335 sendto_one(source_p,
336 ":%s NOTICE %s :You cannot set MAXCLIENTS to < %d, restoring to %d",
337 me.name, source_p->name, MAXCLIENTS_MIN, ServerInfo.max_clients);
338 return;
339 }
340
341 ServerInfo.max_clients = newval;
342
343 sendto_realops_flags(UMODE_ALL, L_ALL,
344 "%s!%s@%s set new MAXCLIENTS to %d (%d current)",
345 source_p->name, source_p->username, source_p->host,
346 ServerInfo.max_clients, Count.local);
347 }
348 else
349 sendto_one(source_p, ":%s NOTICE %s :Current MAXCLIENTS = %d (%d)",
350 me.name, source_p->name, ServerInfo.max_clients, Count.local);
351 }
352
353 /* SET MSGLOCALE */
354 static void
355 quote_msglocale(struct Client *source_p, char *locale)
356 {
357 if (locale != NULL)
358 {
359 set_locale(locale);
360 rebuild_isupport_message_line();
361 sendto_one(source_p, ":%s NOTICE %s :Set MSGLOCALE to '%s'",
362 me.name, source_p->name, get_locale());
363 }
364 else
365 sendto_one(source_p, ":%s NOTICE %s :MSGLOCALE is currently '%s'",
366 me.name, source_p->name, get_locale());
367 }
368
369 /* SET SPAMNUM */
370 static void
371 quote_spamnum(struct Client *source_p, int newval)
372 {
373 if (newval >= 0)
374 {
375 if (newval == 0)
376 {
377 sendto_realops_flags(UMODE_ALL, L_ALL,
378 "%s has disabled ANTI_SPAMBOT", source_p->name);
379 GlobalSetOptions.spam_num = newval;
380 return;
381 }
382
383 GlobalSetOptions.spam_num = IRCD_MAX(newval, MIN_SPAM_NUM);
384 sendto_realops_flags(UMODE_ALL, L_ALL,"%s has changed SPAMNUM to %i",
385 source_p->name, GlobalSetOptions.spam_num);
386 }
387 else
388 sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i",
389 me.name, source_p->name, GlobalSetOptions.spam_num);
390 }
391
392 /* SET SPAMTIME */
393 static void
394 quote_spamtime(struct Client *source_p, int newval)
395 {
396 if (newval > 0)
397 {
398 GlobalSetOptions.spam_time = IRCD_MAX(newval, MIN_SPAM_TIME);
399 sendto_realops_flags(UMODE_ALL, L_ALL, "%s has changed SPAMTIME to %i",
400 source_p->name, GlobalSetOptions.spam_time);
401 }
402 else
403 sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i",
404 me.name, source_p->name, GlobalSetOptions.spam_time);
405 }
406
407 /* this table is what splitmode may be set to */
408 static const char *splitmode_values[] =
409 {
410 "OFF",
411 "ON",
412 "AUTO",
413 NULL
414 };
415
416 /* this table is what splitmode may be */
417 static const char *splitmode_status[] =
418 {
419 "OFF",
420 "AUTO (OFF)",
421 "ON",
422 "AUTO (ON)",
423 NULL
424 };
425
426 /* SET SPLITMODE */
427 static void
428 quote_splitmode(struct Client *source_p, char *charval)
429 {
430 if (charval)
431 {
432 int newval;
433
434 for (newval = 0; splitmode_values[newval]; ++newval)
435 if (irccmp(splitmode_values[newval], charval) == 0)
436 break;
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 /*
571 * mo_set - SET command handler
572 * set options while running
573 */
574 static void
575 mo_set(struct Client *client_p, struct Client *source_p,
576 int parc, char *parv[])
577 {
578 int n;
579 int newval;
580 const char *arg = NULL;
581 const char *intarg = NULL;
582 const struct SetStruct *tab = set_cmd_table;
583
584 if (parc > 1)
585 {
586 /*
587 * Go through all the commands in set_cmd_table, until one is
588 * matched.
589 */
590 for (; tab->handler; ++tab)
591 {
592 if (!irccmp(tab->name, parv[1]))
593 {
594 /*
595 * Command found; now execute the code
596 */
597 n = 2;
598
599 if (tab->wants_char)
600 arg = parv[n++];
601
602 if (tab->wants_int)
603 intarg = parv[n++];
604
605 if ((n - 1) > parc)
606 {
607 if (parc > 2)
608 sendto_one(source_p,
609 ":%s NOTICE %s :SET %s expects (\"%s%s\") args",
610 me.name, source_p->name, tab->name,
611 (tab->wants_char ? "string, " : ""),
612 (tab->wants_char ? "int" : ""));
613 }
614
615 if (parc <= 2)
616 {
617 arg = NULL;
618 intarg = NULL;
619 }
620
621 if (!strcmp(tab->name, "AUTOCONN") && (parc < 4))
622 {
623 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
624 me.name, source_p->name, "SET");
625 return;
626 }
627
628 if (tab->wants_int && (parc > 2))
629 {
630 if (intarg)
631 {
632 if (irccmp(intarg, "yes") == 0 || irccmp(intarg, "on") == 0)
633 newval = 1;
634 else if (irccmp(intarg, "no") == 0|| irccmp(intarg, "off") == 0)
635 newval = 0;
636 else
637 newval = atoi(intarg);
638 }
639 else
640 {
641 newval = -1;
642 }
643
644 if (newval < 0)
645 {
646 sendto_one(source_p,
647 ":%s NOTICE %s :Value less than 0 illegal for %s",
648 me.name, source_p->name,
649 tab->name);
650
651 return;
652 }
653 }
654 else
655 newval = -1;
656
657 if (tab->wants_char)
658 {
659 if (tab->wants_int)
660 tab->handler(source_p, arg, newval);
661 else
662 tab->handler(source_p, arg);
663 return;
664 }
665 else
666 {
667 if (tab->wants_int)
668 tab->handler(source_p, newval);
669 else
670 /* Just in case someone actually wants a
671 * set function that takes no args.. *shrug* */
672 tab->handler(source_p);
673 return;
674 }
675 }
676 }
677
678 /*
679 * Code here will be executed when a /QUOTE SET command is not
680 * found within set_cmd_table.
681 */
682 sendto_one(source_p, ":%s NOTICE %s :Variable not found.",
683 me.name, source_p->name);
684 return;
685 }
686
687 list_quote_commands(source_p);
688 }

Properties

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