ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_set.c
Revision: 1736
Committed: Sun Jan 13 09:31:46 2013 UTC (11 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 16915 byte(s)
Log Message:
- Forward-port -r1732 [Dropped support for linux rt signals]

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 "client.h"
29     #include "event.h"
30     #include "irc_string.h"
31     #include "ircd.h"
32     #include "numeric.h"
33     #include "fdlist.h"
34     #include "s_bsd.h"
35     #include "s_serv.h"
36     #include "send.h"
37     #include "channel.h"
38 michael 1309 #include "conf.h"
39 adx 30 #include "parse.h"
40     #include "modules.h"
41     #include "s_user.h"
42 michael 1243 #include "s_misc.h"
43 adx 30
44    
45     /* Structure used for the SET table itself */
46     struct SetStruct
47     {
48     const char *name;
49     void (*handler)();
50 michael 1013 const int wants_char; /* 1 if it expects (char *, [int]) */
51     const int wants_int; /* 1 if it expects ([char *], int) */
52 adx 30 /* eg: 0, 1 == only an int arg
53     * eg: 1, 1 == char and int args */
54     };
55    
56     static void quote_autoconn(struct Client *, const char *, int);
57     static void quote_autoconnall(struct Client *, int);
58     static void quote_floodcount(struct Client *, int);
59     static void quote_identtimeout(struct Client *, int);
60     static void quote_max(struct Client *, int);
61     static void quote_msglocale(struct Client *, char *);
62     static void quote_spamnum(struct Client *, int);
63     static void quote_spamtime(struct Client *, int);
64     static void quote_splitmode(struct Client *, char *);
65     static void quote_splitnum(struct Client *, int);
66     static void quote_splitusers(struct Client *, int);
67     static void list_quote_commands(struct Client *);
68     static void quote_jfloodtime(struct Client *, int);
69     static void quote_jfloodcount(struct Client *, int);
70    
71     /*
72     * If this ever needs to be expanded to more than one arg of each
73     * type, want_char/want_int could be the count of the arguments,
74     * instead of just a boolean flag...
75     *
76     * -davidt
77     */
78    
79 michael 1013 static const struct SetStruct set_cmd_table[] =
80 adx 30 {
81     /* name function string arg int arg */
82     /* -------------------------------------------------------- */
83     { "AUTOCONN", quote_autoconn, 1, 1 },
84     { "AUTOCONNALL", quote_autoconnall, 0, 1 },
85     { "FLOODCOUNT", quote_floodcount, 0, 1 },
86     { "IDENTTIMEOUT", quote_identtimeout, 0, 1 },
87     { "MAX", quote_max, 0, 1 },
88     { "MSGLOCALE", quote_msglocale, 1, 0 },
89     { "SPAMNUM", quote_spamnum, 0, 1 },
90     { "SPAMTIME", quote_spamtime, 0, 1 },
91     { "SPLITMODE", quote_splitmode, 1, 0 },
92     { "SPLITNUM", quote_splitnum, 0, 1 },
93     { "SPLITUSERS", quote_splitusers, 0, 1 },
94     { "JFLOODTIME", quote_jfloodtime, 0, 1 },
95     { "JFLOODCOUNT", quote_jfloodcount, 0, 1 },
96     /* -------------------------------------------------------- */
97 michael 946 { NULL, NULL, 0, 0 }
98 adx 30 };
99    
100     /*
101     * list_quote_commands() sends the client all the available commands.
102     * Four to a line for now.
103     */
104     static void
105     list_quote_commands(struct Client *source_p)
106     {
107     int j = 0;
108 michael 1013 const struct SetStruct *tab = set_cmd_table;
109 michael 896 const char *names[4] = { "", "", "", "" };
110 adx 30
111     sendto_one(source_p, ":%s NOTICE %s :Available QUOTE SET commands:",
112     me.name, source_p->name);
113    
114 michael 1013 for (; tab->handler; ++tab)
115 adx 30 {
116 michael 1013 names[j++] = tab->name;
117 adx 30
118     if (j > 3)
119     {
120     sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
121     me.name, source_p->name,
122     names[0], names[1],
123     names[2], names[3]);
124     j = 0;
125     names[0] = names[1] = names[2] = names[3] = "";
126     }
127    
128     }
129 michael 896
130 adx 30 if (j)
131     sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
132     me.name, source_p->name,
133     names[0], names[1],
134     names[2], names[3]);
135     }
136    
137     /* SET AUTOCONN */
138     static void
139     quote_autoconn(struct Client *source_p, const char *arg, int newval)
140     {
141 michael 896 if (arg != NULL)
142     {
143 michael 1632 struct MaskItem *conf = find_exact_name_conf(CONF_SERVER, NULL, arg, NULL, NULL);
144 michael 896
145     if (conf != NULL)
146     {
147     if (newval)
148 michael 1632 SetConfAllowAutoConn(conf);
149 michael 896 else
150 michael 1632 ClearConfAllowAutoConn(conf);
151 michael 896
152 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
153 michael 896 "%s has changed AUTOCONN for %s to %i",
154 michael 1141 get_oper_name(source_p), arg, newval);
155 michael 896 sendto_one(source_p,
156     ":%s NOTICE %s :AUTOCONN for %s is now set to %i",
157     me.name, source_p->name, arg, newval);
158     }
159     else
160     {
161     sendto_one(source_p, ":%s NOTICE %s :Can't find %s",
162     me.name, source_p->name, arg);
163     }
164     }
165     else
166     {
167     sendto_one(source_p, ":%s NOTICE %s :Please specify a server name!",
168     me.name, source_p->name);
169     }
170 adx 30 }
171    
172     /* SET AUTOCONNALL */
173     static void
174     quote_autoconnall(struct Client *source_p, int newval)
175     {
176     if (newval >= 0)
177     {
178 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
179     "%s has changed AUTOCONNALL to %i",
180 michael 1141 get_oper_name(source_p), newval);
181 adx 30
182     GlobalSetOptions.autoconn = newval;
183     }
184     else
185     sendto_one(source_p, ":%s NOTICE %s :AUTOCONNALL is currently %i",
186     me.name, source_p->name, GlobalSetOptions.autoconn);
187     }
188    
189     /* SET FLOODCOUNT */
190     static void
191     quote_floodcount(struct Client *source_p, int newval)
192     {
193     if (newval >= 0)
194     {
195     GlobalSetOptions.floodcount = newval;
196 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
197 michael 1141 "%s has changed FLOODCOUNT to %i",
198     get_oper_name(source_p), GlobalSetOptions.floodcount);
199 adx 30 }
200     else
201     sendto_one(source_p, ":%s NOTICE %s :FLOODCOUNT is currently %i",
202     me.name, source_p->name, GlobalSetOptions.floodcount);
203     }
204    
205     /* SET IDENTTIMEOUT */
206     static void
207     quote_identtimeout(struct Client *source_p, int newval)
208     {
209 michael 1219 if (!HasUMode(source_p, UMODE_ADMIN))
210 adx 30 {
211     sendto_one(source_p, form_str(ERR_NOPRIVS),
212     me.name, source_p->name, "set");
213     return;
214     }
215    
216     if (newval > 0)
217     {
218 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
219 michael 1451 "%s has changed IDENTTIMEOUT to %d",
220     get_oper_name(source_p), newval);
221 adx 30 GlobalSetOptions.ident_timeout = newval;
222     }
223     else
224     sendto_one(source_p, ":%s NOTICE %s :IDENTTIMEOUT is currently %d",
225 michael 1451 me.name, source_p->name, GlobalSetOptions.ident_timeout);
226 adx 30 }
227    
228     /* SET MAX */
229     static void
230 michael 896 quote_max(struct Client *source_p, int newval)
231 adx 30 {
232     if (newval > 0)
233     {
234     if (newval > MAXCLIENTS_MAX)
235     {
236     sendto_one(source_p,
237     ":%s NOTICE %s :You cannot set MAXCLIENTS to > %d, restoring to %d",
238 michael 1451 me.name, source_p->name, MAXCLIENTS_MAX, ServerInfo.max_clients);
239 adx 30 return;
240     }
241    
242     if (newval < MAXCLIENTS_MIN)
243     {
244     sendto_one(source_p,
245 michael 1451 ":%s NOTICE %s :You cannot set MAXCLIENTS to < %d, restoring to %d",
246     me.name, source_p->name, MAXCLIENTS_MIN, ServerInfo.max_clients);
247 adx 30 return;
248     }
249    
250     ServerInfo.max_clients = newval;
251    
252 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
253 michael 1451 "%s set new MAXCLIENTS to %d (%d current)",
254     get_oper_name(source_p), ServerInfo.max_clients, Count.local);
255 adx 30 }
256     else
257     sendto_one(source_p, ":%s NOTICE %s :Current MAXCLIENTS = %d (%d)",
258     me.name, source_p->name, ServerInfo.max_clients, Count.local);
259     }
260    
261     /* SET MSGLOCALE */
262     static void
263 michael 896 quote_msglocale(struct Client *source_p, char *locale)
264 adx 30 {
265     if (locale != NULL)
266     {
267     set_locale(locale);
268     rebuild_isupport_message_line();
269     sendto_one(source_p, ":%s NOTICE %s :Set MSGLOCALE to '%s'",
270 michael 1451 me.name, source_p->name, get_locale());
271 adx 30 }
272     else
273     sendto_one(source_p, ":%s NOTICE %s :MSGLOCALE is currently '%s'",
274 michael 1451 me.name, source_p->name, get_locale());
275 adx 30 }
276    
277     /* SET SPAMNUM */
278     static void
279 michael 896 quote_spamnum(struct Client *source_p, int newval)
280 adx 30 {
281 michael 646 if (newval >= 0)
282 adx 30 {
283     if (newval == 0)
284     {
285 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
286 adx 30 "%s has disabled ANTI_SPAMBOT", source_p->name);
287     GlobalSetOptions.spam_num = newval;
288     return;
289     }
290    
291     GlobalSetOptions.spam_num = IRCD_MAX(newval, MIN_SPAM_NUM);
292 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
293     "%s has changed SPAMNUM to %i",
294 michael 1141 get_oper_name(source_p), GlobalSetOptions.spam_num);
295 adx 30 }
296     else
297     sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i",
298 michael 1013 me.name, source_p->name, GlobalSetOptions.spam_num);
299 adx 30 }
300    
301     /* SET SPAMTIME */
302     static void
303 michael 896 quote_spamtime(struct Client *source_p, int newval)
304 adx 30 {
305     if (newval > 0)
306     {
307     GlobalSetOptions.spam_time = IRCD_MAX(newval, MIN_SPAM_TIME);
308 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
309     "%s has changed SPAMTIME to %i",
310 michael 1141 get_oper_name(source_p), GlobalSetOptions.spam_time);
311 adx 30 }
312     else
313     sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i",
314 michael 1013 me.name, source_p->name, GlobalSetOptions.spam_time);
315 adx 30 }
316    
317     /* this table is what splitmode may be set to */
318     static const char *splitmode_values[] =
319     {
320     "OFF",
321     "ON",
322     "AUTO",
323     NULL
324     };
325    
326     /* this table is what splitmode may be */
327     static const char *splitmode_status[] =
328     {
329     "OFF",
330     "AUTO (OFF)",
331     "ON",
332     "AUTO (ON)",
333     NULL
334     };
335    
336     /* SET SPLITMODE */
337     static void
338     quote_splitmode(struct Client *source_p, char *charval)
339     {
340     if (charval)
341     {
342     int newval;
343    
344 michael 896 for (newval = 0; splitmode_values[newval]; ++newval)
345 adx 30 if (irccmp(splitmode_values[newval], charval) == 0)
346     break;
347    
348     /* OFF */
349     if (newval == 0)
350     {
351 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
352 adx 30 "%s is disabling splitmode",
353     get_oper_name(source_p));
354    
355     splitmode = 0;
356     splitchecking = 0;
357    
358     eventDelete(check_splitmode, NULL);
359     }
360     /* ON */
361     else if (newval == 1)
362     {
363 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
364 adx 30 "%s is enabling and activating splitmode",
365 michael 1451 get_oper_name(source_p));
366    
367 adx 30 splitmode = 1;
368     splitchecking = 0;
369    
370     /* we might be deactivating an automatic splitmode, so pull the event */
371     eventDelete(check_splitmode, NULL);
372     }
373     /* AUTO */
374     else if (newval == 2)
375     {
376 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
377 adx 30 "%s is enabling automatic splitmode",
378 michael 1451 get_oper_name(source_p));
379 adx 30
380     splitchecking = 1;
381     check_splitmode(NULL);
382     }
383     }
384     else
385     /* if we add splitchecking to splitmode*2 we get a unique table to
386     * pull values back out of, splitmode can be four states - but you can
387     * only set to three, which means we cant use the same table --fl_
388     */
389     sendto_one(source_p, ":%s NOTICE %s :SPLITMODE is currently %s",
390     me.name, source_p->name,
391 michael 1451 splitmode_status[(splitchecking + (splitmode * 2))]);
392 adx 30 }
393    
394     /* SET SPLITNUM */
395     static void
396     quote_splitnum(struct Client *source_p, int newval)
397     {
398     if (newval >= 0)
399     {
400 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
401 adx 30 "%s has changed SPLITNUM to %i",
402 michael 1451 get_oper_name(source_p), newval);
403 adx 30 split_servers = newval;
404    
405     if (splitchecking)
406     check_splitmode(NULL);
407     }
408     else
409     sendto_one(source_p, ":%s NOTICE %s :SPLITNUM is currently %i",
410     me.name, source_p->name, split_servers);
411     }
412    
413     /* SET SPLITUSERS */
414     static void
415     quote_splitusers(struct Client *source_p, int newval)
416     {
417     if (newval >= 0)
418     {
419 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
420 adx 30 "%s has changed SPLITUSERS to %i",
421 michael 1451 get_oper_name(source_p), newval);
422 adx 30 split_users = newval;
423    
424     if (splitchecking)
425     check_splitmode(NULL);
426     }
427     else
428     sendto_one(source_p, ":%s NOTICE %s :SPLITUSERS is currently %i",
429     me.name, source_p->name, split_users);
430     }
431    
432     /* SET JFLOODTIME */
433     static void
434     quote_jfloodtime(struct Client *source_p, int newval)
435     {
436     if (newval >= 0)
437     {
438 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
439 adx 30 "%s has changed JFLOODTIME to %i",
440 michael 1451 get_oper_name(source_p), newval);
441 adx 30 GlobalSetOptions.joinfloodtime = newval;
442     }
443     else
444     sendto_one(source_p, ":%s NOTICE %s :JFLOODTIME is currently %i",
445     me.name, source_p->name, GlobalSetOptions.joinfloodtime);
446     }
447    
448     /* SET JFLOODCOUNT */
449     static void
450     quote_jfloodcount(struct Client *source_p, int newval)
451     {
452     if (newval >= 0)
453     {
454 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
455 adx 30 "%s has changed JFLOODCOUNT to %i",
456 michael 1451 get_oper_name(source_p), newval);
457 adx 30 GlobalSetOptions.joinfloodcount = newval;
458     }
459     else
460     sendto_one(source_p, ":%s NOTICE %s :JFLOODCOUNT is currently %i",
461     me.name, source_p->name, GlobalSetOptions.joinfloodcount);
462     }
463    
464     /*
465     * mo_set - SET command handler
466     * set options while running
467     */
468     static void
469     mo_set(struct Client *client_p, struct Client *source_p,
470     int parc, char *parv[])
471     {
472     int n;
473     int newval;
474     const char *arg = NULL;
475     const char *intarg = NULL;
476 michael 1013 const struct SetStruct *tab = set_cmd_table;
477 adx 30
478 michael 1460 if (!HasOFlag(source_p, OPER_FLAG_SET))
479     {
480     sendto_one(source_p, form_str(ERR_NOPRIVS),
481     me.name, source_p->name, "set");
482     return;
483     }
484    
485 adx 30 if (parc > 1)
486     {
487 michael 1013 /*
488     * Go through all the commands in set_cmd_table, until one is
489     * matched.
490 adx 30 */
491 michael 1013 for (; tab->handler; ++tab)
492 adx 30 {
493 michael 1013 if (!irccmp(tab->name, parv[1]))
494 adx 30 {
495     /*
496     * Command found; now execute the code
497     */
498     n = 2;
499    
500 michael 1013 if (tab->wants_char)
501 adx 30 arg = parv[n++];
502    
503 michael 1013 if (tab->wants_int)
504 adx 30 intarg = parv[n++];
505    
506     if ((n - 1) > parc)
507     {
508     if (parc > 2)
509     sendto_one(source_p,
510     ":%s NOTICE %s :SET %s expects (\"%s%s\") args",
511 michael 1013 me.name, source_p->name, tab->name,
512     (tab->wants_char ? "string, " : ""),
513     (tab->wants_char ? "int" : ""));
514 adx 30 }
515    
516     if (parc <= 2)
517     {
518     arg = NULL;
519     intarg = NULL;
520     }
521    
522 michael 1013 if (!strcmp(tab->name, "AUTOCONN") && (parc < 4))
523 adx 30 {
524     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
525     me.name, source_p->name, "SET");
526     return;
527     }
528    
529 michael 1013 if (tab->wants_int && (parc > 2))
530 adx 30 {
531     if (intarg)
532     {
533     if (irccmp(intarg, "yes") == 0 || irccmp(intarg, "on") == 0)
534     newval = 1;
535     else if (irccmp(intarg, "no") == 0|| irccmp(intarg, "off") == 0)
536     newval = 0;
537     else
538     newval = atoi(intarg);
539     }
540     else
541     newval = -1;
542    
543     if (newval < 0)
544     {
545     sendto_one(source_p,
546     ":%s NOTICE %s :Value less than 0 illegal for %s",
547     me.name, source_p->name,
548 michael 1013 tab->name);
549 adx 30
550     return;
551     }
552     }
553     else
554     newval = -1;
555    
556 michael 1013 if (tab->wants_char)
557 adx 30 {
558 michael 1013 if (tab->wants_int)
559     tab->handler(source_p, arg, newval);
560 adx 30 else
561 michael 1013 tab->handler(source_p, arg);
562 adx 30 return;
563     }
564     else
565     {
566 michael 1013 if (tab->wants_int)
567     tab->handler(source_p, newval);
568 adx 30 else
569     /* Just in case someone actually wants a
570     * set function that takes no args.. *shrug* */
571 michael 1013 tab->handler(source_p);
572 adx 30 return;
573     }
574     }
575     }
576    
577     /*
578     * Code here will be executed when a /QUOTE SET command is not
579     * found within set_cmd_table.
580     */
581     sendto_one(source_p, ":%s NOTICE %s :Variable not found.",
582     me.name, source_p->name);
583     return;
584     }
585    
586     list_quote_commands(source_p);
587     }
588 michael 1230
589     static struct Message set_msgtab = {
590     "SET", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
591     {m_unregistered, m_not_oper, rfc1459_command_send_error, m_ignore, mo_set, m_ignore}
592     };
593    
594     static void
595     module_init(void)
596     {
597     mod_add_cmd(&set_msgtab);
598     }
599    
600     static void
601     module_exit(void)
602     {
603     mod_del_cmd(&set_msgtab);
604     }
605    
606     struct module module_entry = {
607     .node = { NULL, NULL, NULL },
608     .name = NULL,
609     .version = "$Revision$",
610     .handle = NULL,
611     .modinit = module_init,
612     .modexit = module_exit,
613     .flags = 0
614     };

Properties

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