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