ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/m_set.c
Revision: 30
Committed: Sun Oct 2 20:03:27 2005 UTC (18 years, 5 months ago) by adx
Content type: text/x-csrc
Original Path: ircd-hybrid/modules/m_set.c
File size: 18012 byte(s)
Log Message:
- imported sources
- can be moved later according to the directory/branching scheme,
  but we need the svn up

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     * $Id: m_set.c,v 1.65 2005/09/18 22:24:37 adx Exp $
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: 1.65 $";
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"