ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/src/modules.c
Revision: 329
Committed: Sun Dec 25 10:45:42 2005 UTC (18 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 17191 byte(s)
Log Message:
- Finish off TBURST (untested)

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

Properties

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