From 4a264e2429b378f900555727b978b9bac1978be4 Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Wed, 10 Feb 2010 12:23:13 -0600 Subject: [PATCH] Strip channel mode Z from list sent to 1201-compat servers --- src/mode.cpp | 3 +- src/modules/m_spanningtree/capab.cpp | 17 +++- src/modules/m_spanningtree/compat.cpp | 114 +++++++++++++------------- 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/src/mode.cpp b/src/mode.cpp index 42653a5d7..81ad9c3c6 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -853,7 +853,8 @@ std::string ModeParser::GiveModeList(ModeType m) std::string type2; /* Modes that take a param when adding or removing */ std::string type3; /* Modes that only take a param when adding */ std::string type4; /* Modes that dont take a param */ - type1.push_back('Z'); + if (m == MODETYPE_CHANNEL) + type1.push_back('Z'); for(ModeIDIter id; id; id++) { diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp index 93110644a..1479208c3 100644 --- a/src/modules/m_spanningtree/capab.cpp +++ b/src/modules/m_spanningtree/capab.cpp @@ -135,6 +135,12 @@ void TreeSocket::SendCapabilities(int phase) SetOurChallenge(ServerInstance->GenRandomStr(20)); extra = " CHALLENGE=" + this->GetOurChallenge(); } + std::string chanmodes = ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL); + + if (proto_version < 1202) + { + chanmodes.erase(chanmodes.find('Z'), 1); + } this->WriteLine("CAPAB CAPABILITIES " /* Preprocessor does this one. */ ":NICKMAX="+ConvToStr(ServerInstance->Config->Limits.NickMax)+ @@ -150,7 +156,7 @@ void TreeSocket::SendCapabilities(int phase) " IP6SUPPORT=1"+ " PROTOCOL="+ConvToStr(ProtocolVersion)+extra+ " PREFIX="+ServerInstance->Modes->BuildPrefixes()+ - " CHANMODES="+ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL)+ + " CHANMODES="+chanmodes+ " USERMODES="+ServerInstance->Modes->GiveModeList(MODETYPE_USER)+ " SVSPART=1"); @@ -281,7 +287,14 @@ bool TreeSocket::Capab(const parameterlist ¶ms) } else if (this->capab->CapKeys.find("CHANMODES") != this->capab->CapKeys.end()) { - if (this->capab->CapKeys.find("CHANMODES")->second != ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL)) + std::string chanmodes = ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL); + + if (proto_version < 1202) + { + chanmodes.erase(chanmodes.find('Z'), 1); + } + + if (this->capab->CapKeys.find("CHANMODES")->second != chanmodes) reason = "One or more of the channel modes on the remote server are invalid on this server."; } diff --git a/src/modules/m_spanningtree/compat.cpp b/src/modules/m_spanningtree/compat.cpp index 2df0c91e9..68a51d94a 100644 --- a/src/modules/m_spanningtree/compat.cpp +++ b/src/modules/m_spanningtree/compat.cpp @@ -107,75 +107,75 @@ void TreeSocket::CompatAddModules(std::vector& modlist) void TreeSocket::WriteLine(std::string line) { - if (LinkState == CONNECTED) + if (LinkState == CONNECTED && line[0] != ':') { + ServerInstance->Logs->Log("m_spanningtree", DEFAULT, "Sending line without server prefix!"); + line = ":" + ServerInstance->Config->GetSID() + " " + line; + } + + if (proto_version != ProtocolVersion) + { + std::string::size_type a = line.find(' '); if (line[0] != ':') + a = -1; + std::string::size_type b = line.find(' ', a + 1); + std::string command = line.substr(a + 1, b-a-1); + // now try to find a translation entry + // TODO a more efficient lookup method will be needed later + if (proto_version < 1202 && command == "FIDENT") { - ServerInstance->Logs->Log("m_spanningtree", DEFAULT, "Sending line without server prefix!"); - line = ":" + ServerInstance->Config->GetSID() + " " + line; + ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Rewriting FIDENT for 1201-protocol server"); + line = ":" + ServerInstance->Config->GetSID() + " CHGIDENT " + line.substr(1,a-1) + line.substr(b); } - if (proto_version != ProtocolVersion) + else if (proto_version < 1202 && command == "SAVE") { - std::string::size_type a = line.find(' '); - std::string::size_type b = line.find(' ', a + 1); - std::string command = line.substr(a + 1, b-a-1); - // now try to find a translation entry - // TODO a more efficient lookup method will be needed later - if (proto_version < 1202 && command == "FIDENT") + ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Rewriting SAVE for 1201-protocol server"); + std::string::size_type c = line.find(' ', b + 1); + std::string uid = line.substr(b, c - b); + line = ":" + ServerInstance->Config->GetSID() + " SVSNICK" + uid + line.substr(b); + } + else if (proto_version < 1202 && command == "AWAY") + { + if (b != std::string::npos) { - ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Rewriting FIDENT for 1201-protocol server"); - line = ":" + ServerInstance->Config->GetSID() + " CHGIDENT " + line.substr(1,a-1) + line.substr(b); - } - else if (proto_version < 1202 && command == "SAVE") - { - ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Rewriting SAVE for 1201-protocol server"); + ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Stripping AWAY timestamp for 1201-protocol server"); std::string::size_type c = line.find(' ', b + 1); - std::string uid = line.substr(b, c - b); - line = ":" + ServerInstance->Config->GetSID() + " SVSNICK" + uid + line.substr(b); + line.erase(b,c-b); } - else if (proto_version < 1202 && command == "AWAY") + } + else if (proto_version < 1202 && command == "ENCAP") + { + // :src ENCAP target command [args...] + // A B C D + // Therefore B and C cannot be npos in a valid command + if (b == std::string::npos) + return; + std::string::size_type c = line.find(' ', b + 1); + if (c == std::string::npos) + return; + std::string::size_type d = line.find(' ', c + 1); + std::string subcmd = line.substr(c + 1, d - c - 1); + + if (subcmd == "CHGIDENT" && d != std::string::npos) { - if (b != std::string::npos) - { - ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Stripping AWAY timestamp for 1201-protocol server"); - std::string::size_type c = line.find(' ', b + 1); - line.erase(b,c-b); - } + std::string::size_type e = line.find(' ', d + 1); + if (e == std::string::npos) + return; // not valid + std::string target = line.substr(d + 1, e - d - 1); + + ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Forging acceptance of CHGIDENT from 1201-protocol server"); + recvq.insert(0, ":" + target + " FIDENT " + line.substr(e) + "\n"); } - else if (proto_version < 1202 && command == "ENCAP") + + Command* thiscmd = ServerInstance->Parser->GetHandler(subcmd); + if (thiscmd) { - // :src ENCAP target command [args...] - // A B C D - // Therefore B and C cannot be npos in a valid command - if (b == std::string::npos) - return; - std::string::size_type c = line.find(' ', b + 1); - if (c == std::string::npos) - return; - std::string::size_type d = line.find(' ', c + 1); - std::string subcmd = line.substr(c + 1, d - c - 1); - - if (subcmd == "CHGIDENT" && d != std::string::npos) + Version ver = thiscmd->creator->GetVersion(); + if (ver.Flags & VF_OPTCOMMON) { - std::string::size_type e = line.find(' ', d + 1); - if (e == std::string::npos) - return; // not valid - std::string target = line.substr(d + 1, e - d - 1); - - ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Forging acceptance of CHGIDENT from 1201-protocol server"); - recvq.insert(0, ":" + target + " FIDENT " + line.substr(e) + "\n"); - } - - Command* thiscmd = ServerInstance->Parser->GetHandler(subcmd); - if (thiscmd) - { - Version ver = thiscmd->creator->GetVersion(); - if (ver.Flags & VF_OPTCOMMON) - { - ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Removing ENCAP on '%s' for 1201-protocol server", - subcmd.c_str()); - line.erase(a, c-a); - } + ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Removing ENCAP on '%s' for 1201-protocol server", + subcmd.c_str()); + line.erase(a, c-a); } } }