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