2 * ircd-ratbox: A slightly useful ircd.
3 * modules.c: A module loader.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 * $Id: modules.c 3161 2007-01-25 07:23:01Z nenolod $
36 #include "s_newconf.h"
39 #include "ircd_defs.h"
46 * I have moved the dl* function definitions and
47 * the two functions (load_a_module / unload_a_module) to the
49 * And also made the necessary changes to those functions
50 * to comply with shl_load and friends.
51 * In this file, to keep consistency with the makefile,
52 * I added the ability to load *.sl files, too.
56 #ifndef STATIC_MODULES
58 struct module **modlist
= NULL
;
60 static const char *core_module_table
[] = {
78 #define MODS_INCREMENT 10
80 int max_mods
= MODS_INCREMENT
;
82 static rb_dlink_list mod_paths
;
84 static int mo_modload(struct Client
*, struct Client
*, int, const char **);
85 static int mo_modlist(struct Client
*, struct Client
*, int, const char **);
86 static int mo_modreload(struct Client
*, struct Client
*, int, const char **);
87 static int mo_modunload(struct Client
*, struct Client
*, int, const char **);
88 static int mo_modrestart(struct Client
*, struct Client
*, int, const char **);
90 static int me_modload(struct Client
*, struct Client
*, int, const char **);
91 static int me_modlist(struct Client
*, struct Client
*, int, const char **);
92 static int me_modreload(struct Client
*, struct Client
*, int, const char **);
93 static int me_modunload(struct Client
*, struct Client
*, int, const char **);
94 static int me_modrestart(struct Client
*, struct Client
*, int, const char **);
96 static int do_modload(struct Client
*, const char *);
97 static int do_modunload(struct Client
*, const char *);
98 static int do_modreload(struct Client
*, const char *);
99 static int do_modlist(struct Client
*, const char *);
100 static int do_modrestart(struct Client
*);
102 struct Message modload_msgtab
= {
103 "MODLOAD", 0, 0, 0, MFLG_SLOW
,
104 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, {me_modload
, 2}, {mo_modload
, 2}}
107 struct Message modunload_msgtab
= {
108 "MODUNLOAD", 0, 0, 0, MFLG_SLOW
,
109 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, {me_modunload
, 2}, {mo_modunload
, 2}}
112 struct Message modreload_msgtab
= {
113 "MODRELOAD", 0, 0, 0, MFLG_SLOW
,
114 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, {me_modreload
, 2}, {mo_modreload
, 2}}
117 struct Message modlist_msgtab
= {
118 "MODLIST", 0, 0, 0, MFLG_SLOW
,
119 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, {me_modlist
, 0}, {mo_modlist
, 0}}
122 struct Message modrestart_msgtab
= {
123 "MODRESTART", 0, 0, 0, MFLG_SLOW
,
124 {mg_unreg
, mg_not_oper
, mg_ignore
, mg_ignore
, {me_modrestart
, 0}, {mo_modrestart
, 0}}
130 mod_add_cmd(&modload_msgtab
);
131 mod_add_cmd(&modunload_msgtab
);
132 mod_add_cmd(&modreload_msgtab
);
133 mod_add_cmd(&modlist_msgtab
);
134 mod_add_cmd(&modrestart_msgtab
);
136 /* Add the default paths we look in to the module system --nenolod */
137 mod_add_path(MODPATH
);
138 mod_add_path(AUTOMODPATH
);
145 * side effects - returns a module path from path
147 static struct module_path
*
148 mod_find_path(const char *path
)
151 struct module_path
*mpath
;
153 RB_DLINK_FOREACH(ptr
, mod_paths
.head
)
157 if(!strcmp(path
, mpath
->path
))
168 * side effects - adds path to list
171 mod_add_path(const char *path
)
173 struct module_path
*pathst
;
175 if(mod_find_path(path
))
178 pathst
= rb_malloc(sizeof(struct module_path
));
180 strcpy(pathst
->path
, path
);
181 rb_dlinkAddAlloc(pathst
, &mod_paths
);
188 * side effects - clear the lists of paths
191 mod_clear_paths(void)
193 rb_dlink_node
*ptr
, *next_ptr
;
195 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, mod_paths
.head
)
198 rb_free_rb_dlink_node(ptr
);
201 mod_paths
.head
= mod_paths
.tail
= NULL
;
202 mod_paths
.length
= 0;
213 findmodule_byname(const char *name
)
217 for (i
= 0; i
< num_mods
; i
++)
219 if(!irccmp(modlist
[i
]->name
, name
))
225 /* load_all_modules()
232 load_all_modules(int warn
)
234 DIR *system_module_dir
= NULL
;
235 struct dirent
*ldirent
= NULL
;
236 char module_fq_name
[PATH_MAX
+ 1];
241 modlist
= (struct module **) rb_malloc(sizeof(struct module) * (MODS_INCREMENT
));
243 max_mods
= MODS_INCREMENT
;
245 system_module_dir
= opendir(AUTOMODPATH
);
247 if(system_module_dir
== NULL
)
249 ilog(L_MAIN
, "Could not load modules from %s: %s", AUTOMODPATH
, strerror(errno
));
253 while ((ldirent
= readdir(system_module_dir
)) != NULL
)
255 len
= strlen(ldirent
->d_name
);
256 if((len
> 3) && !strcmp(ldirent
->d_name
+len
-3, SHARED_SUFFIX
))
258 (void) rb_snprintf(module_fq_name
, sizeof(module_fq_name
), "%s/%s", AUTOMODPATH
, ldirent
->d_name
);
259 (void) load_a_module(module_fq_name
, warn
, 0);
263 (void) closedir(system_module_dir
);
266 /* load_core_modules()
270 * side effects - core modules are loaded, if any fail, kill ircd
273 load_core_modules(int warn
)
275 char module_name
[MAXPATHLEN
];
279 for (i
= 0; core_module_table
[i
]; i
++)
281 rb_snprintf(module_name
, sizeof(module_name
), "%s/%s%s", MODPATH
,
282 core_module_table
[i
], SHARED_SUFFIX
);
284 if(load_a_module(module_name
, warn
, 1) == -1)
287 "Error loading core module %s%s: terminating ircd",
288 core_module_table
[i
], SHARED_SUFFIX
);
301 load_one_module(const char *path
, int coremodule
)
303 char modpath
[MAXPATHLEN
];
304 rb_dlink_node
*pathst
;
305 struct module_path
*mpath
;
309 if (server_state_foreground
== 1)
310 inotice("loading module %s ...", path
);
312 RB_DLINK_FOREACH(pathst
, mod_paths
.head
)
314 mpath
= pathst
->data
;
316 rb_snprintf(modpath
, sizeof(modpath
), "%s/%s", mpath
->path
, path
);
317 if((strstr(modpath
, "../") == NULL
) && (strstr(modpath
, "/..") == NULL
))
319 if(stat(modpath
, &statbuf
) == 0)
321 if(S_ISREG(statbuf
.st_mode
))
323 /* Regular files only please */
325 return load_a_module(modpath
, 1, 1);
327 return load_a_module(modpath
, 1, 0);
334 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "Cannot locate module %s", path
);
339 /* load a module .. */
341 mo_modload(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
343 if(!IsOperAdmin(source_p
))
345 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
346 me
.name
, source_p
->name
, "admin");
352 sendto_match_servs(source_p
, parv
[2], CAP_ENCAP
, NOCAPS
,
353 "ENCAP %s MODLOAD %s", parv
[2], parv
[1]);
354 if (match(parv
[2], me
.name
) == 0)
358 return do_modload(source_p
, parv
[1]);
362 me_modload(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
364 if(!find_shared_conf(source_p
->username
, source_p
->host
, source_p
->servptr
->name
, SHARED_MODULE
))
366 sendto_one_notice(source_p
, ":*** You do not have an appropriate shared block "
367 "to load modules on this server.");
371 return do_modload(source_p
, parv
[1]);
375 do_modload(struct Client
*source_p
, const char *module)
377 char *m_bn
= rb_basename(module);
379 if(findmodule_byname(m_bn
) != -1)
381 sendto_one_notice(source_p
, ":Module %s is already loaded", m_bn
);
386 load_one_module(module, 0);
394 /* unload a module .. */
396 mo_modunload(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
398 if(!IsOperAdmin(source_p
))
400 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
401 me
.name
, source_p
->name
, "admin");
407 sendto_match_servs(source_p
, parv
[2], CAP_ENCAP
, NOCAPS
,
408 "ENCAP %s MODUNLOAD %s", parv
[2], parv
[1]);
409 if (match(parv
[2], me
.name
) == 0)
413 return do_modunload(source_p
, parv
[1]);
417 me_modunload(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
419 if(!find_shared_conf(source_p
->username
, source_p
->host
, source_p
->servptr
->name
, SHARED_MODULE
))
421 sendto_one_notice(source_p
, ":*** You do not have an appropriate shared block "
422 "to load modules on this server.");
426 return do_modunload(source_p
, parv
[1]);
430 do_modunload(struct Client
*source_p
, const char *module)
433 char *m_bn
= rb_basename(module);
435 if((modindex
= findmodule_byname(m_bn
)) == -1)
437 sendto_one_notice(source_p
, ":Module %s is not loaded", m_bn
);
442 if(modlist
[modindex
]->core
== 1)
444 sendto_one_notice(source_p
, ":Module %s is a core module and may not be unloaded", m_bn
);
449 if(unload_one_module(m_bn
, 1) == -1)
451 sendto_one_notice(source_p
, ":Module %s is not loaded", m_bn
);
458 /* unload and load in one! */
460 mo_modreload(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
462 if(!IsOperAdmin(source_p
))
464 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
465 me
.name
, source_p
->name
, "admin");
471 sendto_match_servs(source_p
, parv
[2], CAP_ENCAP
, NOCAPS
,
472 "ENCAP %s MODRELOAD %s", parv
[2], parv
[1]);
473 if (match(parv
[2], me
.name
) == 0)
477 return do_modreload(source_p
, parv
[1]);
481 me_modreload(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
483 if(!find_shared_conf(source_p
->username
, source_p
->host
, source_p
->servptr
->name
, SHARED_MODULE
))
485 sendto_one_notice(source_p
, ":*** You do not have an appropriate shared block "
486 "to load modules on this server.");
490 return do_modreload(source_p
, parv
[1]);
494 do_modreload(struct Client
*source_p
, const char *module)
498 char *m_bn
= rb_basename(module);
500 if((modindex
= findmodule_byname(m_bn
)) == -1)
502 sendto_one_notice(source_p
, ":Module %s is not loaded", m_bn
);
507 check_core
= modlist
[modindex
]->core
;
509 if(unload_one_module(m_bn
, 1) == -1)
511 sendto_one_notice(source_p
, ":Module %s is not loaded", m_bn
);
516 if((load_one_module(m_bn
, check_core
) == -1) && check_core
)
518 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
519 "Error reloading core module: %s: terminating ircd", m_bn
);
520 ilog(L_MAIN
, "Error loading core module %s: terminating ircd", m_bn
);
528 /* list modules .. */
530 mo_modlist(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
532 if(!IsOperAdmin(source_p
))
534 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
535 me
.name
, source_p
->name
, "admin");
541 sendto_match_servs(source_p
, parv
[2], CAP_ENCAP
, NOCAPS
,
542 "ENCAP %s MODLIST %s", parv
[2], parv
[1]);
543 if (match(parv
[2], me
.name
) == 0)
547 return do_modlist(source_p
, parc
> 1 ? parv
[1] : 0);
551 me_modlist(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
553 if(!find_shared_conf(source_p
->username
, source_p
->host
, source_p
->servptr
->name
, SHARED_MODULE
))
555 sendto_one_notice(source_p
, ":*** You do not have an appropriate shared block "
556 "to load modules on this server.");
560 return do_modlist(source_p
, parv
[1]);
564 do_modlist(struct Client
*source_p
, const char *pattern
)
568 for (i
= 0; i
< num_mods
; i
++)
572 if(match(pattern
, modlist
[i
]->name
))
574 sendto_one(source_p
, form_str(RPL_MODLIST
),
575 me
.name
, source_p
->name
,
578 modlist
[i
]->version
, modlist
[i
]->core
? "(core)" : "");
583 sendto_one(source_p
, form_str(RPL_MODLIST
),
584 me
.name
, source_p
->name
, modlist
[i
]->name
,
585 modlist
[i
]->address
, modlist
[i
]->version
,
586 modlist
[i
]->core
? "(core)" : "");
590 sendto_one(source_p
, form_str(RPL_ENDOFMODLIST
), me
.name
, source_p
->name
);
594 /* unload and reload all modules */
596 mo_modrestart(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
598 if(!IsOperAdmin(source_p
))
600 sendto_one(source_p
, form_str(ERR_NOPRIVS
),
601 me
.name
, source_p
->name
, "admin");
607 sendto_match_servs(source_p
, parv
[1], CAP_ENCAP
, NOCAPS
,
608 "ENCAP %s MODRESTART", parv
[1]);
609 if (match(parv
[1], me
.name
) == 0)
613 return do_modrestart(source_p
);
617 me_modrestart(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
619 if(!find_shared_conf(source_p
->username
, source_p
->host
, source_p
->servptr
->name
, SHARED_MODULE
))
621 sendto_one_notice(source_p
, ":*** You do not have an appropriate shared block "
622 "to load modules on this server.");
626 return do_modrestart(source_p
);
630 do_modrestart(struct Client
*source_p
)
634 sendto_one_notice(source_p
, ":Reloading all modules");
638 unload_one_module(modlist
[0]->name
, 0);
641 load_core_modules(0);
644 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
645 "Module Restart: %d modules unloaded, %d modules loaded",
647 ilog(L_MAIN
, "Module Restart: %d modules unloaded, %d modules loaded", modnum
, num_mods
);
654 #define RTLD_NOW RTLD_LAZY /* openbsd deficiency */
661 #ifdef CHARYBDIS_PROFILE
662 # ifndef RTLD_PROFILE
663 # warning libdl may not support profiling, sucks. :(
664 # define RTLD_PROFILE 0
668 static void increase_modlist(void);
670 #define MODS_INCREMENT 10
672 static char unknown_ver
[] = "<unknown>";
674 /* This file contains the core functions to use dynamic libraries.
679 #ifdef HAVE_MACH_O_DYLD_H
681 ** jmallett's dl*(3) shims for NSModule(3) systems.
683 #include <mach-o/dyld.h>
687 #define RTLD_LAZY 2185 /* built-in dl*(3) don't care */
690 void undefinedErrorHandler(const char *);
691 NSModule
multipleErrorHandler(NSSymbol
, NSModule
, NSModule
);
692 void linkEditErrorHandler(NSLinkEditErrors
, int, const char *, const char *);
694 void *dlopen(char *, int);
696 void *dlsym(void *, char *);
698 static int firstLoad
= TRUE
;
699 static int myDlError
;
700 static char *myErrorTable
[] = { "Loading file as object failed\n",
701 "Loading file as object succeeded\n",
702 "Not a valid shared object\n",
703 "Architecture of object invalid on this architecture\n",
704 "Invalid or corrupt image\n",
705 "Could not access object\n",
706 "NSCreateObjectFileImageFromFile failed\n",
711 undefinedErrorHandler(const char *symbolName
)
713 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "Undefined symbol: %s", symbolName
);
714 ilog(L_MAIN
, "Undefined symbol: %s", symbolName
);
719 multipleErrorHandler(NSSymbol s
, NSModule old
, NSModule
new)
722 ** This results in substantial leaking of memory... Should free one
725 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
726 "Symbol `%s' found in `%s' and `%s'",
727 NSNameOfSymbol(s
), NSNameOfModule(old
), NSNameOfModule(new));
728 ilog(L_MAIN
, "Symbol `%s' found in `%s' and `%s'",
729 NSNameOfSymbol(s
), NSNameOfModule(old
), NSNameOfModule(new));
730 /* We return which module should be considered valid, I believe */
735 linkEditErrorHandler(NSLinkEditErrors errorClass
, int errnum
,
736 const char *fileName
, const char *errorString
)
738 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
739 "Link editor error: %s for %s", errorString
, fileName
);
740 ilog(L_MAIN
, "Link editor error: %s for %s", errorString
, fileName
);
747 return myDlError
== NSObjectFileImageSuccess
? NULL
: myErrorTable
[myDlError
% 7];
751 dlopen(char *filename
, int unused
)
753 NSObjectFileImage myImage
;
759 ** If we are loading our first symbol (huzzah!) we should go ahead
760 ** and install link editor error handling!
762 NSLinkEditErrorHandlers linkEditorErrorHandlers
;
764 linkEditorErrorHandlers
.undefined
= undefinedErrorHandler
;
765 linkEditorErrorHandlers
.multiple
= multipleErrorHandler
;
766 linkEditorErrorHandlers
.linkEdit
= linkEditErrorHandler
;
767 NSInstallLinkEditErrorHandlers(&linkEditorErrorHandlers
);
770 myDlError
= NSCreateObjectFileImageFromFile(filename
, &myImage
);
771 if(myDlError
!= NSObjectFileImageSuccess
)
775 myModule
= NSLinkModule(myImage
, filename
, NSLINKMODULE_OPTION_PRIVATE
);
776 return (void *) myModule
;
780 dlclose(void *myModule
)
782 NSUnLinkModule(myModule
, FALSE
);
787 dlsym(void *myModule
, char *mySymbolName
)
791 mySymbol
= NSLookupSymbolInModule((NSModule
) myModule
, mySymbolName
);
792 return NSAddressOfSymbol(mySymbol
);
799 * HPUX dl compat functions
801 #if defined(HAVE_SHL_LOAD) && !defined(HAVE_DLOPEN)
802 #define RTLD_LAZY BIND_DEFERRED
803 #define RTLD_GLOBAL DYNAMIC_PATH
804 #define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
805 #define dlclose(handle) shl_unload((shl_t)(handle))
806 #define dlsym(handle,name) hpux_dlsym(handle,name)
807 #define dlerror() strerror(errno)
810 hpux_dlsym(void *handle
, char *name
)
813 if(!shl_findsym((shl_t
*) & handle
, name
, TYPE_UNDEFINED
, &sym_addr
))
820 /* unload_one_module()
822 * inputs - name of module to unload
823 * - 1 to say modules unloaded, 0 to not
824 * output - 0 if successful, -1 if error
825 * side effects - module is unloaded
828 unload_one_module(const char *name
, int warn
)
832 if((modindex
= findmodule_byname(name
)) == -1)
836 ** XXX - The type system in C does not allow direct conversion between
837 ** data and function pointers, but as it happens, most C compilers will
838 ** safely do this, however it is a theoretical overlow to cast as we
839 ** must do here. I have library functions to take care of this, but
840 ** despite being more "correct" for the C language, this is more
841 ** practical. Removing the abuse of the ability to cast ANY pointer
842 ** to and from an integer value here will break some compilers.
845 /* Left the comment in but the code isn't here any more -larne */
846 switch (modlist
[modindex
]->mapi_version
)
850 struct mapi_mheader_av1
*mheader
= modlist
[modindex
]->mapi_header
;
851 if(mheader
->mapi_command_list
)
854 for (m
= mheader
->mapi_command_list
; *m
; ++m
)
858 /* hook events are never removed, we simply lose the
859 * ability to call them --fl
861 if(mheader
->mapi_hfn_list
)
863 mapi_hfn_list_av1
*m
;
864 for (m
= mheader
->mapi_hfn_list
; m
->hapi_name
; ++m
)
865 remove_hook(m
->hapi_name
, m
->fn
);
868 if(mheader
->mapi_unregister
)
869 mheader
->mapi_unregister();
873 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
874 "Unknown/unsupported MAPI version %d when unloading %s!",
875 modlist
[modindex
]->mapi_version
, modlist
[modindex
]->name
);
876 ilog(L_MAIN
, "Unknown/unsupported MAPI version %d when unloading %s!",
877 modlist
[modindex
]->mapi_version
, modlist
[modindex
]->name
);
881 dlclose(modlist
[modindex
]->address
);
883 rb_free(modlist
[modindex
]->name
);
884 memmove(&modlist
[modindex
], &modlist
[modindex
+ 1],
885 sizeof(struct module) * ((num_mods
- 1) - modindex
));
892 ilog(L_MAIN
, "Module %s unloaded", name
);
893 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "Module %s unloaded", name
);
903 * inputs - path name of module, int to notice, int of core
904 * output - -1 if error 0 if success
905 * side effects - loads a module if successful
908 load_a_module(const char *path
, int warn
, int core
)
917 mod_basename
= rb_basename(path
);
919 #ifdef CHARYBDIS_PROFILE
920 tmpptr
= dlopen(path
, RTLD_NOW
| RTLD_LOCAL
| RTLD_PROFILE
);
922 tmpptr
= dlopen(path
, RTLD_NOW
| RTLD_LOCAL
);
927 const char *err
= dlerror();
929 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
930 "Error loading module %s: %s", mod_basename
, err
);
931 ilog(L_MAIN
, "Error loading module %s: %s", mod_basename
, err
);
932 rb_free(mod_basename
);
938 * _mheader is actually a struct mapi_mheader_*, but mapi_version
939 * is always the first member of this structure, so we treate it
940 * as a single int in order to determine the API version.
943 mapi_version
= (int *) (uintptr_t) dlsym(tmpptr
, "_mheader");
944 if((mapi_version
== NULL
945 && (mapi_version
= (int *) (uintptr_t) dlsym(tmpptr
, "__mheader")) == NULL
)
946 || MAPI_MAGIC(*mapi_version
) != MAPI_MAGIC_HDR
)
948 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
949 "Data format error: module %s has no MAPI header.",
951 ilog(L_MAIN
, "Data format error: module %s has no MAPI header.", mod_basename
);
952 (void) dlclose(tmpptr
);
953 rb_free(mod_basename
);
957 switch (MAPI_VERSION(*mapi_version
))
961 struct mapi_mheader_av1
*mheader
= (struct mapi_mheader_av1
*) mapi_version
; /* see above */
962 if(mheader
->mapi_register
&& (mheader
->mapi_register() == -1))
964 ilog(L_MAIN
, "Module %s indicated failure during load.",
966 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
967 "Module %s indicated failure during load.",
970 rb_free(mod_basename
);
973 if(mheader
->mapi_command_list
)
976 for (m
= mheader
->mapi_command_list
; *m
; ++m
)
980 if(mheader
->mapi_hook_list
)
983 for (m
= mheader
->mapi_hook_list
; m
->hapi_name
; ++m
)
984 *m
->hapi_id
= register_hook(m
->hapi_name
);
987 if(mheader
->mapi_hfn_list
)
989 mapi_hfn_list_av1
*m
;
990 for (m
= mheader
->mapi_hfn_list
; m
->hapi_name
; ++m
)
991 add_hook(m
->hapi_name
, m
->fn
);
994 ver
= mheader
->mapi_module_version
;
999 ilog(L_MAIN
, "Module %s has unknown/unsupported MAPI version %d.",
1000 mod_basename
, MAPI_VERSION(*mapi_version
));
1001 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
1002 "Module %s has unknown/unsupported MAPI version %d.",
1003 mod_basename
, *mapi_version
);
1005 rb_free(mod_basename
);
1014 modlist
[num_mods
] = rb_malloc(sizeof(struct module));
1015 modlist
[num_mods
]->address
= tmpptr
;
1016 modlist
[num_mods
]->version
= ver
;
1017 modlist
[num_mods
]->core
= core
;
1018 modlist
[num_mods
]->name
= rb_strdup(mod_basename
);
1019 modlist
[num_mods
]->mapi_header
= mapi_version
;
1020 modlist
[num_mods
]->mapi_version
= MAPI_VERSION(*mapi_version
);
1025 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
1026 "Module %s [version: %s; MAPI version: %d] loaded at 0x%lx",
1027 mod_basename
, ver
, MAPI_VERSION(*mapi_version
),
1028 (unsigned long) tmpptr
);
1029 ilog(L_MAIN
, "Module %s [version: %s; MAPI version: %d] loaded at 0x%lx",
1030 mod_basename
, ver
, MAPI_VERSION(*mapi_version
), (unsigned long) tmpptr
);
1032 rb_free(mod_basename
);
1041 * side effects - expand the size of modlist if necessary
1044 increase_modlist(void)
1046 struct module **new_modlist
= NULL
;
1048 if((num_mods
+ 1) < max_mods
)
1051 new_modlist
= (struct module **) rb_malloc(sizeof(struct module) *
1052 (max_mods
+ MODS_INCREMENT
));
1053 memcpy((void *) new_modlist
, (void *) modlist
, sizeof(struct module) * num_mods
);
1056 modlist
= new_modlist
;
1057 max_mods
+= MODS_INCREMENT
;
1060 #else /* STATIC_MODULES */
1062 /* load_all_modules()
1066 * side effects - all the msgtabs are added for static modules
1069 load_all_modules(int warn
)
1071 load_static_modules();
1074 #endif /* STATIC_MODULES */