X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fconfigreader.cpp;h=d93a1d4d8b843b43f00212ab0afa9a67cfbfbb09;hb=b7e299c2e10d915d5e59df4cb3f54951c8daa999;hp=d4291692ff72385585f84090f5b38c3b9a80b022;hpb=f2acdbc3820f0f4f5ef76a0a64e73d2a320df91f;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/configreader.cpp b/src/configreader.cpp index d4291692f..d93a1d4d8 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -21,6 +21,9 @@ std::vector old_module_names, new_module_names, added_modules, removed_modules; +/* Needs forward declaration */ +bool ValidateDnsServer(ServerConfig* conf, const char* tag, const char* value, ValueItem &data); + ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance) { this->ClearStack(); @@ -43,6 +46,7 @@ ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance) OperMaxChans = 30; LogLevel = DEFAULT; maxbans.clear(); + DNSServerValidator = &ValidateDnsServer; } void ServerConfig::ClearStack() @@ -222,17 +226,6 @@ bool ValidateDnsServer(ServerConfig* conf, const char* tag, const char* value, V if (!*(data.GetString())) { std::string nameserver; -#ifdef WINDOWS - conf->GetInstance()->Log(DEFAULT,"WARNING: not defined, attempting to find working server in the registry..."); - nameserver = FindNameServerWin(); - /* Windows stacks multiple nameservers in one registry key, seperated by commas. - * Spotted by Cataclysm. - */ - if (nameserver.find(',') != std::string::npos) - nameserver = nameserver.substr(0, nameserver.find(',')); - data.Set(nameserver.c_str()); - conf->GetInstance()->Log(DEFAULT," set to '%s' as first active resolver in registry.", nameserver.c_str()); -#else // attempt to look up their nameserver from /etc/resolv.conf conf->GetInstance()->Log(DEFAULT,"WARNING: not defined, attempting to find working server in /etc/resolv.conf..."); ifstream resolv("/etc/resolv.conf"); @@ -262,7 +255,6 @@ bool ValidateDnsServer(ServerConfig* conf, const char* tag, const char* value, V conf->GetInstance()->Log(DEFAULT,"/etc/resolv.conf can't be opened! Defaulting to nameserver '127.0.0.1'!"); data.Set("127.0.0.1"); } -#endif } return true; } @@ -412,16 +404,41 @@ bool DoConnect(ServerConfig* conf, const char* tag, char** entries, ValueList &v int recvq = values[8].GetInteger(); int localmax = values[9].GetInteger(); int globalmax = values[10].GetInteger(); + int port = values[11].GetInteger(); + const char* name = values[12].GetString(); + const char* parent = values[13].GetString(); + int maxchans = values[14].GetInteger(); - if (*allow) + if (*parent) { - ConnectClass c(timeout, flood, allow, pingfreq, password, threshold, sendq, recvq, localmax, globalmax); - conf->Classes.push_back(c); + /* Find 'parent' and inherit a new class from it, + * then overwrite any values that are set here + */ + for (ClassVector::iterator item = conf->Classes.begin(); item != conf->Classes.end(); ++item) + { + if (item->GetName() == name) + { + ConnectClass c(name, *item); + c.Update(timeout, flood, *allow ? allow : deny, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans, port); + conf->Classes.push_back(c); + } + } + throw CoreException("Class name '" + std::string(name) + "' is configured to inherit from class '" + std::string(name) + "' which cannot be found."); } else { - ConnectClass c(deny); - conf->Classes.push_back(c); + if (*allow) + { + ConnectClass c(name, timeout, flood, allow, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans); + c.SetPort(port); + conf->Classes.push_back(c); + } + else + { + ConnectClass c(name, deny); + c.SetPort(port); + conf->Classes.push_back(c); + } } return true; @@ -550,7 +567,7 @@ void ServerConfig::ReportConfigError(const std::string &errormessage, bool bail, { /* Unneeded because of the ServerInstance->Log() aboive? */ printf("There were errors in your configuration:\n%s\n\n",errormessage.c_str()); - InspIRCd::Exit(EXIT_STATUS_CONFIG); + ServerInstance->Exit(EXIT_STATUS_CONFIG); } else { @@ -617,7 +634,7 @@ void ServerConfig::Read(bool bail, userrec* user) {"options", "netbuffersize","10240", new ValueContainerInt (&this->NetBufferSize), DT_INTEGER, ValidateNetBufferSize}, {"options", "maxwho", "128", new ValueContainerInt (&this->MaxWhoResults), DT_INTEGER, ValidateMaxWho}, {"options", "allowhalfop", "0", new ValueContainerBool (&this->AllowHalfop), DT_BOOLEAN, NoValidation}, - {"dns", "server", "", new ValueContainerChar (this->DNSServer), DT_CHARPTR, ValidateDnsServer}, + {"dns", "server", "", new ValueContainerChar (this->DNSServer), DT_CHARPTR, DNSServerValidator}, {"dns", "timeout", "5", new ValueContainerInt (&this->dns_timeout), DT_INTEGER, NoValidation}, {"options", "moduledir", MOD_PATH, new ValueContainerChar (this->ModPath), DT_CHARPTR, NoValidation}, {"disabled", "commands", "", new ValueContainerChar (this->DisabledCommands), DT_CHARPTR, NoValidation}, @@ -655,12 +672,15 @@ void ServerConfig::Read(bool bail, userrec* user) {"connect", {"allow", "deny", "password", "timeout", "pingfreq", "flood", "threshold", "sendq", "recvq", "localmax", "globalmax", "port", + "name", "parent", "maxchans", NULL}, {"", "", "", "", "120", "", "", "", "", "3", "3", "0", + "", "", "0", NULL}, {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_INTEGER, DT_INTEGER, DT_INTEGER, - DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER}, + DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, + DT_CHARPTR, DT_CHARPTR, DT_INTEGER}, InitConnect, DoConnect, DoneConnect}, {"uline", @@ -872,7 +892,7 @@ void ServerConfig::Read(bool bail, userrec* user) FailedPortList pl; ServerInstance->BindPorts(false, found_ports, pl); - if (pl.size()) + if (pl.size() && user) { user->WriteServ("NOTICE %s :*** Not all your client ports could be bound.", user->nick); user->WriteServ("NOTICE %s :*** The following port(s) failed to bind:", user->nick); @@ -928,6 +948,9 @@ void ServerConfig::Read(bool bail, userrec* user) ServerInstance->Log(DEFAULT,"Successfully unloaded %lu of %lu modules and loaded %lu of %lu modules.",(unsigned long)rem,(unsigned long)removed_modules.size(),(unsigned long)add,(unsigned long)added_modules.size()); } + /** Note: This is safe, the method checks for user == NULL */ + ServerInstance->Parser->SetupCommandTable(user); + if (user) user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick); else @@ -973,7 +996,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o include_stack.push_back(filename); /* Start reading characters... */ - while(conf.get(ch)) + while (conf.get(ch)) { /* @@ -999,10 +1022,10 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o * no '>' then die with an error. */ - if((ch == '#') && !in_quote) + if ((ch == '#') && !in_quote) in_comment = true; - switch(ch) + switch (ch) { case '\n': if (in_quote) @@ -1049,11 +1072,11 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o if (ch != '\r') line += ch; - if(ch == '<') + if (ch == '<') { - if(in_tag) + if (in_tag) { - if(!in_quote) + if (!in_quote) { errorstream << "Got another opening < when the first one wasn't closed: " << filename << ":" << linenumber << std::endl; return false; @@ -1061,7 +1084,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } else { - if(in_quote) + if (in_quote) { errorstream << "We're in a quote but outside a tag, interesting. " << filename << ":" << linenumber << std::endl; return false; @@ -1073,11 +1096,11 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } } } - else if(ch == '"') + else if (ch == '"') { - if(in_tag) + if (in_tag) { - if(in_quote) + if (in_quote) { // errorstream << "Closing quote in config tag on line " << linenumber << std::endl; in_quote = false; @@ -1090,7 +1113,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } else { - if(in_quote) + if (in_quote) { errorstream << "Found a (closing) \" outside a tag: " << filename << ":" << linenumber << std::endl; } @@ -1100,11 +1123,11 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } } } - else if(ch == '>') + else if (ch == '>') { - if(!in_quote) + if (!in_quote) { - if(in_tag) + if (in_tag) { // errorstream << "Closing config tag on line " << linenumber << std::endl; in_tag = false; @@ -1114,7 +1137,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o * LoadConf() and load the included config into the same ConfigDataHash */ - if(!this->ParseLine(target, line, linenumber, errorstream)) + if (!this->ParseLine(target, line, linenumber, errorstream)) return false; line.clear(); @@ -1128,6 +1151,13 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } } + /* Fix for bug #392 - if we reach the end of a file and we are still in a quote or comment, most likely the user fucked up */ + if (in_comment || in_quote) + { + errorstream << "Reached end of file whilst still inside a quoted section or tag. This is most likely an error or there \ + is a newline missing from the end of the file: " << filename << ":" << linenumber << std::endl; + } + return true; } @@ -1136,7 +1166,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const std::string &filename, return this->LoadConf(target, filename.c_str(), errorstream); } -bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long linenumber, std::ostringstream &errorstream) +bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &linenumber, std::ostringstream &errorstream) { std::string tagname; std::string current_key; @@ -1148,17 +1178,15 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long lin got_name = got_key = in_quote = false; - //std::cout << "ParseLine(data, '" << line << "', " << linenumber << ", stream)" << std::endl; - for(std::string::iterator c = line.begin(); c != line.end(); c++) { - if(!got_name) + if (!got_name) { /* We don't know the tag name yet. */ - if(*c != ' ') + if (*c != ' ') { - if(*c != '<') + if (*c != '<') { tagname += *c; } @@ -1211,6 +1239,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long lin { /* Got a 'real' \n, treat it as part of the value */ current_value += '\n'; + linenumber++; continue; } else if ((*c == '\r') && (in_quote)) @@ -1234,9 +1263,9 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long lin in_quote = false; got_key = false; - if((tagname == "include") && (current_key == "file")) + if ((tagname == "include") && (current_key == "file")) { - if(!this->DoInclude(target, current_value, errorstream)) + if (!this->DoInclude(target, current_value, errorstream)) return false; } @@ -1246,7 +1275,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long lin } else { - if(in_quote) + if (in_quote) { current_value += *c; }