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: 1618
Committed: Tue Oct 30 21:04:38 2012 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/m_set.c
File size: 17006 byte(s)
Log Message:
- Made m_globops() and ms_globops() use sendto_realops_flags()
- Added message-type parameter to sendto_realops_flags() which can be one of
  SEND_NOTICE, SEND_GLOBAL, SEND_LOCOPS
- Forward-port -r1617

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

Properties

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