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