]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modmanager_static.cpp
Merge pull request #971 from SaberUK/master+numeric-xline
[user/henk/code/inspircd.git] / src / modmanager_static.cpp
index d9ee07a257a7190754c299a76e4986b9da42da6e..ac127b7031b2d5f0e8a61ec56f111396a2e4a3c3 100644 (file)
@@ -1,9 +1,33 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *
+ * This file is part of InspIRCd.  InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define MODNAME "cmd_all"
+
 #include "inspircd.h"
+#include "exitcodes.h"
+#include <iostream>
 
 #ifdef PURE_STATIC
 
+typedef std::map<std::string, AllModuleList*> modmap;
 static std::vector<AllCommandList::fn>* cmdlist = NULL;
-static std::vector<AllModuleList*>* modlist = NULL;
+static modmap* modlist = NULL;
 
 AllCommandList::AllCommandList(fn cmd)
 {
@@ -15,8 +39,8 @@ AllCommandList::AllCommandList(fn cmd)
 AllModuleList::AllModuleList(AllModuleList::fn mod, const std::string& Name) : init(mod), name(Name)
 {
        if (!modlist)
-               modlist = new std::vector<AllModuleList*>();
-       modlist->push_back(this);
+               modlist = new modmap();
+       modlist->insert(std::make_pair(Name, this));
 }
 
 class AllModule : public Module
@@ -34,7 +58,6 @@ class AllModule : public Module
                        {
                                Command* c = (*i)(this);
                                cmds.push_back(c);
-                               ServerInstance->AddCommand(c);
                        }
                }
                catch (...)
@@ -46,8 +69,7 @@ class AllModule : public Module
 
        ~AllModule()
        {
-               for(std::vector<Command*>::iterator i = cmds.begin(); i != cmds.end(); ++i)
-                       delete *i;
+               stdalgo::delete_all(cmds);
        }
 
        Version GetVersion()
@@ -58,126 +80,68 @@ class AllModule : public Module
 
 MODULE_INIT(AllModule)
 
-bool ModuleManager::Load(const char* name)
+bool ModuleManager::Load(const std::string& name, bool defer)
 {
-       for(std::vector<AllModuleList*>::iterator i = modlist->begin(); i != modlist->end(); ++i)
-       {
-               if ((**i).name == name)
-               {
-                       Module* c = NULL;
-                       try
-                       {
-                               c = (*(**i).init)();
-                               Modules[name] = c;
-                               c->init();
-                               FOREACH_MOD(I_OnLoadModule,OnLoadModule(c));
-                               return true;
-                       }
-                       catch (CoreException& modexcept)
-                       {
-                               if (c)
-                                       DoSafeUnload(c);
-                               delete c;
-                               ServerInstance->Logs->Log("MODULE", DEFAULT, "Unable to load " + (**i).name + ": " + modexcept.GetReason());
-                       }
-               }
-       }
-       return false;
-}
+       modmap::iterator it = modlist->find(name);
+       if (it == modlist->end())
+               return false;
+       Module* mod = NULL;
 
-namespace {
-       struct UnloadAction : public HandlerBase0<void>
+       ServiceList newservices;
+       if (!defer)
+               this->NewServices = &newservices;
+
+       try
        {
-               Module* const mod;
-               UnloadAction(Module* m) : mod(m) {}
-               void Call()
+               mod = (*it->second->init)();
+               mod->ModuleSourceFile = name;
+               mod->ModuleDLLManager = NULL;
+               mod->dying = false;
+               Modules[name] = mod;
+               this->NewServices = NULL;
+               if (defer)
                {
-                       ServerInstance->Modules->DoSafeUnload(mod);
-                       ServerInstance->GlobalCulls.Apply();
-                       ServerInstance->GlobalCulls.AddItem(this);
+                       ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "New module introduced: %s", name.c_str());
+                       return true;
                }
-       };
-
-       struct ReloadAction : public HandlerBase0<void>
-       {
-               Module* const mod;
-               HandlerBase1<void, bool>* const callback;
-               ReloadAction(Module* m, HandlerBase1<void, bool>* c)
-                       : mod(m), callback(c) {}
-               void Call()
+               else
                {
-                       std::string name = mod->ModuleSourceFile;
-                       ServerInstance->Modules->DoSafeUnload(mod);
-                       ServerInstance->GlobalCulls.Apply();
-                       bool rv = ServerInstance->Modules->Load(name.c_str());
-                       callback->Call(rv);
-                       ServerInstance->GlobalCulls.AddItem(this);
+                       ConfigStatus confstatus;
+
+                       AttachAll(mod);
+                       AddServices(newservices);
+                       mod->init();
+                       mod->ReadConfig(confstatus);
                }
-       };
-}
+       }
+       catch (CoreException& modexcept)
+       {
+               this->NewServices = NULL;
 
-bool ModuleManager::Unload(Module* mod)
-{
-       if (!CanUnload(mod))
+               if (mod)
+                       DoSafeUnload(mod);
+               ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Unable to load " + name + ": " + modexcept.GetReason());
                return false;
-       ServerInstance->AtomicActions.AddAction(new UnloadAction(mod));
-       return true;
-}
+       }
 
-void ModuleManager::Reload(Module* mod, HandlerBase1<void, bool>* callback)
-{
-       if (CanUnload(mod))
-               ServerInstance->AtomicActions.AddAction(new ReloadAction(mod, callback));
-       else
-               callback->Call(false);
+       FOREACH_MOD(OnLoadModule, (mod));
+       PrioritizeHooks();
+       ServerInstance->ISupport.Build();
+       return true;
 }
 
-void ModuleManager::LoadAll()
+void ModuleManager::LoadCoreModules(std::map<std::string, ServiceList>& servicemap)
 {
-       ModCount = 0;
-       for(std::vector<AllModuleList*>::iterator i = modlist->begin(); i != modlist->end(); ++i)
+       for (modmap::const_iterator i = modlist->begin(); i != modlist->end(); ++i)
        {
-               Module* c = NULL;
-               try
+               const std::string modname = i->first;
+               if (modname[0] == 'c')
                {
-                       c = (*(**i).init)();
-                       c->ModuleSourceFile = (**i).name;
-                       c->ModuleDLLManager = NULL;
-                       Modules[(**i).name] = c;
-                       c->init();
-                       FOREACH_MOD(I_OnLoadModule,OnLoadModule(c));
+                       this->NewServices = &servicemap[modname];
+                       Load(modname, true);
                }
-               catch (CoreException& modexcept)
-               {
-                       if (c)
-                               DoSafeUnload(c);
-                       delete c;
-                       ServerInstance->Logs->Log("MODULE", DEFAULT, "Unable to load " + (**i).name + ": " + modexcept.GetReason());
-               }
-       }
-
-       /* We give every module a chance to re-prioritize when we introduce a new one,
-        * not just the one thats loading, as the new module could affect the preference
-        * of others
-        */
-       for(int tries = 0; tries < 20; tries++)
-       {
-               prioritizationState = tries > 0 ? PRIO_STATE_LAST : PRIO_STATE_FIRST;
-               for (std::map<std::string, Module*>::iterator n = Modules.begin(); n != Modules.end(); ++n)
-                       n->second->Prioritize();
-
-               if (prioritizationState == PRIO_STATE_LAST)
-                       break;
-               if (tries == 19)
-                       ServerInstance->Logs->Log("MODULE", DEFAULT, "Hook priority dependency loop detected");
        }
-
-       ServerInstance->BuildISupport();
-}
-
-void ModuleManager::UnloadAll()
-{
-       // TODO don't really need this, who cares if we leak on exit?
+       this->NewServices = NULL;
 }
 
 #endif