From 8ab1c71d7dc7a0d47e5711dc72e3fc9c3ee850bb Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 29 Dec 2014 17:26:20 -0500 Subject: Allow configuring casemaps --- src/config.cpp | 70 +++++++++++++++++++++++++++++++++++++++++--------------- src/hashcomp.cpp | 38 ++++++++++++------------------ src/init.cpp | 2 -- src/main.cpp | 3 --- 4 files changed, 66 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/config.cpp b/src/config.cpp index 6ac777a98..323a48519 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -72,7 +72,7 @@ const Block::item_map* Block::GetItems() const return NULL; } -template<> const Anope::string Block::Get(const Anope::string &tag, const Anope::string& def) const +template<> Anope::string Block::Get(const Anope::string &tag, const Anope::string& def) const { if (!this) return def; @@ -95,6 +95,27 @@ template<> bool Block::Get(const Anope::string &tag, const Anope::string &def) c return !str.empty() && !str.equals_ci("no") && !str.equals_ci("off") && !str.equals_ci("false") && !str.equals_ci("0"); } +template<> unsigned int Block::Get(const Anope::string &tag, const Anope::string &def) const +{ + const Anope::string &str = Get(tag, def); + std::size_t pos = str.length(); + unsigned long l; + + try + { + l = std::stoul(str.str(), &pos, 0); + } + catch (...) + { + return 0; + } + + if (pos != str.length()) + return 0; + + return l; +} + static void ValidateNotEmpty(const Anope::string &block, const Anope::string &name, const Anope::string &value) { if (value.empty()) @@ -127,6 +148,8 @@ Conf::Conf() : Block("") const Anope::string &type = include->Get("type"), &file = include->Get("name"); + ValidateNotEmpty("include", "name", file); + File f(file, type == "executable"); this->LoadConf(f); } @@ -489,6 +512,34 @@ Conf::Conf() : Block("") this->CommandGroups.push_back(gr); } + for (int i = 0; i < this->CountBlock("casemap"); ++i) + { + Block *casemap = this->GetBlock("casemap", i); + + unsigned char upper = casemap->Get("upper"), + lower = casemap->Get("lower"); + + if (!upper) + { + Anope::string s = casemap->Get("upper"); + if (s.length() == 1) + upper = s[0]; + } + + if (!lower) + { + Anope::string s = casemap->Get("lower"); + if (s.length() == 1) + lower = s[0]; + } + + if (upper && lower) + { + CaseMapUpper[lower] = CaseMapUpper[upper] = upper; + CaseMapLower[lower] = CaseMapLower[upper] = lower; + } + } + /* Below here can't throw */ /* Clear existing conf opers */ @@ -508,23 +559,6 @@ Conf::Conf() : Block("") Log() << "Tied oper " << na->GetAccount()->GetDisplay() << " to type " << o->GetType()->GetName(); } - if (options->Get("casemap", "ascii") == "ascii") - Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype()); - else if (options->Get("casemap") == "rfc1459") - Anope::casemap = std::locale(std::locale(), new Anope::rfc1459_ctype()); - else - { - try - { - Anope::casemap = std::locale(options->Get("casemap").c_str()); - } - catch (const std::runtime_error &) - { - Log() << "Unknown casemap " << options->Get("casemap") << " - casemap not changed"; - } - } - Anope::CaseMapRebuild(); - /* Check the user keys */ if (!options->Get("seed")) Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!"; diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 62bcc404f..e17ae6176 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -10,32 +10,22 @@ #include "services.h" #include "hashcomp.h" #include "anope.h" - -/* Case map in use by Anope */ -std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype()); -/* Cache of the above case map, forced upper */ -static unsigned char case_map_upper[256], case_map_lower[256]; - -/* called whenever Anope::casemap is modified to rebuild the casemap cache */ -void Anope::CaseMapRebuild() -{ - const std::ctype &ct = std::use_facet >(Anope::casemap); - - for (unsigned i = 0; i < sizeof(case_map_upper); ++i) - { - case_map_upper[i] = ct.toupper(i); - case_map_lower[i] = ct.tolower(i); - } -} +#include "config.h" unsigned char Anope::tolower(unsigned char c) { - return case_map_lower[c]; + if (!Config || !Config->CaseMapLower[c]) + return std::tolower(c); + + return Config->CaseMapLower[c]; } unsigned char Anope::toupper(unsigned char c) { - return case_map_upper[c]; + if (!Config || !Config->CaseMapUpper[c]) + return std::toupper(c); + + return Config->CaseMapUpper[c]; } /* @@ -47,7 +37,7 @@ unsigned char Anope::toupper(unsigned char c) bool ci::ci_char_traits::eq(char c1st, char c2nd) { - return case_map_upper[static_cast(c1st)] == case_map_upper[static_cast(c2nd)]; + return Anope::toupper(c1st) == Anope::toupper(c2nd); } bool ci::ci_char_traits::ne(char c1st, char c2nd) @@ -57,15 +47,15 @@ bool ci::ci_char_traits::ne(char c1st, char c2nd) bool ci::ci_char_traits::lt(char c1st, char c2nd) { - return case_map_upper[static_cast(c1st)] < case_map_upper[static_cast(c2nd)]; + return Anope::toupper(c1st) < Anope::toupper(c2nd); } int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n) { for (unsigned i = 0; i < n; ++i) { - unsigned char c1 = case_map_upper[static_cast(*str1)], - c2 = case_map_upper[static_cast(*str2)]; + unsigned char c1 = Anope::toupper(*str1), + c2 = Anope::toupper(*str2); if (c1 > c2) return 1; @@ -82,7 +72,7 @@ int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n) const char *ci::ci_char_traits::find(const char *s1, int n, char c) { - while (n-- > 0 && case_map_upper[static_cast(*s1)] != case_map_upper[static_cast(c)]) + while (n-- > 0 && Anope::toupper(*s1) != Anope::toupper(c)) ++s1; return n >= 0 ? s1 : NULL; } diff --git a/src/init.cpp b/src/init.cpp index 853cf7209..0b381cbf6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -290,8 +290,6 @@ void Anope::Init(int ac, char **av) umask(DEFUMASK); #endif - //Serialize::RegisterTypes(); - /* Parse command line arguments */ ParseCommandLineArguments(ac, av); diff --git a/src/main.cpp b/src/main.cpp index 1f4434f18..65fb8d3f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,9 +116,6 @@ static Anope::string GetFullProgDir(const Anope::string &argv0) int main(int ac, char **av, char **envp) { - /* String comparisons won't work until we build the case map cache, so do it first */ - Anope::CaseMapRebuild(); - BinaryDir = GetFullProgDir(av[0]); if (BinaryDir[BinaryDir.length() - 1] == '.') BinaryDir = BinaryDir.substr(0, BinaryDir.length() - 2); -- cgit