]> jfr.im git - solanum.git/blobdiff - modules/core/m_modules.c
Remove shared blocks
[solanum.git] / modules / core / m_modules.c
index 36233a751a4270fbeb46be5d6ec6d0599cc8eab0..51f453a09e345aabbda59410c71740645b9cd9c5 100644 (file)
@@ -54,6 +54,9 @@ static void do_modreload(struct Client *, const char *);
 static void do_modlist(struct Client *, const char *);
 static void do_modrestart(struct Client *);
 
+extern void modules_do_reload(void *); /* end of ircd/modules.c */
+extern void modules_do_restart(void *); /* end of ircd/modules.c */
+
 struct Message modload_msgtab = {
        "MODLOAD", 0, 0, 0, 0,
        {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_modload, 2}, {mo_modload, 2}}
@@ -108,13 +111,6 @@ mo_modload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sour
 static void
 me_modload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv)
 {
-       if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
-       {
-               sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
-                               "to load modules on this server.");
-               return;
-       }
-
        do_modload(source_p, parv[1]);
 }
 
@@ -144,13 +140,6 @@ mo_modunload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *so
 static void
 me_modunload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv)
 {
-       if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
-       {
-               sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
-                               "to load modules on this server.");
-               return;
-       }
-
        do_modunload(source_p, parv[1]);
 }
 
@@ -179,13 +168,6 @@ mo_modreload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *so
 static void
 me_modreload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv)
 {
-       if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
-       {
-               sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
-                               "to load modules on this server.");
-               return;
-       }
-
        do_modreload(source_p, parv[1]);
 }
 
@@ -214,13 +196,6 @@ mo_modlist(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sour
 static void
 me_modlist(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv)
 {
-       if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
-       {
-               sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
-                               "to load modules on this server.");
-               return;
-       }
-
        do_modlist(source_p, parv[1]);
 }
 
@@ -249,13 +224,6 @@ mo_modrestart(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *s
 static void
 me_modrestart(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv)
 {
-       if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE))
-       {
-               sendto_one_notice(source_p, ":*** You do not have an appropriate shared block "
-                               "to load modules on this server.");
-               return;
-       }
-
        do_modrestart(source_p);
 }
 
@@ -265,109 +233,90 @@ do_modload(struct Client *source_p, const char *module)
        char *m_bn = rb_basename(module);
        int origin;
 
-       if(findmodule_byname(m_bn) != -1)
+       if(findmodule_byname(m_bn) != NULL)
        {
                sendto_one_notice(source_p, ":Module %s is already loaded", m_bn);
                rb_free(m_bn);
                return;
        }
 
+       mod_remember_clicaps();
+
        origin = strcmp(module, m_bn) == 0 ? MAPI_ORIGIN_CORE : MAPI_ORIGIN_EXTENSION;
        load_one_module(module, origin, false);
 
+       mod_notify_clicaps();
+
        rb_free(m_bn);
 }
 
 static void
 do_modunload(struct Client *source_p, const char *module)
 {
-       int modindex;
+       struct module *mod;
        char *m_bn = rb_basename(module);
 
-       if((modindex = findmodule_byname(m_bn)) == -1)
+       if((mod = findmodule_byname(m_bn)) == NULL)
        {
                sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
                rb_free(m_bn);
                return;
        }
 
-       if(modlist[modindex]->core)
+       if(mod->core)
        {
                sendto_one_notice(source_p, ":Module %s is a core module and may not be unloaded", m_bn);
                rb_free(m_bn);
                return;
        }
 
+       mod_remember_clicaps();
+
        if(unload_one_module(m_bn, true) == false)
                sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
 
+       mod_notify_clicaps();
+
        rb_free(m_bn);
 }
 
 static void
 do_modreload(struct Client *source_p, const char *module)
 {
-       int modindex;
-       int check_core;
-       char *m_bn = rb_basename(module);
-
-       if((modindex = findmodule_byname(m_bn)) == -1)
-       {
-               sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
-               rb_free(m_bn);
-               return;
-       }
-
-       check_core = modlist[modindex]->core;
-
-       if(unload_one_module(m_bn, true) == false)
-       {
-               sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
-               rb_free(m_bn);
-               return;
-       }
-
-       if((load_one_module(m_bn, modlist[modindex]->origin, check_core) == false) && check_core)
-       {
-               sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
-                                    "Error reloading core module: %s: terminating ircd", m_bn);
-               ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn);
-               exit(0);
-       }
-
-       rb_free(m_bn);
+       struct modreload *info = rb_malloc(sizeof *info);
+       strcpy(info->module, module);
+       strcpy(info->id, source_p->id);
+       rb_event_addonce("modules_do_reload", modules_do_reload, info, 1);
 }
 
 static void
 do_modrestart(struct Client *source_p)
 {
-       int modnum;
-
        sendto_one_notice(source_p, ":Reloading all modules");
 
-       modnum = num_mods;
-       while (num_mods)
-               unload_one_module(modlist[0]->name, false);
-
-       load_all_modules(false);
-       load_core_modules(false);
-       rehash(false);
-
-       sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
-                            "Module Restart: %d modules unloaded, %d modules loaded",
-                            modnum, num_mods);
-       ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods);
+       /*
+        * If a remote MODRESTART is received, m_encap.so will be reloaded,
+        * but ms_encap is in the call stack (it indirectly calls this
+        * function). Also, this function is itself in a module.
+        *
+        * This will go horribly wrong if either module is reloaded to a
+        * different address.
+        *
+        * So, defer the restart to the event loop and return now.
+        */
+       rb_event_addonce("modules_do_restart", modules_do_restart, NULL, 1);
 }
 
 static void
 do_modlist(struct Client *source_p, const char *pattern)
 {
-       int i;
+       rb_dlink_node *ptr;
 
-       for (i = 0; i < num_mods; i++)
+       RB_DLINK_FOREACH(ptr, module_list.head)
        {
+               struct module *mod = ptr->data;
                const char *origin;
-               switch (modlist[i]->origin)
+               switch (mod->origin)
                {
                case MAPI_ORIGIN_EXTENSION:
                        origin = "extension";
@@ -382,21 +331,21 @@ do_modlist(struct Client *source_p, const char *pattern)
 
                if(pattern)
                {
-                       if(match(pattern, modlist[i]->name))
+                       if(match(pattern, mod->name))
                        {
                                sendto_one(source_p, form_str(RPL_MODLIST),
                                           me.name, source_p->name,
-                                          modlist[i]->name,
-                                          (unsigned long)(uintptr_t)modlist[i]->address, origin,
-                                          modlist[i]->core ? " (core)" : "", modlist[i]->version, modlist[i]->description);
+                                          mod->name,
+                                          (unsigned long)(uintptr_t)mod->address, origin,
+                                          mod->core ? " (core)" : "", mod->version, mod->description);
                        }
                }
                else
                {
                        sendto_one(source_p, form_str(RPL_MODLIST),
-                                  me.name, source_p->name, modlist[i]->name,
-                                  (unsigned long)(uintptr_t)modlist[i]->address, origin,
-                                  modlist[i]->core ? " (core)" : "", modlist[i]->version, modlist[i]->description);
+                                  me.name, source_p->name, mod->name,
+                                  (unsigned long)(uintptr_t)mod->address, origin,
+                                  mod->core ? " (core)" : "", mod->version, mod->description);
                }
        }