ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/modules/m_set.c
Revision: 896
Committed: Sat Nov 3 08:54:09 2007 UTC (18 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/m_set.c
File size: 18786 byte(s)
Log Message:
- Killed s_stats.c

File Contents

# User Rev Content
1 adx 30 /*
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 knight 31 * $Id$
23 adx 30 */
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 michael 896 {m_unregistered, m_not_oper, m_error, m_ignore, mo_set, m_ignore}
53 adx 30 };
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 knight 31 const char *_version = "$Revision$";
69 adx 30 #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 michael 896 const char *names[4] = { "", "", "", "" };
142 adx 30
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 michael 896
162 adx 30 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 michael 896 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 adx 30 }
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 michael 896 quote_log(struct Client *source_p, int newval)
293 adx 30 {
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 michael 896 quote_max(struct Client *source_p, int newval)
326 adx 30 {
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 michael 896 quote_msglocale(struct Client *source_p, char *locale)
362 adx 30 {
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 michael 896 quote_spamnum(struct Client *source_p, int newval)
378 adx 30 {
379 michael 646 if (newval >= 0)
380 adx 30 {
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 michael 896 me.name,
397     source_p->name, GlobalSetOptions.spam_num);
398 adx 30 }
399    
400     /* SET SPAMTIME */
401     static void
402 michael 896 quote_spamtime(struct Client *source_p, int newval)
403 adx 30 {
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 michael 896 for (newval = 0; splitmode_values[newval]; ++newval)
444 adx 30 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