diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/modules.c | 92 |
2 files changed, 76 insertions, 17 deletions
diff --git a/src/main.c b/src/main.c index b48e74797..98fb4b372 100644 --- a/src/main.c +++ b/src/main.c @@ -275,6 +275,7 @@ static void services_shutdown(void) } send_event(EVENT_SHUTDOWN, 1, EVENT_STOP); disconn(servsock); + modules_unload_all(); /* Only legitimate use of this function */ } /*************************************************************************/ diff --git a/src/modules.c b/src/modules.c index fe5d1b26c..53535bdae 100644 --- a/src/modules.c +++ b/src/modules.c @@ -61,6 +61,7 @@ int displayCommandFromHash(CommandHash * cmdTable[], char *name); int displayMessageFromHashl(char *name); int displayMessage(Message * m); + /** * Automaticaly load modules at startup. * This will load modules at startup before the IRCD link is attempted, this @@ -180,6 +181,51 @@ void modules_delayed_init(void) } /** + * Unload ALL loaded modules, no matter what kind of module it is. + * Do NEVER EVER, and i mean NEVER (and if that isn't clear enough + * yet, i mean: NEVER AT ALL) call this unless we're shutting down, + * or we'll fuck up Anope badly (protocol handling won't work for + * example). If anyone calls this function without a justified need + * for it, i reserve the right to break their legs in a painful way. + * And if that isn't enough discouragement, you'll wake up with your + * both legs broken tomorrow ;) -GD + */ +void modules_unload_all(void) +{ +#ifdef USE_MODULES + int idx; + ModuleHash *mh, *next; + void (*func) (void); + + for (idx = 0; idx < MAX_CMD_HASH; idx++) { + mh = MODULE_HASH[idx]; + while (mh) { + next = mh->next; + + if (prepForUnload(mh->m) != MOD_ERR_OK) { + mh = next; + continue; + } + + func = (void (*)(void))ano_modsym(mh->m->handle, "AnopeFini"); + if (func) { + mod_current_module_name = mh->m->name; + func(); /* exec AnopeFini */ + mod_current_module_name = NULL; + } + + if ((ano_modclose(mh->m->handle)) != 0) + alog(ano_moderr()); + else + delModule(mh->m); + + mh = next; + } + } +#endif +} + +/** * Create a new module, setting up the default values as needed. * @param filename the filename of the new module * @return a newly created module struct @@ -369,33 +415,39 @@ int protocolModuleLoaded() * triggering a segfault, as the actaul file in use will be in the * runtime folder. * @param name the name of the module to copy + * @param output the destination to copy the module to * @return MOD_ERR_OK on success */ -int moduleCopyFile(char *name) +int moduleCopyFile(char *name, char *output) { #ifdef USE_MODULES int ch; FILE *source, *target; - char output[4096]; + int srcfp; char input[4096]; int len; - strncpy(output, MODULE_PATH, 4095); /* Get full path with module extension */ strncpy(input, MODULE_PATH, 4095); /* Get full path with module extension */ - len = strlen(output); -#ifdef _WIN32 - strncat(output, "runtime\\", 4095 - len); -#else - strncat(output, "runtime/", 4095 - len); -#endif - len += strlen(output); - strncat(output, name, 4095 - len); + len = strlen(input); strncat(input, name, 4095 - len); - len += strlen(output); - strncat(output, MODULE_EXT, 4095 - len); + len = strlen(output); strncat(input, MODULE_EXT, 4095 - len); #ifndef _WIN32 + if ((srcfp = mkstemp(output)) == -1) + return MOD_ERR_FILE_IO; +#else + if (!mktemp(output)) + return MOD_ERR_FILE_IO; +#endif + + if (debug) + alog("Runtime module location: %s", output); + + /* Linux/UNIX should ignore the b param, why do we still have seperate + * calls for it here? -GD + */ +#ifndef _WIN32 if ((source = fopen(input, "r")) == NULL) { #else if ((source = fopen(input, "rb")) == NULL) { @@ -403,7 +455,7 @@ int moduleCopyFile(char *name) return MOD_ERR_NOEXIST; } #ifndef _WIN32 - if ((target = fopen(output, "w")) == NULL) { + if ((target = fdopen(srcfp, "w")) == NULL) { #else if ((target = fopen(output, "wb")) == NULL) { #endif @@ -447,9 +499,8 @@ int loadModule(Module * m, User * u) if ((m2 = findModule(m->name)) != NULL) { return MOD_ERR_EXISTS; } - - moduleCopyFile(m->name); - + + /* Generate the filename for the temporary copy of the module */ strncpy(buf, MODULE_PATH, 4095); /* Get full path with module extension */ len = strlen(buf); #ifndef _WIN32 @@ -461,7 +512,14 @@ int loadModule(Module * m, User * u) strncat(buf, m->name, 4095 - len); len = strlen(buf); strncat(buf, MODULE_EXT, 4095 - len); + len = strlen(buf); + strncat(buf, ".", 4095 - len); + len = strlen(buf); + strncat(buf, "XXXXXX", 4095 - len); buf[4095] = '\0'; + /* Don't skip return value checking! -GD */ + if (ret = moduleCopyFile(m->name, buf) != MOD_ERR_OK) + return ret; m->filename = sstrdup(buf); ano_modclearerr(); |