X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/2a19fc3f57cb4b9e9d3e0720e667bc374b4a3c29..ea111ea5449c763e08ca441b4bf1243af23a8b7c:/ircd/modules.c diff --git a/ircd/modules.c b/ircd/modules.c index ada22c12..09fc4a98 100644 --- a/ircd/modules.c +++ b/ircd/modules.c @@ -20,13 +20,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA - * - * $Id: modules.c 3161 2007-01-25 07:23:01Z nenolod $ */ #include "stdinc.h" - - #include "modules.h" #include "logger.h" #include "ircd.h" @@ -38,7 +34,8 @@ #include "parse.h" #include "ircd_defs.h" #include "match.h" - +#include "s_serv.h" +#include "capability.h" #include @@ -61,41 +58,55 @@ static const char *core_module_table[] = { NULL }; +#define MOD_WARN_DELTA (90 * 86400) /* time in seconds, 86400 seconds in a day */ + #define MODS_INCREMENT 10 int num_mods = 0; int max_mods = MODS_INCREMENT; static rb_dlink_list mod_paths; -static int mo_modload(struct Client *, struct Client *, int, const char **); -static int mo_modlist(struct Client *, struct Client *, int, const char **); -static int mo_modreload(struct Client *, struct Client *, int, const char **); -static int mo_modunload(struct Client *, struct Client *, int, const char **); -static int mo_modrestart(struct Client *, struct Client *, int, const char **); +static int mo_modload(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int mo_modlist(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int mo_modreload(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int mo_modunload(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int mo_modrestart(struct MsgBuf *, struct Client *, struct Client *, int, const char **); + +static int me_modload(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int me_modlist(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int me_modreload(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int me_modunload(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static int me_modrestart(struct MsgBuf *, struct Client *, struct Client *, int, const char **); + +static int do_modload(struct Client *, const char *); +static int do_modunload(struct Client *, const char *); +static int do_modreload(struct Client *, const char *); +static int do_modlist(struct Client *, const char *); +static int do_modrestart(struct Client *); struct Message modload_msgtab = { - "MODLOAD", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modload, 2}} + "MODLOAD", 0, 0, 0, 0, + {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modload, 2}, {mo_modload, 2}} }; struct Message modunload_msgtab = { - "MODUNLOAD", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modunload, 2}} + "MODUNLOAD", 0, 0, 0, 0, + {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modunload, 2}, {mo_modunload, 2}} }; struct Message modreload_msgtab = { - "MODRELOAD", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modreload, 2}} + "MODRELOAD", 0, 0, 0, 0, + {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modreload, 2}, {mo_modreload, 2}} }; struct Message modlist_msgtab = { - "MODLIST", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modlist, 0}} + "MODLIST", 0, 0, 0, 0, + {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modlist, 0}, {mo_modlist, 0}} }; struct Message modrestart_msgtab = { - "MODRESTART", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modrestart, 0}} + "MODRESTART", 0, 0, 0, 0, + {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modrestart, 0}, {mo_modrestart, 0}} }; void @@ -230,12 +241,12 @@ load_all_modules(int warn) while ((ldirent = readdir(system_module_dir)) != NULL) { - len = strlen(ldirent->d_name); + len = strlen(ldirent->d_name); if((len > 3) && !strcmp(ldirent->d_name+len-3, ".la")) - { - (void) rb_snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s", AUTOMODPATH, ldirent->d_name); - (void) load_a_module(module_fq_name, warn, 0); - } + { + (void) snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s", AUTOMODPATH, ldirent->d_name); + (void) load_a_module(module_fq_name, warn, MAPI_ORIGIN_CORE, 0); + } } (void) closedir(system_module_dir); @@ -256,10 +267,10 @@ load_core_modules(int warn) for (i = 0; core_module_table[i]; i++) { - rb_snprintf(module_name, sizeof(module_name), "%s/%s%s", MODPATH, + snprintf(module_name, sizeof(module_name), "%s/%s%s", MODPATH, core_module_table[i], ".la"); - if(load_a_module(module_name, warn, 1) == -1) + if(load_a_module(module_name, warn, MAPI_ORIGIN_CORE, 1) == -1) { ilog(L_MAIN, "Error loading core module %s%s: terminating ircd", @@ -276,7 +287,7 @@ load_core_modules(int warn) * side effects - */ int -load_one_module(const char *path, int coremodule) +load_one_module(const char *path, int origin, int coremodule) { char modpath[PATH_MAX]; rb_dlink_node *pathst; @@ -287,11 +298,17 @@ load_one_module(const char *path, int coremodule) if (server_state_foreground == 1) inotice("loading module %s ...", path); + if(coremodule != 0) + { + coremodule = 1; + origin = MAPI_ORIGIN_CORE; + } + RB_DLINK_FOREACH(pathst, mod_paths.head) { mpath = pathst->data; - rb_snprintf(modpath, sizeof(modpath), "%s/%s", mpath, path); + snprintf(modpath, sizeof(modpath), "%s/%s", mpath, path); if((strstr(modpath, "../") == NULL) && (strstr(modpath, "/..") == NULL)) { if(stat(modpath, &statbuf) == 0) @@ -299,10 +316,7 @@ load_one_module(const char *path, int coremodule) if(S_ISREG(statbuf.st_mode)) { /* Regular files only please */ - if(coremodule) - return load_a_module(modpath, 1, 1); - else - return load_a_module(modpath, 1, 0); + return load_a_module(modpath, 1, origin, coremodule); } } @@ -316,10 +330,8 @@ load_one_module(const char *path, int coremodule) /* load a module .. */ static int -mo_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv) +mo_modload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) { - char *m_bn; - if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), @@ -327,7 +339,35 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha return 0; } - m_bn = rb_basename(parv[1]); + if(parc > 2) + { + sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS, + "ENCAP %s MODLOAD %s", parv[2], parv[1]); + if (match(parv[2], me.name) == 0) + return 0; + } + + return do_modload(source_p, parv[1]); +} + +static int +me_modload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) +{ + if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE)) + { + sendto_one_notice(source_p, ":*** You do not have an appropriate shared block " + "to load modules on this server."); + return 0; + } + + return do_modload(source_p, parv[1]); +} + +static int +do_modload(struct Client *source_p, const char *module) +{ + char *m_bn = rb_basename(module); + int origin; if(findmodule_byname(m_bn) != -1) { @@ -336,7 +376,8 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha return 0; } - load_one_module(parv[1], 0); + origin = strcmp(module, m_bn) == 0 ? MAPI_ORIGIN_CORE : MAPI_ORIGIN_EXTENSION; + load_one_module(module, origin, 0); rb_free(m_bn); @@ -346,11 +387,8 @@ mo_modload(struct Client *client_p, struct Client *source_p, int parc, const cha /* unload a module .. */ static int -mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv) +mo_modunload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) { - char *m_bn; - int modindex; - if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), @@ -358,7 +396,35 @@ mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const c return 0; } - m_bn = rb_basename(parv[1]); + if(parc > 2) + { + sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS, + "ENCAP %s MODUNLOAD %s", parv[2], parv[1]); + if (match(parv[2], me.name) == 0) + return 0; + } + + return do_modunload(source_p, parv[1]); +} + +static int +me_modunload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) +{ + if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE)) + { + sendto_one_notice(source_p, ":*** You do not have an appropriate shared block " + "to load modules on this server."); + return 0; + } + + return do_modunload(source_p, parv[1]); +} + +static int +do_modunload(struct Client *source_p, const char *module) +{ + int modindex; + char *m_bn = rb_basename(module); if((modindex = findmodule_byname(m_bn)) == -1) { @@ -385,12 +451,8 @@ mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const c /* unload and load in one! */ static int -mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv) +mo_modreload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) { - char *m_bn; - int modindex; - int check_core; - if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), @@ -398,7 +460,36 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c return 0; } - m_bn = rb_basename(parv[1]); + if(parc > 2) + { + sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS, + "ENCAP %s MODRELOAD %s", parv[2], parv[1]); + if (match(parv[2], me.name) == 0) + return 0; + } + + return do_modreload(source_p, parv[1]); +} + +static int +me_modreload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) +{ + if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE)) + { + sendto_one_notice(source_p, ":*** You do not have an appropriate shared block " + "to load modules on this server."); + return 0; + } + + return do_modreload(source_p, parv[1]); +} + +static int +do_modreload(struct Client *source_p, const char *module) +{ + int modindex; + int check_core; + char *m_bn = rb_basename(module); if((modindex = findmodule_byname(m_bn)) == -1) { @@ -416,9 +507,9 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c return 0; } - if((load_one_module(m_bn, check_core) == -1) && check_core) + if((load_one_module(m_bn, modlist[modindex]->origin, check_core) == -1) && check_core) { - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Error reloading core module: %s: terminating ircd", m_bn); ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn); exit(0); @@ -430,10 +521,8 @@ mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const c /* list modules .. */ static int -mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv) +mo_modlist(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) { - int i; - if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), @@ -441,26 +530,68 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha return 0; } + if(parc > 2) + { + sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS, + "ENCAP %s MODLIST %s", parv[2], parv[1]); + if (match(parv[2], me.name) == 0) + return 0; + } + + return do_modlist(source_p, parc > 1 ? parv[1] : 0); +} + +static int +me_modlist(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) +{ + if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE)) + { + sendto_one_notice(source_p, ":*** You do not have an appropriate shared block " + "to load modules on this server."); + return 0; + } + + return do_modlist(source_p, parv[1]); +} + +static int +do_modlist(struct Client *source_p, const char *pattern) +{ + int i; + for (i = 0; i < num_mods; i++) { - if(parc > 1) + const char *origin; + switch (modlist[i]->origin) + { + case MAPI_ORIGIN_EXTENSION: + origin = "extension"; + break; + case MAPI_ORIGIN_CORE: + origin = "builtin"; + break; + default: + origin = "unknown"; + break; + } + + if(pattern) { - if(match(parv[1], modlist[i]->name)) + if(match(pattern, modlist[i]->name)) { sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name, modlist[i]->name, - (unsigned long)(uintptr_t)modlist[i]->address, - modlist[i]->version, modlist[i]->core ? "(core)" : ""); + (unsigned long)(uintptr_t)modlist[i]->address, origin, + modlist[i]->core ? " (core)" : "", modlist[i]->version, modlist[i]->description); } } else { sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name, modlist[i]->name, - (unsigned long)(uintptr_t)modlist[i]->address, - modlist[i]->version, - modlist[i]->core ? "(core)" : ""); + (unsigned long)(uintptr_t)modlist[i]->address, origin, + modlist[i]->core ? " (core)" : "", modlist[i]->version, modlist[i]->description); } } @@ -470,10 +601,8 @@ mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const cha /* unload and reload all modules */ static int -mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv) +mo_modrestart(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) { - int modnum; - if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), @@ -481,6 +610,35 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const return 0; } + if(parc > 1) + { + sendto_match_servs(source_p, parv[1], CAP_ENCAP, NOCAPS, + "ENCAP %s MODRESTART", parv[1]); + if (match(parv[1], me.name) == 0) + return 0; + } + + return do_modrestart(source_p); +} + +static int +me_modrestart(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) +{ + if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE)) + { + sendto_one_notice(source_p, ":*** You do not have an appropriate shared block " + "to load modules on this server."); + return 0; + } + + return do_modrestart(source_p); +} + +static int +do_modrestart(struct Client *source_p) +{ + int modnum; + sendto_one_notice(source_p, ":Reloading all modules"); modnum = num_mods; @@ -491,7 +649,7 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const load_core_modules(0); rehash(0); - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods); ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods); @@ -499,27 +657,12 @@ mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const } - -#ifndef RTLD_NOW -#define RTLD_NOW RTLD_LAZY /* openbsd deficiency */ -#endif - -#ifndef RTLD_LOCAL -#define RTLD_LOCAL 0 -#endif - -#ifdef CHARYBDIS_PROFILE -# ifndef RTLD_PROFILE -# warning libdl may not support profiling, sucks. :( -# define RTLD_PROFILE 0 -# endif -#endif - static void increase_modlist(void); #define MODS_INCREMENT 10 static char unknown_ver[] = ""; +static char unknown_description[] = ""; /* unload_one_module() * @@ -573,6 +716,60 @@ unload_one_module(const char *name, int warn) mheader->mapi_unregister(); break; } + case 2: + { + struct mapi_mheader_av2 *mheader = modlist[modindex]->mapi_header; + + /* XXX duplicate code :( */ + if(mheader->mapi_command_list) + { + struct Message **m; + for (m = mheader->mapi_command_list; *m; ++m) + mod_del_cmd(*m); + } + + /* hook events are never removed, we simply lose the + * ability to call them --fl + */ + if(mheader->mapi_hfn_list) + { + mapi_hfn_list_av1 *m; + for (m = mheader->mapi_hfn_list; m->hapi_name; ++m) + remove_hook(m->hapi_name, m->fn); + } + + if(mheader->mapi_unregister) + mheader->mapi_unregister(); + + if(mheader->mapi_cap_list) + { + mapi_cap_list_av2 *m; + for (m = mheader->mapi_cap_list; m->cap_name; ++m) + { + struct CapabilityIndex *idx; + + switch (m->cap_index) + { + case MAPI_CAP_CLIENT: + idx = cli_capindex; + break; + case MAPI_CAP_SERVER: + idx = serv_capindex; + break; + default: + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Unknown/unsupported CAP index found of type %d on capability %s when unloading %s", + m->cap_index, m->cap_name, modlist[modindex]->name); + ilog(L_MAIN, + "Unknown/unsupported CAP index found of type %d on capability %s when unloading %s", + m->cap_index, m->cap_name, modlist[modindex]->name); + continue; + } + + capability_orphan(idx, m->cap_name); + } + } + } default: sendto_realops_snomask(SNO_GENERAL, L_ALL, "Unknown/unsupported MAPI version %d when unloading %s!", @@ -585,6 +782,7 @@ unload_one_module(const char *name, int warn) lt_dlclose(modlist[modindex]->address); rb_free(modlist[modindex]->name); + rb_free(modlist[modindex]); memmove(&modlist[modindex], &modlist[modindex + 1], sizeof(struct module *) * ((num_mods - 1) - modindex)); @@ -600,20 +798,19 @@ unload_one_module(const char *name, int warn) return 0; } - /* * load_a_module() * - * inputs - path name of module, int to notice, int of core + * inputs - path name of module, int to notice, int of origin, int of core * output - -1 if error 0 if success * side effects - loads a module if successful */ int -load_a_module(const char *path, int warn, int core) +load_a_module(const char *path, int warn, int origin, int core) { lt_dlhandle tmpptr; char *mod_basename; - const char *ver; + const char *ver, *description = NULL; int *mapi_version; @@ -693,7 +890,102 @@ load_a_module(const char *path, int warn, int core) ver = mheader->mapi_module_version; break; } + case 2: + { + struct mapi_mheader_av2 *mheader = (struct mapi_mheader_av2 *)(void *)mapi_version; /* see above */ + /* XXX duplicated code :( */ + if(mheader->mapi_register && (mheader->mapi_register() == -1)) + { + ilog(L_MAIN, "Module %s indicated failure during load.", + mod_basename); + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Module %s indicated failure during load.", + mod_basename); + lt_dlclose(tmpptr); + rb_free(mod_basename); + return -1; + } + + /* Basic date code checks + * + * Don't make them fatal, but do complain about differences within a certain time frame. + * Later on if there are major API changes we can add fatal checks. + * -- Elizafox + */ + if(mheader->mapi_datecode != datecode && mheader->mapi_datecode > 0) + { + long int delta = datecode - mheader->mapi_datecode; + if (delta > MOD_WARN_DELTA) + { + delta /= 86400; + iwarn("Module %s build date is out of sync with ircd build date by %ld days, expect problems", + mod_basename, delta); + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Module %s build date is out of sync with ircd build date by %ld days, expect problems", + mod_basename, delta); + } + } + + if(mheader->mapi_command_list) + { + struct Message **m; + for (m = mheader->mapi_command_list; *m; ++m) + mod_add_cmd(*m); + } + + if(mheader->mapi_hook_list) + { + mapi_hlist_av1 *m; + for (m = mheader->mapi_hook_list; m->hapi_name; ++m) + *m->hapi_id = register_hook(m->hapi_name); + } + + if(mheader->mapi_hfn_list) + { + mapi_hfn_list_av1 *m; + for (m = mheader->mapi_hfn_list; m->hapi_name; ++m) + add_hook(m->hapi_name, m->fn); + } + + /* New in MAPI v2 - version replacement */ + ver = mheader->mapi_module_version ? mheader->mapi_module_version : ircd_version; + description = mheader->mapi_module_description; + + if(mheader->mapi_cap_list) + { + mapi_cap_list_av2 *m; + for (m = mheader->mapi_cap_list; m->cap_name; ++m) + { + struct CapabilityIndex *idx; + int result; + + switch (m->cap_index) + { + case MAPI_CAP_CLIENT: + idx = cli_capindex; + break; + case MAPI_CAP_SERVER: + idx = serv_capindex; + break; + default: + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Unknown/unsupported CAP index found of type %d on capability %s when loading %s", + m->cap_index, m->cap_name, mod_basename); + ilog(L_MAIN, + "Unknown/unsupported CAP index found of type %d on capability %s when loading %s", + m->cap_index, m->cap_name, mod_basename); + continue; + } + + result = capability_put(idx, m->cap_name, m->cap_ownerdata); + if (m->cap_id != NULL) + *(m->cap_id) = result; + } + } + } + + break; default: ilog(L_MAIN, "Module %s has unknown/unsupported MAPI version %d.", mod_basename, MAPI_VERSION(*mapi_version)); @@ -708,25 +1000,45 @@ load_a_module(const char *path, int warn, int core) if(ver == NULL) ver = unknown_ver; + if(description == NULL) + description = unknown_description; + increase_modlist(); modlist[num_mods] = rb_malloc(sizeof(struct module)); modlist[num_mods]->address = tmpptr; modlist[num_mods]->version = ver; + modlist[num_mods]->description = description; modlist[num_mods]->core = core; modlist[num_mods]->name = rb_strdup(mod_basename); modlist[num_mods]->mapi_header = mapi_version; modlist[num_mods]->mapi_version = MAPI_VERSION(*mapi_version); + modlist[num_mods]->origin = origin; num_mods++; if(warn == 1) { + const char *o; + + switch (origin) + { + case MAPI_ORIGIN_EXTENSION: + o = "extension"; + break; + case MAPI_ORIGIN_CORE: + o = "core"; + break; + default: + o = "unknown"; + break; + } + sendto_realops_snomask(SNO_GENERAL, L_ALL, - "Module %s [version: %s; MAPI version: %d] loaded at 0x%lx", - mod_basename, ver, MAPI_VERSION(*mapi_version), + "Module %s [version: %s; MAPI version: %d; origin: %s; description: \"%s\"] loaded at 0x%lx", + mod_basename, ver, MAPI_VERSION(*mapi_version), o, description, (unsigned long) tmpptr); - ilog(L_MAIN, "Module %s [version: %s; MAPI version: %d] loaded at 0x%lx", - mod_basename, ver, MAPI_VERSION(*mapi_version), (unsigned long) tmpptr); + ilog(L_MAIN, "Module %s [version: %s; MAPI version: %d; origin: %s; description: \"%s\"] loaded at 0x%lx", + mod_basename, ver, MAPI_VERSION(*mapi_version), o, description, (unsigned long) tmpptr); } rb_free(mod_basename); return 0;