]>
jfr.im git - irc/rqf/shadowircd.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 494 2006-01-15 16:08:28Z jilles $
27 /* rewritten by jdc */
32 #include "irc_string.h"
33 #include "sprintf_irc.h"
42 #include "s_newconf.h"
47 static int mo_set(struct Client
*, struct Client
*, int, const char **);
49 struct Message set_msgtab
= {
50 "SET", 0, 0, 0, MFLG_SLOW
,
51 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, mg_ignore
, {mo_set
, 0}}
54 mapi_clist_av1 set_clist
[] = { &set_msgtab
, NULL
};
55 DECLARE_MODULE_AV1(set
, NULL
, NULL
, set_clist
, NULL
, NULL
, "$Revision: 494 $");
57 /* Structure used for the SET table itself */
62 int wants_char
; /* 1 if it expects (char *, [int]) */
63 int wants_int
; /* 1 if it expects ([char *], int) */
65 /* eg: 0, 1 == only an int arg
66 * eg: 1, 1 == char and int args */
70 static void quote_adminstring(struct Client
*, const char *);
71 static void quote_autoconn(struct Client
*, char *, int);
72 static void quote_autoconnall(struct Client
*, int);
73 static void quote_floodcount(struct Client
*, int);
74 static void quote_identtimeout(struct Client
*, int);
75 static void quote_idletime(struct Client
*, int);
76 static void quote_max(struct Client
*, int);
77 static void quote_operstring(struct Client
*, const char *);
78 static void quote_spamnum(struct Client
*, int);
79 static void quote_spamtime(struct Client
*, int);
80 static void quote_splitmode(struct Client
*, char *);
81 static void quote_splitnum(struct Client
*, int);
82 static void quote_splitusers(struct Client
*, int);
83 static void list_quote_commands(struct Client
*);
87 * If this ever needs to be expanded to more than one arg of each
88 * type, want_char/want_int could be the count of the arguments,
89 * instead of just a boolean flag...
94 static struct SetStruct set_cmd_table
[] = {
95 /* name function string arg int arg */
96 /* -------------------------------------------------------- */
97 {"ADMINSTRING", quote_adminstring
, 1, 0 },
98 {"AUTOCONN", quote_autoconn
, 1, 1 },
99 {"AUTOCONNALL", quote_autoconnall
, 0, 1 },
100 {"FLOODCOUNT", quote_floodcount
, 0, 1 },
101 {"IDENTTIMEOUT", quote_identtimeout
, 0, 1 },
102 {"IDLETIME", quote_idletime
, 0, 1 },
103 {"MAX", quote_max
, 0, 1 },
104 {"MAXCLIENTS", quote_max
, 0, 1 },
105 {"OPERSTRING", quote_operstring
, 1, 0 },
106 {"SPAMNUM", quote_spamnum
, 0, 1 },
107 {"SPAMTIME", quote_spamtime
, 0, 1 },
108 {"SPLITMODE", quote_splitmode
, 1, 0 },
109 {"SPLITNUM", quote_splitnum
, 0, 1 },
110 {"SPLITUSERS", quote_splitusers
, 0, 1 },
111 /* -------------------------------------------------------- */
112 {(char *) 0, (void (*)()) 0, 0, 0}
117 * list_quote_commands() sends the client all the available commands.
118 * Four to a line for now.
121 list_quote_commands(struct Client
*source_p
)
125 const char *names
[4];
127 sendto_one(source_p
, ":%s NOTICE %s :Available QUOTE SET commands:",
128 me
.name
, source_p
->name
);
130 names
[0] = names
[1] = names
[2] = names
[3] = "";
132 for (i
= 0; set_cmd_table
[i
].handler
; i
++)
134 names
[j
++] = set_cmd_table
[i
].name
;
138 sendto_one(source_p
, ":%s NOTICE %s :%s %s %s %s",
139 me
.name
, source_p
->name
, names
[0], names
[1], names
[2], names
[3]);
141 names
[0] = names
[1] = names
[2] = names
[3] = "";
146 sendto_one(source_p
, ":%s NOTICE %s :%s %s %s %s",
147 me
.name
, source_p
->name
, names
[0], names
[1], names
[2], names
[3]);
152 quote_autoconn(struct Client
*source_p
, char *arg
, int newval
)
154 set_server_conf_autoconn(source_p
, arg
, newval
);
157 /* SET AUTOCONNALL */
159 quote_autoconnall(struct Client
*source_p
, int newval
)
163 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "%s has changed AUTOCONNALL to %i",
164 source_p
->name
, newval
);
166 GlobalSetOptions
.autoconn
= newval
;
170 sendto_one(source_p
, ":%s NOTICE %s :AUTOCONNALL is currently %i",
171 me
.name
, source_p
->name
, GlobalSetOptions
.autoconn
);
178 quote_floodcount(struct Client
*source_p
, int newval
)
182 GlobalSetOptions
.floodcount
= newval
;
183 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
184 "%s has changed FLOODCOUNT to %i", source_p
->name
,
185 GlobalSetOptions
.floodcount
);
189 sendto_one(source_p
, ":%s NOTICE %s :FLOODCOUNT is currently %i",
190 me
.name
, source_p
->name
, GlobalSetOptions
.floodcount
);
194 /* SET IDENTTIMEOUT */
196 quote_identtimeout(struct Client
*source_p
, int newval
)
198 if(!IsOperAdmin(source_p
))
200 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
201 me
.name
, source_p
->name
, "admin");
207 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
208 "%s has changed IDENTTIMEOUT to %d",
209 get_oper_name(source_p
), newval
);
210 GlobalSetOptions
.ident_timeout
= newval
;
213 sendto_one(source_p
, ":%s NOTICE %s :IDENTTIMEOUT is currently %d",
214 me
.name
, source_p
->name
, GlobalSetOptions
.ident_timeout
);
219 quote_idletime(struct Client
*source_p
, int newval
)
225 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
226 "%s has disabled idletime checking", source_p
->name
);
227 GlobalSetOptions
.idletime
= 0;
231 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
232 "%s has changed IDLETIME to %i",
233 source_p
->name
, newval
);
234 GlobalSetOptions
.idletime
= (newval
* 60);
239 sendto_one(source_p
, ":%s NOTICE %s :IDLETIME is currently %i",
240 me
.name
, source_p
->name
, GlobalSetOptions
.idletime
/ 60);
246 quote_max(struct Client
*source_p
, int newval
)
250 if(newval
> MASTER_MAX
)
253 ":%s NOTICE %s :You cannot set MAXCLIENTS to > MASTER_MAX (%d)",
254 me
.name
, source_p
->name
, MASTER_MAX
);
261 ":%s NOTICE %s :You cannot set MAXCLIENTS to < 32 (%d:%d)",
262 me
.name
, source_p
->name
, GlobalSetOptions
.maxclients
,
267 GlobalSetOptions
.maxclients
= newval
;
269 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
270 "%s!%s@%s set new MAXCLIENTS to %d (%lu current)",
271 source_p
->name
, source_p
->username
, source_p
->host
,
272 GlobalSetOptions
.maxclients
,
273 dlink_list_length(&lclient_list
));
279 sendto_one(source_p
, ":%s NOTICE %s :Current Maxclients = %d (%lu)",
280 me
.name
, source_p
->name
, GlobalSetOptions
.maxclients
,
281 dlink_list_length(&lclient_list
));
287 quote_operstring(struct Client
*source_p
, const char *arg
)
291 sendto_one(source_p
, ":%s NOTICE %s :OPERSTRING is currently '%s'",
292 me
.name
, source_p
->name
, GlobalSetOptions
.operstring
);
296 strlcpy(GlobalSetOptions
.operstring
, arg
,
297 sizeof(GlobalSetOptions
.operstring
));
299 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
300 "%s has changed OPERSTRING to '%s'",
301 get_oper_name(source_p
), arg
);
305 /* SET ADMINSTRING */
307 quote_adminstring(struct Client
*source_p
, const char *arg
)
311 sendto_one(source_p
, ":%s NOTICE %s :ADMINSTRING is currently '%s'",
312 me
.name
, source_p
->name
, GlobalSetOptions
.adminstring
);
316 strlcpy(GlobalSetOptions
.adminstring
, arg
,
317 sizeof(GlobalSetOptions
.adminstring
));
319 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
320 "%s has changed ADMINSTRING to '%s'",
321 get_oper_name(source_p
), arg
);
327 quote_spamnum(struct Client
*source_p
, int newval
)
333 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
334 "%s has disabled ANTI_SPAMBOT", source_p
->name
);
335 GlobalSetOptions
.spam_num
= newval
;
338 if(newval
< MIN_SPAM_NUM
)
340 GlobalSetOptions
.spam_num
= MIN_SPAM_NUM
;
342 else /* if (newval < MIN_SPAM_NUM) */
344 GlobalSetOptions
.spam_num
= newval
;
346 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "%s has changed SPAMNUM to %i",
347 source_p
->name
, GlobalSetOptions
.spam_num
);
351 sendto_one(source_p
, ":%s NOTICE %s :SPAMNUM is currently %i",
352 me
.name
, source_p
->name
, GlobalSetOptions
.spam_num
);
358 quote_spamtime(struct Client
*source_p
, int newval
)
362 if(newval
< MIN_SPAM_TIME
)
364 GlobalSetOptions
.spam_time
= MIN_SPAM_TIME
;
366 else /* if (newval < MIN_SPAM_TIME) */
368 GlobalSetOptions
.spam_time
= newval
;
370 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "%s has changed SPAMTIME to %i",
371 source_p
->name
, GlobalSetOptions
.spam_time
);
375 sendto_one(source_p
, ":%s NOTICE %s :SPAMTIME is currently %i",
376 me
.name
, source_p
->name
, GlobalSetOptions
.spam_time
);
380 /* this table is what splitmode may be set to */
381 static const char *splitmode_values
[] = {
388 /* this table is what splitmode may be */
389 static const char *splitmode_status
[] = {
399 quote_splitmode(struct Client
*source_p
, char *charval
)
405 for (newval
= 0; splitmode_values
[newval
]; newval
++)
407 if(!irccmp(splitmode_values
[newval
], charval
))
414 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
415 "%s is disabling splitmode", get_oper_name(source_p
));
420 eventDelete(check_splitmode
, NULL
);
425 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
426 "%s is enabling and activating splitmode",
427 get_oper_name(source_p
));
432 /* we might be deactivating an automatic splitmode, so pull the event */
433 eventDelete(check_splitmode
, NULL
);
438 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
439 "%s is enabling automatic splitmode",
440 get_oper_name(source_p
));
443 check_splitmode(NULL
);
447 /* if we add splitchecking to splitmode*2 we get a unique table to
448 * pull values back out of, splitmode can be four states - but you can
449 * only set to three, which means we cant use the same table --fl_
451 sendto_one(source_p
, ":%s NOTICE %s :SPLITMODE is currently %s",
452 me
.name
, source_p
->name
,
453 splitmode_status
[(splitchecking
+ (splitmode
* 2))]);
458 quote_splitnum(struct Client
*source_p
, int newval
)
462 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
463 "%s has changed SPLITNUM to %i", source_p
->name
, newval
);
464 split_servers
= newval
;
467 check_splitmode(NULL
);
470 sendto_one(source_p
, ":%s NOTICE %s :SPLITNUM is currently %i",
471 me
.name
, source_p
->name
, split_servers
);
476 quote_splitusers(struct Client
*source_p
, int newval
)
480 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
481 "%s has changed SPLITUSERS to %i", source_p
->name
, newval
);
482 split_users
= newval
;
485 check_splitmode(NULL
);
488 sendto_one(source_p
, ":%s NOTICE %s :SPLITUSERS is currently %i",
489 me
.name
, source_p
->name
, split_users
);
493 * mo_set - SET command handler
494 * set options while running
497 mo_set(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
501 const char *arg
= NULL
;
502 const char *intarg
= NULL
;
507 * Go through all the commands in set_cmd_table, until one is
508 * matched. I realize strcmp() is more intensive than a numeric
509 * lookup, but at least it's better than a big-ass switch/case
512 for (i
= 0; set_cmd_table
[i
].handler
; i
++)
514 if(!irccmp(set_cmd_table
[i
].name
, parv
[1]))
517 * Command found; now execute the code
521 if(set_cmd_table
[i
].wants_char
)
526 if(set_cmd_table
[i
].wants_int
)
534 ":%s NOTICE %s :SET %s expects (\"%s%s\") args",
535 me
.name
, source_p
->name
,
536 set_cmd_table
[i
].name
,
538 wants_char
? "string, " : ""),
540 wants_char
? "int" : ""));
550 if(set_cmd_table
[i
].wants_int
&& (parc
> 2))
554 if(!irccmp(intarg
, "yes") || !irccmp(intarg
, "on"))
556 else if(!irccmp(intarg
, "no")
557 || !irccmp(intarg
, "off"))
560 newval
= atoi(intarg
);
570 ":%s NOTICE %s :Value less than 0 illegal for %s",
571 me
.name
, source_p
->name
,
572 set_cmd_table
[i
].name
);
580 if(set_cmd_table
[i
].wants_char
)
582 if(set_cmd_table
[i
].wants_int
)
583 set_cmd_table
[i
].handler(source_p
, arg
, newval
);
585 set_cmd_table
[i
].handler(source_p
, arg
);
590 if(set_cmd_table
[i
].wants_int
)
591 set_cmd_table
[i
].handler(source_p
, newval
);
593 /* Just in case someone actually wants a
594 * set function that takes no args.. *shrug* */
595 set_cmd_table
[i
].handler(source_p
);
602 * Code here will be executed when a /QUOTE SET command is not
603 * found within set_cmd_table.
605 sendto_one(source_p
, ":%s NOTICE %s :Variable not found.", me
.name
, parv
[0]);
609 list_quote_commands(source_p
);