From e07a1a5ffab0a54ff04a7ff93b8c25c69992bf81 Mon Sep 17 00:00:00 2001 From: danieldg Date: Wed, 2 Sep 2009 00:47:14 +0000 Subject: Add VF_OPTCOMMON for optionally common modules git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11619 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/modules/m_spanningtree/capab.cpp | 66 ++++++++++++++++++++++++++---- src/modules/m_spanningtree/treesocket.h | 8 ++-- src/modules/m_spanningtree/treesocket1.cpp | 1 + 3 files changed, 63 insertions(+), 12 deletions(-) (limited to 'src/modules/m_spanningtree') diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp index a1980790f..cd8564892 100644 --- a/src/modules/m_spanningtree/capab.cpp +++ b/src/modules/m_spanningtree/capab.cpp @@ -22,9 +22,9 @@ /* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ -std::string TreeSocket::MyCapabilities() +std::string TreeSocket::MyModules(int filter) { - std::vector modlist = this->ServerInstance->Modules->GetAllModuleNames(VF_COMMON); + std::vector modlist = this->ServerInstance->Modules->GetAllModuleNames(filter); std::string capabilities; sort(modlist.begin(),modlist.end()); for (unsigned int i = 0; i < modlist.size(); i++) @@ -42,7 +42,8 @@ void TreeSocket::SendCapabilities() return; sentcapab = true; - irc::commasepstream modulelist(MyCapabilities()); + irc::commasepstream modulelist(MyModules(VF_COMMON)); + irc::commasepstream optmodulelist(MyModules(VF_OPTCOMMON)); this->WriteLine("CAPAB START"); /* Send module names, split at 509 length */ @@ -64,6 +65,24 @@ void TreeSocket::SendCapabilities() if (line != "CAPAB MODULES ") this->WriteLine(line); + line = "CAPAB MODSUPPORT "; + while (optmodulelist.GetToken(item)) + { + if (line.length() + item.length() + 1 > 509) + { + this->WriteLine(line); + line = "CAPAB MODSUPPORT "; + } + + if (line != "CAPAB MODSUPPORT ") + line.append(","); + + line.append(item); + } + if (line != "CAPAB MODSUPPORT ") + this->WriteLine(line); + + int ip6 = 0; #ifdef IPV6 ip6 = 1; @@ -138,17 +157,18 @@ bool TreeSocket::Capab(const parameterlist ¶ms) } if (params[0] == "START") { - this->ModuleList.clear(); - this->CapKeys.clear(); + ModuleList.clear(); + OptModuleList.clear(); + CapKeys.clear(); } else if (params[0] == "END") { std::string reason; /* Compare ModuleList and check CapKeys */ - if ((this->ModuleList != this->MyCapabilities()) && (this->ModuleList.length())) + if ((this->ModuleList != this->MyModules(VF_COMMON)) && (this->ModuleList.length())) { - std::string diffIneed = ListDifference(this->ModuleList, this->MyCapabilities()); - std::string diffUneed = ListDifference(this->MyCapabilities(), this->ModuleList); + std::string diffIneed = ListDifference(this->ModuleList, this->MyModules(VF_COMMON)); + std::string diffUneed = ListDifference(this->MyModules(VF_COMMON), this->ModuleList); if (diffIneed.length() == 0 && diffUneed.length() == 0) { reason = "Module list in CAPAB is not alphabetically ordered, cannot compare lists."; @@ -164,6 +184,23 @@ bool TreeSocket::Capab(const parameterlist ¶ms) this->SendError("CAPAB negotiation failed: "+reason); return false; } + if (this->OptModuleList != this->MyModules(VF_OPTCOMMON) && this->OptModuleList.length()) + { + std::string diffIneed = ListDifference(this->OptModuleList, this->MyModules(VF_OPTCOMMON)); + std::string diffUneed = ListDifference(this->MyModules(VF_OPTCOMMON), this->OptModuleList); + if (diffIneed.length() == 0 && diffUneed.length() == 0) + { + reason = "Optional Module list in CAPAB is not alphabetically ordered, cannot compare lists."; + } + else + { + ServerInstance->SNO->WriteToSnoMask('l', + "Optional module lists do not match, some commands may not work globally.%s%s%s%s", + diffIneed.length() ? " Not loaded here:" : "", diffIneed.c_str(), + diffUneed.length() ? " Not loaded there:" : "", diffUneed.c_str()); + } + } + if (this->CapKeys.find("PROTOCOL") == this->CapKeys.end()) { reason = "Protocol version not specified"; @@ -230,7 +267,18 @@ bool TreeSocket::Capab(const parameterlist ¶ms) this->ModuleList.append(params[1]); } } - + else if ((params[0] == "MODSUPPORT") && (params.size() == 2)) + { + if (!this->OptModuleList.length()) + { + this->OptModuleList.append(params[1]); + } + else + { + this->OptModuleList.append(","); + this->OptModuleList.append(params[1]); + } + } else if ((params[0] == "CAPABILITIES") && (params.size() == 2)) { irc::tokenstream capabs(params[1]); diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index 3c736b341..1350950eb 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -82,7 +82,8 @@ class TreeSocket : public BufferedSocket int num_lost_servers; /* Servers lost in split */ time_t NextPing; /* Time when we are due to ping this server */ bool LastPingWasGood; /* Responded to last ping we sent? */ - std::string ModuleList; /* Module list of other server from CAPAB */ + std::string ModuleList; /* Required module list of other server from CAPAB */ + std::string OptModuleList; /* Optional module list of other server from CAPAB */ std::map CapKeys; /* CAPAB keys from other server */ Module* Hook; /* I/O hooking module that we're attached to for this socket */ std::string ourchallenge; /* Challenge sent for challenge/response */ @@ -185,9 +186,10 @@ class TreeSocket : public BufferedSocket */ void SendServers(TreeServer* Current, TreeServer* s, int hops); - /** Returns my capabilities as a string + /** Returns module list as a string, filtered by filter + * @param filter a module version bitmask, such as VF_COMMON or VF_OPTCOMMON */ - std::string MyCapabilities(); + std::string MyModules(int filter); /** Send my capabilities to the remote side */ diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index 9706271bf..e77e6717e 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -88,6 +88,7 @@ Module* TreeSocket::GetHook() void TreeSocket::CleanNegotiationInfo() { ModuleList.clear(); + OptModuleList.clear(); CapKeys.clear(); ourchallenge.clear(); theirchallenge.clear(); -- cgit v1.2.3