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