]>
jfr.im git - solanum.git/blob - modules/m_set.c
2 * ircd-ratbox: A slightly useful ircd.
3 * m_set.c: Sets a server parameter.
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
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.
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.
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
24 * $Id: m_set.c 3406 2007-04-13 19:06:53Z jilles $
27 /* rewritten by jdc */
39 #include "s_newconf.h"
44 static int mo_set(struct Client
*, struct Client
*, int, const char **);
46 struct Message set_msgtab
= {
47 "SET", 0, 0, 0, MFLG_SLOW
,
48 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, mg_ignore
, {mo_set
, 0}}
51 mapi_clist_av1 set_clist
[] = { &set_msgtab
, NULL
};
52 DECLARE_MODULE_AV1(set
, NULL
, NULL
, set_clist
, NULL
, NULL
, "$Revision: 3406 $");
54 /* Structure used for the SET table itself */
59 int wants_char
; /* 1 if it expects (char *, [int]) */
60 int wants_int
; /* 1 if it expects ([char *], int) */
62 /* eg: 0, 1 == only an int arg
63 * eg: 1, 1 == char and int args */
67 static void quote_adminstring(struct Client
*, const char *);
68 static void quote_autoconn(struct Client
*, char *, int);
69 static void quote_autoconnall(struct Client
*, int);
70 static void quote_floodcount(struct Client
*, int);
71 static void quote_identtimeout(struct Client
*, int);
72 static void quote_max(struct Client
*, int);
73 static void quote_operstring(struct Client
*, const char *);
74 static void quote_spamnum(struct Client
*, int);
75 static void quote_spamtime(struct Client
*, int);
76 static void quote_splitmode(struct Client
*, char *);
77 static void quote_splitnum(struct Client
*, int);
78 static void quote_splitusers(struct Client
*, int);
79 static void list_quote_commands(struct Client
*);
83 * If this ever needs to be expanded to more than one arg of each
84 * type, want_char/want_int could be the count of the arguments,
85 * instead of just a boolean flag...
90 static struct SetStruct set_cmd_table
[] = {
91 /* name function string arg int arg */
92 /* -------------------------------------------------------- */
93 {"ADMINSTRING", quote_adminstring
, 1, 0 },
94 {"AUTOCONN", quote_autoconn
, 1, 1 },
95 {"AUTOCONNALL", quote_autoconnall
, 0, 1 },
96 {"FLOODCOUNT", quote_floodcount
, 0, 1 },
97 {"IDENTTIMEOUT", quote_identtimeout
, 0, 1 },
98 {"MAX", quote_max
, 0, 1 },
99 {"MAXCLIENTS", quote_max
, 0, 1 },
100 {"OPERSTRING", quote_operstring
, 1, 0 },
101 {"SPAMNUM", quote_spamnum
, 0, 1 },
102 {"SPAMTIME", quote_spamtime
, 0, 1 },
103 {"SPLITMODE", quote_splitmode
, 1, 0 },
104 {"SPLITNUM", quote_splitnum
, 0, 1 },
105 {"SPLITUSERS", quote_splitusers
, 0, 1 },
106 /* -------------------------------------------------------- */
107 {(char *) 0, (void (*)()) 0, 0, 0}
112 * list_quote_commands() sends the client all the available commands.
113 * Four to a line for now.
116 list_quote_commands(struct Client
*source_p
)
120 const char *names
[4];
122 sendto_one_notice(source_p
, ":Available QUOTE SET commands:");
124 names
[0] = names
[1] = names
[2] = names
[3] = "";
126 for (i
= 0; set_cmd_table
[i
].handler
; i
++)
128 names
[j
++] = set_cmd_table
[i
].name
;
132 sendto_one_notice(source_p
, ":%s %s %s %s",
133 names
[0], names
[1], names
[2], names
[3]);
135 names
[0] = names
[1] = names
[2] = names
[3] = "";
140 sendto_one_notice(source_p
, ":%s %s %s %s",
141 names
[0], names
[1], names
[2], names
[3]);
146 quote_autoconn(struct Client
*source_p
, char *arg
, int newval
)
148 set_server_conf_autoconn(source_p
, arg
, newval
);
151 /* SET AUTOCONNALL */
153 quote_autoconnall(struct Client
*source_p
, int newval
)
157 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "%s has changed AUTOCONNALL to %i",
158 source_p
->name
, newval
);
160 GlobalSetOptions
.autoconn
= newval
;
164 sendto_one_notice(source_p
, ":AUTOCONNALL is currently %i",
165 GlobalSetOptions
.autoconn
);
172 quote_floodcount(struct Client
*source_p
, int newval
)
176 GlobalSetOptions
.floodcount
= newval
;
177 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
178 "%s has changed FLOODCOUNT to %i", source_p
->name
,
179 GlobalSetOptions
.floodcount
);
183 sendto_one_notice(source_p
, ":FLOODCOUNT is currently %i",
184 GlobalSetOptions
.floodcount
);
188 /* SET IDENTTIMEOUT */
190 quote_identtimeout(struct Client
*source_p
, int newval
)
192 if(!IsOperAdmin(source_p
))
194 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
195 me
.name
, source_p
->name
, "admin");
201 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
202 "%s has changed IDENTTIMEOUT to %d",
203 get_oper_name(source_p
), newval
);
204 GlobalSetOptions
.ident_timeout
= newval
;
207 sendto_one_notice(source_p
, ":IDENTTIMEOUT is currently %d",
208 GlobalSetOptions
.ident_timeout
);
213 quote_max(struct Client
*source_p
, int newval
)
217 if(newval
> maxconnections
- MAX_BUFFER
)
219 sendto_one_notice(source_p
,
220 ":You cannot set MAXCLIENTS to > %d",
221 maxconnections
- MAX_BUFFER
);
227 sendto_one_notice(source_p
, ":You cannot set MAXCLIENTS to < 32 (%d:%d)",
228 GlobalSetOptions
.maxclients
, rb_getmaxconnect());
232 GlobalSetOptions
.maxclients
= newval
;
234 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
235 "%s!%s@%s set new MAXCLIENTS to %d (%lu current)",
236 source_p
->name
, source_p
->username
, source_p
->host
,
237 GlobalSetOptions
.maxclients
,
238 rb_dlink_list_length(&lclient_list
));
244 sendto_one_notice(source_p
, ":Current Maxclients = %d (%lu)",
245 GlobalSetOptions
.maxclients
, rb_dlink_list_length(&lclient_list
));
251 quote_operstring(struct Client
*source_p
, const char *arg
)
255 sendto_one_notice(source_p
, ":OPERSTRING is currently '%s'", GlobalSetOptions
.operstring
);
259 rb_strlcpy(GlobalSetOptions
.operstring
, arg
,
260 sizeof(GlobalSetOptions
.operstring
));
262 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
263 "%s has changed OPERSTRING to '%s'",
264 get_oper_name(source_p
), arg
);
268 /* SET ADMINSTRING */
270 quote_adminstring(struct Client
*source_p
, const char *arg
)
274 sendto_one_notice(source_p
, ":ADMINSTRING is currently '%s'", GlobalSetOptions
.adminstring
);
278 rb_strlcpy(GlobalSetOptions
.adminstring
, arg
,
279 sizeof(GlobalSetOptions
.adminstring
));
281 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
282 "%s has changed ADMINSTRING to '%s'",
283 get_oper_name(source_p
), arg
);
289 quote_spamnum(struct Client
*source_p
, int newval
)
295 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
296 "%s has disabled ANTI_SPAMBOT", source_p
->name
);
297 GlobalSetOptions
.spam_num
= newval
;
300 if(newval
< MIN_SPAM_NUM
)
302 GlobalSetOptions
.spam_num
= MIN_SPAM_NUM
;
304 else /* if (newval < MIN_SPAM_NUM) */
306 GlobalSetOptions
.spam_num
= newval
;
308 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "%s has changed SPAMNUM to %i",
309 source_p
->name
, GlobalSetOptions
.spam_num
);
313 sendto_one_notice(source_p
, ":SPAMNUM is currently %i", GlobalSetOptions
.spam_num
);
319 quote_spamtime(struct Client
*source_p
, int newval
)
323 if(newval
< MIN_SPAM_TIME
)
325 GlobalSetOptions
.spam_time
= MIN_SPAM_TIME
;
327 else /* if (newval < MIN_SPAM_TIME) */
329 GlobalSetOptions
.spam_time
= newval
;
331 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "%s has changed SPAMTIME to %i",
332 source_p
->name
, GlobalSetOptions
.spam_time
);
336 sendto_one_notice(source_p
, ":SPAMTIME is currently %i", GlobalSetOptions
.spam_time
);
340 /* this table is what splitmode may be set to */
341 static const char *splitmode_values
[] = {
348 /* this table is what splitmode may be */
349 static const char *splitmode_status
[] = {
359 quote_splitmode(struct Client
*source_p
, char *charval
)
365 for (newval
= 0; splitmode_values
[newval
]; newval
++)
367 if(!irccmp(splitmode_values
[newval
], charval
))
374 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
375 "%s is disabling splitmode", get_oper_name(source_p
));
380 rb_event_delete(check_splitmode_ev
);
381 check_splitmode_ev
= NULL
;
386 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
387 "%s is enabling and activating splitmode",
388 get_oper_name(source_p
));
393 /* we might be deactivating an automatic splitmode, so pull the event */
394 rb_event_delete(check_splitmode_ev
);
395 check_splitmode_ev
= NULL
;
400 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
401 "%s is enabling automatic splitmode",
402 get_oper_name(source_p
));
405 check_splitmode(NULL
);
409 /* if we add splitchecking to splitmode*2 we get a unique table to
410 * pull values back out of, splitmode can be four states - but you can
411 * only set to three, which means we cant use the same table --fl_
413 sendto_one_notice(source_p
, ":SPLITMODE is currently %s",
414 splitmode_status
[(splitchecking
+ (splitmode
* 2))]);
419 quote_splitnum(struct Client
*source_p
, int newval
)
423 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
424 "%s has changed SPLITNUM to %i", source_p
->name
, newval
);
425 split_servers
= newval
;
428 check_splitmode(NULL
);
431 sendto_one_notice(source_p
, ":SPLITNUM is currently %i", split_servers
);
436 quote_splitusers(struct Client
*source_p
, int newval
)
440 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
441 "%s has changed SPLITUSERS to %i", source_p
->name
, newval
);
442 split_users
= newval
;
445 check_splitmode(NULL
);
448 sendto_one_notice(source_p
, ":SPLITUSERS is currently %i", split_users
);
452 * mo_set - SET command handler
453 * set options while running
456 mo_set(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
460 const char *arg
= NULL
;
461 const char *intarg
= NULL
;
466 * Go through all the commands in set_cmd_table, until one is
467 * matched. I realize strcmp() is more intensive than a numeric
468 * lookup, but at least it's better than a big-ass switch/case
471 for (i
= 0; set_cmd_table
[i
].handler
; i
++)
473 if(!irccmp(set_cmd_table
[i
].name
, parv
[1]))
476 * Command found; now execute the code
480 if(set_cmd_table
[i
].wants_char
)
485 if(set_cmd_table
[i
].wants_int
)
492 sendto_one_notice(source_p
,
493 ":SET %s expects (\"%s%s\") args",
494 set_cmd_table
[i
].name
,
496 wants_char
? "string, " : ""),
498 wants_char
? "int" : ""));
508 if(set_cmd_table
[i
].wants_int
&& (parc
> 2))
512 if(!irccmp(intarg
, "yes") || !irccmp(intarg
, "on"))
514 else if(!irccmp(intarg
, "no")
515 || !irccmp(intarg
, "off"))
518 newval
= atoi(intarg
);
527 sendto_one_notice(source_p
,
528 ":Value less than 0 illegal for %s",
529 set_cmd_table
[i
].name
);
537 if(set_cmd_table
[i
].wants_char
)
539 if(set_cmd_table
[i
].wants_int
)
540 set_cmd_table
[i
].handler(source_p
, arg
, newval
);
542 set_cmd_table
[i
].handler(source_p
, arg
);
547 if(set_cmd_table
[i
].wants_int
)
548 set_cmd_table
[i
].handler(source_p
, newval
);
550 /* Just in case someone actually wants a
551 * set function that takes no args.. *shrug* */
552 set_cmd_table
[i
].handler(source_p
);
559 * Code here will be executed when a /QUOTE SET command is not
560 * found within set_cmd_table.
562 sendto_one_notice(source_p
, ":Variable not found.");
566 list_quote_commands(source_p
);