added module management commands
[NeonServV5.git] / src / modules.c
index dc3f59842aec364da536a1c144de5b4595bdf274..53ff4afc4e6463f0fa3053420e070a491e025489 100644 (file)
@@ -248,23 +248,6 @@ void *global_functions[] = {
 /* 188 */ (Function) get_patchlevel
 };
 
-#define MODINFO_STATE_STARTED 0x01
-
-struct ModuleInfo {
-    char *name;
-    int module_id;
-    #ifndef WIN32
-    void *module;
-    #else
-    HMODULE module;
-    #endif
-    int state;
-    void *startfunc;
-    void *loopfunc;
-    void *stopfunc;
-    struct ModuleInfo *next;
-};
-
 static int module_id_counter = 1;
 static struct ModuleInfo *modules = NULL;
 
@@ -281,6 +264,10 @@ void loadModules() {
 }
 
 int loadModule(char *name) {
+    struct ModuleInfo *modinfo;
+    for(modinfo = modules; modinfo; modinfo = modinfo->next) {
+        if(!stricmp(modinfo->name, name)) return 0;
+    }
     char fname[256];
     #ifndef WIN32
     sprintf(fname, "%s.so", name);
@@ -327,7 +314,7 @@ int loadModule(char *name) {
         putlog(LOGLEVEL_ERROR, "Error loading module '%s': module reported error (errid: %d)\n", name, errid);
         return 0;
     }
-    struct ModuleInfo *modinfo = malloc(sizeof(*modinfo));
+    modinfo = malloc(sizeof(*modinfo));
     if(!modinfo) {
         unregister_module_hooks(module_id);
         return 0;
@@ -353,7 +340,40 @@ static void closemodule(HMODULE module) {
 }
 #endif
 
-int reload_module(char *name) {
+int ext_load_module(char *name) {
+    if(!loadModule(name)) return 0;
+    struct ModuleInfo *modinfo;
+    for(modinfo = modules; modinfo; modinfo = modinfo->next) {
+        if(!(modinfo->state & MODINFO_STATE_STARTED)) {
+            modinfo->state |= MODINFO_STATE_STARTED;
+            ((void (*)(int)) modinfo->startfunc)(MODSTATE_STARTSTOP);
+        } else
+            ((void (*)(int)) modinfo->startfunc)(MODSTATE_REBIND);
+    }
+    return 1;
+}
+
+int ext_unload_module(char *name) {
+    struct ModuleInfo *old_modinfo, *old_prev = NULL;
+    for(old_modinfo = modules; old_modinfo; old_modinfo = old_modinfo->next) {
+        if(!stricmp(old_modinfo->name, name)) {
+            if(old_prev)
+                old_prev->next = old_modinfo->next;
+            else
+                modules = old_modinfo->next;
+            unregister_module_hooks(old_modinfo->module_id);
+            ((void (*)(int)) old_modinfo->stopfunc)(MODSTATE_STARTSTOP);
+            closemodule(old_modinfo->module);
+            free(old_modinfo->name);
+            free(old_modinfo);
+            return 1;
+        } else
+            old_prev = old_modinfo;
+    }
+    return 0;
+}
+
+int ext_reload_module(char *name) {
     struct ModuleInfo *old_modinfo, *old_prev = NULL;
     for(old_modinfo = modules; old_modinfo; old_modinfo = old_modinfo->next) {
         if(!stricmp(old_modinfo->name, name)) {
@@ -375,13 +395,17 @@ int reload_module(char *name) {
     for(modinfo = modules; modinfo; modinfo = modinfo->next) {
         if(!(modinfo->state & MODINFO_STATE_STARTED)) {
             modinfo->state |= MODINFO_STATE_STARTED;
-            ((void (*)(int)) modinfo->startfunc)(MODSTATE_STARTSTOP);
+            ((void (*)(int)) modinfo->startfunc)(MODSTATE_RELOAD);
         } else
             ((void (*)(int)) modinfo->startfunc)(MODSTATE_REBIND);
     }
     return 1;
 }
 
+struct ModuleInfo *ext_get_modules(struct ModuleInfo *last) {
+    return (last ? last->next : modules);
+}
+
 void start_modules() {
     struct ModuleInfo *modinfo;
     for(modinfo = modules; modinfo; modinfo = modinfo->next) {