]> jfr.im git - solanum.git/blame - modules/m_set.c
Remove $Id tags from everything.
[solanum.git] / modules / m_set.c
CommitLineData
212380e3
AC
1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * m_set.c: Sets a server parameter.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
212380e3
AC
23 */
24
25/* rewritten by jdc */
26
27#include "stdinc.h"
28#include "client.h"
4562c604 29#include "match.h"
212380e3
AC
30#include "ircd.h"
31#include "numeric.h"
212380e3
AC
32#include "s_serv.h"
33#include "send.h"
34#include "common.h"
35#include "channel.h"
36#include "s_conf.h"
37#include "s_newconf.h"
38#include "msg.h"
39#include "parse.h"
40#include "modules.h"
41
428ca87b 42static int mo_set(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
212380e3
AC
43
44struct Message set_msgtab = {
7baa37a9 45 "SET", 0, 0, 0, 0,
212380e3
AC
46 {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_set, 0}}
47};
48
49mapi_clist_av1 set_clist[] = { &set_msgtab, NULL };
f4ed5745 50DECLARE_MODULE_AV1(set, NULL, NULL, set_clist, NULL, NULL, "$Revision: 3406 $");
212380e3
AC
51
52/* Structure used for the SET table itself */
53struct SetStruct
54{
55 const char *name;
21dc257c 56 void (*handler)(struct Client *source_p, const char *chararg, int intarg);
212380e3
AC
57 int wants_char; /* 1 if it expects (char *, [int]) */
58 int wants_int; /* 1 if it expects ([char *], int) */
59
60 /* eg: 0, 1 == only an int arg
61 * eg: 1, 1 == char and int args */
62};
63
64
21dc257c 65static void quote_adminstring(struct Client *, const char *, int);
a3143c9b 66static void quote_autoconn(struct Client *, const char *, int);
21dc257c
JT
67static void quote_autoconnall(struct Client *, const char *, int);
68static void quote_floodcount(struct Client *, const char *, int);
69static void quote_identtimeout(struct Client *, const char *, int);
70static void quote_max(struct Client *, const char *, int);
71static void quote_operstring(struct Client *, const char *, int);
72static void quote_spamnum(struct Client *, const char *, int);
73static void quote_spamtime(struct Client *, const char *, int);
74static void quote_splitmode(struct Client *, const char *, int);
75static void quote_splitnum(struct Client *, const char *, int);
76static void quote_splitusers(struct Client *, const char *, int);
77
212380e3
AC
78static void list_quote_commands(struct Client *);
79
80
55abcbb2 81/*
212380e3
AC
82 * If this ever needs to be expanded to more than one arg of each
83 * type, want_char/want_int could be the count of the arguments,
84 * instead of just a boolean flag...
85 *
86 * -davidt
87 */
88
89static struct SetStruct set_cmd_table[] = {
90 /* name function string arg int arg */
91 /* -------------------------------------------------------- */
92 {"ADMINSTRING", quote_adminstring, 1, 0 },
93 {"AUTOCONN", quote_autoconn, 1, 1 },
94 {"AUTOCONNALL", quote_autoconnall, 0, 1 },
95 {"FLOODCOUNT", quote_floodcount, 0, 1 },
96 {"IDENTTIMEOUT", quote_identtimeout, 0, 1 },
212380e3
AC
97 {"MAX", quote_max, 0, 1 },
98 {"MAXCLIENTS", quote_max, 0, 1 },
99 {"OPERSTRING", quote_operstring, 1, 0 },
100 {"SPAMNUM", quote_spamnum, 0, 1 },
101 {"SPAMTIME", quote_spamtime, 0, 1 },
102 {"SPLITMODE", quote_splitmode, 1, 0 },
103 {"SPLITNUM", quote_splitnum, 0, 1 },
104 {"SPLITUSERS", quote_splitusers, 0, 1 },
105 /* -------------------------------------------------------- */
21dc257c 106 {(char *) 0, (void (*)(struct Client *, const char *, int)) 0, 0, 0}
212380e3
AC
107};
108
109
110/*
111 * list_quote_commands() sends the client all the available commands.
112 * Four to a line for now.
113 */
114static void
115list_quote_commands(struct Client *source_p)
116{
117 int i;
118 int j = 0;
119 const char *names[4];
120
5366977b 121 sendto_one_notice(source_p, ":Available QUOTE SET commands:");
212380e3
AC
122
123 names[0] = names[1] = names[2] = names[3] = "";
124
125 for (i = 0; set_cmd_table[i].handler; i++)
126 {
127 names[j++] = set_cmd_table[i].name;
128
129 if(j > 3)
130 {
5366977b
AC
131 sendto_one_notice(source_p, ":%s %s %s %s",
132 names[0], names[1], names[2], names[3]);
212380e3
AC
133 j = 0;
134 names[0] = names[1] = names[2] = names[3] = "";
135 }
136
137 }
138 if(j)
5366977b
AC
139 sendto_one_notice(source_p, ":%s %s %s %s",
140 names[0], names[1], names[2], names[3]);
212380e3
AC
141}
142
143/* SET AUTOCONN */
144static void
a3143c9b 145quote_autoconn(struct Client *source_p, const char *arg, int newval)
212380e3
AC
146{
147 set_server_conf_autoconn(source_p, arg, newval);
148}
149
150/* SET AUTOCONNALL */
151static void
21dc257c 152quote_autoconnall(struct Client *source_p, const char *arg, int newval)
212380e3
AC
153{
154 if(newval >= 0)
155 {
156 sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed AUTOCONNALL to %i",
157 source_p->name, newval);
158
159 GlobalSetOptions.autoconn = newval;
160 }
161 else
162 {
5366977b
AC
163 sendto_one_notice(source_p, ":AUTOCONNALL is currently %i",
164 GlobalSetOptions.autoconn);
212380e3
AC
165 }
166}
167
168
169/* SET FLOODCOUNT */
170static void
21dc257c 171quote_floodcount(struct Client *source_p, const char *arg, int newval)
212380e3
AC
172{
173 if(newval >= 0)
174 {
175 GlobalSetOptions.floodcount = newval;
176 sendto_realops_snomask(SNO_GENERAL, L_ALL,
177 "%s has changed FLOODCOUNT to %i", source_p->name,
178 GlobalSetOptions.floodcount);
179 }
180 else
181 {
5366977b
AC
182 sendto_one_notice(source_p, ":FLOODCOUNT is currently %i",
183 GlobalSetOptions.floodcount);
212380e3
AC
184 }
185}
186
187/* SET IDENTTIMEOUT */
188static void
21dc257c 189quote_identtimeout(struct Client *source_p, const char *arg, int newval)
212380e3
AC
190{
191 if(!IsOperAdmin(source_p))
192 {
193 sendto_one(source_p, form_str(ERR_NOPRIVS),
194 me.name, source_p->name, "admin");
195 return;
196 }
197
198 if(newval > 0)
199 {
200 sendto_realops_snomask(SNO_GENERAL, L_ALL,
201 "%s has changed IDENTTIMEOUT to %d",
202 get_oper_name(source_p), newval);
203 GlobalSetOptions.ident_timeout = newval;
204 }
205 else
5366977b
AC
206 sendto_one_notice(source_p, ":IDENTTIMEOUT is currently %d",
207 GlobalSetOptions.ident_timeout);
212380e3
AC
208}
209
212380e3
AC
210/* SET MAX */
211static void
21dc257c 212quote_max(struct Client *source_p, const char *arg, int newval)
212380e3
AC
213{
214 if(newval > 0)
215 {
8bd5767b
JT
216 if(newval > maxconnections - MAX_BUFFER)
217 {
218 sendto_one_notice(source_p,
219 ":You cannot set MAXCLIENTS to > %d",
220 maxconnections - MAX_BUFFER);
221 return;
6c70c576
JT
222 }
223
212380e3
AC
224 if(newval < 32)
225 {
101db4c4
VY
226 sendto_one_notice(source_p, ":You cannot set MAXCLIENTS to < 32 (%d:%d)",
227 GlobalSetOptions.maxclients, rb_getmaxconnect());
212380e3
AC
228 return;
229 }
230
231 GlobalSetOptions.maxclients = newval;
232
233 sendto_realops_snomask(SNO_GENERAL, L_ALL,
234 "%s!%s@%s set new MAXCLIENTS to %d (%lu current)",
235 source_p->name, source_p->username, source_p->host,
55abcbb2 236 GlobalSetOptions.maxclients,
5b96d9a6 237 rb_dlink_list_length(&lclient_list));
212380e3
AC
238
239 return;
240 }
241 else
242 {
5366977b 243 sendto_one_notice(source_p, ":Current Maxclients = %d (%lu)",
5b96d9a6 244 GlobalSetOptions.maxclients, rb_dlink_list_length(&lclient_list));
212380e3
AC
245 }
246}
247
248/* SET OPERSTRING */
249static void
21dc257c 250quote_operstring(struct Client *source_p, const char *arg, int newval)
212380e3
AC
251{
252 if(EmptyString(arg))
253 {
5366977b 254 sendto_one_notice(source_p, ":OPERSTRING is currently '%s'", GlobalSetOptions.operstring);
212380e3
AC
255 }
256 else
257 {
f427c8b0 258 rb_strlcpy(GlobalSetOptions.operstring, arg,
212380e3 259 sizeof(GlobalSetOptions.operstring));
55abcbb2 260
212380e3
AC
261 sendto_realops_snomask(SNO_GENERAL, L_ALL,
262 "%s has changed OPERSTRING to '%s'",
263 get_oper_name(source_p), arg);
264 }
265}
266
267/* SET ADMINSTRING */
268static void
21dc257c 269quote_adminstring(struct Client *source_p, const char *arg, int newval)
212380e3
AC
270{
271 if(EmptyString(arg))
272 {
5366977b 273 sendto_one_notice(source_p, ":ADMINSTRING is currently '%s'", GlobalSetOptions.adminstring);
212380e3
AC
274 }
275 else
276 {
f427c8b0 277 rb_strlcpy(GlobalSetOptions.adminstring, arg,
212380e3 278 sizeof(GlobalSetOptions.adminstring));
55abcbb2 279
212380e3
AC
280 sendto_realops_snomask(SNO_GENERAL, L_ALL,
281 "%s has changed ADMINSTRING to '%s'",
282 get_oper_name(source_p), arg);
283 }
284}
285
286/* SET SPAMNUM */
287static void
21dc257c 288quote_spamnum(struct Client *source_p, const char *arg, int newval)
212380e3
AC
289{
290 if(newval > 0)
291 {
292 if(newval == 0)
293 {
294 sendto_realops_snomask(SNO_GENERAL, L_ALL,
295 "%s has disabled ANTI_SPAMBOT", source_p->name);
296 GlobalSetOptions.spam_num = newval;
297 return;
298 }
299 if(newval < MIN_SPAM_NUM)
300 {
301 GlobalSetOptions.spam_num = MIN_SPAM_NUM;
302 }
303 else /* if (newval < MIN_SPAM_NUM) */
304 {
305 GlobalSetOptions.spam_num = newval;
306 }
307 sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed SPAMNUM to %i",
308 source_p->name, GlobalSetOptions.spam_num);
309 }
310 else
311 {
5366977b 312 sendto_one_notice(source_p, ":SPAMNUM is currently %i", GlobalSetOptions.spam_num);
212380e3
AC
313 }
314}
315
316/* SET SPAMTIME */
317static void
21dc257c 318quote_spamtime(struct Client *source_p, const char *arg, int newval)
212380e3
AC
319{
320 if(newval > 0)
321 {
322 if(newval < MIN_SPAM_TIME)
323 {
324 GlobalSetOptions.spam_time = MIN_SPAM_TIME;
325 }
326 else /* if (newval < MIN_SPAM_TIME) */
327 {
328 GlobalSetOptions.spam_time = newval;
329 }
330 sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed SPAMTIME to %i",
331 source_p->name, GlobalSetOptions.spam_time);
332 }
333 else
334 {
5366977b 335 sendto_one_notice(source_p, ":SPAMTIME is currently %i", GlobalSetOptions.spam_time);
212380e3
AC
336 }
337}
338
339/* this table is what splitmode may be set to */
340static const char *splitmode_values[] = {
341 "OFF",
342 "ON",
343 "AUTO",
344 NULL
345};
346
347/* this table is what splitmode may be */
348static const char *splitmode_status[] = {
349 "OFF",
350 "AUTO (OFF)",
351 "ON",
352 "AUTO (ON)",
353 NULL
354};
355
356/* SET SPLITMODE */
357static void
21dc257c 358quote_splitmode(struct Client *source_p, const char *charval, int intval)
212380e3
AC
359{
360 if(charval)
361 {
362 int newval;
363
364 for (newval = 0; splitmode_values[newval]; newval++)
365 {
366 if(!irccmp(splitmode_values[newval], charval))
367 break;
368 }
369
370 /* OFF */
371 if(newval == 0)
372 {
373 sendto_realops_snomask(SNO_GENERAL, L_ALL,
374 "%s is disabling splitmode", get_oper_name(source_p));
375
376 splitmode = 0;
377 splitchecking = 0;
378
fa832850 379 rb_event_delete(check_splitmode_ev);
6a309903 380 check_splitmode_ev = NULL;
212380e3
AC
381 }
382 /* ON */
383 else if(newval == 1)
384 {
385 sendto_realops_snomask(SNO_GENERAL, L_ALL,
386 "%s is enabling and activating splitmode",
387 get_oper_name(source_p));
388
389 splitmode = 1;
390 splitchecking = 0;
391
392 /* we might be deactivating an automatic splitmode, so pull the event */
fa832850 393 rb_event_delete(check_splitmode_ev);
6a309903 394 check_splitmode_ev = NULL;
212380e3
AC
395 }
396 /* AUTO */
397 else if(newval == 2)
398 {
399 sendto_realops_snomask(SNO_GENERAL, L_ALL,
400 "%s is enabling automatic splitmode",
401 get_oper_name(source_p));
402
403 splitchecking = 1;
404 check_splitmode(NULL);
405 }
406 }
407 else
55abcbb2 408 /* if we add splitchecking to splitmode*2 we get a unique table to
212380e3
AC
409 * pull values back out of, splitmode can be four states - but you can
410 * only set to three, which means we cant use the same table --fl_
411 */
5366977b 412 sendto_one_notice(source_p, ":SPLITMODE is currently %s",
212380e3
AC
413 splitmode_status[(splitchecking + (splitmode * 2))]);
414}
415
416/* SET SPLITNUM */
417static void
21dc257c 418quote_splitnum(struct Client *source_p, const char *arg, int newval)
212380e3
AC
419{
420 if(newval >= 0)
421 {
422 sendto_realops_snomask(SNO_GENERAL, L_ALL,
423 "%s has changed SPLITNUM to %i", source_p->name, newval);
424 split_servers = newval;
425
426 if(splitchecking)
427 check_splitmode(NULL);
428 }
429 else
5366977b 430 sendto_one_notice(source_p, ":SPLITNUM is currently %i", split_servers);
212380e3
AC
431}
432
433/* SET SPLITUSERS */
434static void
21dc257c 435quote_splitusers(struct Client *source_p, const char *arg, int newval)
212380e3
AC
436{
437 if(newval >= 0)
438 {
439 sendto_realops_snomask(SNO_GENERAL, L_ALL,
440 "%s has changed SPLITUSERS to %i", source_p->name, newval);
441 split_users = newval;
442
443 if(splitchecking)
444 check_splitmode(NULL);
445 }
446 else
5366977b 447 sendto_one_notice(source_p, ":SPLITUSERS is currently %i", split_users);
212380e3
AC
448}
449
450/*
451 * mo_set - SET command handler
452 * set options while running
453 */
454static int
428ca87b 455mo_set(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
212380e3
AC
456{
457 int newval;
458 int i, n;
459 const char *arg = NULL;
460 const char *intarg = NULL;
461
462 if(parc > 1)
463 {
464 /*
465 * Go through all the commands in set_cmd_table, until one is
466 * matched. I realize strcmp() is more intensive than a numeric
467 * lookup, but at least it's better than a big-ass switch/case
468 * statement.
469 */
470 for (i = 0; set_cmd_table[i].handler; i++)
471 {
472 if(!irccmp(set_cmd_table[i].name, parv[1]))
473 {
474 /*
475 * Command found; now execute the code
476 */
477 n = 2;
478
479 if(set_cmd_table[i].wants_char)
480 {
481 arg = parv[n++];
482 }
483
484 if(set_cmd_table[i].wants_int)
485 {
486 intarg = parv[n++];
487 }
488
489 if((n - 1) > parc)
490 {
5366977b
AC
491 sendto_one_notice(source_p,
492 ":SET %s expects (\"%s%s\") args",
212380e3
AC
493 set_cmd_table[i].name,
494 (set_cmd_table[i].
495 wants_char ? "string, " : ""),
496 (set_cmd_table[i].
497 wants_char ? "int" : ""));
498 return 0;
499 }
500
501 if(parc <= 2)
502 {
503 arg = NULL;
504 intarg = NULL;
505 }
506
507 if(set_cmd_table[i].wants_int && (parc > 2))
508 {
509 if(intarg)
510 {
511 if(!irccmp(intarg, "yes") || !irccmp(intarg, "on"))
512 newval = 1;
513 else if(!irccmp(intarg, "no")
514 || !irccmp(intarg, "off"))
515 newval = 0;
516 else
517 newval = atoi(intarg);
518 }
519 else
520 {
521 newval = -1;
522 }
523
524 if(newval < 0)
525 {
5366977b
AC
526 sendto_one_notice(source_p,
527 ":Value less than 0 illegal for %s",
212380e3
AC
528 set_cmd_table[i].name);
529
530 return 0;
531 }
532 }
533 else
534 newval = -1;
535
21dc257c
JT
536 set_cmd_table[i].handler(source_p, arg, newval);
537 return 0;
212380e3
AC
538 }
539 }
540
541 /*
542 * Code here will be executed when a /QUOTE SET command is not
543 * found within set_cmd_table.
544 */
5366977b 545 sendto_one_notice(source_p, ":Variable not found.");
212380e3
AC
546 return 0;
547 }
548
549 list_quote_commands(source_p);
550
551 return 0;
552}