fixed reloadmod command to use old module name (case insensitive reload)
[NeonServV5.git] / src / modules.c
index b8d3fec91cec76eb27d3d540531fd2e87fe5a95d..b848f6d3d13af756379039c3667edce98776d8f8 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;
 
@@ -273,7 +256,7 @@ static void unregister_module_hooks(int module_id);
 void loadModules() {
     char **modulelist = get_all_fieldnames("modules");
     int i = 0;
-    while(*modulelist[i]) {
+    while(modulelist[i]) {
         loadModule(modulelist[i]);
         i++;
     }
@@ -281,12 +264,16 @@ 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.a", name);
+    sprintf(fname, "%s.so", name);
     void* module = dlopen(fname, RTLD_LAZY);
     if(!module) {
-        sprintf(fname, ".libs/%s.a", name);
+        sprintf(fname, ".libs/%s.so", name);
         module = dlopen(fname, RTLD_LAZY);
         if(!module) {
             putlog(LOGLEVEL_ERROR, "Error loading module '%s': %s not found.\n", name, fname);
@@ -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,10 +340,45 @@ 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) {
+    char libname[256];
+    struct ModuleInfo *old_modinfo, *old_prev = NULL;
+    for(old_modinfo = modules; old_modinfo; old_modinfo = old_modinfo->next) {
+        if(!stricmp(old_modinfo->name, name)) {
+            strcpy(libname, old_modinfo->name);
             if(old_prev)
                 old_prev->next = old_modinfo->next;
             else
@@ -370,18 +392,22 @@ int reload_module(char *name) {
         } else
             old_prev = old_modinfo;
     }
-    if(!loadModule(name)) return 0;
+    if(!loadModule(libname)) 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);
+            ((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) {