]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/configreader.cpp
Fix for bug #569, thanks dz.
[user/henk/code/inspircd.git] / src / configreader.cpp
index f42bd79cd14e7431288820e2873b403acf729e45..8f6c93b1bf8e98baca123e7baaba2c54db5e90ba 100644 (file)
@@ -19,7 +19,8 @@
 /* $CopyInstall: conf/inspircd.helpop.example $(CONPATH) */
 /* $CopyInstall: conf/inspircd.censor.example $(CONPATH) */
 /* $CopyInstall: conf/inspircd.filter.example $(CONPATH) */
-/* $CopyInstall: docs/inspircd.conf.example $(CONPATH) */
+/* $CopyInstall: conf/inspircd.conf.example $(CONPATH) */
+/* $CopyInstall: conf/modules.conf.example $(CONPATH) */
 
 #include "inspircd.h"
 #include <fstream>
@@ -53,6 +54,8 @@ ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance)
        debugging = 0;
        MaxChans = 20;
        OperMaxChans = 30;
+       c_ipv4_range = 32;
+       c_ipv6_range = 128;
        maxbans.clear();
        DNSServerValidator = &ValidateDnsServer;
 }
@@ -528,7 +531,7 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*)
                         ((*name && (cc->GetName() == name)) || // if the name is the same
                         (*allow && (cc->GetHost() == allow)) || // or the allow is the same
                         (*deny && (cc->GetHost() == deny))) && // or the deny is the same
-                        (!port || port && (cc->GetPort() == port)) // and there is no port, or there is a port and the port is the same
+                        (!port || (port && (cc->GetPort() == port))) // and there is no port, or there is a port and the port is the same
                   )
                {
                        /* reenable class so users can be shoved into it :P */
@@ -844,6 +847,8 @@ void ServerConfig::Read(bool bail, User* user)
                {"die",         "value",        "",                     new ValueContainerChar (this->DieValue),                DT_CHARPTR,  NoValidation},
                {"channels",    "users",        "20",                   new ValueContainerUInt (&this->MaxChans),               DT_INTEGER,  NoValidation},
                {"channels",    "opers",        "60",                   new ValueContainerUInt (&this->OperMaxChans),           DT_INTEGER,  NoValidation},
+               {"cidr",        "ipv4clone",    "32",                   new ValueContainerInt (&this->c_ipv4_range),            DT_INTEGER,  NoValidation},
+               {"cidr",        "ipv6clone",    "128",                  new ValueContainerInt (&this->c_ipv6_range),            DT_INTEGER,  NoValidation},
                {"limits",      "maxnick",      "32",                   new ValueContainerST (&this->Limits.NickMax),           DT_INTEGER,  NoValidation},
                {"limits",      "maxchan",      "64",                   new ValueContainerST (&this->Limits.ChanMax),           DT_INTEGER,  NoValidation},
                {"limits",      "maxmodes",     "20",                   new ValueContainerST (&this->Limits.MaxModes),          DT_INTEGER,  NoValidation},
@@ -1302,15 +1307,20 @@ void ServerConfig::Read(bool bail, User* user)
 
        }
 
-       /** Note: This is safe, the method checks for user == NULL */
-       ServerInstance->Threads->Mutex(true);
-       ServerInstance->Parser->SetupCommandTable(user);
-       ServerInstance->Threads->Mutex(false);
-
-       if (user)
-               user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick.c_str());
+       if (bail)
+       {
+               /** Note: This is safe, the method checks for user == NULL */
+               ServerInstance->Threads->Mutex(true);
+               ServerInstance->Parser->SetupCommandTable(user);
+               ServerInstance->Threads->Mutex(false);
+       }
        else
-               ServerInstance->SNO->WriteToSnoMask('A', "*** Successfully rehashed server.");
+       {
+               if (user)
+                       user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick.c_str());
+               else
+                       ServerInstance->SNO->WriteToSnoMask('A', "*** Successfully rehashed server.");
+       }
 
 }
 
@@ -1319,13 +1329,13 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
 {
        std::string line;
        char ch;
-       long linenumber;
+       long linenumber = 1;
+       long last_successful_parse = 1;
        bool in_tag;
        bool in_quote;
        bool in_comment;
        int character_count = 0;
 
-       linenumber = 1;
        in_tag = false;
        in_quote = false;
        in_comment = false;
@@ -1430,7 +1440,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
 
                if ((ch != '<') && (!in_tag) && (!in_comment) && (ch > ' ') && (ch != 9))
                {
-                       errorstream << "Stray character outside of a configuration tag: '" << ch << "': " << filename << ":" << linenumber << std::endl;
+                       errorstream << "You have stray characters beyond the tag which starts at " << filename << ":" << last_successful_parse << std::endl;
                        return false;
                }
 
@@ -1440,7 +1450,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
                        {
                                if (!in_quote)
                                {
-                                       errorstream << "Got another opening < when the first one wasn't closed: " << filename << ":" << linenumber << std::endl;
+                                       errorstream << "The tag at location " << filename << ":" << last_successful_parse << " was valid, but there is an error in the tag which comes after it. You are possibly missing a \" or >. Please check this." << std::endl;
                                        return false;
                                }
                        }
@@ -1448,7 +1458,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
                        {
                                if (in_quote)
                                {
-                                       errorstream << "Parser error: Inside a quote but not within a tag!: " << filename << ":" << linenumber << std::endl;
+                                       errorstream << "Parser error: Inside a quote but not within the last valid tag, which was opened at: " << filename << ":" << last_successful_parse << std::endl;
                                        return false;
                                }
                                else
@@ -1477,11 +1487,11 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
                        {
                                if (in_quote)
                                {
-                                       errorstream << "Found a closing \" outside a tag: " << filename << ":" << linenumber << std::endl;
+                                       errorstream << "The tag immediately after the one at " << filename << ":" << last_successful_parse << " has a missing closing \" symbol. Please check this." << std::endl;
                                }
                                else
                                {
-                                       errorstream << "Found a opening \" outside a tag: " << filename << ":" << linenumber << std::endl;
+                                       errorstream << "You have opened a quote (\") beyond the tag at " << filename << ":" << last_successful_parse << " without opening a new tag. Please check this." << std::endl;
                                }
                        }
                }
@@ -1498,14 +1508,18 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
                                         * If this finds an <include> then ParseLine can simply call
                                         * LoadConf() and load the included config into the same ConfigDataHash
                                         */
+                                       long bl = linenumber;
                                        if (!this->ParseLine(target, filename, line, linenumber, errorstream))
                                                return false;
+                                       last_successful_parse = linenumber;
+
+                                       linenumber = bl;
        
                                        line.clear();
                                }
                                else
                                {
-                                       errorstream << "Got a closing > when we weren't inside a tag: " << filename << ":" << linenumber << std::endl;
+                                       errorstream << "You forgot to close the tag which comes immediately after the one at " << filename << ":" << last_successful_parse << std::endl;
                                        return false;
                                }
                        }
@@ -1534,6 +1548,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
        std::string current_key;
        std::string current_value;
        KeyValList results;
+       char last_char = 0;
        bool got_name;
        bool got_key;
        bool in_quote;
@@ -1554,7 +1569,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
                                                tagname += *c;
                                        else
                                        {
-                                               errorstream << "Invalid character in value name: '" << *c << "' in value '" << tagname << "' in filename: " << filename << ":" << linenumber << std::endl;
+                                               errorstream << "Invalid character in value name of tag: '" << *c << "' in value '" << tagname << "' in filename: " << filename << ":" << linenumber << std::endl;
                                                return false;
                                        }
                                }
@@ -1574,11 +1589,11 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
                        if (!got_key)
                        {
                                /* We're still reading the key name */
-                               if (*c != '=')
+                               if ((*c != '=') && (*c != '>'))
                                {
                                        if (*c != ' ')
                                        {
-                                               if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <='Z') || (*c >= '0' && *c <= '9') || *c == '_' || *c == '>')
+                                               if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <='Z') || (*c >= '0' && *c <= '9') || *c == '_')
                                                        current_key += *c;
                                                else
                                                {
@@ -1618,12 +1633,13 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
                                {
                                        /* Got a 'real' \n, treat it as part of the value */
                                        current_value += '\n';
-                                       linenumber++;
                                        continue;
                                }
                                else if ((*c == '\r') && (in_quote))
+                               {
                                        /* Got a \r, drop it */
                                        continue;
+                               }
 
                                if (*c == '"')
                                {
@@ -1662,6 +1678,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
                                {
                                        if (in_quote)
                                        {
+                                               last_char = *c;
                                                current_value += *c;
                                        }
                                }
@@ -2061,7 +2078,7 @@ bool ServerConfig::DirValid(const char* dirandfile)
 
 std::string ServerConfig::GetFullProgDir()
 {
-       char buffer[PATH_MAX+1];
+       char buffer[PATH_MAX];
 #ifdef WINDOWS
        /* Windows has specific api calls to get the exe path that never fail.
         * For once, windows has something of use, compared to the POSIX code