diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/inspircd.cpp | 11 | ||||
-rw-r--r-- | src/modules.cpp | 42 | ||||
-rw-r--r-- | src/modules/m_cloaking.cpp | 5 | ||||
-rw-r--r-- | src/modules/m_oper_hash.cpp | 3 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 4 |
5 files changed, 58 insertions, 7 deletions
diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 12134f3f6..e7801f1d5 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -505,6 +505,17 @@ bool InspIRCd::UnloadModule(const char* filename) snprintf(MODERR,MAXBUF,"Module not unloadable (marked static)"); return false; } + std::pair<int,std::string> intercount = GetInterfaceInstanceCount(modules[j]); + if (intercount.first > 0) + { + this->Log(DEFAULT,"Failed to unload module %s, being used by %d other(s) via interface '%s'",filename, intercount.first, intercount.second.c_str()); + snprintf(MODERR,MAXBUF,"Module not unloadable (Still in use by %d other module%s which %s using its interface '%s') -- unload dependent modules first!", + intercount.first, + intercount.first > 1 ? "s" : "", + intercount.first > 1 ? "are" : "is", + intercount.second.c_str()); + return false; + } /* Give the module a chance to tidy out all its metadata */ for (chan_hash::iterator c = this->chanlist.begin(); c != this->chanlist.end(); c++) { diff --git a/src/modules.cpp b/src/modules.cpp index 4ae033c8b..b670291ec 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -258,12 +258,12 @@ bool InspIRCd::PublishInterface(const std::string &InterfaceName, Module* Mod) { modulelist ml; ml.push_back(Mod); - Interfaces[InterfaceName] = ml; + Interfaces[InterfaceName] = std::make_pair(0, ml); return true; } else { - iter->second.push_back(Mod); + iter->second.second.push_back(Mod); return true; } return false; @@ -276,12 +276,12 @@ bool InspIRCd::UnpublishInterface(const std::string &InterfaceName, Module* Mod) if (iter == Interfaces.end()) return false; - for (modulelist::iterator x = iter->second.begin(); x != iter->second.end(); x++) + for (modulelist::iterator x = iter->second.second.begin(); x != iter->second.second.end(); x++) { if (*x == Mod) { - iter->second.erase(x); - if (iter->second.empty()) + iter->second.second.erase(x); + if (iter->second.second.empty()) Interfaces.erase(InterfaceName); return true; } @@ -295,7 +295,37 @@ modulelist* InspIRCd::FindInterface(const std::string &InterfaceName) if (iter == Interfaces.end()) return NULL; else - return &(iter->second); + return &(iter->second.second); +} + +void InspIRCd::UseInterface(const std::string &InterfaceName) +{ + interfacelist::iterator iter = Interfaces.find(InterfaceName); + if (iter != Interfaces.end()) + iter->second.first++; + +} + +void InspIRCd::DoneWithInterface(const std::string &InterfaceName) +{ + interfacelist::iterator iter = Interfaces.find(InterfaceName); + if (iter != Interfaces.end()) + iter->second.first--; +} + +std::pair<int,std::string> InspIRCd::GetInterfaceInstanceCount(Module* m) +{ + for (interfacelist::iterator iter = Interfaces.begin(); iter != Interfaces.end(); iter++) + { + for (modulelist::iterator x = iter->second.second.begin(); x != iter->second.second.end(); x++) + { + if (*x == m) + { + return std::make_pair(iter->second.first, iter->first); + } + } + } + return std::make_pair(0, ""); } const std::string& InspIRCd::GetModuleName(Module* m) diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index ffa189007..a32f7348d 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -230,7 +230,9 @@ class ModuleCloaking : public Module ModuleCloaking(InspIRCd* Me) : Module::Module(Me) { - /* Attempt to locate the Hash service provider, bail if we can't find it */ + ServerInstance->UseInterface("HashRequest"); + + /* Attempt to locate the md5 service provider, bail if we can't find it */ HashModule = ServerInstance->FindModule("m_md5.so"); if (!HashModule) throw ModuleException("Can't find m_md5.so. Please load m_md5.so before m_cloaking.so."); @@ -248,6 +250,7 @@ class ModuleCloaking : public Module { ServerInstance->Modes->DelMode(cu); DELETE(cu); + ServerInstance->DoneWithInterface("HashRequest"); } virtual Version GetVersion() diff --git a/src/modules/m_oper_hash.cpp b/src/modules/m_oper_hash.cpp index b9e246c2b..61a43b1e1 100644 --- a/src/modules/m_oper_hash.cpp +++ b/src/modules/m_oper_hash.cpp @@ -91,6 +91,8 @@ class ModuleOperHash : public Module Conf = NULL; OnRehash(""); + ServerInstance->UseInterface("HashRequest"); + /* Find all modules which implement the interface 'HashRequest' */ modulelist* ml = ServerInstance->FindInterface("HashRequest"); @@ -121,6 +123,7 @@ class ModuleOperHash : public Module virtual ~ModuleOperHash() { + ServerInstance->DoneWithInterface("HashRequest"); } void Implements(char* List) diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index c0d2d7428..ef7e17820 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -4188,6 +4188,8 @@ class ModuleSpanningTree : public Module ModuleSpanningTree(InspIRCd* Me) : Module::Module(Me), max_local(0), max_global(0) { + ServerInstance->UseInterface("InspSocketHook"); + Utils = new SpanningTreeUtilities(Me, this); command_rconnect = new cmd_rconnect(ServerInstance, this, Utils); @@ -5402,6 +5404,8 @@ class ModuleSpanningTree : public Module delete Utils; if (SyncTimer) ServerInstance->Timers->DelTimer(SyncTimer); + + ServerInstance->DoneWithInterface("InspSocketHook"); } virtual Version GetVersion() |