ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/modules.c
Revision: 908
Committed: Sun Nov 4 23:21:51 2007 UTC (17 years, 9 months ago) by stu
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/src/modules.c
File size: 17364 byte(s)
Log Message:
Completely redo the build system.  Now uses libtool and automake.  Suggest you clean out your tree and then do ./autogen.sh.

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 "tools.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 #include "list.h"
40
41 #define SHARED_SUFFIX "so"
42
43 /* -TimeMr14C:
44 * I have moved the dl* function definitions and
45 * the two functions (load_a_module / unload_a_module) to the
46 * file dynlink.c
47 * And also made the necessary changes to those functions
48 * to comply with shl_load and friends.
49 * In this file, to keep consistency with the makefile,
50 * I added the ability to load *.sl files, too.
51 * 27/02/2002
52 */
53
54 #ifndef STATIC_MODULES
55
56 dlink_list mod_list = { NULL, NULL, 0 };
57
58 static const char *core_module_table[] =
59 {
60 "m_die",
61 "m_join",
62 "m_kick",
63 "m_kill",
64 "m_message",
65 "m_mode",
66 "m_nick",
67 "m_part",
68 "m_quit",
69 "m_server",
70 "m_sjoin",
71 "m_squit",
72 NULL
73 };
74
75 static dlink_list mod_paths = { NULL, NULL, 0 };
76 static dlink_list conf_modules = { NULL, NULL, 0 };
77
78 static void mo_modload(struct Client *, struct Client *, int, char *[]);
79 static void mo_modlist(struct Client *, struct Client *, int, char *[]);
80 static void mo_modreload(struct Client *, struct Client *, int, char *[]);
81 static void mo_modunload(struct Client *, struct Client *, int, char *[]);
82 static void mo_modrestart(struct Client *, struct Client *, int, char *[]);
83
84 struct Message modload_msgtab = {
85 "MODLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
86 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modload, m_ignore}
87 };
88
89 struct Message modunload_msgtab = {
90 "MODUNLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
91 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modunload, m_ignore}
92 };
93
94 struct Message modreload_msgtab = {
95 "MODRELOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
96 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modreload, m_ignore}
97 };
98
99 struct Message modlist_msgtab = {
100 "MODLIST", 0, 0, 0, 0, MFLG_SLOW, 0,
101 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modlist, m_ignore}
102 };
103
104 struct Message modrestart_msgtab = {
105 "MODRESTART", 0, 0, 0, 0, MFLG_SLOW, 0,
106 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modrestart, m_ignore}
107 };
108
109
110 extern struct Message error_msgtab;
111
112 /*
113 * modules_init
114 *
115 * input - NONE
116 * output - NONE
117 * side effects - The basic module manipulation modules are loaded
118 */
119 void
120 modules_init(void)
121 {
122 mod_add_cmd(&modload_msgtab);
123 mod_add_cmd(&modunload_msgtab);
124 mod_add_cmd(&modreload_msgtab);
125 mod_add_cmd(&modlist_msgtab);
126 mod_add_cmd(&modrestart_msgtab);
127 mod_add_cmd(&error_msgtab);
128 }
129
130 /* mod_find_path()
131 *
132 * input - path
133 * output - none
134 * side effects - returns a module path from path
135 */
136 static struct module_path *
137 mod_find_path(const char *path)
138 {
139 dlink_node *ptr;
140 struct module_path *mpath;
141
142 DLINK_FOREACH(ptr, mod_paths.head)
143 {
144 mpath = ptr->data;
145
146 if (!strcmp(path, mpath->path))
147 return mpath;
148 }
149
150 return NULL;
151 }
152
153 /* mod_add_path()
154 *
155 * input - path
156 * output - NONE
157 * side effects - adds path to list
158 */
159 void
160 mod_add_path(const char *path)
161 {
162 struct module_path *pathst;
163
164 if (mod_find_path(path))
165 return;
166
167 pathst = MyMalloc(sizeof(struct module_path));
168
169 strlcpy(pathst->path, path, sizeof(pathst->path));
170 dlinkAdd(pathst, &pathst->node, &mod_paths);
171 }
172
173 /* add_conf_module
174 *
175 * input - module name
176 * output - NONE
177 * side effects - adds module to conf_mod
178 */
179 void
180 add_conf_module(const char *name)
181 {
182 struct module_path *pathst;
183
184 pathst = MyMalloc(sizeof(struct module_path));
185
186 strlcpy(pathst->path, name, sizeof(pathst->path));
187 dlinkAdd(pathst, &pathst->node, &conf_modules);
188 }
189
190 /* mod_clear_paths()
191 *
192 * input - NONE
193 * output - NONE
194 * side effects - clear the lists of paths and conf modules
195 */
196 void
197 mod_clear_paths(void)
198 {
199 struct module_path *pathst;
200 dlink_node *ptr;
201 dlink_node *next_ptr;
202
203 DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
204 {
205 pathst = ptr->data;
206
207 dlinkDelete(&pathst->node, &mod_paths);
208 MyFree(pathst);
209 }
210
211 DLINK_FOREACH_SAFE(ptr, next_ptr, conf_modules.head)
212 {
213 pathst = ptr->data;
214
215 dlinkDelete(&pathst->node, &conf_modules);
216 MyFree(pathst);
217 }
218 }
219
220 /* findmodule_byname
221 *
222 * input - name of module
223 * output - NULL if not found or pointer to module
224 * side effects - NONE
225 */
226 dlink_node *
227 findmodule_byname(const char *name)
228 {
229 dlink_node *ptr;
230 struct module *modp;
231
232 DLINK_FOREACH(ptr, mod_list.head)
233 {
234 modp = ptr->data;
235
236 if (strcmp(modp->name, name) == 0)
237 return ptr;
238 }
239
240 return NULL;
241 }
242
243 /* load_all_modules()
244 *
245 * input - int flag warn
246 * output - NONE
247 * side effects - load all modules found in autoload directory
248 */
249 void
250 load_all_modules(int warn)
251 {
252 DIR *system_module_dir = NULL;
253 struct dirent *ldirent = NULL;
254 char module_fq_name[PATH_MAX + 1];
255
256 modules_init();
257
258 if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
259 {
260 ilog(L_WARN, "Could not load modules from %s: %s",
261 AUTOMODPATH, strerror(errno));
262 return;
263 }
264
265 while ((ldirent = readdir(system_module_dir)) != NULL)
266 {
267 const char *offset = strrchr(ldirent->d_name, '.');
268
269 if (offset && !strcmp(offset, SHARED_SUFFIX))
270 {
271 snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
272 AUTOMODPATH, ldirent->d_name);
273 load_a_module(module_fq_name, warn, 0);
274 }
275 }
276
277 closedir(system_module_dir);
278 }
279
280 /* load_conf_modules()
281 *
282 * input - NONE
283 * output - NONE
284 * side effects - load modules given in ircd.conf
285 */
286 void
287 load_conf_modules(void)
288 {
289 dlink_node *ptr = NULL;
290 struct module_path *mpath = NULL;
291
292 DLINK_FOREACH(ptr, conf_modules.head)
293 {
294 mpath = ptr->data;
295
296 if (findmodule_byname(mpath->path) == NULL)
297 load_one_module(mpath->path, 0);
298 }
299 }
300
301 /* load_core_modules()
302 *
303 * input - int flag warn
304 * output - NONE
305 * side effects - core modules are loaded, if any fail, kill ircd
306 */
307 void
308 load_core_modules(int warn)
309 {
310 char module_name[PATH_MAX + 1];
311 int i = 0;
312
313 for (; core_module_table[i]; ++i)
314 {
315 snprintf(module_name, sizeof(module_name), "%s%s%s", MODPATH,
316 core_module_table[i], SHARED_SUFFIX);
317
318 if (load_a_module(module_name, warn, 1) == -1)
319 {
320 ilog(L_CRIT, "Error loading core module %s%s: terminating ircd",
321 core_module_table[i], SHARED_SUFFIX);
322 exit(EXIT_FAILURE);
323 }
324 }
325 }
326
327 /* load_one_module()
328 *
329 * input - pointer to path
330 * - flagged as core module or not
331 * output - -1 if error
332 * side effects - module is loaded if found.
333 */
334 int
335 load_one_module(char *path, int coremodule)
336 {
337 dlink_node *ptr = NULL;
338 char modpath[PATH_MAX + 1];
339 struct stat statbuf;
340
341 DLINK_FOREACH(ptr, mod_paths.head)
342 {
343 const struct module_path *mpath = ptr->data;
344
345 snprintf(modpath, sizeof(modpath), "%s/%s", mpath->path, path);
346
347 if (strstr(modpath, "../") == NULL &&
348 strstr(modpath, "/..") == NULL)
349 {
350 if (!stat(modpath, &statbuf))
351 {
352 if (S_ISREG(statbuf.st_mode))
353 {
354 /* Regular files only please */
355 return load_a_module(modpath, 1, coremodule);
356 }
357 }
358 }
359 }
360
361 sendto_realops_flags(UMODE_ALL, L_ALL,
362 "Cannot locate module %s", path);
363 ilog(L_WARN, "Cannot locate module %s", path);
364 return -1;
365 }
366
367 /* load a module .. */
368 static void
369 mo_modload(struct Client *client_p, struct Client *source_p,
370 int parc, char *parv[])
371 {
372 char *m_bn;
373
374 if (!IsAdmin(source_p))
375 {
376 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
377 me.name, source_p->name);
378 return;
379 }
380
381 m_bn = basename(parv[1]);
382
383 if (findmodule_byname(m_bn) != NULL)
384 {
385 sendto_one(source_p, ":%s NOTICE %s :Module %s is already loaded",
386 me.name, source_p->name, m_bn);
387 return;
388 }
389
390 load_one_module(parv[1], 0);
391 }
392
393 /* unload a module .. */
394 static void
395 mo_modunload(struct Client *client_p, struct Client *source_p,
396 int parc, char *parv[])
397 {
398 char *m_bn;
399 dlink_node *ptr;
400 struct module *modp;
401
402 if (!IsAdmin(source_p))
403 {
404 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
405 me.name, source_p->name);
406 return;
407 }
408
409 m_bn = basename(parv[1]);
410
411 if ((ptr = findmodule_byname(m_bn)) == NULL)
412 {
413 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
414 me.name, source_p->name, m_bn);
415 return;
416 }
417
418 modp = ptr->data;
419
420 if (modp->core == 1)
421 {
422 sendto_one(source_p,
423 ":%s NOTICE %s :Module %s is a core module and may not be unloaded",
424 me.name, source_p->name, m_bn);
425 return;
426 }
427
428 /* XXX might want to simply un dlink it here */
429
430 if (unload_one_module(m_bn, 1) == -1)
431 {
432 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
433 me.name, source_p->name, m_bn);
434 }
435 }
436
437 /* unload and load in one! */
438 static void
439 mo_modreload(struct Client *client_p, struct Client *source_p,
440 int parc, char *parv[])
441 {
442 char *m_bn;
443 dlink_node *ptr;
444 struct module *modp;
445 int check_core;
446
447 if (!IsAdmin(source_p))
448 {
449 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
450 me.name, source_p->name);
451 return;
452 }
453
454 m_bn = basename(parv[1]);
455
456 if ((ptr = findmodule_byname(m_bn)) == NULL)
457 {
458 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
459 me.name, source_p->name, m_bn);
460 return;
461 }
462
463 modp = ptr->data;
464 check_core = modp->core;
465
466 if (unload_one_module(m_bn, 1) == -1)
467 {
468 sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
469 me.name, source_p->name, m_bn);
470 return;
471 }
472
473 if ((load_one_module(parv[1], check_core) == -1) && check_core)
474 {
475 sendto_realops_flags(UMODE_ALL, L_ALL, "Error reloading core "
476 "module: %s: terminating ircd", parv[1]);
477 ilog(L_CRIT, "Error loading core module %s: terminating ircd", parv[1]);
478 exit(0);
479 }
480 }
481
482 /* list modules .. */
483 static void
484 mo_modlist(struct Client *client_p, struct Client *source_p,
485 int parc, char *parv[])
486 {
487 dlink_node *ptr;
488 struct module *modp;
489
490 if (!IsAdmin(source_p))
491 {
492 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
493 me.name, source_p->name);
494 return;
495 }
496
497 DLINK_FOREACH(ptr, mod_list.head)
498 {
499 modp = ptr->data;
500
501 if (parc > 1)
502 {
503 if (match(parv[1], modp->name))
504 {
505 sendto_one(source_p, form_str(RPL_MODLIST), me.name, parv[0],
506 modp->name, modp->address,
507 modp->version, modp->core?"(core)":"");
508 }
509 }
510 else
511 {
512 sendto_one(source_p, form_str(RPL_MODLIST), me.name, parv[0],
513 modp->name, modp->address,
514 modp->version, modp->core?"(core)":"");
515 }
516 }
517
518 sendto_one(source_p, form_str(RPL_ENDOFMODLIST),
519 me.name, source_p->name);
520 }
521
522 /* unload and reload all modules */
523 static void
524 mo_modrestart(struct Client *client_p, struct Client *source_p,
525 int parc, char *parv[])
526 {
527 unsigned int modnum = 0;
528 dlink_node *ptr;
529 dlink_node *tptr;
530 struct module *modp;
531
532 if (!IsAdmin(source_p))
533 {
534 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
535 me.name, source_p->name);
536 return;
537 }
538
539 sendto_one(source_p, ":%s NOTICE %s :Reloading all modules",
540 me.name, source_p->name);
541
542 modnum = dlink_list_length(&mod_list);
543
544 DLINK_FOREACH_SAFE(ptr, tptr, mod_list.head)
545 {
546 modp = ptr->data;
547 unload_one_module(modp->name, 0);
548 }
549
550 load_all_modules(0);
551 load_conf_modules();
552 load_core_modules(0);
553
554 sendto_realops_flags(UMODE_ALL, L_ALL,
555 "Module Restart: %u modules unloaded, %lu modules loaded",
556 modnum, dlink_list_length(&mod_list));
557 ilog(L_WARN, "Module Restart: %u modules unloaded, %lu modules loaded",
558 modnum, dlink_list_length(&mod_list));
559 }
560
561 #else /* STATIC_MODULES */
562 #include "s_serv.h"
563
564 /* load_all_modules()
565 *
566 * input - warn flag
567 * output - NONE
568 * side effects - all the msgtabs are added for static modules
569 */
570 void
571 load_all_modules(int warn)
572 {
573 mod_add_cmd(&error_msgtab);
574 mod_add_cmd(&accept_msgtab);
575 mod_add_cmd(&admin_msgtab);
576 mod_add_cmd(&away_msgtab);
577 mod_add_cmd(&bmask_msgtab);
578 mod_add_cmd(&cap_msgtab);
579 mod_add_cmd(&capab_msgtab);
580 mod_add_cmd(&cburst_msgtab);
581 mod_add_cmd(&close_msgtab);
582 mod_add_cmd(&connect_msgtab);
583 #ifdef HAVE_LIBCRYPTO
584 mod_add_cmd(&challenge_msgtab);
585 mod_add_cmd(&cryptlink_msgtab);
586 #endif
587 mod_add_cmd(&die_msgtab);
588 mod_add_cmd(&drop_msgtab);
589 mod_add_cmd(&eob_msgtab);
590 mod_add_cmd(&etrace_msgtab);
591 mod_add_cmd(&gline_msgtab);
592 add_capability("GLN", CAP_GLN, 1);
593 mod_add_cmd(&hash_msgtab);
594 mod_add_cmd(&ungline_msgtab);
595 mod_add_cmd(&info_msgtab);
596 mod_add_cmd(&invite_msgtab);
597 mod_add_cmd(&ison_msgtab);
598 mod_add_cmd(&join_msgtab);
599 mod_add_cmd(&kick_msgtab);
600 mod_add_cmd(&kill_msgtab);
601 mod_add_cmd(&kline_msgtab);
602 add_capability("KLN", CAP_KLN, 1);
603 mod_add_cmd(&dline_msgtab);
604 mod_add_cmd(&unkline_msgtab);
605 mod_add_cmd(&undline_msgtab);
606 mod_add_cmd(&knock_msgtab);
607 add_capability("KNOCK", CAP_KNOCK, 1);
608 mod_add_cmd(&knockll_msgtab);
609 mod_add_cmd(&links_msgtab);
610 mod_add_cmd(&list_msgtab);
611 mod_add_cmd(&lljoin_msgtab);
612 mod_add_cmd(&llnick_msgtab);
613 mod_add_cmd(&locops_msgtab);
614 mod_add_cmd(&lusers_msgtab);
615 mod_add_cmd(&privmsg_msgtab);
616 mod_add_cmd(&notice_msgtab);
617 mod_add_cmd(&map_msgtab);
618 mod_add_cmd(&mode_msgtab);
619 mod_add_cmd(&motd_msgtab);
620 mod_add_cmd(&names_msgtab);
621 mod_add_cmd(&nburst_msgtab);
622 mod_add_cmd(&nick_msgtab);
623 mod_add_cmd(&omotd_msgtab);
624 mod_add_cmd(&oper_msgtab);
625 mod_add_cmd(&operwall_msgtab);
626 mod_add_cmd(&part_msgtab);
627 mod_add_cmd(&pass_msgtab);
628 mod_add_cmd(&ping_msgtab);
629 mod_add_cmd(&pong_msgtab);
630 mod_add_cmd(&post_msgtab);
631 mod_add_cmd(&get_msgtab);
632 mod_add_cmd(&put_msgtab);
633 mod_add_cmd(&quit_msgtab);
634 mod_add_cmd(&rehash_msgtab);
635 mod_add_cmd(&restart_msgtab);
636 mod_add_cmd(&resv_msgtab);
637 mod_add_cmd(&rkline_msgtab);
638 mod_add_cmd(&rxline_msgtab);
639 mod_add_cmd(&server_msgtab);
640 mod_add_cmd(&set_msgtab);
641 mod_add_cmd(&sid_msgtab);
642 mod_add_cmd(&sjoin_msgtab);
643 mod_add_cmd(&squit_msgtab);
644 mod_add_cmd(&stats_msgtab);
645 mod_add_cmd(&svinfo_msgtab);
646 mod_add_cmd(&tb_msgtab);
647 add_capability("TB", CAP_TB, 1);
648 mod_add_cmd(&tburst_msgtab);
649 add_capability("TBURST", CAP_TBURST, 1);
650 mod_add_cmd(&testline_msgtab);
651 mod_add_cmd(&testgecos_msgtab);
652 mod_add_cmd(&testmask_msgtab);
653 mod_add_cmd(&time_msgtab);
654 mod_add_cmd(&tmode_msgtab);
655 mod_add_cmd(&topic_msgtab);
656 mod_add_cmd(&trace_msgtab);
657 add_capability("UNKLN", CAP_UNKLN, 1);
658 mod_add_cmd(&uid_msgtab);
659 mod_add_cmd(&unresv_msgtab);
660 mod_add_cmd(&unxline_msgtab);
661 mod_add_cmd(&user_msgtab);
662 mod_add_cmd(&userhost_msgtab);
663 mod_add_cmd(&users_msgtab);
664 mod_add_cmd(&version_msgtab);
665 mod_add_cmd(&wallops_msgtab);
666 mod_add_cmd(&watch_msgtab);
667 mod_add_cmd(&who_msgtab);
668 mod_add_cmd(&whois_msgtab);
669 mod_add_cmd(&whowas_msgtab);
670 mod_add_cmd(&xline_msgtab);
671 mod_add_cmd(&help_msgtab);
672 mod_add_cmd(&uhelp_msgtab);
673 #ifdef BUILD_CONTRIB
674 mod_add_cmd(&bs_msgtab);
675 mod_add_cmd(&botserv_msgtab);
676 mod_add_cmd(&capture_msgtab);
677 mod_add_cmd(&chanserv_msgtab);
678 mod_add_cmd(&chghost_msgtab);
679 mod_add_cmd(&chgident_msgtab);
680 mod_add_cmd(&chgname_msgtab);
681 mod_add_cmd(&classlist_msgtab);
682 mod_add_cmd(&clearchan_msgtab);
683 mod_add_cmd(&cs_msgtab);
684 mod_add_cmd(&ctrace_msgtab);
685 mod_add_cmd(&delspoof_msgtab);
686 mod_add_cmd(&flags_msgtab);
687 mod_add_cmd(&forcejoin_msgtab);
688 mod_add_cmd(&forcepart_msgtab);
689 mod_add_cmd(&global_msgtab);
690 mod_add_cmd(&help_msgtab);
691 mod_add_cmd(&uhelp_msgtab);
692 mod_add_cmd(&helpserv_msgtab);
693 mod_add_cmd(&hostserv_msgtab);
694 mod_add_cmd(&identify_msgtab);
695 mod_add_cmd(&jupe_msgtab);
696 mod_add_cmd(&killhost_msgtab);
697 mod_add_cmd(&ltrace_msgtab);
698 mod_add_cmd(&memoserv_msgtab);
699 mod_add_cmd(&mkpasswd_msgtab);
700 mod_add_cmd(&ms_msgtab);
701 mod_add_cmd(&nickserv_msgtab);
702 mod_add_cmd(&ns_msgtab);
703 mod_add_cmd(&ojoin_msgtab);
704 mod_add_cmd(&operserv_msgtab);
705 mod_add_cmd(&operspy_msgtab);
706 mod_add_cmd(&opme_msgtab);
707 mod_add_cmd(&os_msgtab);
708 mod_add_cmd(&seenserv_msgtab);
709 mod_add_cmd(&spoof_msgtab);
710 mod_add_cmd(&statserv_msgtab);
711 mod_add_cmd(&svsnick_msgtab);
712 mod_add_cmd(&uncapture_msgtab);
713 /* FIXME: what about spy*? */
714 #endif
715 }
716 #endif /* STATIC_MODULES */

Properties

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