X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fconfigreader.cpp;h=b5d999f1d2e543ec519fa3de82b62c808ef085ea;hb=84083a73e80734e39892f44411549d2381654c95;hp=06513253ce3e9aae91add9c00d54593b96fe6820;hpb=8f0f9654f841f8034be4c071660a378a91434782;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/configreader.cpp b/src/configreader.cpp index 06513253c..b5d999f1d 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -478,13 +478,7 @@ bool ValidateInvite(ServerConfig* conf, const char*, const char*, ValueItem &dat bool ValidateSID(ServerConfig* conf, const char*, const char*, ValueItem &data) { - int sid = data.GetInteger(); - if ((sid > 999) || (sid < 0)) - { - sid = sid % 1000; - data.Set(sid); - conf->GetInstance()->Log(DEFAULT,"WARNING: Server ID is less than 0 or greater than 999. Set to %d", sid); - } +// std::string sid = data.GetString(); return true; } @@ -527,20 +521,28 @@ bool InitConnect(ServerConfig* conf, const char*) conf->GetInstance()->Log(DEBUG, "Address of class is %p", c); } - for (ClassVector::iterator i = conf->Classes.begin(); i != conf->Classes.end(); i++) + for (ClassVector::iterator i = conf->Classes.begin(); i != conf->Classes.end() ; ) { - ConnectClass *c = *i; + ConnectClass* c = *i; /* only delete a class with refcount 0 */ if (c->RefCount == 0) { conf->GetInstance()->Log(DEFAULT, "Removing connect class, refcount is 0!"); + + /* This was causing a crash, because we'd set i to .begin() just here, but then the for loop's increment would + * set it to .begin() + 1. Which if it was already the last thing in the list, wasn't good. + * Now the increment is in the else { } below. + */ conf->Classes.erase(i); i = conf->Classes.begin(); // start over so we don't trample on a bad iterator } - - /* also mark all existing classes disabled, if they still exist in the conf, they will be reenabled. */ - c->SetDisabled(true); + else + { + /* also mark all existing classes disabled, if they still exist in the conf, they will be reenabled. */ + c->SetDisabled(true); + i++; + } } return true; @@ -788,7 +790,7 @@ void ServerConfig::Read(bool bail, User* user, int pass) static char hidemodes[MAXBUF]; /* Modes to not allow listing from users below halfop */ static char exemptchanops[MAXBUF]; /* Exempt channel ops from these modes */ static char announceinvites[MAXBUF]; /* options:announceinvites setting */ - std::ostringstream errstr; /* String stream containing the error output */ + errstr.clear(); /* These tags MUST occur and must ONLY occur once in the config file */ static char* Once[] = { "server", "admin", "files", "power", "options", NULL }; @@ -801,7 +803,7 @@ void ServerConfig::Read(bool bail, User* user, int pass) {"server", "name", "", new ValueContainerChar (this->ServerName), DT_HOSTNAME, ValidateServerName}, {"server", "description", "Configure Me", new ValueContainerChar (this->ServerDesc), DT_CHARPTR, NoValidation}, {"server", "network", "Network", new ValueContainerChar (this->Network), DT_NOSPACES, NoValidation}, - {"server", "id", "0", new ValueContainerInt (&this->sid), DT_NOSPACES, ValidateSID}, + {"server", "id", "", new ValueContainerChar (this->sid), DT_CHARPTR, ValidateSID}, {"admin", "name", "", new ValueContainerChar (this->AdminName), DT_CHARPTR, NoValidation}, {"admin", "email", "Mis@configu.red", new ValueContainerChar (this->AdminEmail), DT_CHARPTR, NoValidation}, {"admin", "nick", "Misconfigured", new ValueContainerChar (this->AdminNick), DT_CHARPTR, NoValidation}, @@ -813,6 +815,9 @@ void ServerConfig::Read(bool bail, User* user, int pass) {"options", "prefixquit", "", new ValueContainerChar (this->PrefixQuit), DT_CHARPTR, NoValidation}, {"options", "suffixquit", "", new ValueContainerChar (this->SuffixQuit), DT_CHARPTR, NoValidation}, {"options", "fixedquit", "", new ValueContainerChar (this->FixedQuit), DT_CHARPTR, NoValidation}, + {"options", "prefixpart", "", new ValueContainerChar (this->PrefixPart), DT_CHARPTR, NoValidation}, + {"options", "suffixpart", "", new ValueContainerChar (this->SuffixPart), DT_CHARPTR, NoValidation}, + {"options", "fixedpart", "", new ValueContainerChar (this->FixedPart), DT_CHARPTR, NoValidation}, {"options", "loglevel", "default", new ValueContainerChar (debug), DT_CHARPTR, ValidateLogLevel}, {"options", "netbuffersize","10240", new ValueContainerInt (&this->NetBufferSize), DT_INTEGER, ValidateNetBufferSize}, {"options", "maxwho", "128", new ValueContainerInt (&this->MaxWhoResults), DT_INTEGER, ValidateMaxWho}, @@ -933,7 +938,7 @@ void ServerConfig::Read(bool bail, User* user, int pass) /* Load and parse the config file, if there are any errors then explode */ /* Make a copy here so if it fails then we can carry on running with an unaffected config */ - ConfigDataHash newconfig; + newconfig.clear(); if (this->LoadConf(newconfig, ServerInstance->ConfigFileName, errstr, pass)) { @@ -1142,6 +1147,14 @@ void ServerConfig::Read(bool bail, User* user, int pass) * at this point */ + if (pass == 0) + { + ServerInstance->Log(DEBUG, "Downloading configuration"); + + TotalDownloaded = 0; + FileErrors = 0; + } + if (!ServerInstance->Res) ServerInstance->Res = new DNS(ServerInstance); /** Note: This is safe, the method checks for user == NULL */ @@ -1247,52 +1260,22 @@ void ServerConfig::Read(bool bail, User* user, int pass) ServerInstance->WriteOpers("*** Successfully rehashed server."); } -bool ServerConfig::Downloading() -{ - if (isatty(0) && isatty(1) && isatty(2)) - { - printf("."); - fflush(stdout); - } - - /* Returns true if there are still files in the process of downloading */ - return (TotalDownloaded < IncludedFiles.size()); -} - -void ServerConfig::Complete(const std::string &filename, bool error) -{ - std::map::iterator x = IncludedFiles.find(filename); - - if (x != IncludedFiles.end()) - { - TotalDownloaded++; - if (error) - { - delete x->second; - x->second = NULL; - FileErrors++; - } - } - - return; -} - -void ServerConfig::StartDownloads() +/* XXX: This can and will block! */ +void ServerConfig::DoDownloads() { - if (isatty(0) && isatty(1) && isatty(2)) - printf("Downloading configuration "); - - TotalDownloaded = 0; - FileErrors = 0; + ServerInstance->Log(DEBUG,"In DoDownloads()"); /* Reads all local files into the IncludedFiles map, then initiates sockets for the remote ones */ for (std::map::iterator x = IncludedFiles.begin(); x != IncludedFiles.end(); ++x) { + if (CompletedFiles.find(x->first) != CompletedFiles.end()) + continue; + + ServerInstance->Log(DEBUG,"StartDownloads File: %s", x->first.c_str()); + std::string file = x->first; - ServerInstance->Log(DEBUG,"Begin download for %s", file.c_str()); if ((file[0] == '/') || (file.substr(0, 7) == "file://")) { - ServerInstance->Log(DEBUG,"Core-handled schema for %s", file.c_str()); /* For file:// schema files, we use std::ifstream which is a derivative of std::istream. * For all other file schemas, we use a std::stringstream. */ @@ -1311,7 +1294,6 @@ void ServerConfig::StartDownloads() x->second = NULL; FileErrors++; } - TotalDownloaded++; } else @@ -1330,11 +1312,16 @@ void ServerConfig::StartDownloads() delete x->second; x->second = NULL; } + else + { + /* Search new file here for more includes to parse */ + } } + CompletedFiles[x->first] = true; } } -bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream, int pass) +bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream, int pass, std::istream *scan_for_includes_only) { std::string line; std::istream* conf = NULL; @@ -1350,13 +1337,22 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o in_quote = false; in_comment = false; + if (scan_for_includes_only) + { + ServerInstance->Log(DEBUG,"scan_for_includes_only set"); + conf = scan_for_includes_only; + } + if (std::string(filename) == CONFIG_FILE) { - conf = new std::ifstream(filename); - if (conf->fail()) + if (!scan_for_includes_only) { - errorstream << "File " << filename << " could not be opened." << std::endl; - return false; + conf = new std::ifstream(filename); + if (conf->fail()) + { + errorstream << "File " << filename << " could not be opened." << std::endl; + return false; + } } } else @@ -1381,16 +1377,21 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } else { - if (x->second) - conf = IncludedFiles.find(filename)->second; - else + if (!scan_for_includes_only) { - errorstream << "File " << filename << " could not be opened." << std::endl; - return false; + if (x->second) + conf = IncludedFiles.find(filename)->second; + else + { + errorstream << "File " << filename << " could not be opened." << std::endl; + return false; + } } } } + ServerInstance->Log(DEBUG,"Start to read conf %s %08lx", filename, conf); + /* Start reading characters... */ while (conf->get(ch)) { @@ -1406,6 +1407,8 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o if ((character_count++ < 2) && (ch == '\xFF' || ch == '\xFE')) { errorstream << "File " << filename << " cannot be read, as it is encoded in braindead UTF-16. Save your file as plain ASCII!" << std::endl; + if (!scan_for_includes_only) + delete conf; return false; } @@ -1461,6 +1464,8 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o else { errorstream << "End of file after a \\, what did you want to escape?: " << filename << ":" << linenumber << std::endl; + if (!scan_for_includes_only) + delete conf; return false; } } @@ -1475,6 +1480,8 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o if (!in_quote) { errorstream << "Got another opening < when the first one wasn't closed: " << filename << ":" << linenumber << std::endl; + if (!scan_for_includes_only) + delete conf; return false; } } @@ -1483,6 +1490,8 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o if (in_quote) { errorstream << "We're in a quote but outside a tag, interesting. " << filename << ":" << linenumber << std::endl; + if (!scan_for_includes_only) + delete conf; return false; } else @@ -1533,14 +1542,20 @@ 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, pass)) + if (!this->ParseLine(target, line, linenumber, errorstream, pass, scan_for_includes_only)) + { + if (!scan_for_includes_only) + delete conf; return false; + } line.clear(); } else { errorstream << "Got a closing > when we weren't inside a tag: " << filename << ":" << linenumber << std::endl; + if (!scan_for_includes_only) + delete conf; return false; } } @@ -1554,15 +1569,17 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o is a newline missing from the end of the file: " << filename << ":" << linenumber << std::endl; } + if (!scan_for_includes_only) + delete conf; return true; } -bool ServerConfig::LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream, int pass) +bool ServerConfig::LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream, int pass, std::istream* scan_for_includs_only) { - return this->LoadConf(target, filename.c_str(), errorstream, pass); + return this->LoadConf(target, filename.c_str(), errorstream, pass, scan_for_includs_only); } -bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &linenumber, std::ostringstream &errorstream, int pass) +bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &linenumber, std::ostringstream &errorstream, int pass, std::istream* scan_for_includes_only) { std::string tagname; std::string current_key; @@ -1652,7 +1669,8 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &li else { /* Leaving quotes, we have the value */ - results.push_back(KeyVal(current_key, current_value)); + if (!scan_for_includes_only) + results.push_back(KeyVal(current_key, current_value)); // std::cout << "<" << tagname << ":" << current_key << "> " << current_value << std::endl; @@ -1660,8 +1678,8 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &li got_key = false; if ((tagname == "include") && (current_key == "file")) - { - if (!this->DoInclude(target, current_value, errorstream, pass)) + { + if (!this->DoInclude(target, current_value, errorstream, pass, scan_for_includes_only)) return false; } @@ -1681,12 +1699,13 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &li } /* Finished parsing the tag, add it to the config hash */ - target.insert(std::pair (tagname, results)); + if (!scan_for_includes_only) + target.insert(std::pair (tagname, results)); return true; } -bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream, int pass) +bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream, int pass, std::istream* scan_for_includes_only) { std::string confpath; std::string newfile; @@ -1712,7 +1731,7 @@ bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, st } } - return LoadConf(target, newfile, errorstream, pass); + return LoadConf(target, newfile, errorstream, pass, scan_for_includes_only); } bool ServerConfig::ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds) @@ -2080,11 +2099,7 @@ InspIRCd* ServerConfig::GetInstance() std::string ServerConfig::GetSID() { - std::string OurSID; - OurSID += (char)((sid / 100) + 48); - OurSID += (char)((sid / 10) % 10 + 48); - OurSID += (char)(sid % 10 + 48); - return OurSID; + return sid; } ValueItem::ValueItem(int value) @@ -2284,4 +2299,3 @@ bool DoneELine(ServerConfig* conf, const char* tag) conf->GetInstance()->XLines->CheckELines(); return true; } -