]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/configparser.cpp
Convert the ISO 8859-2 nationalchars files to codepage configs.
[user/henk/code/inspircd.git] / src / configparser.cpp
index 0102c910c3bf21c72276d04acb2dc3baa25c50ad..556442627570796b2e293ce2cd647ad714031884 100644 (file)
@@ -36,7 +36,10 @@ enum ParseFlags
        FLAG_NO_EXEC = 2,
 
        // All includes are disabled.
-       FLAG_NO_INC = 4
+       FLAG_NO_INC = 4,
+
+       // &env.FOO; is disabled.
+       FLAG_NO_ENV = 8
 };
 
 // Represents the position within a config file.
@@ -158,12 +161,20 @@ struct Parser
                }
        }
 
+       bool wordchar(char ch)
+       {
+               return isalnum(ch)
+                       || ch == '-'
+                       || ch == '.'
+                       || ch == '_';
+       }
+
        void nextword(std::string& rv)
        {
                int ch = next();
                while (isspace(ch))
                        ch = next();
-               while (isalnum(ch) || ch == '_'|| ch == '-')
+               while (wordchar(ch))
                {
                        rv.push_back(ch);
                        ch = next();
@@ -205,7 +216,7 @@ struct Parser
                                while (1)
                                {
                                        ch = next();
-                                       if (isalnum(ch) || (varname.empty() && ch == '#'))
+                                       if (wordchar(ch) || (varname.empty() && ch == '#'))
                                                varname.push_back(ch);
                                        else if (ch == ';')
                                                break;
@@ -233,6 +244,17 @@ struct Parser
                                                throw CoreException("Invalid numeric character reference '&" + varname + ";'");
                                        value.push_back(static_cast<char>(lvalue));
                                }
+                               else if (varname.compare(0, 4, "env.") == 0)
+                               {
+                                       if (flags & FLAG_NO_ENV)
+                                               throw CoreException("XML environment entity reference in file included with noenv=\"yes\"");
+
+                                       const char* envstr = getenv(varname.c_str() + 4);
+                                       if (!envstr)
+                                               throw CoreException("Undefined XML environment entity reference '&" + varname + ";'");
+
+                                       value.append(envstr);
+                               }
                                else
                                {
                                        insp::flat_map<std::string, std::string>::iterator var = stack.vars.find(varname);
@@ -400,6 +422,8 @@ void ParseStack::DoInclude(ConfigTag* tag, int flags)
                        flags |= FLAG_NO_INC;
                if (tag->getBool("noexec", false))
                        flags |= FLAG_NO_EXEC;
+               if (tag->getBool("noenv", false))
+                       flags |= FLAG_NO_ENV;
 
                if (!ParseFile(ServerInstance->Config->Paths.PrependConfig(name), flags, mandatorytag))
                        throw CoreException("Included");
@@ -410,13 +434,15 @@ void ParseStack::DoInclude(ConfigTag* tag, int flags)
                        flags |= FLAG_NO_INC;
                if (tag->getBool("noexec", false))
                        flags |= FLAG_NO_EXEC;
+               if (tag->getBool("noenv", false))
+                       flags |= FLAG_NO_ENV;
 
                const std::string includedir = ServerInstance->Config->Paths.PrependConfig(name);
                std::vector<std::string> files;
                if (!FileSystem::GetFileList(includedir, files, "*.conf"))
                        throw CoreException("Unable to read directory for include: " + includedir);
 
-               std::sort(files.begin(), files.end()); 
+               std::sort(files.begin(), files.end());
                for (std::vector<std::string>::const_iterator iter = files.begin(); iter != files.end(); ++iter)
                {
                        const std::string path = includedir + '/' + *iter;
@@ -432,6 +458,8 @@ void ParseStack::DoInclude(ConfigTag* tag, int flags)
                        flags |= FLAG_NO_INC;
                if (tag->getBool("noexec", true))
                        flags |= FLAG_NO_EXEC;
+               if (tag->getBool("noenv", true))
+                       flags |= FLAG_NO_ENV;
 
                if (!ParseFile(name, flags, mandatorytag, true))
                        throw CoreException("Included");
@@ -600,7 +628,7 @@ namespace
 long ConfigTag::getInt(const std::string &key, long def, long min, long max)
 {
        std::string result;
-       if(!readString(key, result))
+       if(!readString(key, result) || result.empty())
                return def;
 
        const char* res_cstr = result.c_str();
@@ -617,7 +645,7 @@ long ConfigTag::getInt(const std::string &key, long def, long min, long max)
 unsigned long ConfigTag::getUInt(const std::string& key, unsigned long def, unsigned long min, unsigned long max)
 {
        std::string result;
-       if (!readString(key, result))
+       if (!readString(key, result) || result.empty())
                return def;
 
        const char* res_cstr = result.c_str();
@@ -634,7 +662,7 @@ unsigned long ConfigTag::getUInt(const std::string& key, unsigned long def, unsi
 unsigned long ConfigTag::getDuration(const std::string& key, unsigned long def, unsigned long min, unsigned long max)
 {
        std::string duration;
-       if (!readString(key, duration))
+       if (!readString(key, duration) || duration.empty())
                return def;
 
        unsigned long ret;
@@ -663,7 +691,7 @@ double ConfigTag::getFloat(const std::string& key, double def, double min, doubl
 bool ConfigTag::getBool(const std::string &key, bool def)
 {
        std::string result;
-       if(!readString(key, result))
+       if(!readString(key, result) || result.empty())
                return def;
 
        if (stdalgo::string::equalsci(result, "yes") || stdalgo::string::equalsci(result, "true") || stdalgo::string::equalsci(result, "on") || result == "1")