ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_set.c
Revision: 33
Committed: Sun Oct 2 20:50:00 2005 UTC (18 years, 5 months ago) by knight
Content type: text/x-csrc
File size: 17960 byte(s)
Log Message:
- svn:keywords

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

Properties

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