]> jfr.im git - solanum.git/blobdiff - ircd/modules.c
ircd: serv_connect: don't try to connect if that would exceed the class limit
[solanum.git] / ircd / modules.c
index 43bf94f62d32550734f15f9317b36bebb984f6e9..ffa080774146376b07134bf55a4b37334bda5445 100644 (file)
@@ -43,7 +43,8 @@
 #      error "Charybdis requires loadable module support."
 #endif
 
-struct module **modlist = NULL;
+rb_dlink_list module_list;
+rb_dlink_list mod_paths;
 
 static const char *core_module_table[] = {
        "m_ban",
@@ -65,19 +66,13 @@ static const char *core_module_table[] = {
 
 #define MOD_WARN_DELTA (90 * 86400)    /* time in seconds, 86400 seconds in a day */
 
-#define MODS_INCREMENT 10
-int num_mods = 0;
-int max_mods = MODS_INCREMENT;
-
-static rb_dlink_list mod_paths;
-
 void
-modules_init(void)
+init_modules(void)
 {
        if(lt_dlinit())
        {
                ilog(L_MAIN, "lt_dlinit failed");
-               exit(0);
+               exit(EXIT_FAILURE);
        }
 
        /* Add the default paths we look in to the module system --nenolod */
@@ -153,25 +148,27 @@ mod_clear_paths(void)
  * output       - index of module on success, -1 on failure
  * side effects - none
  */
-int
+struct module *
 findmodule_byname(const char *name)
 {
-       int i;
+       rb_dlink_node *ptr;
        char name_ext[PATH_MAX + 1];
 
        rb_strlcpy(name_ext, name, sizeof name_ext);
        rb_strlcat(name_ext, LT_MODULE_EXT, sizeof name_ext);
 
-       for (i = 0; i < num_mods; i++)
+       RB_DLINK_FOREACH(ptr, module_list.head)
        {
-               if(!irccmp(modlist[i]->name, name))
-                       return i;
+               struct module *mod = ptr->data;
 
-               if(!irccmp(modlist[i]->name, name_ext))
-                       return i;
+               if(!irccmp(mod->name, name))
+                       return mod;
+
+               if(!irccmp(mod->name, name_ext))
+                       return mod;
        }
 
-       return -1;
+       return NULL;
 }
 
 /* load_all_modules()
@@ -188,12 +185,6 @@ load_all_modules(bool warn)
        char module_fq_name[PATH_MAX + 1];
        size_t module_ext_len = strlen(LT_MODULE_EXT);
 
-       modules_init();
-
-       modlist = (struct module **) rb_malloc(sizeof(struct module *) * (MODS_INCREMENT));
-
-       max_mods = MODS_INCREMENT;
-
        system_module_dir = opendir(ircd_paths[IRCD_PATH_AUTOLOAD_MODULES]);
 
        if(system_module_dir == NULL)
@@ -241,7 +232,7 @@ load_core_modules(bool warn)
                        ilog(L_MAIN,
                             "Error loading core module %s: terminating ircd",
                             core_module_table[i]);
-                       exit(0);
+                       exit(EXIT_FAILURE);
                }
        }
 }
@@ -285,10 +276,6 @@ load_one_module(const char *path, int origin, bool coremodule)
        return false;
 }
 
-static void increase_modlist(void);
-
-#define MODS_INCREMENT 10
-
 static char unknown_ver[] = "<unknown>";
 static char unknown_description[] = "<none>";
 
@@ -302,9 +289,12 @@ static char unknown_description[] = "<none>";
 bool
 unload_one_module(const char *name, bool warn)
 {
-       int modindex;
+       struct module *mod;
+
+       if((mod = findmodule_byname(name)) == NULL)
+               return false;
 
-       if((modindex = findmodule_byname(name)) == -1)
+       if(mod->core)
                return false;
 
        /*
@@ -318,11 +308,11 @@ unload_one_module(const char *name, bool warn)
         **          -jmallett
         */
        /* Left the comment in but the code isn't here any more         -larne */
-       switch (modlist[modindex]->mapi_version)
+       switch (mod->mapi_version)
        {
        case 1:
                {
-                       struct mapi_mheader_av1 *mheader = modlist[modindex]->mapi_header;
+                       struct mapi_mheader_av1 *mheader = mod->mapi_header;
                        if(mheader->mapi_command_list)
                        {
                                struct Message **m;
@@ -346,7 +336,7 @@ unload_one_module(const char *name, bool warn)
                }
        case 2:
                {
-                       struct mapi_mheader_av2 *mheader = modlist[modindex]->mapi_header;
+                       struct mapi_mheader_av2 *mheader = mod->mapi_header;
 
                        /* XXX duplicate code :( */
                        if(mheader->mapi_command_list)
@@ -387,10 +377,10 @@ unload_one_module(const char *name, bool warn)
                                        default:
                                                sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                                        "Unknown/unsupported CAP index found of type %d on capability %s when unloading %s",
-                                                       m->cap_index, m->cap_name, modlist[modindex]->name);
+                                                       m->cap_index, m->cap_name, mod->name);
                                                ilog(L_MAIN,
                                                        "Unknown/unsupported CAP index found of type %d on capability %s when unloading %s",
-                                                       m->cap_index, m->cap_name, modlist[modindex]->name);
+                                                       m->cap_index, m->cap_name, mod->name);
                                                continue;
                                        }
 
@@ -401,25 +391,22 @@ unload_one_module(const char *name, bool warn)
                                        }
                                }
                        }
+                       break;
                }
        default:
                sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                     "Unknown/unsupported MAPI version %d when unloading %s!",
-                                    modlist[modindex]->mapi_version, modlist[modindex]->name);
+                                    mod->mapi_version, mod->name);
                ilog(L_MAIN, "Unknown/unsupported MAPI version %d when unloading %s!",
-                    modlist[modindex]->mapi_version, modlist[modindex]->name);
+                    mod->mapi_version, mod->name);
                break;
        }
 
-       lt_dlclose(modlist[modindex]->address);
-
-       rb_free(modlist[modindex]->name);
-       rb_free(modlist[modindex]);
-       memmove(&modlist[modindex], &modlist[modindex + 1],
-              sizeof(struct module *) * ((num_mods - 1) - modindex));
+       lt_dlclose(mod->address);
 
-       if(num_mods != 0)
-               num_mods--;
+       rb_dlinkDelete(&mod->node, &module_list);
+       rb_free(mod->name);
+       rb_free(mod);
 
        if(warn)
        {
@@ -440,6 +427,7 @@ unload_one_module(const char *name, bool warn)
 bool
 load_a_module(const char *path, bool warn, int origin, bool core)
 {
+       struct module *mod;
        lt_dlhandle tmpptr;
        char *mod_displayname, *c;
        const char *ver, *description = NULL;
@@ -642,18 +630,16 @@ load_a_module(const char *path, bool warn, int origin, bool core)
        if(description == NULL)
                description = unknown_description;
 
-       increase_modlist();
-
-       modlist[num_mods] = rb_malloc(sizeof(struct module));
-       modlist[num_mods]->address = tmpptr;
-       modlist[num_mods]->version = ver;
-       modlist[num_mods]->description = description;
-       modlist[num_mods]->core = core;
-       modlist[num_mods]->name = rb_strdup(mod_displayname);
-       modlist[num_mods]->mapi_header = mapi_version;
-       modlist[num_mods]->mapi_version = MAPI_VERSION(*mapi_version);
-       modlist[num_mods]->origin = origin;
-       num_mods++;
+       mod = rb_malloc(sizeof(struct module));
+       mod->address = tmpptr;
+       mod->version = ver;
+       mod->description = description;
+       mod->core = core;
+       mod->name = rb_strdup(mod_displayname);
+       mod->mapi_header = mapi_version;
+       mod->mapi_version = MAPI_VERSION(*mapi_version);
+       mod->origin = origin;
+       rb_dlinkAdd(mod, &mod->node, &module_list);
 
        if(warn)
        {
@@ -683,26 +669,37 @@ load_a_module(const char *path, bool warn, int origin, bool core)
        return true;
 }
 
-/*
- * increase_modlist
- *
- * inputs      - NONE
- * output      - NONE
- * side effects        - expand the size of modlist if necessary
- */
-static void
-increase_modlist(void)
+void
+modules_do_restart(void *unused)
 {
-       struct module **new_modlist = NULL;
+       unsigned int modnum = 0;
+       rb_dlink_node *ptr, *nptr;
 
-       if((num_mods + 1) < max_mods)
-               return;
+       RB_DLINK_FOREACH_SAFE(ptr, nptr, module_list.head)
+       {
+               struct module *mod = ptr->data;
+               if(!unload_one_module(mod->name, false))
+               {
+                       ilog(L_MAIN, "Module Restart: %s was not unloaded %s",
+                            mod->name,
+                            mod->core? "(core module)" : "");
+
+                       if(!mod->core)
+                               sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+                                                      "Module Restart: %s failed to unload",
+                                                      mod->name);
+                       continue;
+               }
+
+               modnum++;
+       }
 
-       new_modlist = (struct module **) rb_malloc(sizeof(struct module *) *
-                                                 (max_mods + MODS_INCREMENT));
-       memcpy((void *) new_modlist, (void *) modlist, sizeof(struct module *) * num_mods);
+       load_all_modules(false);
+       load_core_modules(false);
+       rehash(false);
 
-       rb_free(modlist);
-       modlist = new_modlist;
-       max_mods += MODS_INCREMENT;
+       sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+                            "Module Restart: %u modules unloaded, %lu modules loaded",
+                            modnum, rb_dlink_list_length(&module_list));
+       ilog(L_MAIN, "Module Restart: %u modules unloaded, %lu modules loaded", modnum, rb_dlink_list_length(&module_list));
 }