ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_set.c
Revision: 1013
Committed: Sun Oct 18 14:26:49 2009 UTC (14 years, 5 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/m_set.c
File size: 18481 byte(s)
Log Message:
- Add -Wextra -Wcast-align -Wbad-function-cast to CFLAGS if --enable-warnings is specified
- Fixed several compile warnings
- 64-bit cleanliness fixes, e.g., reorganize data structures to reduce storage/unnecessary padding

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 946 {m_unregistered, m_not_oper, rfc1459_command_send_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 michael 1013 const int wants_char; /* 1 if it expects (char *, [int]) */
77     const int wants_int; /* 1 if it expects ([char *], int) */
78 adx 30 /* 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 michael 1013 static const struct SetStruct set_cmd_table[] =
109 adx 30 {
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 michael 946 { NULL, NULL, 0, 0 }
130 adx 30 };
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 michael 1013 const struct SetStruct *tab = set_cmd_table;
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 michael 1013 for (; tab->handler; ++tab)
147 adx 30 {
148 michael 1013 names[j++] = tab->name;
149 adx 30
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     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 michael 1013 source_p->name, get_log_level(),
309     get_log_level_as_string(get_log_level()));
310 adx 30 }
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 michael 896 quote_max(struct Client *source_p, int newval)
320 adx 30 {
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 michael 896 quote_msglocale(struct Client *source_p, char *locale)
356 adx 30 {
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 michael 896 quote_spamnum(struct Client *source_p, int newval)
372 adx 30 {
373 michael 646 if (newval >= 0)
374 adx 30 {
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 michael 1013 source_p->name, GlobalSetOptions.spam_num);
386 adx 30 }
387     else
388     sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i",
389 michael 1013 me.name, source_p->name, GlobalSetOptions.spam_num);
390 adx 30 }
391    
392     /* SET SPAMTIME */
393     static void
394 michael 896 quote_spamtime(struct Client *source_p, int newval)
395 adx 30 {
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 michael 1013 source_p->name, GlobalSetOptions.spam_time);
401 adx 30 }
402     else
403     sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i",
404 michael 1013 me.name, source_p->name, GlobalSetOptions.spam_time);
405 adx 30 }
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 michael 896 for (newval = 0; splitmode_values[newval]; ++newval)
435 adx 30 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 michael 1013 const struct SetStruct *tab = set_cmd_table;
583 adx 30
584     if (parc > 1)
585     {
586 michael 1013 /*
587     * Go through all the commands in set_cmd_table, until one is
588     * matched.
589 adx 30 */
590 michael 1013 for (; tab->handler; ++tab)
591 adx 30 {
592 michael 1013 if (!irccmp(tab->name, parv[1]))
593 adx 30 {
594     /*
595     * Command found; now execute the code
596     */
597     n = 2;
598    
599 michael 1013 if (tab->wants_char)
600 adx 30 arg = parv[n++];
601    
602 michael 1013 if (tab->wants_int)
603 adx 30 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 michael 1013 me.name, source_p->name, tab->name,
611     (tab->wants_char ? "string, " : ""),
612     (tab->wants_char ? "int" : ""));
613 adx 30 }
614    
615     if (parc <= 2)
616     {
617     arg = NULL;
618     intarg = NULL;
619     }
620    
621 michael 1013 if (!strcmp(tab->name, "AUTOCONN") && (parc < 4))
622 adx 30 {
623     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
624     me.name, source_p->name, "SET");
625     return;
626     }
627    
628 michael 1013 if (tab->wants_int && (parc > 2))
629 adx 30 {
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 michael 1013 tab->name);
650 adx 30
651     return;
652     }
653     }
654     else
655     newval = -1;
656    
657 michael 1013 if (tab->wants_char)
658 adx 30 {
659 michael 1013 if (tab->wants_int)
660     tab->handler(source_p, arg, newval);
661 adx 30 else
662 michael 1013 tab->handler(source_p, arg);
663 adx 30 return;
664     }
665     else
666     {
667 michael 1013 if (tab->wants_int)
668     tab->handler(source_p, newval);
669 adx 30 else
670     /* Just in case someone actually wants a
671     * set function that takes no args.. *shrug* */
672 michael 1013 tab->handler(source_p);
673 adx 30 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