ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/modules.c
Revision: 3031
Committed: Tue Feb 25 11:50:53 2014 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 9117 byte(s)
Log Message:
- modules.c:load_one_module(): renamed variables to make less confusing

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 modules.c
23 * \brief A module loader.
24 * \version $Id$
25 */
26
27 #include "ltdl.h"
28
29 #include "stdinc.h"
30 #include "list.h"
31 #include "modules.h"
32 #include "log.h"
33 #include "ircd.h"
34 #include "client.h"
35 #include "send.h"
36 #include "conf.h"
37 #include "numeric.h"
38 #include "parse.h"
39 #include "ircd_defs.h"
40 #include "irc_string.h"
41 #include "memory.h"
42
43
44 static dlink_list modules_list;
45 static dlink_list modules_path;
46 static dlink_list modules_conf;
47
48 static const char *unknown_ver = "<unknown>";
49 static const char *core_module_table[] =
50 {
51 "m_die.la",
52 "m_error.la",
53 "m_join.la",
54 "m_kick.la",
55 "m_kill.la",
56 "m_message.la",
57 "m_mode.la",
58 "m_nick.la",
59 "m_part.la",
60 "m_quit.la",
61 "m_server.la",
62 "m_sjoin.la",
63 "m_squit.la",
64 NULL
65 };
66
67
68 dlink_list *
69 modules_get_list(void)
70 {
71 return &modules_list;
72 }
73
74 int
75 modules_valid_suffix(const char *name)
76 {
77 return ((name = strrchr(name, '.'))) && !strcmp(name, ".la");
78 }
79
80 /* unload_one_module()
81 *
82 * inputs - name of module to unload
83 * - 1 to say modules unloaded, 0 to not
84 * output - 0 if successful, -1 if error
85 * side effects - module is unloaded
86 */
87 int
88 unload_one_module(const char *name, int warn)
89 {
90 struct module *modp = NULL;
91
92 if ((modp = findmodule_byname(name)) == NULL)
93 return -1;
94
95 if (modp->modexit)
96 modp->modexit();
97
98 assert(dlink_list_length(&modules_list) > 0);
99 dlinkDelete(&modp->node, &modules_list);
100 MyFree(modp->name);
101
102 lt_dlclose(modp->handle);
103
104 if (warn == 1)
105 {
106 ilog(LOG_TYPE_IRCD, "Module %s unloaded", name);
107 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
108 "Module %s unloaded", name);
109 }
110
111 return 0;
112 }
113
114 /* load_a_module()
115 *
116 * inputs - path name of module, int to notice, int of core
117 * output - -1 if error 0 if success
118 * side effects - loads a module if successful
119 */
120 int
121 load_a_module(const char *path, int warn)
122 {
123 lt_dlhandle tmpptr = NULL;
124 const char *mod_basename = NULL;
125 struct module *modp = NULL;
126
127 if (findmodule_byname((mod_basename = libio_basename(path))))
128 return 1;
129
130 if (!(tmpptr = lt_dlopen(path)))
131 {
132 const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
133
134 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
135 "Error loading module %s: %s",
136 mod_basename, err);
137 ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
138 return -1;
139 }
140
141 if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL)
142 {
143 const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
144
145 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
146 "Error loading module %s: %s",
147 mod_basename, err);
148 ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
149 lt_dlclose(tmpptr);
150 return -1;
151 }
152
153 modp->handle = tmpptr;
154
155 if (EmptyString(modp->version))
156 modp->version = unknown_ver;
157
158 modp->name = xstrdup(mod_basename);
159 dlinkAdd(modp, &modp->node, &modules_list);
160
161 if (modp->modinit)
162 modp->modinit();
163
164 if (warn == 1)
165 {
166 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
167 "Module %s [version: %s handle: %p] loaded.",
168 modp->name, modp->version, tmpptr);
169 ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.",
170 modp->name, modp->version, tmpptr);
171 }
172
173 return 0;
174 }
175
176 /*
177 * modules_init
178 *
179 * input - NONE
180 * output - NONE
181 * side effects - The basic module manipulation modules are loaded
182 */
183 void
184 modules_init(void)
185 {
186 if (lt_dlinit())
187 {
188 ilog(LOG_TYPE_IRCD, "Couldn't initialize the libltdl run time dynamic"
189 " link library. Exiting.");
190 exit(0);
191 }
192 }
193
194 /* mod_find_path()
195 *
196 * input - path
197 * output - none
198 * side effects - returns a module path from path
199 */
200 static struct module_path *
201 mod_find_path(const char *path)
202 {
203 dlink_node *ptr = NULL;
204
205 DLINK_FOREACH(ptr, modules_path.head)
206 {
207 struct module_path *mpath = ptr->data;
208
209 if (!strcmp(path, mpath->path))
210 return mpath;
211 }
212
213 return NULL;
214 }
215
216 /* mod_add_path()
217 *
218 * input - path
219 * output - NONE
220 * side effects - adds path to list
221 */
222 void
223 mod_add_path(const char *path)
224 {
225 struct module_path *pathst;
226
227 if (mod_find_path(path))
228 return;
229
230 pathst = MyMalloc(sizeof(struct module_path));
231
232 strlcpy(pathst->path, path, sizeof(pathst->path));
233 dlinkAdd(pathst, &pathst->node, &modules_path);
234 }
235
236 /* add_conf_module
237 *
238 * input - module name
239 * output - NONE
240 * side effects - adds module to conf_mod
241 */
242 void
243 add_conf_module(const char *name)
244 {
245 struct module_path *pathst;
246
247 pathst = MyMalloc(sizeof(struct module_path));
248
249 strlcpy(pathst->path, name, sizeof(pathst->path));
250 dlinkAdd(pathst, &pathst->node, &modules_conf);
251 }
252
253 /* mod_clear_paths()
254 *
255 * input - NONE
256 * output - NONE
257 * side effects - clear the lists of paths and conf modules
258 */
259 void
260 mod_clear_paths(void)
261 {
262 dlink_node *ptr = NULL, *next_ptr = NULL;
263
264 DLINK_FOREACH_SAFE(ptr, next_ptr, modules_path.head)
265 {
266 dlinkDelete(ptr, &modules_path);
267 MyFree(ptr->data);
268 }
269
270 DLINK_FOREACH_SAFE(ptr, next_ptr, modules_conf.head)
271 {
272 dlinkDelete(ptr, &modules_conf);
273 MyFree(ptr->data);
274 }
275 }
276
277 /* findmodule_byname
278 *
279 * input - name of module
280 * output - NULL if not found or pointer to module
281 * side effects - NONE
282 */
283 struct module *
284 findmodule_byname(const char *name)
285 {
286 dlink_node *ptr = NULL;
287
288 DLINK_FOREACH(ptr, modules_list.head)
289 {
290 struct module *modp = ptr->data;
291
292 if (strcmp(modp->name, name) == 0)
293 return modp;
294 }
295
296 return NULL;
297 }
298
299 /* load_all_modules()
300 *
301 * input - int flag warn
302 * output - NONE
303 * side effects - load all modules found in autoload directory
304 */
305 void
306 load_all_modules(int warn)
307 {
308 DIR *system_module_dir = NULL;
309 struct dirent *ldirent = NULL;
310 char module_fq_name[HYB_PATH_MAX + 1];
311
312 if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
313 {
314 ilog(LOG_TYPE_IRCD, "Could not load modules from %s: %s",
315 AUTOMODPATH, strerror(errno));
316 return;
317 }
318
319 while ((ldirent = readdir(system_module_dir)) != NULL)
320 {
321 if (modules_valid_suffix(ldirent->d_name))
322 {
323 snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
324 AUTOMODPATH, ldirent->d_name);
325 load_a_module(module_fq_name, warn);
326 }
327 }
328
329 closedir(system_module_dir);
330 }
331
332 /* load_conf_modules()
333 *
334 * input - NONE
335 * output - NONE
336 * side effects - load modules given in ircd.conf
337 */
338 void
339 load_conf_modules(void)
340 {
341 dlink_node *ptr = NULL;
342
343 DLINK_FOREACH(ptr, modules_conf.head)
344 {
345 struct module_path *mpath = ptr->data;
346
347 if (findmodule_byname(mpath->path) == NULL)
348 load_one_module(mpath->path);
349 }
350 }
351
352 /* load_core_modules()
353 *
354 * input - int flag warn
355 * output - NONE
356 * side effects - core modules are loaded, if any fail, kill ircd
357 */
358 void
359 load_core_modules(int warn)
360 {
361 char module_name[HYB_PATH_MAX + 1];
362 int i = 0;
363
364 for (; core_module_table[i]; ++i)
365 {
366 snprintf(module_name, sizeof(module_name), "%s%s",
367 MODPATH, core_module_table[i]);
368
369 if (load_a_module(module_name, warn) == -1)
370 {
371 ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd",
372 core_module_table[i]);
373 exit(EXIT_FAILURE);
374 }
375 }
376 }
377
378 /* load_one_module()
379 *
380 * input - pointer to path
381 * - flagged as core module or not
382 * output - -1 if error
383 * side effects - module is loaded if found.
384 */
385 int
386 load_one_module(const char *name)
387 {
388 dlink_node *ptr = NULL;
389 char path[HYB_PATH_MAX + 1];
390 struct stat statbuf;
391
392 DLINK_FOREACH(ptr, modules_path.head)
393 {
394 const struct module_path *mpath = ptr->data;
395
396 snprintf(path, sizeof(path), "%s/%s", mpath->path, name);
397
398 if (!modules_valid_suffix(name))
399 continue;
400
401 if (strstr(path, "../") == NULL &&
402 strstr(path, "/..") == NULL)
403 if (!stat(path, &statbuf))
404 if (S_ISREG(statbuf.st_mode)) /* Regular files only please */
405 return load_a_module(path, 1);
406 }
407
408 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
409 "Cannot locate module %s", name);
410 ilog(LOG_TYPE_IRCD, "Cannot locate module %s", name);
411 return -1;
412 }

Properties

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