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