]> jfr.im git - irc/rqf/shadowircd.git/blob - modules/m_info.c
Remove idle time checking (auto disconnecting users idle too long).
[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 "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: 3396 $");
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 "max_clients",
97 OUTPUT_DECIMAL,
98 &ServerInfo.max_clients,
99 "Maximum clients allowed (configured)",
100 },
101 {
102 "anti_nick_flood",
103 OUTPUT_BOOLEAN,
104 &ConfigFileEntry.anti_nick_flood,
105 "NICK flood protection"
106 },
107 {
108 "anti_spam_exit_message_time",
109 OUTPUT_DECIMAL,
110 &ConfigFileEntry.anti_spam_exit_message_time,
111 "Duration a client must be connected for to have an exit message"
112 },
113 {
114 "caller_id_wait",
115 OUTPUT_DECIMAL,
116 &ConfigFileEntry.caller_id_wait,
117 "Minimum delay between notifying UMODE +g users of messages"
118 },
119 {
120 "client_exit",
121 OUTPUT_BOOLEAN,
122 &ConfigFileEntry.client_exit,
123 "Prepend 'Client Exit:' to user QUIT messages"
124 },
125 {
126 "client_flood",
127 OUTPUT_DECIMAL,
128 &ConfigFileEntry.client_flood,
129 "Number of lines before a client Excess Flood's",
130 },
131 {
132 "connect_timeout",
133 OUTPUT_DECIMAL,
134 &ConfigFileEntry.connect_timeout,
135 "Connect timeout for connections to servers"
136 },
137 {
138 "default_floodcount",
139 OUTPUT_DECIMAL,
140 &ConfigFileEntry.default_floodcount,
141 "Startup value of FLOODCOUNT",
142 },
143 {
144 "default_adminstring",
145 OUTPUT_STRING,
146 &ConfigFileEntry.default_adminstring,
147 "Default adminstring at startup.",
148 },
149 {
150 "default_operstring",
151 OUTPUT_STRING,
152 &ConfigFileEntry.default_operstring,
153 "Default operstring at startup.",
154 },
155 {
156 "servicestring",
157 OUTPUT_STRING,
158 &ConfigFileEntry.servicestring,
159 "String shown in whois for opered services.",
160 },
161 {
162 "disable_auth",
163 OUTPUT_BOOLEAN_YN,
164 &ConfigFileEntry.disable_auth,
165 "Controls whether auth checking is disabled or not"
166 },
167 {
168 "disable_fake_channels",
169 OUTPUT_BOOLEAN_YN,
170 &ConfigFileEntry.disable_fake_channels,
171 "Controls whether bold etc are disabled for JOIN"
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 "kline_delay",
290 OUTPUT_DECIMAL,
291 &ConfigFileEntry.kline_delay,
292 "Duration of time to delay kline checking"
293 },
294 {
295 "kline_reason",
296 OUTPUT_STRING,
297 &ConfigFileEntry.kline_reason,
298 "K-lined clients sign off with this reason"
299 },
300 {
301 "dline_with_reason",
302 OUTPUT_BOOLEAN_YN,
303 &ConfigFileEntry.dline_with_reason,
304 "Display D-line reason to client on disconnect"
305 },
306 {
307 "kline_with_reason",
308 OUTPUT_BOOLEAN_YN,
309 &ConfigFileEntry.kline_with_reason,
310 "Display K-line reason to client on disconnect"
311 },
312 {
313 "max_accept",
314 OUTPUT_DECIMAL,
315 &ConfigFileEntry.max_accept,
316 "Maximum nicknames on accept list",
317 },
318 {
319 "max_nick_changes",
320 OUTPUT_DECIMAL,
321 &ConfigFileEntry.max_nick_changes,
322 "NICK change threshhold setting"
323 },
324 {
325 "max_nick_time",
326 OUTPUT_DECIMAL,
327 &ConfigFileEntry.max_nick_time,
328 "NICK flood protection time interval"
329 },
330 {
331 "max_targets",
332 OUTPUT_DECIMAL,
333 &ConfigFileEntry.max_targets,
334 "The maximum number of PRIVMSG/NOTICE targets"
335 },
336 {
337 "min_nonwildcard",
338 OUTPUT_DECIMAL,
339 &ConfigFileEntry.min_nonwildcard,
340 "Minimum non-wildcard chars in K/G lines",
341 },
342 {
343 "min_nonwildcard_simple",
344 OUTPUT_DECIMAL,
345 &ConfigFileEntry.min_nonwildcard_simple,
346 "Minimum non-wildcard chars in xlines/resvs",
347 },
348 {
349 "network_name",
350 OUTPUT_STRING,
351 &ServerInfo.network_name,
352 "Network name"
353 },
354 {
355 "network_desc",
356 OUTPUT_STRING,
357 &ServerInfo.network_desc,
358 "Network description"
359 },
360 {
361 "nick_delay",
362 OUTPUT_DECIMAL,
363 &ConfigFileEntry.nick_delay,
364 "Delay nicks are locked for on split",
365 },
366 {
367 "no_oper_flood",
368 OUTPUT_BOOLEAN,
369 &ConfigFileEntry.no_oper_flood,
370 "Disable flood control for operators",
371 },
372 {
373 "non_redundant_klines",
374 OUTPUT_BOOLEAN,
375 &ConfigFileEntry.non_redundant_klines,
376 "Check for and disallow redundant K-lines"
377 },
378 {
379 "operspy_admin_only",
380 OUTPUT_BOOLEAN,
381 &ConfigFileEntry.operspy_admin_only,
382 "Send +Z operspy notices to admins only"
383 },
384 {
385 "operspy_dont_care_user_info",
386 OUTPUT_BOOLEAN,
387 &ConfigFileEntry.operspy_dont_care_user_info,
388 "Remove accountability and some '!' requirement from non-channel operspy"
389 },
390 {
391 "pace_wait",
392 OUTPUT_DECIMAL,
393 &ConfigFileEntry.pace_wait,
394 "Minimum delay between uses of certain commands"
395 },
396 {
397 "pace_wait_simple",
398 OUTPUT_DECIMAL,
399 &ConfigFileEntry.pace_wait_simple,
400 "Minimum delay between less intensive commands"
401 },
402 {
403 "ping_cookie",
404 OUTPUT_BOOLEAN,
405 &ConfigFileEntry.ping_cookie,
406 "Require ping cookies to connect",
407 },
408 {
409 "reject_after_count",
410 OUTPUT_DECIMAL,
411 &ConfigFileEntry.reject_after_count,
412 "Client rejection threshold setting",
413 },
414 {
415 "reject_ban_time",
416 OUTPUT_DECIMAL,
417 &ConfigFileEntry.reject_ban_time,
418 "Client rejection time interval",
419 },
420 {
421 "reject_duration",
422 OUTPUT_DECIMAL,
423 &ConfigFileEntry.reject_duration,
424 "Client rejection cache duration",
425 },
426 {
427 "short_motd",
428 OUTPUT_BOOLEAN_YN,
429 &ConfigFileEntry.short_motd,
430 "Do not show MOTD; only tell clients they should read it"
431 },
432 {
433 "stats_e_disabled",
434 OUTPUT_BOOLEAN_YN,
435 &ConfigFileEntry.stats_e_disabled,
436 "STATS e output is disabled",
437 },
438 {
439 "stats_c_oper_only",
440 OUTPUT_BOOLEAN_YN,
441 &ConfigFileEntry.stats_c_oper_only,
442 "STATS C output is only shown to operators",
443 },
444 {
445 "stats_h_oper_only",
446 OUTPUT_BOOLEAN_YN,
447 &ConfigFileEntry.stats_h_oper_only,
448 "STATS H output is only shown to operators",
449 },
450 {
451 "stats_i_oper_only",
452 OUTPUT_BOOLEAN2,
453 &ConfigFileEntry.stats_i_oper_only,
454 "STATS I output is only shown to operators",
455 },
456 {
457 "stats_k_oper_only",
458 OUTPUT_BOOLEAN2,
459 &ConfigFileEntry.stats_k_oper_only,
460 "STATS K output is only shown to operators",
461 },
462 {
463 "stats_o_oper_only",
464 OUTPUT_BOOLEAN_YN,
465 &ConfigFileEntry.stats_o_oper_only,
466 "STATS O output is only shown to operators",
467 },
468 {
469 "stats_P_oper_only",
470 OUTPUT_BOOLEAN_YN,
471 &ConfigFileEntry.stats_P_oper_only,
472 "STATS P is only shown to operators",
473 },
474 {
475 "stats_y_oper_only",
476 OUTPUT_BOOLEAN_YN,
477 &ConfigFileEntry.stats_y_oper_only,
478 "STATS Y is only shown to operators",
479 },
480 {
481 "tkline_expire_notices",
482 OUTPUT_BOOLEAN,
483 &ConfigFileEntry.tkline_expire_notices,
484 "Notices given to opers when tklines expire"
485 },
486 {
487 "ts_max_delta",
488 OUTPUT_DECIMAL,
489 &ConfigFileEntry.ts_max_delta,
490 "Maximum permitted TS delta from another server"
491 },
492 {
493 "ts_warn_delta",
494 OUTPUT_DECIMAL,
495 &ConfigFileEntry.ts_warn_delta,
496 "Maximum permitted TS delta before displaying a warning"
497 },
498 {
499 "warn_no_nline",
500 OUTPUT_BOOLEAN,
501 &ConfigFileEntry.warn_no_nline,
502 "Display warning if connecting server lacks N-line"
503 },
504 {
505 "default_split_server_count",
506 OUTPUT_DECIMAL,
507 &ConfigChannel.default_split_server_count,
508 "Startup value of SPLITNUM",
509 },
510 {
511 "default_split_user_count",
512 OUTPUT_DECIMAL,
513 &ConfigChannel.default_split_user_count,
514 "Startup value of SPLITUSERS",
515 },
516 {
517 "knock_delay",
518 OUTPUT_DECIMAL,
519 &ConfigChannel.knock_delay,
520 "Delay between a users KNOCK attempts"
521 },
522 {
523 "knock_delay_channel",
524 OUTPUT_DECIMAL,
525 &ConfigChannel.knock_delay_channel,
526 "Delay between KNOCK attempts to a channel",
527 },
528 {
529 "kick_on_split_riding",
530 OUTPUT_BOOLEAN_YN,
531 &ConfigChannel.kick_on_split_riding,
532 "Kick users riding splits to join +i or +k channels"
533 },
534 {
535 "max_bans",
536 OUTPUT_DECIMAL,
537 &ConfigChannel.max_bans,
538 "Total +b/e/I/q modes allowed in a channel",
539 },
540 {
541 "max_bans_large",
542 OUTPUT_DECIMAL,
543 &ConfigChannel.max_bans_large,
544 "Total +b/e/I/q modes allowed in a +L channel",
545 },
546 {
547 "max_chans_per_user",
548 OUTPUT_DECIMAL,
549 &ConfigChannel.max_chans_per_user,
550 "Maximum number of channels a user can join",
551 },
552 {
553 "no_create_on_split",
554 OUTPUT_BOOLEAN_YN,
555 &ConfigChannel.no_create_on_split,
556 "Disallow creation of channels when split",
557 },
558 {
559 "no_join_on_split",
560 OUTPUT_BOOLEAN_YN,
561 &ConfigChannel.no_join_on_split,
562 "Disallow joining channels when split",
563 },
564 {
565 "use_except",
566 OUTPUT_BOOLEAN_YN,
567 &ConfigChannel.use_except,
568 "Enable chanmode +e (ban exceptions)",
569 },
570 {
571 "use_invex",
572 OUTPUT_BOOLEAN_YN,
573 &ConfigChannel.use_invex,
574 "Enable chanmode +I (invite exceptions)",
575 },
576 {
577 "use_forward",
578 OUTPUT_BOOLEAN_YN,
579 &ConfigChannel.use_forward,
580 "Enable chanmode +f (channel forwarding)",
581 },
582 {
583 "use_knock",
584 OUTPUT_BOOLEAN_YN,
585 &ConfigChannel.use_knock,
586 "Enable /KNOCK",
587 },
588 {
589 "disable_hidden",
590 OUTPUT_BOOLEAN_YN,
591 &ConfigServerHide.disable_hidden,
592 "Prevent servers from hiding themselves from a flattened /links",
593 },
594 {
595 "flatten_links",
596 OUTPUT_BOOLEAN_YN,
597 &ConfigServerHide.flatten_links,
598 "Flatten /links list",
599 },
600 {
601 "hidden",
602 OUTPUT_BOOLEAN_YN,
603 &ConfigServerHide.hidden,
604 "Hide this server from a flattened /links on remote servers",
605 },
606 {
607 "links_delay",
608 OUTPUT_DECIMAL,
609 &ConfigServerHide.links_delay,
610 "Links rehash delay"
611 },
612 /* --[ END OF TABLE ]---------------------------------------------- */
613 { (char *) 0, (unsigned int) 0, (void *) 0, (char *) 0}
614 };
615 /* *INDENT-ON* */
616
617 /*
618 ** m_info
619 ** parv[0] = sender prefix
620 ** parv[1] = servername
621 */
622 static int
623 m_info(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
624 {
625 static time_t last_used = 0L;
626
627 if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
628 {
629 /* safe enough to give this on a local connect only */
630 sendto_one(source_p, form_str(RPL_LOAD2HI),
631 me.name, source_p->name, "INFO");
632 sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
633 return 0;
634 }
635 else
636 last_used = CurrentTime;
637
638 if(hunt_server(client_p, source_p, ":%s INFO :%s", 1, parc, parv) != HUNTED_ISME)
639 return 0;
640
641 info_spy(source_p);
642
643 send_info_text(source_p);
644 send_birthdate_online_time(source_p);
645
646 sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
647 return 0;
648 }
649
650 /*
651 ** mo_info
652 ** parv[0] = sender prefix
653 ** parv[1] = servername
654 */
655 static int
656 mo_info(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
657 {
658 if(hunt_server(client_p, source_p, ":%s INFO :%s", 1, parc, parv) == HUNTED_ISME)
659 {
660 info_spy(source_p);
661
662 send_info_text(source_p);
663
664 if(IsOper(source_p))
665 send_conf_options(source_p);
666
667 send_birthdate_online_time(source_p);
668
669 sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
670 }
671
672 return 0;
673 }
674
675 /*
676 * send_info_text
677 *
678 * inputs - client pointer to send info text to
679 * output - none
680 * side effects - info text is sent to client
681 */
682 static void
683 send_info_text(struct Client *source_p)
684 {
685 const char **text = infotext;
686
687 while (*text)
688 {
689 sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), *text++);
690 }
691
692 sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
693 }
694
695 /*
696 * send_birthdate_online_time
697 *
698 * inputs - client pointer to send to
699 * output - none
700 * side effects - birthdate and online time are sent
701 */
702 static void
703 send_birthdate_online_time(struct Client *source_p)
704 {
705 sendto_one(source_p, ":%s %d %s :Birth Date: %s, compile # %s",
706 get_id(&me, source_p), RPL_INFO,
707 get_id(source_p, source_p), creation, generation);
708
709 sendto_one(source_p, ":%s %d %s :On-line since %s",
710 get_id(&me, source_p), RPL_INFO,
711 get_id(source_p, source_p), myctime(startup_time));
712 }
713
714 /*
715 * send_conf_options
716 *
717 * inputs - client pointer to send to
718 * output - none
719 * side effects - send config options to client
720 */
721 static void
722 send_conf_options(struct Client *source_p)
723 {
724 Info *infoptr;
725 int i = 0;
726
727 /*
728 * Now send them a list of all our configuration options
729 * (mostly from config.h)
730 */
731 for (infoptr = MyInformation; infoptr->name; infoptr++)
732 {
733 if(infoptr->intvalue)
734 {
735 sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
736 get_id(&me, source_p), RPL_INFO,
737 get_id(source_p, source_p),
738 infoptr->name, infoptr->intvalue,
739 infoptr->desc);
740 }
741 else
742 {
743 sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
744 get_id(&me, source_p), RPL_INFO,
745 get_id(source_p, source_p),
746 infoptr->name, infoptr->strvalue,
747 infoptr->desc);
748 }
749 }
750
751 /*
752 * Parse the info_table[] and do the magic.
753 */
754 for (i = 0; info_table[i].name; i++)
755 {
756 switch (info_table[i].output_type)
757 {
758 /*
759 * For "char *" references
760 */
761 case OUTPUT_STRING:
762 {
763 char *option = *((char **) info_table[i].option);
764
765 sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
766 get_id(&me, source_p), RPL_INFO,
767 get_id(source_p, source_p),
768 info_table[i].name,
769 option ? option : "NONE",
770 info_table[i].desc ? info_table[i].desc : "<none>");
771
772 break;
773 }
774 /*
775 * For "char foo[]" references
776 */
777 case OUTPUT_STRING_PTR:
778 {
779 char *option = (char *) info_table[i].option;
780
781 sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
782 get_id(&me, source_p), RPL_INFO,
783 get_id(source_p, source_p),
784 info_table[i].name,
785 EmptyString(option) ? "NONE" : option,
786 info_table[i].desc ? info_table[i].desc : "<none>");
787
788 break;
789 }
790 /*
791 * Output info_table[i].option as a decimal value.
792 */
793 case OUTPUT_DECIMAL:
794 {
795 int option = *((int *) info_table[i].option);
796
797 sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
798 get_id(&me, source_p), RPL_INFO,
799 get_id(source_p, source_p),
800 info_table[i].name,
801 option,
802 info_table[i].desc ? info_table[i].desc : "<none>");
803
804 break;
805 }
806
807 /*
808 * Output info_table[i].option as "ON" or "OFF"
809 */
810 case OUTPUT_BOOLEAN:
811 {
812 int option = *((int *) info_table[i].option);
813
814 sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
815 get_id(&me, source_p), RPL_INFO,
816 get_id(source_p, source_p),
817 info_table[i].name,
818 option ? "ON" : "OFF",
819 info_table[i].desc ? info_table[i].desc : "<none>");
820
821 break;
822 }
823 /*
824 * Output info_table[i].option as "YES" or "NO"
825 */
826 case OUTPUT_BOOLEAN_YN:
827 {
828 int option = *((int *) info_table[i].option);
829
830 sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
831 get_id(&me, source_p), RPL_INFO,
832 get_id(source_p, source_p),
833 info_table[i].name,
834 option ? "YES" : "NO",
835 info_table[i].desc ? info_table[i].desc : "<none>");
836
837 break;
838 }
839
840 case OUTPUT_BOOLEAN2:
841 {
842 int option = *((int *) info_table[i].option);
843
844 sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
845 me.name, RPL_INFO, source_p->name,
846 info_table[i].name,
847 option ? ((option == 1) ? "MASK" : "YES") : "NO",
848 info_table[i].desc ? info_table[i].desc : "<none>");
849 } /* switch (info_table[i].output_type) */
850 }
851 } /* forloop */
852
853
854 /* Don't send oper_only_umodes...it's a bit mask, we will have to decode it
855 ** in order for it to show up properly to opers who issue INFO
856 */
857
858 sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
859 }
860
861 /* info_spy()
862 *
863 * input - pointer to client
864 * output - none
865 * side effects - hook doing_info is called
866 */
867 static void
868 info_spy(struct Client *source_p)
869 {
870 hook_data hd;
871
872 hd.client = source_p;
873 hd.arg1 = hd.arg2 = NULL;
874
875 call_hook(doing_info_hook, &hd);
876 }