]> jfr.im git - irc/quakenet/newserv.git/blobdiff - core/modules.c
Sample node search module.
[irc/quakenet/newserv.git] / core / modules.c
index 022b9f4c47a56d9f0a27d96b3264da75f0029e7f..1a35ae087d12a33b1b8467c04c6faa750d4aa6a5 100644 (file)
 #include "../lib/sstring.h"
 #include "../lib/irc_string.h"
 #include "../lib/splitline.h"
+#include "../lib/strlfunc.h"
 #include "config.h"
 #include "error.h"
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include "schedule.h"
 
 #define DEPFILE        "modules.dep"
 
@@ -44,6 +46,9 @@
  * At the end of the second pass we should have a correctly filled in array!
  */
 
+sstring *safereload_str;
+schedule *safereload_sched;
+
 struct module_dep {
   sstring *name;
   unsigned int numparents;
@@ -66,8 +71,15 @@ void clearmoduledeps() {
   unsigned int i;
   
   for (i=0;i<knownmodules;i++) {
-    free(moduledeps[i].parents);
-    free(moduledeps[i].children);
+    freesstring(moduledeps[i].name);
+    if (moduledeps[i].parents) {
+      free(moduledeps[i].parents);
+      moduledeps[i].parents=NULL;
+    }
+    if (moduledeps[i].children) {
+      free(moduledeps[i].children);
+      moduledeps[i].children=NULL;
+    }
   }
   
   knownmodules=0;
@@ -93,7 +105,7 @@ void initmoduledeps() {
   char *largv[100];
   char largc;
   char *ch;
-  struct module_dep *mdp, *tmdp, *mdps;
+  struct module_dep *mdp, *tmdp;
   unsigned int i,j;
   
   sprintf(buf,"%s/%s",moddir->content,DEPFILE);
@@ -124,7 +136,9 @@ void initmoduledeps() {
       /* Add us to the array */
       i=knownmodules++;
       if (i>=MAXMODULES) {
-        Error("core",ERR_FATAL,"Too many modules in dependency file; rebuild with higher MAXMODULES.\n");
+        Error("core",ERR_ERROR,
+               "Too many modules in dependency file; rebuild with higher MAXMODULES.  Module dependencies disabled.\n");
+        clearmoduledeps();
         return;
       }
       
@@ -138,8 +152,10 @@ void initmoduledeps() {
       /* Fill in the parents array */
       for (i=0;i<(largc-1);i++) {
         if (!(mdp->parents[i]=getmoduledep(largv[i+1]))) {
-          Error("core",ERR_WARNING,"Couldn't find parent module %s of %s.",largv[i+1],largv[0]);
-          continue;
+          Error("core",ERR_WARNING,"Couldn't find parent module %s of %s.  Module dependencies disabled.",
+                  largv[i+1],largv[0]);
+          clearmoduledeps();
+          return;
         }
         mdp->parents[i]->numchildren++; /* break the bad news */
       }
@@ -204,7 +220,7 @@ void initmodules() {
 }
 
 int insmod(char *modulename) {
-  int i, n;
+  int i;
   module *mods;
   char buf[1024];
   const char *(*verinfo)(void);
@@ -403,3 +419,63 @@ void reloadmarked(void) {
     }
   }
 }
+
+void safereloadcallback(void *arg) {
+  safereload_sched=NULL;
+  
+  if (!safereload_str)
+    return;
+  
+  preparereload(safereload_str->content);
+  rmmod(safereload_str->content);
+  insmod(safereload_str->content);
+  reloadmarked();
+
+  freesstring(safereload_str);
+  safereload_str=NULL;
+}
+
+void safereload(char *themodule) {
+  if (safereload_str)
+    freesstring(safereload_str);
+  
+  safereload_str=getsstring(themodule, 100);
+  
+  if (safereload_sched)
+    deleteschedule(safereload_sched, safereloadcallback, NULL);
+  
+  scheduleoneshot(1, safereloadcallback, NULL);
+}
+
+void newserv_shutdown() {
+  module *mods;
+  char buf[1024];
+
+  while (modules.cursi) {
+    mods=(module *)(modules.content);
+
+    strlcpy(buf, mods[0].name->content, sizeof(buf));
+    rmmod(buf);
+  }
+  
+  clearmoduledeps();
+
+  if (moddir!=NULL)
+    freesstring(moddir);
+
+  if (modsuffix!=NULL)
+    freesstring(modsuffix);
+
+  Error("core",ERR_INFO,"All modules removed.  Exiting.");
+}
+
+/* very slow, make sure you cache the pointer! */
+void *ndlsym(char *modulename, char *fn) {
+  module *mods=(module *)(modules.content);
+  int i=getindex(modulename);
+
+  if (i<0)
+    return NULL;
+
+  return dlsym(mods[i].handle, fn);
+}