]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules.cpp
Make sure banredirect metadata can not be duplicated
[user/henk/code/inspircd.git] / src / modules.cpp
index 4e4d20c701b2630832636599ac0241a4717ccd61..79a33e6172599f5f618627c58e3413fc902991b9 100644 (file)
@@ -328,7 +328,7 @@ bool ModuleManager::CanUnload(Module* mod)
 {
        std::map<std::string, Module*>::iterator modfind = Modules.find(mod->ModuleSourceFile);
 
-       if (modfind == Modules.end() || modfind->second != mod)
+       if ((modfind == Modules.end()) || (modfind->second != mod) || (mod->dying))
        {
                LastModuleError = "Module " + mod->ModuleSourceFile + " is not loaded, cannot unload it!";
                ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
@@ -340,6 +340,8 @@ bool ModuleManager::CanUnload(Module* mod)
                ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
                return false;
        }
+
+       mod->dying = true;
        return true;
 }
 
@@ -350,18 +352,23 @@ void ModuleManager::DoSafeUnload(Module* mod)
        std::vector<reference<ExtensionItem> > items;
        ServerInstance->Extensions.BeginUnregister(modfind->second, items);
        /* Give the module a chance to tidy out all its metadata */
-       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
+       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); )
        {
-               mod->OnCleanup(TYPE_CHANNEL,c->second);
-               c->second->doUnhookExtensions(items);
-               const UserMembList* users = c->second->GetUsers();
+               Channel* chan = c->second;
+               ++c;
+               mod->OnCleanup(TYPE_CHANNEL, chan);
+               chan->doUnhookExtensions(items);
+               const UserMembList* users = chan->GetUsers();
                for(UserMembCIter mi = users->begin(); mi != users->end(); mi++)
                        mi->second->doUnhookExtensions(items);
        }
-       for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++)
+       for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); )
        {
-               mod->OnCleanup(TYPE_USER,u->second);
-               u->second->doUnhookExtensions(items);
+               User* user = u->second;
+               // The module may quit the user (e.g. SSL mod unloading) and that will remove it from the container
+               ++u;
+               mod->OnCleanup(TYPE_USER, user);
+               user->doUnhookExtensions(items);
        }
        for(char m='A'; m <= 'z'; m++)
        {
@@ -634,7 +641,8 @@ static ConfigTag* SlowGetTag(const std::string &tag, int index)
 std::string ConfigReader::ReadValue(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool allow_linefeeds)
 {
        std::string result = default_value;
-       if (!SlowGetTag(tag, index)->readString(name, result, allow_linefeeds))
+       ConfigTag* conftag = SlowGetTag(tag, index);
+       if (!conftag || !conftag->readString(name, result, allow_linefeeds))
        {
                this->error = CONF_VALUE_NOT_FOUND;
        }
@@ -649,7 +657,8 @@ std::string ConfigReader::ReadValue(const std::string &tag, const std::string &n
 bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, const std::string &default_value, int index)
 {
        bool def = (default_value == "yes");
-       return SlowGetTag(tag, index)->getBool(name, def);
+       ConfigTag* conftag = SlowGetTag(tag, index);
+       return conftag ? conftag->getBool(name, def) : def;
 }
 
 bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, int index)
@@ -661,7 +670,8 @@ bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, int
 int ConfigReader::ReadInteger(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool need_positive)
 {
        int v = atoi(default_value.c_str());
-       int result = SlowGetTag(tag, index)->getInt(name, v);
+       ConfigTag* conftag = SlowGetTag(tag, index);
+       int result = conftag ? conftag->getInt(name, v) : v;
 
        if ((need_positive) && (result < 0))
        {
@@ -763,7 +773,7 @@ bool FileReader::Exists()
 
 std::string FileReader::GetLine(int x)
 {
-       if ((x<0) || ((unsigned)x>fc.size()))
+       if ((x<0) || ((unsigned)x>=fc.size()))
                return "";
        return fc[x];
 }