ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_module.c
Revision: 4545
Committed: Fri Aug 22 08:46:13 2014 UTC (11 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 7976 byte(s)
Log Message:
- Implemented pseudo {} blocks (service aliases)
- Fixed compile warnings with -Wmissing-field-initializers

File Contents

# User Rev Content
1 michael 1447 /*
2 michael 2820 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 michael 1447 *
4 michael 2820 * Copyright (c) 2000-2014 ircd-hybrid development team
5 michael 1447 *
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     /*! \file m_module.c
23     * \brief Includes required functions for processing the MODULE command.
24     * \version $Id$
25     */
26    
27     #include "stdinc.h"
28     #include "list.h"
29     #include "client.h"
30     #include "irc_string.h"
31     #include "ircd.h"
32     #include "numeric.h"
33     #include "conf.h"
34     #include "log.h"
35     #include "send.h"
36     #include "parse.h"
37     #include "modules.h"
38    
39    
40 michael 3339 /*! \brief LOAD subcommand handler
41     * Attempts to load a module, throwing an error if
42     * the module has already been loaded
43     * \param source_p Pointer to client issuing the command
44 michael 3340 * \param arg Additional argument which might be needed by this handler
45 michael 1447 */
46 michael 3339 static void
47 michael 3340 module_load(struct Client *source_p, const char *arg)
48 michael 1447 {
49     const char *m_bn = NULL;
50    
51 michael 3340 if (findmodule_byname((m_bn = libio_basename(arg))))
52 michael 1447 {
53 michael 3339 sendto_one_notice(source_p, &me, ":Module %s is already loaded", m_bn);
54     return;
55 michael 1447 }
56    
57 michael 3340 load_one_module(arg);
58 michael 3339 }
59    
60     /*! \brief UNLOAD subcommand handler
61     * Attempts to unload a module, throwing an error if
62     * the module could not be found
63     * \param source_p Pointer to client issuing the command
64 michael 3340 * \param arg Additional argument which might be needed by this handler
65 michael 3339 */
66     static void
67 michael 3340 module_unload(struct Client *source_p, const char *arg)
68 michael 3339 {
69     const char *m_bn = NULL;
70     const struct module *modp = NULL;
71    
72 michael 3340 if ((modp = findmodule_byname((m_bn = libio_basename(arg)))) == NULL)
73 michael 1447 {
74 michael 3339 sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn);
75     return;
76 michael 1447 }
77    
78 michael 3339 if (modp->flags & MODULE_FLAG_CORE)
79 michael 1447 {
80 michael 3339 sendto_one_notice(source_p, &me, ":Module %s is a core module and may not be unloaded",
81     m_bn);
82     return;
83     }
84 michael 1448
85 michael 3339 if (modp->flags & MODULE_FLAG_NOUNLOAD)
86     {
87     sendto_one_notice(source_p, &me, ":Module %s is a resident module and may not be unloaded",
88     m_bn);
89     return;
90 michael 1447 }
91    
92 michael 3339 if (unload_one_module(m_bn, 1) == -1)
93     sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn);
94     }
95    
96     /*! \brief RELOAD subcommand handler
97     * Attempts to reload a module, throwing an error if
98     * the module could not be found or loaded
99     * \param source_p Pointer to client issuing the command
100 michael 3340 * \param arg Additional argument which might be needed by this handler
101 michael 3339 */
102     static void
103 michael 3340 module_reload(struct Client *source_p, const char *arg)
104 michael 3339 {
105     const char *m_bn = NULL;
106     struct module *modp = NULL;
107     int check_core = 0;
108    
109 michael 3340 if (!strcmp(arg, "*"))
110 michael 1447 {
111 michael 3339 unsigned int modnum = 0;
112     dlink_node *ptr = NULL, *ptr_next = NULL;
113 michael 1448
114 michael 3339 sendto_one_notice(source_p, &me, ":Reloading all modules");
115 michael 1447
116 michael 3339 modnum = dlink_list_length(modules_get_list());
117    
118     DLINK_FOREACH_SAFE(ptr, ptr_next, modules_get_list()->head)
119 michael 1447 {
120 michael 3339 modp = ptr->data;
121 michael 1447
122 michael 3339 if (!(modp->flags & MODULE_FLAG_NOUNLOAD))
123     unload_one_module(modp->name, 0);
124 michael 1448 }
125    
126 michael 3339 load_all_modules(0);
127     load_conf_modules();
128     load_core_modules(0);
129    
130     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
131     "Module Restart: %u modules unloaded, %u modules loaded",
132     modnum, dlink_list_length(modules_get_list()));
133     ilog(LOG_TYPE_IRCD, "Module Restart: %u modules unloaded, %u modules loaded",
134     modnum, dlink_list_length(modules_get_list()));
135     return;
136 michael 1447 }
137    
138 michael 3340 if ((modp = findmodule_byname((m_bn = libio_basename(arg)))) == NULL)
139 michael 1447 {
140 michael 3339 sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn);
141     return;
142     }
143 michael 1448
144 michael 3339 if (modp->flags & MODULE_FLAG_NOUNLOAD)
145     {
146     sendto_one_notice(source_p, &me, ":Module %s is a resident module and may not be unloaded",
147     m_bn);
148     return;
149     }
150 michael 1447
151 michael 3339 check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
152 michael 1447
153 michael 3339 if (unload_one_module(m_bn, 1) == -1)
154     {
155     sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn);
156     return;
157     }
158 michael 1447
159 michael 3340 if ((load_one_module(arg) == -1) && check_core)
160 michael 3339 {
161     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
162     "Error reloading core "
163 michael 3340 "module: %s: terminating ircd", arg);
164     ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd", arg);
165 michael 3339 exit(0);
166     }
167     }
168 michael 1448
169 michael 3339 /*! \brief LIST subcommand handler
170     * Shows a list of loaded modules
171     * \param source_p Pointer to client issuing the command
172 michael 3340 * \param arg Additional argument which might be needed by this handler
173 michael 3339 */
174     static void
175 michael 3340 module_list(struct Client *source_p, const char *arg)
176 michael 3339 {
177     const dlink_node *ptr = NULL;
178 michael 1447
179 michael 3339 DLINK_FOREACH(ptr, modules_get_list()->head)
180     {
181     const struct module *modp = ptr->data;
182 michael 1447
183 michael 3340 if (!EmptyString(arg) && match(arg, modp->name))
184 michael 3339 continue;
185 michael 1447
186 michael 3339 sendto_one_numeric(source_p, &me, RPL_MODLIST,
187     modp->name, modp->handle,
188     modp->version, (modp->flags & MODULE_FLAG_CORE) ? "(core)" : "");
189     }
190 michael 1447
191 michael 3339 sendto_one_numeric(source_p, &me, RPL_ENDOFMODLIST);
192     }
193 michael 1448
194 michael 3339 struct ModuleStruct
195     {
196     const char *cmd;
197 michael 3340 void (*handler)(struct Client *, const char *);
198 michael 3870 const unsigned int arg_required;
199 michael 3339 };
200 michael 1447
201 michael 3339 static const struct ModuleStruct module_cmd_table[] =
202     {
203     { "LOAD", module_load, 1 },
204     { "UNLOAD", module_unload, 1 },
205     { "RELOAD", module_reload, 1 },
206     { "LIST", module_list, 0 },
207     { NULL, NULL, 0 }
208     };
209 michael 1447
210 michael 3339 /*! \brief MODULE command handler
211     *
212     * \param source_p Pointer to allocated Client struct from which the message
213     * originally comes from. This can be a local or remote client.
214     * \param parc Integer holding the number of supplied arguments.
215     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
216     * pointers.
217     * \note Valid arguments for this command are:
218     * - parv[0] = command
219     * - parv[1] = MODULE subcommand [LOAD, UNLOAD, RELOAD, LIST]
220     * - parv[2] = module name
221     */
222     static int
223     mo_module(struct Client *source_p, int parc, char *parv[])
224     {
225     if (!HasOFlag(source_p, OPER_FLAG_MODULE))
226     {
227     sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "module");
228     return 0;
229     }
230 michael 1447
231 michael 3339 if (EmptyString(parv[1]))
232     {
233     sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "MODULE");
234 michael 2820 return 0;
235 michael 1447 }
236    
237 michael 3339 for (const struct ModuleStruct *tab = module_cmd_table; tab->handler; ++tab)
238 michael 1447 {
239 michael 3339 if (irccmp(tab->cmd, parv[1]))
240     continue;
241 michael 1447
242 michael 3339 if (tab->arg_required && EmptyString(parv[2]))
243 michael 1447 {
244 michael 3339 sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "MODULE");
245     return 0;
246 michael 1447 }
247    
248 michael 3340 tab->handler(source_p, parv[2]);
249 michael 2820 return 0;
250 michael 1447 }
251 michael 1566
252 michael 3110 sendto_one_notice(source_p, &me, ":%s is not a valid option. "
253     "Choose from LOAD, UNLOAD, RELOAD, LIST",
254     parv[1]);
255 michael 2820 return 0;
256 michael 1447 }
257    
258 michael 2820 static struct Message module_msgtab =
259     {
260 michael 4545 "MODULE", NULL, 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
261 michael 2820 { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_module, m_ignore }
262 michael 1447 };
263    
264     static void
265     module_init(void)
266     {
267     mod_add_cmd(&module_msgtab);
268     }
269    
270     static void
271     module_exit(void)
272     {
273     mod_del_cmd(&module_msgtab);
274     }
275    
276 michael 2820 struct module module_entry =
277     {
278 michael 1447 .node = { NULL, NULL, NULL },
279     .name = NULL,
280     .version = "$Revision$",
281     .handle = NULL,
282     .modinit = module_init,
283     .modexit = module_exit,
284 michael 1448 .flags = MODULE_FLAG_NOUNLOAD
285 michael 1447 };

Properties

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