ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/releases/8.2.0beta2/modules/m_info.c
Revision: 2283
Committed: Tue Jun 18 19:13:20 2013 UTC (13 years, 1 month ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/m_info.c
File size: 18327 byte(s)
Log Message:
- Added generall::cycle_on_host_change configuration option as requested
  by Adam <adam@anope.org>

File Contents

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

Properties

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