X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fconfigreader.cpp;h=b5d999f1d2e543ec519fa3de82b62c808ef085ea;hb=84083a73e80734e39892f44411549d2381654c95;hp=2138d0638baba6d00ffac7d6dfdb7c992d544a3e;hpb=0e6f0d340ba68c8969608c70f57947577f028201;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/configreader.cpp b/src/configreader.cpp index 2138d0638..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,16 @@ 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 */ ServerInstance->Parser->SetupCommandTable(user); ServerInstance->Modules->LoadAll(); @@ -1208,6 +1223,10 @@ void ServerConfig::Read(bool bail, User* user, int pass) { for (std::vector::iterator adding = added_modules.begin(); adding != added_modules.end(); adding++) { + /* Skip over modules that are aleready loaded for some reason */ + if (ServerInstance->Modules->Find(*adding)) + continue; + if (bail) printf_c("[\033[1;32m*\033[0m] Loading module:\t\033[1;32m%s\033[0m\n", adding->c_str()); @@ -1241,24 +1260,22 @@ void ServerConfig::Read(bool bail, User* user, int pass) ServerInstance->WriteOpers("*** Successfully rehashed server."); } -bool ServerConfig::Downloading() +/* XXX: This can and will block! */ +void ServerConfig::DoDownloads() { - ServerInstance->Log(DEBUG, "ServerConfig::Downloading() TotalDownloaded %u of %u", TotalDownloaded, IncludedFiles.size()); - /* Returns true if there are still files in the process of downloading */ - return (TotalDownloaded < IncludedFiles.size()); -} + ServerInstance->Log(DEBUG,"In DoDownloads()"); -void ServerConfig::StartDownloads() -{ - TotalDownloaded = 0; /* 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 %s", file.c_str(), file.substr(0,7).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. */ @@ -1271,18 +1288,40 @@ void ServerConfig::StartDownloads() delete x->second; x->second = conf; } - + else + { + delete x->second; + x->second = NULL; + FileErrors++; + } TotalDownloaded++; } else { /* Modules handle these */ ServerInstance->Log(DEBUG,"Module-handled schema for %s", x->first.c_str()); + + /* For now, error it */ + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnDownloadFile, OnDownloadFile(file, x->second)); + if (MOD_RESULT == 0) + { + /* No module claimed this file */ + TotalDownloaded++; + FileErrors++; + 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; @@ -1298,19 +1337,28 @@ 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 { - /* Check if the file open failed first */ - if (IncludedFiles.find(filename) == IncludedFiles.end()) + std::map::iterator x = IncludedFiles.find(filename); + if (x == IncludedFiles.end()) { if (pass == 0) { @@ -1328,9 +1376,22 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } } else - conf = IncludedFiles.find(filename)->second; + { + if (!scan_for_includes_only) + { + 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)) { @@ -1346,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; } @@ -1401,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; } } @@ -1415,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; } } @@ -1423,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 @@ -1473,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; } } @@ -1494,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; @@ -1592,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; @@ -1600,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; } @@ -1621,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; @@ -1652,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) @@ -2020,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) @@ -2224,4 +2299,3 @@ bool DoneELine(ServerConfig* conf, const char* tag) conf->GetInstance()->XLines->CheckELines(); return true; } -