+/*
+ * 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)
{
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
MODULE_INIT(AllModule)
-bool ModuleManager::Load(const std::string& name, bool)
+bool ModuleManager::Load(const std::string& name, bool defer)
{
- for(std::vector<AllModuleList*>::iterator i = modlist->begin(); i != modlist->end(); ++i)
+ modmap::iterator it = modlist->find(name);
+ if (it == modlist->end())
+ return false;
+ Module* mod = NULL;
+ try
{
- if ((**i).name == name)
+ mod = (*it->second->init)();
+ mod->ModuleSourceFile = name;
+ mod->ModuleDLLManager = NULL;
+ Modules[name] = mod;
+ if (defer)
{
- 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());
- }
+ ServerInstance->Logs->Log("MODULE", DEFAULT,"New module introduced: %s", name.c_str());
+ return true;
}
+ else
+ {
+ mod->init();
+ }
+ }
+ catch (CoreException& modexcept)
+ {
+ if (mod)
+ DoSafeUnload(mod);
+ ServerInstance->Logs->Log("MODULE", DEFAULT, "Unable to load " + name + ": " + modexcept.GetReason());
+ return false;
}
- return false;
+ FOREACH_MOD(I_OnLoadModule,OnLoadModule(mod));
+ /* 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 while loading " + name);
+ }
+
+ ServerInstance->BuildISupport();
+ return true;
}
namespace {
void ModuleManager::LoadAll()
{
- ModCount = 0;
- for(std::vector<AllModuleList*>::iterator i = modlist->begin(); i != modlist->end(); ++i)
+ Load("cmd_all", true);
+ Load("cmd_whowas.so", true);
+
+ ConfigTagList tags = ServerInstance->Config->ConfTags("module");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- Module* c = NULL;
- try
+ ConfigTag* tag = i->second;
+ std::string name = tag->getString("name");
+ std::cout << "[" << con_green << "*" << con_reset << "] Loading module:\t" << con_green << name << con_reset << std::endl;
+
+ if (!this->Load(name, true))
{
- c = (*(**i).init)();
- c->ModuleSourceFile = (**i).name;
- c->ModuleDLLManager = NULL;
- Modules[(**i).name] = c;
- c->init();
+ ServerInstance->Logs->Log("MODULE", DEFAULT, this->LastError());
+ std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << this->LastError() << std::endl << std::endl;
+ ServerInstance->Exit(EXIT_STATUS_MODULE);
+ }
+ }
+
+ for(std::map<std::string, Module*>::iterator i = Modules.begin(); i != Modules.end(); i++)
+ {
+ Module* mod = i->second;
+ try
+ {
+ mod->init();
}
catch (CoreException& modexcept)
{
- if (c)
- DoSafeUnload(c);
- delete c;
- ServerInstance->Logs->Log("MODULE", DEFAULT, "Unable to load " + (**i).name + ": " + modexcept.GetReason());
+ LastModuleError = "Unable to initialize " + mod->ModuleSourceFile + ": " + modexcept.GetReason();
+ ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
+ std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << LastModuleError << std::endl << std::endl;
+ ServerInstance->Exit(EXIT_STATUS_MODULE);
}
}
if (prioritizationState == PRIO_STATE_LAST)
break;
if (tries == 19)
+ {
ServerInstance->Logs->Log("MODULE", DEFAULT, "Hook priority dependency loop detected");
+ ServerInstance->Exit(EXIT_STATUS_MODULE);
+ }
}
-
- ServerInstance->BuildISupport();
-}
-
-void ModuleManager::UnloadAll()
-{
}
#endif