ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_module.c
Revision: 8059
Committed: Thu Mar 23 16:13:39 2017 UTC (9 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 8076 byte(s)
Log Message:
- Fixed style inconsistencies in various places

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

Properties

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