diff options
author | Peter Powell <petpow@saberuk.com> | 2017-07-30 17:34:05 +0100 |
---|---|---|
committer | Peter Powell <petpow@saberuk.com> | 2017-09-08 20:11:50 +0100 |
commit | 51a47e7d757df63370168ab5000d13ca9c349ecd (patch) | |
tree | 52db2b2e585988b27f1ba7c26792208f323bc610 | |
parent | 5a3f8af9f963b164832fabc1163611a2b768a890 (diff) |
Implement support for configurable casemapping & default to ASCII.
-rw-r--r-- | docs/conf/inspircd.conf.example | 8 | ||||
-rw-r--r-- | include/configreader.h | 4 | ||||
-rw-r--r-- | src/configreader.cpp | 13 | ||||
-rw-r--r-- | src/modules/m_nationalchars.cpp | 10 | ||||
-rw-r--r-- | src/modules/m_spanningtree/capab.cpp | 19 | ||||
-rw-r--r-- | src/server.cpp | 2 |
6 files changed, 48 insertions, 8 deletions
diff --git a/docs/conf/inspircd.conf.example b/docs/conf/inspircd.conf.example index 90f260ad3..136346f7c 100644 --- a/docs/conf/inspircd.conf.example +++ b/docs/conf/inspircd.conf.example @@ -563,6 +563,14 @@ # the correct parameters are. syntaxhints="no" + # casemapping: This sets the case mapping method to be used by the + # server. This MUST be the same on all servers. Possible values are: + # "ascii" (recommended) + # "rfc1459" (default, required for linking to 2.0 servers) + # NOTE: if you are using the nationalchars module this setting will be + # ignored. You should use <nationalchars:casemapping> instead. + casemapping="ascii" + # cyclehostsfromuser: If enabled, the source of the mode change for # cyclehosts will be the user who cycled. This can look nicer, but # triggers anti-takeover mechanisms of some obsolete bots. diff --git a/include/configreader.h b/include/configreader.h index 1a0e70080..36bb3297e 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -424,6 +424,10 @@ class CoreExport ServerConfig */ bool SyntaxHints; + /** The name of the casemapping method used by this server. + */ + std::string CaseMapping; + /** If set to true, the CycleHosts mode change will be sourced from the user, * rather than the server */ diff --git a/src/configreader.cpp b/src/configreader.cpp index f29356c0c..696035a74 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -400,6 +400,14 @@ void ServerConfig::Fill() sid = server->getString("id"); if (!sid.empty() && !InspIRCd::IsSID(sid)) throw CoreException(sid + " is not a valid server ID. A server ID must be 3 characters long, with the first character a digit and the next two characters a digit or letter."); + + CaseMapping = options->getString("casemapping", "rfc1459"); + if (CaseMapping == "ascii") + national_case_insensitive_map = ascii_case_insensitive_map; + else if (CaseMapping == "rfc1459") + national_case_insensitive_map = rfc_case_insensitive_map; + else + throw CoreException("<options:casemapping> must be set to 'ascii', or 'rfc1459'"); } else { @@ -410,6 +418,11 @@ void ServerConfig::Fill() std::string nsid = server->getString("id"); if (!nsid.empty() && nsid != sid) throw CoreException("You must restart to change the server id"); + + std::string casemapping = options->getString("casemapping"); + if (!casemapping.empty() && casemapping != CaseMapping) + throw CoreException("You must restart to change the server casemapping"); + } SoftLimit = ConfValue("performance")->getInt("softlimit", (SocketEngine::GetMaxFds() > 0 ? SocketEngine::GetMaxFds() : LONG_MAX), 10); CCOnConnect = ConfValue("performance")->getBool("clonesonconnect", true); diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index 8e836c407..d03468de7 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -218,7 +218,7 @@ bool lwbNickHandler::Call(const std::string& nick) class ModuleNationalChars : public Module { lwbNickHandler myhandler; - std::string charset, casemapping; + std::string charset; unsigned char m_additional[256], m_additionalUp[256], m_lower[256], m_upper[256]; caller1<bool, const std::string&> rememberer; bool forcequit; @@ -262,18 +262,14 @@ class ModuleNationalChars : public Module ServerInstance->IsNick = &myhandler; } - void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE - { - tokens["CASEMAPPING"] = casemapping; - } - void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { ConfigTag* tag = ServerInstance->Config->ConfValue("nationalchars"); charset = tag->getString("file"); - casemapping = tag->getString("casemapping", FileSystem::GetFileName(charset)); + std::string casemapping = tag->getString("casemapping", FileSystem::GetFileName(charset)); if (casemapping.find(' ') != std::string::npos) throw ModuleException("<nationalchars:casemapping> must not contain any spaces!"); + ServerInstance->Config->CaseMapping = casemapping; #if defined _WIN32 if (!FileSystem::StartsWithWindowsDriveLetter(charset)) charset.insert(0, "./locales/"); diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp index d22481518..7f9f9edb7 100644 --- a/src/modules/m_spanningtree/capab.cpp +++ b/src/modules/m_spanningtree/capab.cpp @@ -182,6 +182,7 @@ void TreeSocket::SendCapabilities(int phase) " PREFIX="+ServerInstance->Modes->BuildPrefixes()+ " CHANMODES="+ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL)+ " USERMODES="+ServerInstance->Modes->GiveModeList(MODETYPE_USER)+ + " CASEMAPPING="+ServerInstance->Config->CaseMapping+ // XXX: Advertise the presence or absence of m_globops in CAPAB CAPABILITIES. // Services want to know about it, and since m_globops was not marked as VF_(OPT)COMMON // in 2.0, we advertise it here to not break linking to previous versions. @@ -343,6 +344,24 @@ bool TreeSocket::Capab(const parameterlist ¶ms) if (this->capab->CapKeys.find("USERMODES")->second != ServerInstance->Modes->GiveModeList(MODETYPE_USER)) reason = "One or more of the user modes on the remote server are invalid on this server."; } + else + { + // We default to rfc1459 here because if this key is not sent then + // the remote server is running the 2.0 protocol which uses rfc1459 + // by default. + std::string casemapping = "rfc1459"; + std::map<std::string, std::string>::iterator citer = this->capab->CapKeys.find("CASEMAPPING"); + if (citer != this->capab->CapKeys.end()) + casemapping = citer->second; + + if (casemapping != ServerInstance->Config->CaseMapping) + { + reason = "The casemapping of the remote server differs to that of the local server." + " Local casemapping: " + ServerInstance->Config->CaseMapping + + " Remote casemapping: " + casemapping; + } + + } /* Challenge response, store their challenge for our password */ std::map<std::string,std::string>::iterator n = this->capab->CapKeys.find("CHALLENGE"); diff --git a/src/server.cpp b/src/server.cpp index 6782187fe..f18c9c86c 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -164,7 +164,7 @@ void ISupportManager::Build() std::map<std::string, std::string> tokens; tokens["AWAYLEN"] = ConvToStr(ServerInstance->Config->Limits.MaxAway); - tokens["CASEMAPPING"] = "rfc1459"; + tokens["CASEMAPPING"] = ServerInstance->Config->CaseMapping; tokens["CHANLIMIT"] = InspIRCd::Format("#:%u", ServerInstance->Config->MaxChans); tokens["CHANMODES"] = ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL); tokens["CHANNELLEN"] = ConvToStr(ServerInstance->Config->Limits.ChanMax); |