summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgeniusdex geniusdex@31f1291d-b8d6-0310-a050-a5561fc1590b <geniusdex geniusdex@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864>2005-07-01 21:32:09 +0000
committergeniusdex geniusdex@31f1291d-b8d6-0310-a050-a5561fc1590b <geniusdex geniusdex@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864>2005-07-01 21:32:09 +0000
commit5e079dce4b630cbbd3fcdd3cbc3f87f12dff1b37 (patch)
tree5f55919423e648ac117994a455103226af916919 /src
parent0190e74b31835ffbd3e451c7de7e9a151c5511d2 (diff)
BUILD : 1.7.10 (841) BUGS : 400 NOTES : Modules will now get a more random filename in the runtime/ folder, which makes sure that no duplicate filenames will occur, which makes sure listchans can run at the same time as services since they both use the same protocol module, which in turn fixes bug 400. And all modules are now properly unloaded on shutdown :)
git-svn-id: svn://svn.anope.org/anope/trunk@841 31f1291d-b8d6-0310-a050-a5561fc1590b git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@594 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/main.c1
-rw-r--r--src/modules.c92
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();