ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_module.c
Revision: 5014
Committed: Tue Dec 9 17:51:47 2014 UTC (10 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 8042 byte(s)
Log Message:
- Removed unused header includes:wq

File Contents

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

Properties

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