X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules.cpp;h=f940a0fd8948e20aaf0cf6ed53a99fd3a3eb50fa;hb=b4a174ee9c32d62ea6bf010e837e8c5b1c3d36a3;hp=2bb594a57bb3c1991b673f33c8c61384a36e29eb;hpb=8f62016f16cf2419817738904153cb3711b20d7e;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules.cpp b/src/modules.cpp index 2bb594a57..f940a0fd8 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -1,6 +1,7 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2020 Matt Schatz * Copyright (C) 2019 nia * Copyright (C) 2019 iwalkalone * Copyright (C) 2013, 2017-2020 Sadie Powell @@ -14,7 +15,7 @@ * Copyright (C) 2007-2008 Robin Burchell * Copyright (C) 2007 Oliver Lupton * Copyright (C) 2007 Dennis Friis - * Copyright (C) 2006-2010 Craig Edwards + * Copyright (C) 2005-2010 Craig Edwards * * 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 @@ -64,6 +65,8 @@ Module::Module() CullResult Module::cull() { + if (ModuleDLLManager) + ServerInstance->GlobalCulls.AddItem(ModuleDLLManager); return classbase::cull(); } @@ -129,18 +132,19 @@ void Module::OnUserInvite(User*, User*, Channel*, time_t, unsigned int, CUList& void Module::OnPostTopicChange(User*, Channel*, const std::string&) { DetachEvent(I_OnPostTopicChange); } void Module::OnDecodeMetaData(Extensible*, const std::string&, const std::string&) { DetachEvent(I_OnDecodeMetaData); } void Module::OnChangeHost(User*, const std::string&) { DetachEvent(I_OnChangeHost); } +void Module::OnChangeRealHost(User*, const std::string&) { DetachEvent(I_OnChangeRealHost); } void Module::OnChangeRealName(User*, const std::string&) { DetachEvent(I_OnChangeRealName); } void Module::OnChangeIdent(User*, const std::string&) { DetachEvent(I_OnChangeIdent); } void Module::OnAddLine(User*, XLine*) { DetachEvent(I_OnAddLine); } void Module::OnDelLine(User*, XLine*) { DetachEvent(I_OnDelLine); } void Module::OnExpireLine(XLine*) { DetachEvent(I_OnExpireLine); } -void Module::OnCleanup(ExtensionItem::ExtensibleType, Extensible*) { } +void Module::OnCleanup(ExtensionItem::ExtensibleType, Extensible*) { } ModResult Module::OnChannelPreDelete(Channel*) { DetachEvent(I_OnChannelPreDelete); return MOD_RES_PASSTHRU; } void Module::OnChannelDelete(Channel*) { DetachEvent(I_OnChannelDelete); } void Module::OnBuildNeighborList(User*, IncludeChanList&, std::map&) { DetachEvent(I_OnBuildNeighborList); } void Module::OnGarbageCollect() { DetachEvent(I_OnGarbageCollect); } ModResult Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { DetachEvent(I_OnSetConnectClass); return MOD_RES_PASSTHRU; } -void Module::OnUserMessage(User*, const MessageTarget&, const MessageDetails&) { DetachEvent(I_OnUserMessage); } +void Module::OnUserMessage(User*, const MessageTarget&, const MessageDetails&) { DetachEvent(I_OnUserMessage); } ModResult Module::OnNumeric(User*, const Numeric::Numeric&) { DetachEvent(I_OnNumeric); return MOD_RES_PASSTHRU; } ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { DetachEvent(I_OnAcceptConnection); return MOD_RES_PASSTHRU; } void Module::OnSetUserIP(LocalUser*) { DetachEvent(I_OnSetUserIP); } @@ -163,6 +167,26 @@ void ServiceProvider::DisableAutoRegister() stdalgo::erase(*ServerInstance->Modules->NewServices, this); } +const char* ServiceProvider::GetTypeString() const +{ + switch (service) + { + case SERVICE_COMMAND: + return "command"; + case SERVICE_MODE: + return "mode"; + case SERVICE_METADATA: + return "metadata"; + case SERVICE_IOHOOK: + return "iohook"; + case SERVICE_DATA: + return "data service"; + case SERVICE_CUSTOM: + return "module service"; + } + return "unknown service"; +} + ModuleManager::ModuleManager() { } @@ -232,7 +256,7 @@ bool ModuleManager::SetPriority(Module* mod, Implementation i, Priority s, Modul } /* Eh? this module doesnt exist, probably trying to set priority on an event - * theyre not attached to. + * they're not attached to. */ return false; @@ -313,7 +337,7 @@ swap_now: bool ModuleManager::PrioritizeHooks() { /* 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 + * not just the one that's loading, as the new module could affect the preference * of others */ for (int tries = 0; tries < 20; tries++) @@ -395,17 +419,20 @@ void ModuleManager::DoSafeUnload(Module* mod) for (user_hash::const_iterator u = users.begin(); u != users.end(); ) { User* user = u->second; - // The module may quit the user (e.g. SSL mod unloading) and that will remove it from the container + // The module may quit the user (e.g. TLS (SSL) mod unloading) and that will remove it from the container ++u; mod->OnCleanup(ExtensionItem::EXT_USER, user); user->doUnhookExtensions(items); } - for(std::multimap::iterator i = DataProviders.begin(); i != DataProviders.end(); ) + for (DataProviderMap::iterator i = DataProviders.begin(); i != DataProviders.end(); ) { - std::multimap::iterator curr = i++; + DataProviderMap::iterator curr = i++; if (curr->second->creator == mod) + { DataProviders.erase(curr); + FOREACH_MOD(OnServiceDel, (*curr->second)); + } } dynamic_reference_base::reset_all(); @@ -415,7 +442,7 @@ void ModuleManager::DoSafeUnload(Module* mod) Modules.erase(modfind); ServerInstance->GlobalCulls.AddItem(mod); - ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Module %s unloaded",mod->ModuleSourceFile.c_str()); + ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "The %s module was unloaded", mod->ModuleSourceFile.c_str()); ServerInstance->ISupport.Build(); } @@ -450,11 +477,8 @@ namespace UnloadAction(Module* m) : mod(m) {} void Call() CXX11_OVERRIDE { - DLLManager* dll = mod->ModuleDLLManager; ServerInstance->Modules->DoSafeUnload(mod); ServerInstance->GlobalCulls.Apply(); - // In pure static mode this is always NULL - delete dll; ServerInstance->GlobalCulls.AddItem(this); } }; @@ -478,13 +502,17 @@ void ModuleManager::LoadAll() for (ConfigIter i = tags.first; i != tags.second; ++i) { ConfigTag* tag = i->second; - std::string name = ExpandModName(tag->getString("name")); - this->NewServices = &servicemap[name]; + + const std::string shortname = tag->getString("name"); + if (shortname.empty()) + continue; // Skip malformed module tags. // Skip modules which are already loaded. + const std::string name = ExpandModName(shortname); if (Modules.find(name) != Modules.end()) continue; + this->NewServices = &servicemap[name]; std::cout << "[" << con_green << "*" << con_reset << "] Loading module:\t" << con_green << name << con_reset << std::endl; if (!this->Load(name, true)) { @@ -557,6 +585,8 @@ void ModuleManager::AddServices(const ServiceList& list) void ModuleManager::AddService(ServiceProvider& item) { + ServerInstance->Logs->Log("SERVICE", LOG_DEBUG, "Adding %s %s provided by %s", item.name.c_str(), + item.GetTypeString(), item.creator ? item.creator->ModuleSourceFile.c_str() : "the core"); switch (item.service) { case SERVICE_DATA: @@ -584,6 +614,8 @@ void ModuleManager::AddService(ServiceProvider& item) void ModuleManager::DelService(ServiceProvider& item) { + ServerInstance->Logs->Log("SERVICE", LOG_DEBUG, "Deleting %s %s provided by %s", item.name.c_str(), + item.GetTypeString(), item.creator ? item.creator->ModuleSourceFile.c_str() : "the core"); switch (item.service) { case SERVICE_MODE: @@ -594,7 +626,7 @@ void ModuleManager::DelService(ServiceProvider& item) case SERVICE_IOHOOK: { DelReferent(&item); - return; + break; } default: throw ModuleException("Cannot delete unknown service type"); @@ -610,7 +642,7 @@ ServiceProvider* ModuleManager::FindService(ServiceType type, const std::string& case SERVICE_DATA: case SERVICE_IOHOOK: { - std::multimap::iterator i = DataProviders.find(name); + DataProviderMap::iterator i = DataProviders.find(name); if (i != DataProviders.end() && i->second->service == type) return i->second; return NULL; @@ -623,12 +655,13 @@ ServiceProvider* ModuleManager::FindService(ServiceType type, const std::string& std::string ModuleManager::ExpandModName(const std::string& modname) { - // Transform "callerid" -> "m_callerid.so" unless it already has a ".so" extension, - // so coremods in the "core_*.so" form aren't changed - std::string ret = modname; - if ((modname.length() < 3) || (modname.compare(modname.size() - 3, 3, ".so"))) - ret.insert(0, "m_").append(".so"); - return ret; + std::string fullname; + if (modname.compare(0, 5, "core_") != 0 && modname.compare(0, 2, "m_") != 0) + fullname.append("m_"); + fullname.append(modname); + if (modname.length() < 3 || modname.compare(modname.size() - 3, 3, ".so") != 0) + fullname.append(".so"); + return fullname; } dynamic_reference_base::dynamic_reference_base(Module* Creator, const std::string& Name) @@ -663,7 +696,7 @@ void dynamic_reference_base::resolve() { // Because find() may return any element with a matching key in case count(key) > 1 use lower_bound() // to ensure a dynref with the same name as another one resolves to the same object - std::multimap::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name); + ModuleManager::DataProviderMap::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name); if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name)) { ServiceProvider* newvalue = i->second; @@ -696,7 +729,7 @@ void ModuleManager::AddReferent(const std::string& name, ServiceProvider* servic void ModuleManager::DelReferent(ServiceProvider* service) { - for (std::multimap::iterator i = DataProviders.begin(); i != DataProviders.end(); ) + for (DataProviderMap::iterator i = DataProviders.begin(); i != DataProviders.end(); ) { ServiceProvider* curr = i->second; if (curr == service)