ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_module.c
Revision: 3339
Committed: Fri Apr 18 11:50:41 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 7815 byte(s)
Log Message:
- Clean up m_module.c

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., 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 /*! \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 * \param parv Argument vector
45 */
46 static void
47 module_load(struct Client *source_p, char *parv[])
48 {
49 const char *m_bn = NULL;
50
51 if (findmodule_byname((m_bn = libio_basename(parv[2]))))
52 {
53 sendto_one_notice(source_p, &me, ":Module %s is already loaded", m_bn);
54 return;
55 }
56
57 load_one_module(parv[2]);
58 }
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 * \param parv Argument vector
65 */
66 static void
67 module_unload(struct Client *source_p, char *parv[])
68 {
69 const char *m_bn = NULL;
70 const struct module *modp = NULL;
71
72 if ((modp = findmodule_byname((m_bn = libio_basename(parv[2])))) == NULL)
73 {
74 sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn);
75 return;
76 }
77
78 if (modp->flags & MODULE_FLAG_CORE)
79 {
80 sendto_one_notice(source_p, &me, ":Module %s is a core module and may not be unloaded",
81 m_bn);
82 return;
83 }
84
85 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 }
91
92 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 * \param parv Argument vector
101 */
102 static void
103 module_reload(struct Client *source_p, char *parv[])
104 {
105 const char *m_bn = NULL;
106 struct module *modp = NULL;
107 int check_core = 0;
108
109 if (!strcmp(parv[2], "*"))
110 {
111 unsigned int modnum = 0;
112 dlink_node *ptr = NULL, *ptr_next = NULL;
113
114 sendto_one_notice(source_p, &me, ":Reloading all modules");
115
116 modnum = dlink_list_length(modules_get_list());
117
118 DLINK_FOREACH_SAFE(ptr, ptr_next, modules_get_list()->head)
119 {
120 modp = ptr->data;
121
122 if (!(modp->flags & MODULE_FLAG_NOUNLOAD))
123 unload_one_module(modp->name, 0);
124 }
125
126 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 }
137
138 if ((modp = findmodule_byname((m_bn = libio_basename(parv[2])))) == NULL)
139 {
140 sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn);
141 return;
142 }
143
144 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
151 check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
152
153 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
159 if ((load_one_module(parv[2]) == -1) && check_core)
160 {
161 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
162 "Error reloading core "
163 "module: %s: terminating ircd", parv[2]);
164 ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd", parv[2]);
165 exit(0);
166 }
167 }
168
169 /*! \brief LIST subcommand handler
170 * Shows a list of loaded modules
171 * \param source_p Pointer to client issuing the command
172 * \param parv Argument vector
173 */
174 static void
175 module_list(struct Client *source_p, char *parv[])
176 {
177 const dlink_node *ptr = NULL;
178
179 DLINK_FOREACH(ptr, modules_get_list()->head)
180 {
181 const struct module *modp = ptr->data;
182
183 if (!EmptyString(parv[2]) && match(parv[2], modp->name))
184 continue;
185
186 sendto_one_numeric(source_p, &me, RPL_MODLIST,
187 modp->name, modp->handle,
188 modp->version, (modp->flags & MODULE_FLAG_CORE) ? "(core)" : "");
189 }
190
191 sendto_one_numeric(source_p, &me, RPL_ENDOFMODLIST);
192 }
193
194 struct ModuleStruct
195 {
196 const char *cmd;
197 void (*handler)(struct Client *, char *[]);
198 const int arg_required;
199 };
200
201 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
210 /*! \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
231 if (EmptyString(parv[1]))
232 {
233 sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "MODULE");
234 return 0;
235 }
236
237 for (const struct ModuleStruct *tab = module_cmd_table; tab->handler; ++tab)
238 {
239 if (irccmp(tab->cmd, parv[1]))
240 continue;
241
242 if (tab->arg_required && EmptyString(parv[2]))
243 {
244 sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "MODULE");
245 return 0;
246 }
247
248 tab->handler(source_p, parv);
249 return 0;
250 }
251
252 sendto_one_notice(source_p, &me, ":%s is not a valid option. "
253 "Choose from LOAD, UNLOAD, RELOAD, LIST",
254 parv[1]);
255 return 0;
256 }
257
258 static struct Message module_msgtab =
259 {
260 "MODULE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
261 { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_module, m_ignore }
262 };
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 struct module module_entry =
277 {
278 .node = { NULL, NULL, NULL },
279 .name = NULL,
280 .version = "$Revision$",
281 .handle = NULL,
282 .modinit = module_init,
283 .modexit = module_exit,
284 .flags = MODULE_FLAG_NOUNLOAD
285 };

Properties

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