]> jfr.im git - solanum.git/blame - modules/m_info.c
Replace RPL_WHOISTEXT(337) with RPL_WHOISSPECIAL(320) (#419)
[solanum.git] / modules / m_info.c
CommitLineData
212380e3
AC
1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * m_info.c: Sends information about the server.
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#include "stdinc.h"
212380e3
AC
26#include "m_info.h"
27#include "channel.h"
28#include "client.h"
4562c604 29#include "match.h"
212380e3
AC
30#include "ircd.h"
31#include "hook.h"
32#include "numeric.h"
33#include "s_serv.h"
34#include "s_user.h"
35#include "send.h"
36#include "s_conf.h"
37#include "msg.h"
38#include "parse.h"
39#include "modules.h"
d4f7eb4c 40#include "s_newconf.h"
212380e3 41
eeabf33a
EM
42static const char info_desc[] =
43 "Provides the INFO command for retrieving server copyright, credits, and other info";
44
212380e3
AC
45static void send_conf_options(struct Client *source_p);
46static void send_birthdate_online_time(struct Client *source_p);
47static void send_info_text(struct Client *source_p);
48static void info_spy(struct Client *);
49
3c7d6fcc
EM
50static void m_info(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
51static void mo_info(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
212380e3
AC
52
53struct Message info_msgtab = {
7baa37a9 54 "INFO", 0, 0, 0, 0,
212380e3
AC
55 {mg_unreg, {m_info, 0}, {mo_info, 0}, mg_ignore, mg_ignore, {mo_info, 0}}
56};
57
58int doing_info_hook;
59
60mapi_clist_av1 info_clist[] = { &info_msgtab, NULL };
61mapi_hlist_av1 info_hlist[] = {
62 { "doing_info", &doing_info_hook },
63 { NULL, NULL }
64};
65
f1156bf0 66DECLARE_MODULE_AV2(info, NULL, NULL, info_clist, info_hlist, NULL, NULL, NULL, info_desc);
212380e3 67
0ee3f45c
EK
68enum info_output_type {
69 OUTPUT_STRING, /* Output option as %s w/ dereference */
70 OUTPUT_STRING_PTR, /* Output option as %s w/out deference */
71 OUTPUT_DECIMAL, /* Output option as decimal (%d) */
72 OUTPUT_BOOLEAN, /* Output option as "ON" or "OFF" */
73 OUTPUT_BOOLEAN_YN, /* Output option as "YES" or "NO" */
74 OUTPUT_INTBOOL, /* BOOLEAN encoded as an int */
75 OUTPUT_INTBOOL_YN, /* BOOLEAN_YN encoded as an int */
76 OUTPUT_YESNOMASK, /* Output option as "YES/NO/MASKED" */
27076304 77 OUTPUT_STATSL, /* Output as "YES/NO/SELF" */
0ee3f45c
EK
78};
79
80#define INFO_STRING(ptr) OUTPUT_STRING, .option.string_p = (ptr)
81#define INFO_STRING_PTR(ptr) OUTPUT_STRING_PTR, .option.string = (ptr)
82#define INFO_BOOLEAN(ptr) OUTPUT_BOOLEAN, .option.bool_ = (ptr)
83#define INFO_BOOLEAN_YN(ptr) OUTPUT_BOOLEAN_YN, .option.bool_ = (ptr)
84#define INFO_INTBOOL(ptr) OUTPUT_INTBOOL, .option.int_ = (ptr)
85#define INFO_INTBOOL_YN(ptr) OUTPUT_INTBOOL_YN, .option.int_ = (ptr)
86#define INFO_YESNOMASK(ptr) OUTPUT_YESNOMASK, .option.int_ = (ptr)
87#define INFO_DECIMAL(ptr) OUTPUT_DECIMAL, .option.int_ = (ptr)
27076304 88#define INFO_STATSL(ptr) OUTPUT_STATSL, .option.statsl = (ptr)
0ee3f45c 89
212380e3
AC
90struct InfoStruct
91{
b3701ae2 92 const char *name;
b3701ae2 93 const char *desc;
0ee3f45c
EK
94 enum info_output_type output_type;
95 union
96 {
97 const int *int_;
98 const bool *bool_;
78744107
EK
99 char *const *string_p;
100 const char *string;
27076304 101 const enum stats_l_oper_only *statsl;
0ee3f45c 102 } option;
212380e3 103};
b3701ae2 104
212380e3
AC
105/* *INDENT-OFF* */
106static struct InfoStruct info_table[] = {
b3701ae2 107
212380e3
AC
108 {
109 "opers_see_all_users",
0ee3f45c
EK
110 "Farconnect notices available or operspy accountability limited",
111 INFO_BOOLEAN(&opers_see_all_users)
212380e3 112 },
8bd5767b
JT
113 {
114 "max_connections",
0ee3f45c
EK
115 "Max number connections",
116 INFO_DECIMAL(&maxconnections),
d8228627 117 },
212380e3
AC
118 {
119 "anti_nick_flood",
0ee3f45c
EK
120 "NICK flood protection",
121 INFO_INTBOOL(&ConfigFileEntry.anti_nick_flood),
212380e3
AC
122 },
123 {
124 "anti_spam_exit_message_time",
0ee3f45c
EK
125 "Duration a client must be connected for to have an exit message",
126 INFO_DECIMAL(&ConfigFileEntry.anti_spam_exit_message_time),
212380e3
AC
127 },
128 {
129 "caller_id_wait",
0ee3f45c
EK
130 "Minimum delay between notifying UMODE +g users of messages",
131 INFO_DECIMAL(&ConfigFileEntry.caller_id_wait),
212380e3
AC
132 },
133 {
134 "client_exit",
0ee3f45c
EK
135 "Prepend 'Quit:' to user QUIT messages",
136 INFO_INTBOOL(&ConfigFileEntry.client_exit),
212380e3
AC
137 },
138 {
e6e54763 139 "client_flood_max_lines",
212380e3 140 "Number of lines before a client Excess Flood's",
0ee3f45c 141 INFO_DECIMAL(&ConfigFileEntry.client_flood_max_lines),
212380e3 142 },
e6e54763
SB
143 {
144 "client_flood_burst_rate",
a75bf40d 145 "Maximum lines per second during flood grace period",
0ee3f45c 146 INFO_DECIMAL(&ConfigFileEntry.client_flood_burst_rate),
e6e54763
SB
147 },
148 {
149 "client_flood_burst_max",
a75bf40d 150 "Number of lines to process at once before delaying",
0ee3f45c 151 INFO_DECIMAL(&ConfigFileEntry.client_flood_burst_max),
e6e54763
SB
152 },
153 {
154 "client_flood_message_num",
e6e54763 155 "Number of messages to allow per client_flood_message_time outside of burst",
0ee3f45c 156 INFO_DECIMAL(&ConfigFileEntry.client_flood_message_num),
e6e54763
SB
157 },
158 {
159 "client_flood_message_time",
e6e54763 160 "Time to allow per client_flood_message_num outside of burst",
0ee3f45c 161 INFO_DECIMAL(&ConfigFileEntry.client_flood_message_time),
e6e54763 162 },
2d656284 163 {
b3a00991 164 "post_registration_delay",
2d656284 165 "Time to wait before processing commands from a new client",
0ee3f45c 166 INFO_DECIMAL(&ConfigFileEntry.post_registration_delay),
2d656284 167 },
212380e3
AC
168 {
169 "connect_timeout",
0ee3f45c
EK
170 "Connect timeout for connections to servers",
171 INFO_DECIMAL(&ConfigFileEntry.connect_timeout),
212380e3 172 },
0ffb8106 173 {
944b0584 174 "default_ident_timeout",
0ffb8106 175 "Amount of time the server waits for ident responses from clients",
0ee3f45c 176 INFO_DECIMAL(&ConfigFileEntry.default_ident_timeout),
0ffb8106 177 },
212380e3
AC
178 {
179 "default_floodcount",
212380e3 180 "Startup value of FLOODCOUNT",
0ee3f45c 181 INFO_DECIMAL(&ConfigFileEntry.default_floodcount),
212380e3
AC
182 },
183 {
184 "default_adminstring",
212380e3 185 "Default adminstring at startup.",
0ee3f45c 186 INFO_STRING(&ConfigFileEntry.default_adminstring),
212380e3
AC
187 },
188 {
189 "default_operstring",
212380e3 190 "Default operstring at startup.",
0ee3f45c 191 INFO_STRING(&ConfigFileEntry.default_operstring),
212380e3
AC
192 },
193 {
194 "servicestring",
212380e3 195 "String shown in whois for opered services.",
0ee3f45c 196 INFO_STRING(&ConfigFileEntry.servicestring),
212380e3 197 },
27076304
EK
198 {
199 "drain_reason",
200 "Message to quit users with if this server is draining.",
201 INFO_STRING(&ConfigFileEntry.drain_reason),
202 },
05bc814d
MD
203 {
204 "sasl_only_client_message",
205 "Message to quit users with if they require SASL authentication.",
206 INFO_STRING(&ConfigFileEntry.sasl_only_client_message),
207 },
e4a62bbc
MD
208 {
209 "identd_only_client_message",
210 "Message to quit users with if they require Identd.",
211 INFO_STRING(&ConfigFileEntry.identd_only_client_message),
212 },
213 {
214 "sctp_forbidden_client_message",
215 "Message to quit users with if they attempt using SCTP.",
216 INFO_STRING(&ConfigFileEntry.sctp_forbidden_client_message),
217 },
218 {
219 "ssltls_only_client_message",
220 "Message to quit users with if they require SSL/TLS.",
221 INFO_STRING(&ConfigFileEntry.ssltls_only_client_message),
222 },
223 {
224 "not_authorised_client_message",
225 "Message to quit users with if they are not authorised.",
226 INFO_STRING(&ConfigFileEntry.not_authorised_client_message),
227 },
228 {
229 "illegal_hostname_client_message",
230 "Message to users when their hostname contains illegal characters.",
231 INFO_STRING(&ConfigFileEntry.illegal_hostname_client_message),
232 },
233 {
234 "server_full_client_message",
235 "Message to users when the server is full.",
236 INFO_STRING(&ConfigFileEntry.server_full_client_message),
237 },
238 {
239 "illegal_name_long_client_message",
240 "Long message to users when their username contains illegal characters.",
241 INFO_STRING(&ConfigFileEntry.illegal_name_long_client_message),
242 },
243 {
244 "illegal_name_short_client_message",
245 "Short message to users when their username contains illegal characters.",
246 INFO_STRING(&ConfigFileEntry.illegal_name_short_client_message),
247 },
212380e3
AC
248 {
249 "disable_auth",
0ee3f45c
EK
250 "Controls whether auth checking is disabled or not",
251 INFO_INTBOOL_YN(&ConfigFileEntry.disable_auth),
212380e3
AC
252 },
253 {
254 "disable_fake_channels",
0ee3f45c
EK
255 "Controls whether bold etc are disabled for JOIN",
256 INFO_INTBOOL_YN(&ConfigFileEntry.disable_fake_channels),
212380e3 257 },
212380e3
AC
258 {
259 "dots_in_ident",
0ee3f45c
EK
260 "Number of permissible dots in an ident",
261 INFO_DECIMAL(&ConfigFileEntry.dots_in_ident),
212380e3
AC
262 },
263 {
264 "failed_oper_notice",
0ee3f45c
EK
265 "Inform opers if someone /oper's with the wrong password",
266 INFO_INTBOOL(&ConfigFileEntry.failed_oper_notice),
212380e3
AC
267 },
268 {
269 "fname_userlog",
0ee3f45c
EK
270 "User log file",
271 INFO_STRING(&ConfigFileEntry.fname_userlog),
212380e3
AC
272 },
273 {
274 "fname_fuserlog",
0ee3f45c
EK
275 "Failed user log file",
276 INFO_STRING(&ConfigFileEntry.fname_fuserlog),
212380e3
AC
277 },
278
279 {
280 "fname_operlog",
0ee3f45c
EK
281 "Operator log file",
282 INFO_STRING(&ConfigFileEntry.fname_operlog),
212380e3
AC
283 },
284 {
285 "fname_foperlog",
0ee3f45c
EK
286 "Failed operator log file",
287 INFO_STRING(&ConfigFileEntry.fname_foperlog),
212380e3
AC
288 },
289 {
290 "fname_serverlog",
0ee3f45c
EK
291 "Server connect/disconnect log file",
292 INFO_STRING(&ConfigFileEntry.fname_serverlog),
212380e3 293 },
00533129
KB
294 {
295 "fname_killlog",
0ee3f45c
EK
296 "KILL log file",
297 INFO_STRING(&ConfigFileEntry.fname_killlog),
00533129 298 },
212380e3
AC
299 {
300 "fname_klinelog",
0ee3f45c
EK
301 "KLINE etc log file",
302 INFO_STRING(&ConfigFileEntry.fname_klinelog),
212380e3 303 },
212380e3
AC
304 {
305 "fname_operspylog",
0ee3f45c
EK
306 "Oper spy log file",
307 INFO_STRING(&ConfigFileEntry.fname_operspylog),
212380e3
AC
308 },
309 {
310 "fname_ioerrorlog",
0ee3f45c
EK
311 "IO error log file",
312 INFO_STRING(&ConfigFileEntry.fname_ioerrorlog),
212380e3 313 },
212380e3
AC
314 {
315 "global_snotices",
0ee3f45c
EK
316 "Send out certain server notices globally",
317 INFO_INTBOOL_YN(&ConfigFileEntry.global_snotices),
212380e3
AC
318 },
319 {
320 "hide_error_messages",
0ee3f45c
EK
321 "Hide ERROR messages coming from servers",
322 INFO_YESNOMASK(&ConfigFileEntry.hide_error_messages),
212380e3
AC
323 },
324 {
325 "hide_spoof_ips",
0ee3f45c
EK
326 "Hide IPs of spoofed users",
327 INFO_INTBOOL_YN(&ConfigFileEntry.hide_spoof_ips),
212380e3 328 },
212380e3
AC
329 {
330 "kline_reason",
0ee3f45c
EK
331 "K-lined clients sign off with this reason",
332 INFO_STRING(&ConfigFileEntry.kline_reason),
212380e3
AC
333 },
334 {
335 "dline_with_reason",
0ee3f45c
EK
336 "Display D-line reason to client on disconnect",
337 INFO_INTBOOL_YN(&ConfigFileEntry.dline_with_reason),
212380e3
AC
338 },
339 {
340 "kline_with_reason",
0ee3f45c
EK
341 "Display K-line reason to client on disconnect",
342 INFO_INTBOOL_YN(&ConfigFileEntry.kline_with_reason),
212380e3 343 },
27076304
EK
344 {
345 "hide_tkdline_duration",
346 "Hide \"Temporary K-line 123 min.\" from user K/D-lline reasons",
347 INFO_INTBOOL_YN(&ConfigFileEntry.hide_tkdline_duration),
348 },
212380e3
AC
349 {
350 "max_accept",
212380e3 351 "Maximum nicknames on accept list",
0ee3f45c 352 INFO_DECIMAL(&ConfigFileEntry.max_accept),
212380e3
AC
353 },
354 {
355 "max_nick_changes",
0ee3f45c
EK
356 "NICK change threshold setting",
357 INFO_DECIMAL(&ConfigFileEntry.max_nick_changes),
212380e3
AC
358 },
359 {
360 "max_nick_time",
0ee3f45c
EK
361 "NICK flood protection time interval",
362 INFO_DECIMAL(&ConfigFileEntry.max_nick_time),
212380e3
AC
363 },
364 {
365 "max_targets",
0ee3f45c
EK
366 "The maximum number of PRIVMSG/NOTICE targets",
367 INFO_DECIMAL(&ConfigFileEntry.max_targets),
212380e3
AC
368 },
369 {
370 "min_nonwildcard",
aae358c0 371 "Minimum non-wildcard chars in K lines",
0ee3f45c 372 INFO_DECIMAL(&ConfigFileEntry.min_nonwildcard),
212380e3
AC
373 },
374 {
375 "min_nonwildcard_simple",
212380e3 376 "Minimum non-wildcard chars in xlines/resvs",
0ee3f45c 377 INFO_DECIMAL(&ConfigFileEntry.min_nonwildcard_simple),
212380e3
AC
378 },
379 {
380 "network_name",
0ee3f45c
EK
381 "Network name",
382 INFO_STRING(&ServerInfo.network_name),
212380e3 383 },
212380e3
AC
384 {
385 "nick_delay",
212380e3 386 "Delay nicks are locked for on split",
0ee3f45c 387 INFO_DECIMAL(&ConfigFileEntry.nick_delay),
212380e3
AC
388 },
389 {
390 "no_oper_flood",
212380e3 391 "Disable flood control for operators",
0ee3f45c 392 INFO_INTBOOL(&ConfigFileEntry.no_oper_flood),
212380e3
AC
393 },
394 {
395 "non_redundant_klines",
0ee3f45c
EK
396 "Check for and disallow redundant K-lines",
397 INFO_INTBOOL(&ConfigFileEntry.non_redundant_klines),
212380e3
AC
398 },
399 {
400 "operspy_admin_only",
0ee3f45c
EK
401 "Send +Z operspy notices to admins only",
402 INFO_INTBOOL(&ConfigFileEntry.operspy_admin_only),
212380e3
AC
403 },
404 {
405 "operspy_dont_care_user_info",
0ee3f45c
EK
406 "Remove accountability and some '!' requirement from non-channel operspy",
407 INFO_INTBOOL(&ConfigFileEntry.operspy_dont_care_user_info),
212380e3
AC
408 },
409 {
410 "pace_wait",
0ee3f45c
EK
411 "Minimum delay between uses of certain commands",
412 INFO_DECIMAL(&ConfigFileEntry.pace_wait),
212380e3
AC
413 },
414 {
415 "pace_wait_simple",
0ee3f45c
EK
416 "Minimum delay between less intensive commands",
417 INFO_DECIMAL(&ConfigFileEntry.pace_wait_simple),
212380e3
AC
418 },
419 {
420 "ping_cookie",
212380e3 421 "Require ping cookies to connect",
0ee3f45c 422 INFO_INTBOOL(&ConfigFileEntry.ping_cookie),
212380e3 423 },
d1c028f2
DS
424 {
425 "ping_warn_time",
426 "Amount of time between warnings about unresponsive servers",
427 INFO_DECIMAL(&ConfigFileEntry.ping_warn_time),
428 },
212380e3
AC
429 {
430 "reject_after_count",
212380e3 431 "Client rejection threshold setting",
0ee3f45c 432 INFO_DECIMAL(&ConfigFileEntry.reject_after_count),
212380e3
AC
433 },
434 {
435 "reject_ban_time",
212380e3 436 "Client rejection time interval",
0ee3f45c 437 INFO_DECIMAL(&ConfigFileEntry.reject_ban_time),
212380e3
AC
438 },
439 {
440 "reject_duration",
212380e3 441 "Client rejection cache duration",
0ee3f45c 442 INFO_DECIMAL(&ConfigFileEntry.reject_duration),
212380e3
AC
443 },
444 {
445 "short_motd",
0ee3f45c
EK
446 "Do not show MOTD; only tell clients they should read it",
447 INFO_INTBOOL_YN(&ConfigFileEntry.short_motd),
212380e3
AC
448 },
449 {
450 "stats_e_disabled",
212380e3 451 "STATS e output is disabled",
0ee3f45c 452 INFO_INTBOOL_YN(&ConfigFileEntry.stats_e_disabled),
212380e3
AC
453 },
454 {
455 "stats_c_oper_only",
212380e3 456 "STATS C output is only shown to operators",
0ee3f45c 457 INFO_INTBOOL_YN(&ConfigFileEntry.stats_c_oper_only),
212380e3 458 },
212380e3
AC
459 {
460 "stats_i_oper_only",
212380e3 461 "STATS I output is only shown to operators",
0ee3f45c 462 INFO_YESNOMASK(&ConfigFileEntry.stats_i_oper_only),
212380e3
AC
463 },
464 {
465 "stats_k_oper_only",
212380e3 466 "STATS K output is only shown to operators",
0ee3f45c 467 INFO_YESNOMASK(&ConfigFileEntry.stats_k_oper_only),
212380e3 468 },
27076304
EK
469 {
470 "stats_l_oper_only",
471 "STATS l/L output is only shown to operators",
472 INFO_STATSL(&ConfigFileEntry.stats_l_oper_only),
473 },
212380e3
AC
474 {
475 "stats_o_oper_only",
212380e3 476 "STATS O output is only shown to operators",
0ee3f45c 477 INFO_INTBOOL_YN(&ConfigFileEntry.stats_o_oper_only),
212380e3
AC
478 },
479 {
480 "stats_P_oper_only",
212380e3 481 "STATS P is only shown to operators",
0ee3f45c 482 INFO_INTBOOL_YN(&ConfigFileEntry.stats_P_oper_only),
212380e3
AC
483 },
484 {
485 "stats_y_oper_only",
212380e3 486 "STATS Y is only shown to operators",
0ee3f45c 487 INFO_INTBOOL_YN(&ConfigFileEntry.stats_y_oper_only),
212380e3 488 },
43946961
JT
489 {
490 "throttle_count",
43946961 491 "Connection throttle threshold",
0ee3f45c 492 INFO_DECIMAL(&ConfigFileEntry.throttle_count),
43946961
JT
493 },
494 {
495 "throttle_duration",
43946961 496 "Connection throttle duration",
0ee3f45c 497 INFO_DECIMAL(&ConfigFileEntry.throttle_duration),
43946961 498 },
212380e3
AC
499 {
500 "tkline_expire_notices",
0ee3f45c
EK
501 "Notices given to opers when tklines expire",
502 INFO_INTBOOL(&ConfigFileEntry.tkline_expire_notices),
212380e3
AC
503 },
504 {
505 "ts_max_delta",
0ee3f45c
EK
506 "Maximum permitted TS delta from another server",
507 INFO_DECIMAL(&ConfigFileEntry.ts_max_delta),
212380e3
AC
508 },
509 {
510 "ts_warn_delta",
0ee3f45c
EK
511 "Maximum permitted TS delta before displaying a warning",
512 INFO_DECIMAL(&ConfigFileEntry.ts_warn_delta),
212380e3
AC
513 },
514 {
515 "warn_no_nline",
0ee3f45c
EK
516 "Display warning if connecting server lacks connect block",
517 INFO_INTBOOL(&ConfigFileEntry.warn_no_nline),
212380e3 518 },
1702b694
JT
519 {
520 "use_propagated_bans",
0ee3f45c
EK
521 "KLINE sets fully propagated bans",
522 INFO_INTBOOL(&ConfigFileEntry.use_propagated_bans),
1702b694 523 },
e88a1f1b
KB
524 {
525 "max_ratelimit_tokens",
e88a1f1b 526 "The maximum number of tokens that can be accumulated for executing rate-limited commands",
0ee3f45c 527 INFO_DECIMAL(&ConfigFileEntry.max_ratelimit_tokens),
e88a1f1b 528 },
d42e6915
JT
529 {
530 "away_interval",
d42e6915 531 "The minimum time between aways",
0ee3f45c 532 INFO_DECIMAL(&ConfigFileEntry.away_interval),
d42e6915 533 },
fff4f763
EK
534 {
535 "tls_ciphers_oper_only",
fff4f763 536 "TLS cipher strings are hidden in whois for non-opers",
0ee3f45c 537 INFO_INTBOOL_YN(&ConfigFileEntry.tls_ciphers_oper_only),
fff4f763 538 },
212380e3
AC
539 {
540 "default_split_server_count",
212380e3 541 "Startup value of SPLITNUM",
0ee3f45c 542 INFO_DECIMAL(&ConfigChannel.default_split_server_count),
212380e3
AC
543 },
544 {
545 "default_split_user_count",
212380e3 546 "Startup value of SPLITUSERS",
0ee3f45c 547 INFO_DECIMAL(&ConfigChannel.default_split_user_count),
212380e3
AC
548 },
549 {
550 "knock_delay",
0ee3f45c
EK
551 "Delay between a users KNOCK attempts",
552 INFO_DECIMAL(&ConfigChannel.knock_delay),
212380e3
AC
553 },
554 {
555 "knock_delay_channel",
212380e3 556 "Delay between KNOCK attempts to a channel",
0ee3f45c 557 INFO_DECIMAL(&ConfigChannel.knock_delay_channel),
212380e3 558 },
212380e3
AC
559 {
560 "kick_on_split_riding",
0ee3f45c
EK
561 "Kick users riding splits to join +i or +k channels",
562 INFO_INTBOOL_YN(&ConfigChannel.kick_on_split_riding),
212380e3 563 },
341f971e
SB
564 {
565 "disable_local_channels",
0ee3f45c
EK
566 "Disable local channels (&channels)",
567 INFO_INTBOOL_YN(&ConfigChannel.disable_local_channels),
341f971e 568 },
212380e3
AC
569 {
570 "max_bans",
212380e3 571 "Total +b/e/I/q modes allowed in a channel",
0ee3f45c 572 INFO_DECIMAL(&ConfigChannel.max_bans),
212380e3
AC
573 },
574 {
575 "max_bans_large",
212380e3 576 "Total +b/e/I/q modes allowed in a +L channel",
0ee3f45c 577 INFO_DECIMAL(&ConfigChannel.max_bans_large),
212380e3
AC
578 },
579 {
580 "max_chans_per_user",
212380e3 581 "Maximum number of channels a user can join",
0ee3f45c 582 INFO_DECIMAL(&ConfigChannel.max_chans_per_user),
212380e3 583 },
a4721f5e
AC
584 {
585 "max_chans_per_user_large",
a4721f5e 586 "Maximum extended number of channels a user can join",
0ee3f45c 587 INFO_DECIMAL(&ConfigChannel.max_chans_per_user_large),
a4721f5e 588 },
212380e3
AC
589 {
590 "no_create_on_split",
212380e3 591 "Disallow creation of channels when split",
0ee3f45c 592 INFO_INTBOOL_YN(&ConfigChannel.no_create_on_split),
212380e3
AC
593 },
594 {
595 "no_join_on_split",
212380e3 596 "Disallow joining channels when split",
0ee3f45c 597 INFO_INTBOOL_YN(&ConfigChannel.no_join_on_split),
212380e3 598 },
6865c0b0
JT
599 {
600 "only_ascii_channels",
0ee3f45c
EK
601 "Controls whether non-ASCII is disabled for JOIN",
602 INFO_INTBOOL_YN(&ConfigChannel.only_ascii_channels),
6865c0b0 603 },
212380e3
AC
604 {
605 "use_except",
212380e3 606 "Enable chanmode +e (ban exceptions)",
0ee3f45c 607 INFO_INTBOOL_YN(&ConfigChannel.use_except),
212380e3
AC
608 },
609 {
610 "use_invex",
212380e3 611 "Enable chanmode +I (invite exceptions)",
0ee3f45c 612 INFO_INTBOOL_YN(&ConfigChannel.use_invex),
212380e3 613 },
2da6f6eb
JT
614 {
615 "use_forward",
2da6f6eb 616 "Enable chanmode +f (channel forwarding)",
0ee3f45c 617 INFO_INTBOOL_YN(&ConfigChannel.use_forward),
2da6f6eb 618 },
212380e3
AC
619 {
620 "use_knock",
212380e3 621 "Enable /KNOCK",
0ee3f45c 622 INFO_INTBOOL_YN(&ConfigChannel.use_knock),
212380e3 623 },
c2c25552
JT
624 {
625 "resv_forcepart",
0ee3f45c
EK
626 "Force-part local users on channel RESV",
627 INFO_INTBOOL_YN(&ConfigChannel.resv_forcepart),
c2c25552 628 },
04e5ed6c
JK
629 {
630 "opmod_send_statusmsg",
0ee3f45c
EK
631 "Send messages to @#channel if affected by +z",
632 INFO_INTBOOL_YN(&ConfigChannel.opmod_send_statusmsg),
04e5ed6c 633 },
dfeba655
EK
634 {
635 "ip_bans_through_vhost",
636 "Channel IP bans see through dynamic spoofs",
637 INFO_INTBOOL_YN(&ConfigChannel.ip_bans_through_vhost),
638 },
27076304
EK
639 {
640 "hide_opers",
641 "Hide all opers from unprivileged users",
642 INFO_INTBOOL_YN(&ConfigFileEntry.hide_opers),
643 },
644 {
645 "hide_opers_in_whois",
646 "Don't send RPL_WHOISOPERATOR to non-opers",
647 INFO_INTBOOL_YN(&ConfigFileEntry.hide_opers_in_whois),
648 },
212380e3
AC
649 {
650 "disable_hidden",
212380e3 651 "Prevent servers from hiding themselves from a flattened /links",
0ee3f45c 652 INFO_INTBOOL_YN(&ConfigServerHide.disable_hidden),
212380e3
AC
653 },
654 {
655 "flatten_links",
212380e3 656 "Flatten /links list",
0ee3f45c 657 INFO_INTBOOL_YN(&ConfigServerHide.flatten_links),
212380e3
AC
658 },
659 {
660 "hidden",
212380e3 661 "Hide this server from a flattened /links on remote servers",
0ee3f45c 662 INFO_INTBOOL_YN(&ConfigServerHide.hidden),
212380e3
AC
663 },
664 {
665 "links_delay",
0ee3f45c
EK
666 "Links rehash delay",
667 INFO_DECIMAL(&ConfigServerHide.links_delay),
212380e3 668 },
40ecb85a 669 {
670 "oper_secure_only",
671 "Require TLS to become an oper",
672 INFO_INTBOOL_YN(&ConfigFileEntry.oper_secure_only),
673 },
b3701ae2 674
0ee3f45c 675 { NULL, NULL, 0, { NULL } },
212380e3
AC
676};
677/* *INDENT-ON* */
678
679/*
e6e54763
SB
680 ** m_info
681 ** parv[1] = servername
682 */
3c7d6fcc 683static void
428ca87b 684m_info(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
212380e3
AC
685{
686 static time_t last_used = 0L;
687
e3354945 688 if((last_used + ConfigFileEntry.pace_wait) > rb_current_time())
212380e3
AC
689 {
690 /* safe enough to give this on a local connect only */
691 sendto_one(source_p, form_str(RPL_LOAD2HI),
e6e54763 692 me.name, source_p->name, "INFO");
212380e3 693 sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
3c7d6fcc 694 return;
212380e3
AC
695 }
696 else
e3354945 697 last_used = rb_current_time();
212380e3
AC
698
699 if(hunt_server(client_p, source_p, ":%s INFO :%s", 1, parc, parv) != HUNTED_ISME)
3c7d6fcc 700 return;
212380e3
AC
701
702 info_spy(source_p);
703
704 send_info_text(source_p);
705 send_birthdate_online_time(source_p);
706
707 sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
212380e3
AC
708}
709
710/*
e6e54763
SB
711 ** mo_info
712 ** parv[1] = servername
713 */
3c7d6fcc 714static void
428ca87b 715mo_info(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
212380e3
AC
716{
717 if(hunt_server(client_p, source_p, ":%s INFO :%s", 1, parc, parv) == HUNTED_ISME)
718 {
719 info_spy(source_p);
212380e3
AC
720 send_info_text(source_p);
721
d4f7eb4c 722 if(IsOperGeneral(source_p))
8ee12f0c 723 {
212380e3 724 send_conf_options(source_p);
8ee12f0c
JT
725 sendto_one_numeric(source_p, RPL_INFO, ":%s",
726 rb_lib_version());
727 }
212380e3
AC
728
729 send_birthdate_online_time(source_p);
730
731 sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
732 }
212380e3
AC
733}
734
735/*
736 * send_info_text
737 *
738 * inputs - client pointer to send info text to
739 * output - none
740 * side effects - info text is sent to client
741 */
742static void
743send_info_text(struct Client *source_p)
744{
745 const char **text = infotext;
746
747 while (*text)
748 {
749 sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), *text++);
750 }
751
752 sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
753}
754
755/*
756 * send_birthdate_online_time
757 *
758 * inputs - client pointer to send to
759 * output - none
760 * side effects - birthdate and online time are sent
761 */
762static void
763send_birthdate_online_time(struct Client *source_p)
764{
08d75d97 765 char tbuf[26]; /* this needs to be 26 - see ctime_r manpage */
212380e3 766 sendto_one(source_p, ":%s %d %s :Birth Date: %s, compile # %s",
55abcbb2 767 get_id(&me, source_p), RPL_INFO,
e6e54763 768 get_id(source_p, source_p), creation, generation);
212380e3
AC
769
770 sendto_one(source_p, ":%s %d %s :On-line since %s",
55abcbb2 771 get_id(&me, source_p), RPL_INFO,
e6e54763 772 get_id(source_p, source_p), rb_ctime(startup_time, tbuf, sizeof(tbuf)));
212380e3
AC
773}
774
775/*
776 * send_conf_options
777 *
778 * inputs - client pointer to send to
779 * output - none
780 * side effects - send config options to client
781 */
782static void
783send_conf_options(struct Client *source_p)
784{
785 Info *infoptr;
786 int i = 0;
787
788 /*
789 * Now send them a list of all our configuration options
9b8e9eb3 790 * (mostly from defaults.h)
212380e3
AC
791 */
792 for (infoptr = MyInformation; infoptr->name; infoptr++)
793 {
794 if(infoptr->intvalue)
795 {
cf3b1525 796 sendto_one(source_p, ":%s %d %s :%-30s %-16d [%s]",
e6e54763
SB
797 get_id(&me, source_p), RPL_INFO,
798 get_id(source_p, source_p),
55abcbb2 799 infoptr->name, infoptr->intvalue,
e6e54763 800 infoptr->desc);
212380e3
AC
801 }
802 else
803 {
cf3b1525 804 sendto_one(source_p, ":%s %d %s :%-30s %-16s [%s]",
e6e54763
SB
805 get_id(&me, source_p), RPL_INFO,
806 get_id(source_p, source_p),
55abcbb2 807 infoptr->name, infoptr->strvalue,
e6e54763 808 infoptr->desc);
212380e3
AC
809 }
810 }
811
812 /*
813 * Parse the info_table[] and do the magic.
814 */
815 for (i = 0; info_table[i].name; i++)
816 {
dce5f18f 817 static char opt_buf[BUFSIZE];
78744107 818 const char *opt_value = opt_buf;
dce5f18f
EK
819
820
212380e3
AC
821 switch (info_table[i].output_type)
822 {
0ee3f45c
EK
823 case OUTPUT_STRING:
824 {
78744107 825 const char *option = *info_table[i].option.string_p;
dce5f18f 826 opt_value = option != NULL ? option : "NONE";
0ee3f45c
EK
827 break;
828 }
829 case OUTPUT_STRING_PTR:
830 {
78744107 831 const char *option = info_table[i].option.string;
dce5f18f 832 opt_value = option != NULL ? option : "NONE";
0ee3f45c
EK
833 break;
834 }
835 case OUTPUT_DECIMAL:
836 {
837 int option = *info_table[i].option.int_;
dce5f18f 838 snprintf(opt_buf, sizeof opt_buf, "%d", option);
0ee3f45c
EK
839 break;
840 }
841 case OUTPUT_BOOLEAN:
842 {
843 bool option = *info_table[i].option.bool_;
dce5f18f 844 opt_value = option ? "ON" : "OFF";
0ee3f45c
EK
845 break;
846 }
847 case OUTPUT_BOOLEAN_YN:
848 {
849 bool option = *info_table[i].option.bool_;
dce5f18f 850 opt_value = option ? "YES" : "NO";
0ee3f45c
EK
851 break;
852 }
853 case OUTPUT_YESNOMASK:
854 {
855 int option = *info_table[i].option.int_;
dce5f18f
EK
856 opt_value = option == 0 ? "NO" :
857 option == 1 ? "MASK" :
858 "YES";
859 break;
0ee3f45c
EK
860 }
861 case OUTPUT_INTBOOL:
862 {
863 bool option = *info_table[i].option.int_;
dce5f18f 864 opt_value = option ? "ON" : "OFF";
0ee3f45c
EK
865 break;
866 }
867 case OUTPUT_INTBOOL_YN:
868 {
869 bool option = *info_table[i].option.int_;
dce5f18f 870 opt_value = option ? "YES" : "NO";
0ee3f45c
EK
871 break;
872 }
27076304
EK
873 case OUTPUT_STATSL:
874 {
875 enum stats_l_oper_only option = *info_table[i].option.statsl;
876 opt_value = option == STATS_L_OPER_ONLY_NO ? "NO" :
877 option == STATS_L_OPER_ONLY_SELF ? "SELF" :
878 "YES";
879 break;
880 }
212380e3 881 }
dce5f18f
EK
882
883 sendto_one(source_p, ":%s %d %s :%-30s %-16s [%s]",
884 get_id(&me, source_p), RPL_INFO,
885 get_id(source_p, source_p),
886 info_table[i].name,
887 opt_value,
888 info_table[i].desc ? info_table[i].desc : "<none>");
b3701ae2 889 }
212380e3
AC
890
891
892 /* Don't send oper_only_umodes...it's a bit mask, we will have to decode it
893 ** in order for it to show up properly to opers who issue INFO
894 */
895
896 sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
897}
898
899/* info_spy()
55abcbb2 900 *
212380e3
AC
901 * input - pointer to client
902 * output - none
903 * side effects - hook doing_info is called
904 */
905static void
906info_spy(struct Client *source_p)
907{
908 hook_data hd;
909
910 hd.client = source_p;
911 hd.arg1 = hd.arg2 = NULL;
912
913 call_hook(doing_info_hook, &hd);
914}