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