ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/releases/8.1.0beta2/src/modules.c
Revision: 1234
Committed: Fri Sep 23 08:15:04 2011 UTC (14 years, 10 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/src/modules.c
File size: 12216 byte(s)
Log Message:
- replace all instances of parv[0] with source_p->name

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * modules.c: A module loader.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "list.h"
27 #include "modules.h"
28 #include "s_log.h"
29 #include "ircd.h"
30 #include "client.h"
31 #include "send.h"
32 #include "s_conf.h"
33 #include "handlers.h"
34 #include "numeric.h"
35 #include "parse.h"
36 #include "ircd_defs.h"
37 #include "irc_string.h"
38 #include "memory.h"
39
40
41 dlink_list mod_list = { NULL, NULL, 0 };
42
43 static const char *core_module_table[] =
44 {
45 "m_die.la",
46 "m_error.la",
47 "m_join.la",
48 "m_kick.la",
49 "m_kill.la",
50 "m_message.la",
51 "m_mode.la",
52 "m_nick.la",
53 "m_part.la",
54 "m_quit.la",
55 "m_server.la",
56 "m_sjoin.la",
57 "m_squit.la",
58 NULL
59 };
60
61 static dlink_list mod_paths = { NULL, NULL, 0 };
62 static dlink_list conf_modules = { NULL, NULL, 0 };
63
64 static void mo_modload(struct Client *, struct Client *, int, char *[]);
65 static void mo_modlist(struct Client *, struct Client *, int, char *[]);
66 static void mo_modreload(struct Client *, struct Client *, int, char *[]);
67 static void mo_modunload(struct Client *, struct Client *, int, char *[]);
68 static void mo_modrestart(struct Client *, struct Client *, int, char *[]);
69
70 struct Message modload_msgtab = {
71 "MODLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
72 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modload, m_ignore}
73 };
74
75 struct Message modunload_msgtab = {
76 "MODUNLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
77 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modunload, m_ignore}
78 };
79
80 struct Message modreload_msgtab = {
81 "MODRELOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
82 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modreload, m_ignore}
83 };
84
85 struct Message modlist_msgtab = {
86 "MODLIST", 0, 0, 0, 0, MFLG_SLOW, 0,
87 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modlist, m_ignore}
88 };
89
90 struct Message modrestart_msgtab = {
91 "MODRESTART", 0, 0, 0, 0, MFLG_SLOW, 0,
92 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modrestart, m_ignore}
93 };
94
95
96 /*
97 * modules_init
98 *
99 * input - NONE
100 * output - NONE
101 * side effects - The basic module manipulation modules are loaded
102 */
103 void
104 modules_init(void)
105 {
106 dynlink_init();
107
108 mod_add_cmd(&modload_msgtab);
109 mod_add_cmd(&modunload_msgtab);
110 mod_add_cmd(&modreload_msgtab);
111 mod_add_cmd(&modlist_msgtab);
112 mod_add_cmd(&modrestart_msgtab);
113 }
114
115 /* mod_find_path()
116 *
117 * input - path
118 * output - none
119 * side effects - returns a module path from path
120 */
121 static struct module_path *
122 mod_find_path(const char *path)
123 {
124 dlink_node *ptr;
125 struct module_path *mpath;
126
127 DLINK_FOREACH(ptr, mod_paths.head)
128 {
129 mpath = ptr->data;
130
131 if (!strcmp(path, mpath->path))
132 return mpath;
133 }
134
135 return NULL;
136 }
137
138 /* mod_add_path()
139 *
140 * input - path
141 * output - NONE
142 * side effects - adds path to list
143 */
144 void
145 mod_add_path(const char *path)
146 {
147 struct module_path *pathst;
148
149 if (mod_find_path(path))
150 return;
151
152 pathst = MyMalloc(sizeof(struct module_path));
153
154 strlcpy(pathst->path, path, sizeof(pathst->path));
155 dlinkAdd(pathst, &pathst->node, &mod_paths);
156 }
157
158 /* add_conf_module
159 *
160 * input - module name
161 * output - NONE
162 * side effects - adds module to conf_mod
163 */
164 void
165 add_conf_module(const char *name)
166 {
167 struct module_path *pathst;
168
169 pathst = MyMalloc(sizeof(struct module_path));
170
171 strlcpy(pathst->path, name, sizeof(pathst->path));
172 dlinkAdd(pathst, &pathst->node, &conf_modules);
173 }
174
175 /* mod_clear_paths()
176 *
177 * input - NONE
178 * output - NONE
179 * side effects - clear the lists of paths and conf modules
180 */
181 void
182 mod_clear_paths(void)
183 {
184 struct module_path *pathst;
185 dlink_node *ptr;
186 dlink_node *next_ptr;
187
188 DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
189 {
190 pathst = ptr->data;
191
192 dlinkDelete(&pathst->node, &mod_paths);
193 MyFree(pathst);
194 }
195
196 DLINK_FOREACH_SAFE(ptr, next_ptr, conf_modules.head)
197 {
198 pathst = ptr->data;
199
200 dlinkDelete(&pathst->node, &conf_modules);
201 MyFree(pathst);
202 }
203 }
204
205 /* findmodule_byname
206 *
207 * input - name of module
208 * output - NULL if not found or pointer to module
209 * side effects - NONE
210 */
211 struct module *
212 findmodule_byname(const char *name)
213 {
214 dlink_node *ptr = NULL;
215
216 DLINK_FOREACH(ptr, mod_list.head)
217 {
218 struct module *modp = ptr->data;
219
220 if (strcmp(modp->name, name) == 0)
221 return modp;
222 }
223
224 return NULL;
225 }
226
227 /* load_all_modules()
228 *
229 * input - int flag warn
230 * output - NONE
231 * side effects - load all modules found in autoload directory
232 */
233 void
234 load_all_modules(int warn)
235 {
236 DIR *system_module_dir = NULL;
237 struct dirent *ldirent = NULL;
238 char module_fq_name[PATH_MAX + 1];
239
240 modules_init();
241
242 if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
243 {
244 ilog(L_WARN, "Could not load modules from %s: %s",
245 AUTOMODPATH, strerror(errno));
246 return;
247 }
248
249 while ((ldirent = readdir(system_module_dir)) != NULL)
250 {
251 if (modules_valid_suffix(ldirent->d_name))
252 {
253 snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
254 AUTOMODPATH, ldirent->d_name);
255 load_a_module(module_fq_name, warn, 0);
256 }
257 }
258
259 closedir(system_module_dir);
260 }
261
262 /* load_conf_modules()
263 *
264 * input - NONE
265 * output - NONE
266 * side effects - load modules given in ircd.conf
267 */
268 void
269 load_conf_modules(void)
270 {
271 dlink_node *ptr = NULL;
272 struct module_path *mpath = NULL;
273
274 DLINK_FOREACH(ptr, conf_modules.head)
275 {
276 mpath = ptr->data;
277
278 if (findmodule_byname(mpath->path) == NULL)
279 load_one_module(mpath->path, 0);
280 }
281 }
282
283 /* load_core_modules()
284 *
285 * input - int flag warn
286 * output - NONE
287 * side effects - core modules are loaded, if any fail, kill ircd
288 */
289 void
290 load_core_modules(int warn)
291 {
292 char module_name[PATH_MAX + 1];
293 int i = 0;
294
295 for (; core_module_table[i]; ++i)
296 {
297 snprintf(module_name, sizeof(module_name), "%s%s",
298 MODPATH, core_module_table[i]);
299
300 if (load_a_module(module_name, warn, 1) == -1)
301 {
302 ilog(L_CRIT, "Error loading core module %s: terminating ircd",
303 core_module_table[i]);
304 exit(EXIT_FAILURE);
305 }
306 }
307 }
308
309 /* load_one_module()
310 *
311 * input - pointer to path
312 * - flagged as core module or not
313 * output - -1 if error
314 * side effects - module is loaded if found.
315 */
316 int
317 load_one_module(const char *path, int coremodule)
318 {
319 dlink_node *ptr = NULL;
320 char modpath[PATH_MAX + 1];
321 struct stat statbuf;
322
323 DLINK_FOREACH(ptr, mod_paths.head)
324 {
325 const struct module_path *mpath = ptr->data;
326
327 snprintf(modpath, sizeof(modpath), "%s/%s", mpath->path, path);
328
329 if (!modules_valid_suffix(path))
330 continue;
331
332 if (strstr(modpath, "../") == NULL &&
333 strstr(modpath, "/..") == NULL)
334 {
335 if (!stat(modpath, &statbuf))
336 {
337 if (S_ISREG(statbuf.st_mode))
338 {
339 /* Regular files only please */
340 return load_a_module(modpath, 1, coremodule);
341 }
342 }
343 }
344 }
345
346 sendto_realops_flags(UMODE_ALL, L_ALL,
347 "Cannot locate module %s", path);
348 ilog(L_WARN, "Cannot locate module %s", path);
349 return -1;
350 }
351
352 /* load a module .. */
353 static void
354 mo_modload(struct Client *client_p, struct Client *source_p,
355 int parc, char *parv[])
356 {
357 const char *m_bn = NULL;
358
359 if (!HasOFlag(source_p, OPER_FLAG_MODULE))
360 {
361 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
362 me.name, source_p->name);
363 return;
364 }
365
366 m_bn = libio_basename(parv[1]);
367
368 if (findmodule_byname(m_bn) != NULL)
369 {
370 sendto_one(source_p, ":%s NOTICE %s :Module %s is already loaded",
371 me.name, source_p->name, m_bn);
372 return;
373 }
374
375 load_one_module(parv[1], 0);
376 }
377
378 /* unload a module .. */
379 static void
380 mo_modunload(struct Client *client_p, struct Client *source_p,
381 int parc, char *parv[])
382 {
383 const char *m_bn = NULL;
384 struct module *modp = NULL;
385
386 if (!HasOFlag(source_p, OPER_FLAG_MODULE))
387 {
388 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
389 me.name, source_p->name);
390 return;
391 }
392
393 m_bn = libio_basename(parv[1]);
394
395 if ((modp = findmodule_byname(m_bn)) == NULL)
396 {
397 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
398 me.name, source_p->name, m_bn);
399 return;
400 }
401
402 if (modp->flags & MODULE_FLAG_CORE)
403 {
404 sendto_one(source_p,
405 ":%s NOTICE %s :Module %s is a core module and may not be unloaded",
406 me.name, source_p->name, m_bn);
407 return;
408 }
409
410 if (unload_one_module(m_bn, 1) == -1)
411 {
412 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
413 me.name, source_p->name, m_bn);
414 }
415 }
416
417 /* unload and load in one! */
418 static void
419 mo_modreload(struct Client *client_p, struct Client *source_p,
420 int parc, char *parv[])
421 {
422 const char *m_bn = NULL;
423 struct module *modp = NULL;
424 int check_core;
425
426 if (!HasOFlag(source_p, OPER_FLAG_MODULE))
427 {
428 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
429 me.name, source_p->name);
430 return;
431 }
432
433 m_bn = libio_basename(parv[1]);
434
435 if ((modp = findmodule_byname(m_bn)) == NULL)
436 {
437 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
438 me.name, source_p->name, m_bn);
439 return;
440 }
441
442 check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
443
444 if (unload_one_module(m_bn, 1) == -1)
445 {
446 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
447 me.name, source_p->name, m_bn);
448 return;
449 }
450
451 if ((load_one_module(parv[1], check_core) == -1) && check_core)
452 {
453 sendto_realops_flags(UMODE_ALL, L_ALL, "Error reloading core "
454 "module: %s: terminating ircd", parv[1]);
455 ilog(L_CRIT, "Error loading core module %s: terminating ircd", parv[1]);
456 exit(0);
457 }
458 }
459
460 /* list modules .. */
461 static void
462 mo_modlist(struct Client *client_p, struct Client *source_p,
463 int parc, char *parv[])
464 {
465 const dlink_node *ptr = NULL;
466
467 if (!HasOFlag(source_p, OPER_FLAG_MODULE))
468 {
469 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
470 me.name, source_p->name);
471 return;
472 }
473
474 DLINK_FOREACH(ptr, mod_list.head)
475 {
476 const struct module *modp = ptr->data;
477
478 if (parc > 1 && !match(parv[1], modp->name))
479 continue;
480
481 sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name,
482 modp->name, modp->handle,
483 modp->version, (modp->flags & MODULE_FLAG_CORE) ?"(core)":"");
484 }
485
486 sendto_one(source_p, form_str(RPL_ENDOFMODLIST),
487 me.name, source_p->name);
488 }
489
490 /* unload and reload all modules */
491 static void
492 mo_modrestart(struct Client *client_p, struct Client *source_p,
493 int parc, char *parv[])
494 {
495 unsigned int modnum = 0;
496 dlink_node *ptr = NULL, *ptr_next = NULL;
497
498 if (!HasOFlag(source_p, OPER_FLAG_MODULE))
499 {
500 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
501 me.name, source_p->name);
502 return;
503 }
504
505 sendto_one(source_p, ":%s NOTICE %s :Reloading all modules",
506 me.name, source_p->name);
507
508 modnum = dlink_list_length(&mod_list);
509
510 DLINK_FOREACH_SAFE(ptr, ptr_next, mod_list.head)
511 {
512 struct module *modp = ptr->data;
513 unload_one_module(modp->name, 0);
514 }
515
516 load_all_modules(0);
517 load_conf_modules();
518 load_core_modules(0);
519
520 sendto_realops_flags(UMODE_ALL, L_ALL,
521 "Module Restart: %u modules unloaded, %u modules loaded",
522 modnum, dlink_list_length(&mod_list));
523 ilog(L_WARN, "Module Restart: %u modules unloaded, %u modules loaded",
524 modnum, dlink_list_length(&mod_list));
525 }

Properties

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