ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_set.c
Revision: 1834
Committed: Fri Apr 19 19:50:27 2013 UTC (10 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 16915 byte(s)
Log Message:
- Revert to -r1831

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 if (newval > MAXCLIENTS_MAX)
235 {
236 sendto_one(source_p,
237 ":%s NOTICE %s :You cannot set MAXCLIENTS to > %d, restoring to %d",
238 me.name, source_p->name, MAXCLIENTS_MAX, ServerInfo.max_clients);
239 return;
240 }
241
242 if (newval < MAXCLIENTS_MIN)
243 {
244 sendto_one(source_p,
245 ":%s NOTICE %s :You cannot set MAXCLIENTS to < %d, restoring to %d",
246 me.name, source_p->name, MAXCLIENTS_MIN, ServerInfo.max_clients);
247 return;
248 }
249
250 ServerInfo.max_clients = newval;
251
252 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
253 "%s set new MAXCLIENTS to %d (%d current)",
254 get_oper_name(source_p), ServerInfo.max_clients, Count.local);
255 }
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 quote_msglocale(struct Client *source_p, char *locale)
264 {
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 me.name, source_p->name, get_locale());
271 }
272 else
273 sendto_one(source_p, ":%s NOTICE %s :MSGLOCALE is currently '%s'",
274 me.name, source_p->name, get_locale());
275 }
276
277 /* SET SPAMNUM */
278 static void
279 quote_spamnum(struct Client *source_p, int newval)
280 {
281 if (newval >= 0)
282 {
283 if (newval == 0)
284 {
285 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
286 "%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 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
293 "%s has changed SPAMNUM to %i",
294 get_oper_name(source_p), GlobalSetOptions.spam_num);
295 }
296 else
297 sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i",
298 me.name, source_p->name, GlobalSetOptions.spam_num);
299 }
300
301 /* SET SPAMTIME */
302 static void
303 quote_spamtime(struct Client *source_p, int newval)
304 {
305 if (newval > 0)
306 {
307 GlobalSetOptions.spam_time = IRCD_MAX(newval, MIN_SPAM_TIME);
308 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
309 "%s has changed SPAMTIME to %i",
310 get_oper_name(source_p), GlobalSetOptions.spam_time);
311 }
312 else
313 sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i",
314 me.name, source_p->name, GlobalSetOptions.spam_time);
315 }
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 for (newval = 0; splitmode_values[newval]; ++newval)
345 if (irccmp(splitmode_values[newval], charval) == 0)
346 break;
347
348 /* OFF */
349 if (newval == 0)
350 {
351 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
352 "%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 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
364 "%s is enabling and activating splitmode",
365 get_oper_name(source_p));
366
367 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 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
377 "%s is enabling automatic splitmode",
378 get_oper_name(source_p));
379
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 splitmode_status[(splitchecking + (splitmode * 2))]);
392 }
393
394 /* SET SPLITNUM */
395 static void
396 quote_splitnum(struct Client *source_p, int newval)
397 {
398 if (newval >= 0)
399 {
400 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
401 "%s has changed SPLITNUM to %i",
402 get_oper_name(source_p), newval);
403 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 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
420 "%s has changed SPLITUSERS to %i",
421 get_oper_name(source_p), newval);
422 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 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
439 "%s has changed JFLOODTIME to %i",
440 get_oper_name(source_p), newval);
441 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 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
455 "%s has changed JFLOODCOUNT to %i",
456 get_oper_name(source_p), newval);
457 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 const struct SetStruct *tab = set_cmd_table;
477
478 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 if (parc > 1)
486 {
487 /*
488 * Go through all the commands in set_cmd_table, until one is
489 * matched.
490 */
491 for (; tab->handler; ++tab)
492 {
493 if (!irccmp(tab->name, parv[1]))
494 {
495 /*
496 * Command found; now execute the code
497 */
498 n = 2;
499
500 if (tab->wants_char)
501 arg = parv[n++];
502
503 if (tab->wants_int)
504 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 me.name, source_p->name, tab->name,
512 (tab->wants_char ? "string, " : ""),
513 (tab->wants_char ? "int" : ""));
514 }
515
516 if (parc <= 2)
517 {
518 arg = NULL;
519 intarg = NULL;
520 }
521
522 if (!strcmp(tab->name, "AUTOCONN") && (parc < 4))
523 {
524 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
525 me.name, source_p->name, "SET");
526 return;
527 }
528
529 if (tab->wants_int && (parc > 2))
530 {
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 tab->name);
549
550 return;
551 }
552 }
553 else
554 newval = -1;
555
556 if (tab->wants_char)
557 {
558 if (tab->wants_int)
559 tab->handler(source_p, arg, newval);
560 else
561 tab->handler(source_p, arg);
562 return;
563 }
564 else
565 {
566 if (tab->wants_int)
567 tab->handler(source_p, newval);
568 else
569 /* Just in case someone actually wants a
570 * set function that takes no args.. *shrug* */
571 tab->handler(source_p);
572 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
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