ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/modules.c
Revision: 120
Committed: Thu Oct 13 09:51:10 2005 UTC (19 years, 10 months ago) by michael
Content type: text/x-csrc
File size: 17087 byte(s)
Log Message:
- More TBURST changes

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

Properties

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