X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules.cpp;h=b2d2f23c68af1acf45b429bd3de819298f0393de;hb=4e3d7a6e30eadf714483994681b8b2534229f4a8;hp=5f1081a1c529ad935466857116918dd4ef6215b2;hpb=46a39046196f55b52336e19662bb7bac85b731ac;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules.cpp b/src/modules.cpp index 5f1081a1c..b2d2f23c6 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -32,7 +32,7 @@ #include "dns.h" #include "exitcodes.h" -#ifndef WIN32 +#ifndef _WIN32 #include #endif @@ -176,6 +176,7 @@ ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MO void Module::OnHookIO(StreamSocket*, ListenSocket*) { } ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; } void Module::OnSendWhoLine(User*, const std::vector&, User*, std::string&) { } +void Module::OnSetUserIP(LocalUser*) { } ModuleManager::ModuleManager() : ModCount(0) { @@ -313,7 +314,7 @@ swap_now: for (unsigned int j = my_pos; j != swap_pos; j += incrmnt) { - if (( j + incrmnt > EventHandlers[i].size() - 1) || (j + incrmnt < 0)) + if ((j + incrmnt > EventHandlers[i].size() - 1) || ((incrmnt == -1) && (j == 0))) continue; std::swap(EventHandlers[i][j], EventHandlers[i][j+incrmnt]); @@ -327,7 +328,7 @@ bool ModuleManager::CanUnload(Module* mod) { std::map::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); @@ -339,6 +340,8 @@ bool ModuleManager::CanUnload(Module* mod) ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); return false; } + + mod->dying = true; return true; } @@ -349,18 +352,23 @@ void ModuleManager::DoSafeUnload(Module* mod) std::vector > 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++) { @@ -447,7 +455,8 @@ void ModuleManager::AddService(ServiceProvider& item) throw ModuleException("Mode "+std::string(item.name)+" already exists."); return; case SERVICE_METADATA: - ServerInstance->Extensions.Register(static_cast(&item)); + if (!ServerInstance->Extensions.Register(static_cast(&item))) + throw ModuleException("Extension " + std::string(item.name) + " already exists."); return; case SERVICE_DATA: case SERVICE_IOHOOK: @@ -557,7 +566,7 @@ dynamic_reference_base::operator bool() if (i != ServerInstance->Modules->DataProviders.end()) value = static_cast(i->second); } - return value; + return (value != NULL); } void InspIRCd::SendMode(const std::vector& parameters, User *user) @@ -761,7 +770,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]; }