ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_set.c
Revision: 1632
Committed: Sun Nov 4 15:37:10 2012 UTC (12 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 16942 byte(s)
Log Message:
- Initial rewrite of the configuration subsystem

File Contents

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

Properties

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