ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/modules.c
Revision: 217
Committed: Thu Nov 3 13:59:27 2005 UTC (20 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 17352 byte(s)
Log Message:
- Fixed compile error in m_invite.c and s_serv.c
- Added m_watch.c

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

Properties

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