X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules.cpp;h=7ac4d2062aa3657d278a726bd6eb1777c69fc928;hb=551d687ec6d7ce44be35fae0dd7345fe73c4f63a;hp=b09639b2eaabd7ddd3e38b6d76066502bf61ac0b;hpb=927937d6105d17fbcd8c85bbf185477d87264bc4;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules.cpp b/src/modules.cpp index b09639b2e..7ac4d2062 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -109,7 +109,7 @@ ModResult Module::OnUserPreNotice(User*, void*, int, std::string&, char, CUList& ModResult Module::OnUserPreNick(User*, const std::string&) { return MOD_RES_PASSTHRU; } void Module::OnUserPostNick(User*, const std::string&) { } ModResult Module::OnPreMode(User*, User*, Channel*, const std::vector&) { return MOD_RES_PASSTHRU; } -void Module::On005Numeric(std::string&) { } +void Module::On005Numeric(std::map&) { } ModResult Module::OnKill(User*, User*, const std::string&) { return MOD_RES_PASSTHRU; } void Module::OnLoadModule(Module*) { } void Module::OnUnloadModule(Module*) { } @@ -331,13 +331,13 @@ bool ModuleManager::CanUnload(Module* mod) if (modfind == Modules.end() || modfind->second != mod) { LastModuleError = "Module " + mod->ModuleSourceFile + " is not loaded, cannot unload it!"; - ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); + ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, LastModuleError); return false; } if (mod->GetVersion().Flags & VF_STATIC) { LastModuleError = "Module " + mod->ModuleSourceFile + " not unloadable (marked static)"; - ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); + ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, LastModuleError); return false; } return true; @@ -345,6 +345,11 @@ bool ModuleManager::CanUnload(Module* mod) void ModuleManager::DoSafeUnload(Module* mod) { + // First, notify all modules that a module is about to be unloaded, so in case + // they pass execution to the soon to be unloaded module, it will happen now, + // i.e. before we unregister the services of the module being unloaded + FOREACH_MOD(I_OnUnloadModule,OnUnloadModule(mod)); + std::map::iterator modfind = Modules.find(mod->ModuleSourceFile); std::vector > items; @@ -368,10 +373,10 @@ void ModuleManager::DoSafeUnload(Module* mod) ModeHandler* mh; mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER); if (mh && mh->creator == mod) - ServerInstance->Modes->DelMode(mh); + this->DelService(*mh); mh = ServerInstance->Modes->FindMode(m, MODETYPE_CHANNEL); if (mh && mh->creator == mod) - ServerInstance->Modes->DelMode(mh); + this->DelService(*mh); } for(std::multimap::iterator i = DataProviders.begin(); i != DataProviders.end(); ) { @@ -385,16 +390,14 @@ void ModuleManager::DoSafeUnload(Module* mod) /* Tidy up any dangling resolvers */ ServerInstance->Res->CleanResolvers(mod); - FOREACH_MOD(I_OnUnloadModule,OnUnloadModule(mod)); - DetachAll(mod); Modules.erase(modfind); ServerInstance->GlobalCulls.AddItem(mod); - ServerInstance->Logs->Log("MODULE", DEFAULT,"Module %s unloaded",mod->ModuleSourceFile.c_str()); + ServerInstance->Logs->Log("MODULE", LOG_DEFAULT,"Module %s unloaded",mod->ModuleSourceFile.c_str()); this->ModCount--; - ServerInstance->BuildISupport(); + ServerInstance->ISupport.Build(); } void ModuleManager::UnloadAll() @@ -436,6 +439,8 @@ void ModuleManager::AddService(ServiceProvider& item) case SERVICE_MODE: if (!ServerInstance->Modes->AddMode(static_cast(&item))) throw ModuleException("Mode "+std::string(item.name)+" already exists."); + DataProviders.insert(std::make_pair("mode/" + item.name, &item)); + dynamic_reference_base::reset_all(); return; case SERVICE_METADATA: if (!ServerInstance->Extensions.Register(static_cast(&item))) @@ -444,6 +449,9 @@ void ModuleManager::AddService(ServiceProvider& item) case SERVICE_DATA: case SERVICE_IOHOOK: { + if (item.name.substr(0, 5) == "mode/") + throw ModuleException("The \"mode/\" service name prefix is reserved."); + DataProviders.insert(std::make_pair(item.name, &item)); std::string::size_type slash = item.name.find('/'); if (slash != std::string::npos) @@ -466,7 +474,7 @@ void ModuleManager::DelService(ServiceProvider& item) case SERVICE_MODE: if (!ServerInstance->Modes->DelMode(static_cast(&item))) throw ModuleException("Mode "+std::string(item.name)+" does not exist."); - return; + // Fall through case SERVICE_DATA: case SERVICE_IOHOOK: {