ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/m_info.c
Revision: 3096
Committed: Sat Mar 1 23:31:45 2014 UTC (12 years, 4 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/m_info.c
File size: 18371 byte(s)
Log Message:
- Applied Adam's "Put the command name in parv[0], not prefix name" patch

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2820 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 2820 * Copyright (c) 1997-2014 ircd-hybrid development team
5 adx 30 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19     * USA
20     */
21    
22 michael 2820 /*! \file m_info.c
23     * \brief Includes required functions for processing the INFO command.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1011 #include "list.h"
29 adx 30 #include "channel.h"
30     #include "client.h"
31     #include "irc_string.h"
32     #include "ircd.h"
33     #include "numeric.h"
34 michael 2970 #include "s_misc.h"
35 adx 30 #include "s_serv.h"
36     #include "s_user.h"
37     #include "send.h"
38 michael 1309 #include "conf.h"
39 adx 30 #include "parse.h"
40     #include "modules.h"
41    
42 michael 1230
43 adx 30 /*
44     * jdc -- Structure for our configuration value table
45     */
46     struct InfoStruct
47     {
48     const char *name; /* Displayed variable name */
49     unsigned int output_type; /* See below #defines */
50     void *option; /* Pointer reference to the value */
51     const char *desc; /* ASCII description of the variable */
52     };
53    
54     /* Types for output_type in InfoStruct */
55 michael 1827 #define OUTPUT_STRING 0x0001 /* Output option as %s w/ dereference */
56     #define OUTPUT_STRING_PTR 0x0002 /* Output option as %s w/out deference */
57     #define OUTPUT_DECIMAL 0x0004 /* Output option as decimal (%d) */
58     #define OUTPUT_BOOLEAN 0x0008 /* Output option as "ON" or "OFF" */
59     #define OUTPUT_BOOLEAN_YN 0x0010 /* Output option as "YES" or "NO" */
60     #define OUTPUT_BOOLEAN2 0x0020 /* Output option as "YES/NO/MASKED" */
61 adx 30
62     static const struct InfoStruct info_table[] =
63     {
64     /* --[ START OF TABLE ]-------------------------------------------- */
65 michael 1318
66 adx 30 {
67 michael 1318 "CPATH",
68     OUTPUT_STRING,
69     &ConfigFileEntry.configfile,
70 michael 1702 "Path to main configuration file"
71 michael 1318 },
72     {
73     "DPATH",
74     OUTPUT_STRING,
75     &ConfigFileEntry.dpath,
76 michael 1841 "Root directory of installation"
77 michael 1318 },
78     {
79     "DLPATH",
80     OUTPUT_STRING,
81     &ConfigFileEntry.dlinefile,
82 michael 1702 "Path to D-line database file"
83 michael 1318 },
84     {
85     "KPATH",
86     OUTPUT_STRING,
87     &ConfigFileEntry.klinefile,
88 michael 1702 "Path to K-line database file"
89 michael 1318 },
90     {
91 michael 1702 "GPATH",
92     OUTPUT_STRING,
93     &ConfigFileEntry.glinefile,
94     "Path to G-line database file"
95     },
96     {
97     "XPATH",
98     OUTPUT_STRING,
99     &ConfigFileEntry.xlinefile,
100     "Path to X-line database file"
101     },
102     {
103     "RESVPATH",
104     OUTPUT_STRING,
105 michael 1841 &ConfigFileEntry.resvfile,
106 michael 1702 "Path to resv database file"
107     },
108     {
109 adx 30 "network_name",
110     OUTPUT_STRING,
111     &ServerInfo.network_name,
112     "Network name"
113     },
114     {
115     "network_desc",
116     OUTPUT_STRING,
117     &ServerInfo.network_desc,
118     "Network description"
119     },
120     {
121     "hub",
122     OUTPUT_BOOLEAN_YN,
123     &ServerInfo.hub,
124     "Server is a hub"
125     },
126     {
127 michael 1754 "max_clients",
128     OUTPUT_DECIMAL,
129     &ServerInfo.max_clients,
130     "Maximum number of clients permitted simultaneously on this server"
131     },
132     {
133     "max_nick_length",
134     OUTPUT_DECIMAL,
135     &ServerInfo.max_nick_length,
136     "Maximum nickname length"
137     },
138     {
139     "max_topic_length",
140     OUTPUT_DECIMAL,
141     &ServerInfo.max_topic_length,
142     "Maximum topic length"
143     },
144     {
145 adx 30 "use_logging",
146     OUTPUT_BOOLEAN_YN,
147     &ConfigLoggingEntry.use_logging,
148     "Enable logging"
149     },
150     {
151 michael 1767 "disable_fake_channels",
152     OUTPUT_BOOLEAN_YN,
153     &ConfigChannel.disable_fake_channels,
154     "Forbids channels with special ASCII characters in their name"
155     },
156     {
157 adx 30 "knock_delay",
158     OUTPUT_DECIMAL,
159     &ConfigChannel.knock_delay,
160     "Delay between a users KNOCK attempts"
161     },
162     {
163     "knock_delay_channel",
164     OUTPUT_DECIMAL,
165     &ConfigChannel.knock_delay_channel,
166     "Delay between KNOCK attempts to a channel"
167     },
168     {
169     "max_chans_per_user",
170     OUTPUT_DECIMAL,
171     &ConfigChannel.max_chans_per_user,
172     "Maximum number of channels a user can join"
173     },
174     {
175 michael 1432 "max_chans_per_oper",
176     OUTPUT_DECIMAL,
177     &ConfigChannel.max_chans_per_oper,
178     "Maximum number of channels an oper can join"
179     },
180     {
181 adx 30 "max_bans",
182     OUTPUT_DECIMAL,
183     &ConfigChannel.max_bans,
184     "Total +b/e/I modes allowed in a channel"
185     },
186     {
187     "default_split_user_count",
188     OUTPUT_DECIMAL,
189     &ConfigChannel.default_split_user_count,
190     "Startup value of SPLITUSERS"
191     },
192     {
193     "default_split_server_count",
194     OUTPUT_DECIMAL,
195     &ConfigChannel.default_split_server_count,
196     "Startup value of SPLITNUM"
197     },
198     {
199     "no_create_on_split",
200     OUTPUT_BOOLEAN_YN,
201     &ConfigChannel.no_create_on_split,
202     "Disallow creation of channels when split"
203     },
204     {
205     "no_join_on_split",
206     OUTPUT_BOOLEAN_YN,
207     &ConfigChannel.no_join_on_split,
208     "Disallow joining channels when split"
209     },
210     {
211     "flatten_links",
212     OUTPUT_BOOLEAN_YN,
213     &ConfigServerHide.flatten_links,
214     "Flatten /links list"
215     },
216     {
217     "links_delay",
218     OUTPUT_DECIMAL,
219     &ConfigServerHide.links_delay,
220     "Links rehash delay"
221     },
222     {
223     "hidden",
224     OUTPUT_BOOLEAN_YN,
225     &ConfigServerHide.hidden,
226     "Hide this server from a flattened /links on remote servers"
227     },
228     {
229     "hide_servers",
230     OUTPUT_BOOLEAN_YN,
231     &ConfigServerHide.hide_servers,
232     "Hide servernames from users"
233     },
234     {
235 michael 1854 "hide_services",
236     OUTPUT_BOOLEAN_YN,
237     &ConfigServerHide.hide_services,
238     "Hides the location of services server"
239     },
240     {
241 adx 30 "hidden_name",
242     OUTPUT_STRING,
243     &ConfigServerHide.hidden_name,
244     "Server name users see if hide_servers = yes"
245     },
246     {
247     "hide_server_ips",
248     OUTPUT_BOOLEAN_YN,
249     &ConfigServerHide.hide_server_ips,
250 michael 1936 "Prevent people from seeing server IP addresses"
251 adx 30 },
252     {
253     "gline_min_cidr",
254     OUTPUT_DECIMAL,
255     &ConfigFileEntry.gline_min_cidr,
256     "Minimum required length of a CIDR bitmask for IPv4 G-Lines"
257     },
258     {
259     "gline_min_cidr6",
260     OUTPUT_DECIMAL,
261     &ConfigFileEntry.gline_min_cidr6,
262     "Minimum required length of a CIDR bitmask for IPv6 G-Lines"
263     },
264     {
265     "invisible_on_connect",
266     OUTPUT_BOOLEAN_YN,
267     &ConfigFileEntry.invisible_on_connect,
268     "Automatically set mode +i on connecting users"
269     },
270     {
271     "kill_chase_time_limit",
272     OUTPUT_DECIMAL,
273     &ConfigFileEntry.kill_chase_time_limit,
274     "Nick Change Tracker for KILL"
275     },
276     {
277     "hide_spoof_ips",
278     OUTPUT_BOOLEAN_YN,
279     &ConfigFileEntry.hide_spoof_ips,
280 michael 1936 "Hide spoofed IP addresses"
281 adx 30 },
282     {
283     "ignore_bogus_ts",
284     OUTPUT_BOOLEAN_YN,
285     &ConfigFileEntry.ignore_bogus_ts,
286     "Ignore bogus timestamps from other servers"
287     },
288     {
289 michael 2283 "cycle_on_host_change",
290     OUTPUT_BOOLEAN_YN,
291     &ConfigFileEntry.cycle_on_host_change,
292     "Send a fake QUIT/JOIN combination on host change"
293     },
294     {
295 adx 30 "disable_auth",
296     OUTPUT_BOOLEAN_YN,
297     &ConfigFileEntry.disable_auth,
298     "Completely disable ident lookups"
299     },
300     {
301     "disable_remote_commands",
302     OUTPUT_BOOLEAN_YN,
303 michael 2196 &ConfigServerHide.disable_remote_commands,
304 adx 30 "Prevent users issuing commands on remote servers"
305     },
306     {
307     "tkline_expire_notices",
308     OUTPUT_BOOLEAN_YN,
309     &ConfigFileEntry.tkline_expire_notices,
310     "Show temporary kline/xline expire notices"
311     },
312     {
313     "default_floodcount",
314     OUTPUT_DECIMAL,
315     &ConfigFileEntry.default_floodcount,
316     "Startup value of FLOODCOUNT"
317     },
318     {
319     "failed_oper_notice",
320     OUTPUT_BOOLEAN,
321     &ConfigFileEntry.failed_oper_notice,
322 michael 1702 "Inform opers if someone tries to /oper with the wrong password"
323 adx 30 },
324     {
325     "dots_in_ident",
326     OUTPUT_DECIMAL,
327     &ConfigFileEntry.dots_in_ident,
328     "Number of permissable dots in an ident"
329     },
330     {
331     "min_nonwildcard",
332     OUTPUT_DECIMAL,
333     &ConfigFileEntry.min_nonwildcard,
334     "Minimum non-wildcard chars in K/G lines"
335     },
336     {
337     "min_nonwildcard_simple",
338     OUTPUT_DECIMAL,
339     &ConfigFileEntry.min_nonwildcard_simple,
340     "Minimum non-wildcards in gecos bans"
341     },
342     {
343     "max_accept",
344     OUTPUT_DECIMAL,
345     &ConfigFileEntry.max_accept,
346     "Maximum nicknames on accept list"
347     },
348     {
349     "anti_nick_flood",
350     OUTPUT_BOOLEAN,
351     &ConfigFileEntry.anti_nick_flood,
352     "NICK flood protection"
353     },
354     {
355     "max_nick_time",
356     OUTPUT_DECIMAL,
357     &ConfigFileEntry.max_nick_time,
358     "NICK flood protection time interval"
359     },
360     {
361     "max_nick_changes",
362     OUTPUT_DECIMAL,
363     &ConfigFileEntry.max_nick_changes,
364     "NICK change threshhold setting"
365     },
366     {
367     "anti_spam_exit_message_time",
368     OUTPUT_DECIMAL,
369     &ConfigFileEntry.anti_spam_exit_message_time,
370     "Duration a client must be connected for to have an exit message"
371     },
372     {
373     "ts_warn_delta",
374     OUTPUT_DECIMAL,
375     &ConfigFileEntry.ts_warn_delta,
376     "Maximum permitted TS delta before displaying a warning"
377     },
378     {
379     "ts_max_delta",
380     OUTPUT_DECIMAL,
381     &ConfigFileEntry.ts_max_delta,
382     "Maximum permitted TS delta from another server"
383     },
384     {
385     "warn_no_nline",
386     OUTPUT_BOOLEAN,
387     &ConfigFileEntry.warn_no_nline,
388     "Display warning if connecting server lacks N-line"
389     },
390     {
391 michael 1767 "stats_e_disabled",
392     OUTPUT_BOOLEAN_YN,
393     &ConfigFileEntry.stats_e_disabled,
394     "Whether or not STATS e is disabled"
395     },
396     {
397 adx 30 "stats_o_oper_only",
398     OUTPUT_BOOLEAN_YN,
399     &ConfigFileEntry.stats_o_oper_only,
400     "STATS O output is only shown to operators"
401     },
402     {
403     "stats_P_oper_only",
404     OUTPUT_BOOLEAN_YN,
405     &ConfigFileEntry.stats_P_oper_only,
406     "STATS P is only shown to operators"
407     },
408     {
409 michael 2269 "stats_u_oper_only",
410     OUTPUT_BOOLEAN_YN,
411     &ConfigFileEntry.stats_u_oper_only,
412     "STATS u is only shown to operators"
413     },
414     {
415 adx 30 "stats_i_oper_only",
416     OUTPUT_BOOLEAN2,
417     &ConfigFileEntry.stats_i_oper_only,
418     "STATS I output is only shown to operators"
419     },
420     {
421     "stats_k_oper_only",
422     OUTPUT_BOOLEAN2,
423     &ConfigFileEntry.stats_k_oper_only,
424     "STATS K output is only shown to operators"
425     },
426     {
427     "caller_id_wait",
428     OUTPUT_DECIMAL,
429     &ConfigFileEntry.caller_id_wait,
430     "Minimum delay between notifying UMODE +g users of messages"
431     },
432     {
433     "opers_bypass_callerid",
434     OUTPUT_BOOLEAN_YN,
435     &ConfigFileEntry.opers_bypass_callerid,
436     "Allows IRC operators to message users who are +g (callerid)"
437     },
438     {
439     "pace_wait_simple",
440     OUTPUT_DECIMAL,
441     &ConfigFileEntry.pace_wait_simple,
442     "Minimum delay between less intensive commands"
443     },
444     {
445     "pace_wait",
446     OUTPUT_DECIMAL,
447     &ConfigFileEntry.pace_wait,
448     "Minimum delay between uses of certain commands"
449     },
450     {
451     "short_motd",
452     OUTPUT_BOOLEAN_YN,
453     &ConfigFileEntry.short_motd,
454     "Do not show MOTD; only tell clients they should read it"
455     },
456     {
457     "ping_cookie",
458     OUTPUT_BOOLEAN,
459     &ConfigFileEntry.ping_cookie,
460     "Require ping cookies to connect"
461     },
462     {
463     "no_oper_flood",
464     OUTPUT_BOOLEAN,
465     &ConfigFileEntry.no_oper_flood,
466     "Reduce flood control for operators"
467     },
468     {
469     "true_no_oper_flood",
470     OUTPUT_BOOLEAN,
471     &ConfigFileEntry.true_no_oper_flood,
472     "Completely disable flood control for operators"
473     },
474     {
475     "oper_pass_resv",
476     OUTPUT_BOOLEAN_YN,
477     &ConfigFileEntry.oper_pass_resv,
478     "Opers can over-ride RESVs"
479     },
480     {
481     "max_targets",
482     OUTPUT_DECIMAL,
483     &ConfigFileEntry.max_targets,
484     "The maximum number of PRIVMSG/NOTICE targets"
485     },
486     {
487     "throttle_time",
488     OUTPUT_DECIMAL,
489     &ConfigFileEntry.throttle_time,
490     "Minimum time between client reconnects"
491     },
492     {
493     "glines",
494     OUTPUT_BOOLEAN,
495     &ConfigFileEntry.glines,
496     "G-line (network-wide K-line) support"
497     },
498     {
499 michael 1459 "gline_duration",
500 adx 30 OUTPUT_DECIMAL,
501     &ConfigFileEntry.gline_time,
502     "Expiry time for G-lines"
503     },
504 michael 1459 {
505     "gline_request_duration",
506     OUTPUT_DECIMAL,
507     &ConfigFileEntry.gline_request_time,
508     "Expiry time for pending G-lines"
509     },
510    
511 adx 30 /* --[ END OF TABLE ]---------------------------------------------- */
512     {
513     NULL,
514     0,
515     NULL,
516     0
517     }
518     };
519    
520     /* send_birthdate_online_time()
521     *
522     * inputs - client pointer to send to
523     * output - NONE
524     * side effects - birthdate and online time are sent
525     */
526     static void
527     send_birthdate_online_time(struct Client *source_p)
528     {
529     if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
530     sendto_one(source_p, ":%s %d %s :On-line since %s",
531     me.id, RPL_INFO, source_p->id,
532 michael 1241 myctime(me.localClient->firsttime));
533 adx 30 else
534     sendto_one(source_p, ":%s %d %s :On-line since %s",
535     me.name, RPL_INFO, source_p->name,
536 michael 1241 myctime(me.localClient->firsttime));
537 adx 30 }
538    
539     /* send_conf_options()
540     *
541     * inputs - client pointer to send to
542     * output - NONE
543     * side effects - send config options to client
544     */
545     static void
546     send_conf_options(struct Client *source_p)
547     {
548     const char *from, *to;
549     const struct InfoStruct *iptr = NULL;
550    
551     /* Now send them a list of all our configuration options
552 michael 912 * (mostly from defaults.h and config.h)
553 adx 30 */
554     if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
555     {
556     from = me.id;
557     to = source_p->id;
558     }
559     else
560     {
561     from = me.name;
562     to = source_p->name;
563     }
564    
565     /*
566     * Parse the info_table[] and do the magic.
567     */
568     for (iptr = info_table; iptr->name; ++iptr)
569     {
570     switch (iptr->output_type)
571     {
572     /* For "char *" references */
573     case OUTPUT_STRING:
574     {
575     const char *option = *((char **)iptr->option);
576    
577     sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
578     from, RPL_INFO, to,
579     iptr->name, option ? option : "NONE",
580     iptr->desc ? iptr->desc : "<none>");
581     break;
582     }
583    
584     /* For "char foo[]" references */
585     case OUTPUT_STRING_PTR:
586     {
587     const char *option = iptr->option;
588    
589     sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
590     from, RPL_INFO, to,
591     iptr->name, option ? option : "NONE",
592     iptr->desc ? iptr->desc : "<none>");
593     break;
594     }
595    
596     /* Output info_table[i].option as a decimal value. */
597     case OUTPUT_DECIMAL:
598     {
599     const int option = *((int *)iptr->option);
600    
601     sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
602     from, RPL_INFO, to, iptr->name,
603     option, iptr->desc ? iptr->desc : "<none>");
604     break;
605     }
606    
607     /* Output info_table[i].option as "ON" or "OFF" */
608     case OUTPUT_BOOLEAN:
609     {
610     const int option = *((int *)iptr->option);
611    
612     sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
613     from, RPL_INFO, to,
614     iptr->name, option ? "ON" : "OFF",
615     iptr->desc ? iptr->desc : "<none>");
616    
617     break;
618     }
619    
620     /* Output info_table[i].option as "YES" or "NO" */
621     case OUTPUT_BOOLEAN_YN:
622     {
623 michael 1827 const int option = *((int *)iptr->option);
624 adx 30
625     sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
626     from, RPL_INFO, to,
627     iptr->name, option ? "YES" : "NO",
628     iptr->desc ? iptr->desc : "<none>");
629     break;
630     }
631    
632     case OUTPUT_BOOLEAN2:
633     {
634 michael 1827 const int option = *((int *)iptr->option);
635 adx 30
636     sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
637     from, RPL_INFO, to,
638     iptr->name, option ? ((option == 1) ? "MASK" : "YES") : "NO",
639     iptr->desc ? iptr->desc : "<none>");
640     break;
641     }
642     }
643     }
644    
645 michael 1834 sendto_one(source_p, form_str(RPL_INFO),
646 adx 30 from, to, "");
647     }
648 michael 1230
649 michael 1827 /* send_info_text()
650     *
651     * inputs - client pointer to send info text to
652     * output - NONE
653     * side effects - info text is sent to client
654     */
655 michael 2820 static int
656 michael 1827 send_info_text(struct Client *source_p)
657     {
658     const char **text = infotext;
659     char *source, *target;
660    
661     sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE,
662     "INFO requested by %s (%s@%s) [%s]",
663     source_p->name, source_p->username,
664     source_p->host, source_p->servptr->name);
665    
666     if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) &&
667     HasID(source_p))
668     source = me.id, target = source_p->id;
669     else
670     source = me.name, target = source_p->name;
671    
672     while (*text)
673     {
674     const char *line = *text++;
675    
676     if (*line == '\0')
677     line = " ";
678    
679 michael 1834 sendto_one(source_p, form_str(RPL_INFO),
680 michael 1827 source, target, line);
681     }
682    
683     if (HasUMode(source_p, UMODE_OPER))
684     send_conf_options(source_p);
685    
686     send_birthdate_online_time(source_p);
687    
688 michael 1834 sendto_one(source_p, form_str(RPL_ENDOFINFO),
689 michael 1827 me.name, source_p->name);
690 michael 2820 return 0;
691 michael 1827 }
692    
693     /*
694     ** m_info()
695 michael 3096 ** parv[0] = command
696 michael 1827 ** parv[1] = servername
697     */
698 michael 2820 static int
699 michael 1827 m_info(struct Client *client_p, struct Client *source_p,
700     int parc, char *parv[])
701     {
702     static time_t last_used = 0;
703    
704     if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
705     {
706     /* safe enough to give this on a local connect only */
707 michael 1834 sendto_one(source_p, form_str(RPL_LOAD2HI),
708 michael 1827 me.name, source_p->name);
709 michael 2820 return 0;
710 michael 1827 }
711    
712     last_used = CurrentTime;
713    
714 michael 2196 if (!ConfigServerHide.disable_remote_commands)
715 michael 3079 if (hunt_server(client_p, source_p, ":%s INFO :%s", 1,
716 michael 1827 parc, parv) != HUNTED_ISME)
717 michael 2820 return 0;
718 michael 1827
719 michael 2820 return send_info_text(source_p);
720 michael 1827 }
721    
722     /*
723     ** ms_info()
724 michael 3096 ** parv[0] = command
725 michael 1827 ** parv[1] = servername
726     */
727 michael 2820 static int
728 michael 1827 ms_info(struct Client *client_p, struct Client *source_p,
729     int parc, char *parv[])
730     {
731     if (hunt_server(client_p, source_p, ":%s INFO :%s", 1,
732     parc, parv) != HUNTED_ISME)
733 michael 2820 return 0;
734 michael 1827
735 michael 2820 return send_info_text(source_p);
736 michael 1827 }
737    
738 michael 2820 static struct Message info_msgtab =
739     {
740 michael 1230 "INFO", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
741 michael 1827 { m_unregistered, m_info, ms_info, m_ignore, ms_info, m_ignore }
742 michael 1230 };
743    
744     static void
745     module_init(void)
746     {
747     mod_add_cmd(&info_msgtab);
748     }
749    
750     static void
751     module_exit(void)
752     {
753     mod_del_cmd(&info_msgtab);
754     }
755    
756 michael 2820 struct module module_entry =
757     {
758 michael 1230 .node = { NULL, NULL, NULL },
759     .name = NULL,
760     .version = "$Revision$",
761     .handle = NULL,
762     .modinit = module_init,
763     .modexit = module_exit,
764     .flags = 0
765     };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision