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