X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fconfigreader.cpp;h=2093c82c8e313366c820347560cabbf46e8eb7c3;hb=68730d4c9701b34c962302e6410908865fb2ba28;hp=a3471327918b5ca11ba0f8ff60deeee291b2b6fd;hpb=5f8f96e0b6ed20f01dcda78e19e6fb1168d27f5f;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/configreader.cpp b/src/configreader.cpp index a34713279..2093c82c8 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -157,7 +157,7 @@ void ServerConfig::Update005() void ServerConfig::Send005(User* user) { for (std::vector::iterator line = ServerInstance->Config->isupport.begin(); line != ServerInstance->Config->isupport.end(); line++) - user->WriteServ("005 %s %s", user->nick, line->c_str()); + user->WriteNumeric(005, "%s %s", user->nick, line->c_str()); } bool ServerConfig::CheckOnce(const char* tag) @@ -368,14 +368,9 @@ bool ValidateDnsServer(ServerConfig* conf, const char*, const char*, ValueItem & bool ValidateServerName(ServerConfig* conf, const char*, const char*, ValueItem &data) { + conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Validating server name"); /* If we already have a servername, and they changed it, we should throw an exception. */ - if ((strcasecmp(conf->ServerName, data.GetString())) && (*conf->ServerName)) - { - throw CoreException("Configuration error: You cannot change your servername at runtime! Please restart your server for this change to be applied."); - /* We don't actually reach this return of course... */ - return false; - } - if (!strchr(data.GetString(),'.')) + if (!strchr(data.GetString(), '.')) { conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: '%s' is not a fully-qualified domain name. Changed to '%s%c'",data.GetString(),data.GetString(),'.'); std::string moo = std::string(data.GetString()).append("."); @@ -478,6 +473,8 @@ bool ValidateInvite(ServerConfig* conf, const char*, const char*, ValueItem &dat bool ValidateSID(ServerConfig* conf, const char*, const char*, ValueItem &data) { + conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Validating server id"); + const char *sid = data.GetString(); if (*sid && !conf->GetInstance()->IsSID(sid)) @@ -485,6 +482,8 @@ bool ValidateSID(ServerConfig* conf, const char*, const char*, ValueItem &data) throw CoreException(std::string(sid) + " is not a valid server ID. A server ID must be 3 characters long, with the first character a digit and the next two characters a digit or letter."); } + strlcpy(conf->sid, sid, 5); + return true; } @@ -520,13 +519,6 @@ bool InitConnect(ServerConfig* conf, const char*) { conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Reading connect classes..."); - for (ClassVector::iterator i = conf->Classes.begin(); i != conf->Classes.end(); i++) - { - ConnectClass *c = *i; - - conf->GetInstance()->Logs->Log("CONFIG",DEBUG, "Address of class is %p", c); - } - for (ClassVector::iterator i = conf->Classes.begin(); i != conf->Classes.end() ; ) { ConnectClass* c = *i; @@ -809,10 +801,10 @@ void ServerConfig::Read(bool bail, User* user) {"options", "softlimit", MAXCLIENTS_S, new ValueContainerUInt (&this->SoftLimit), DT_INTEGER, ValidateSoftLimit}, {"options", "somaxconn", SOMAXCONN_S, new ValueContainerInt (&this->MaxConn), DT_INTEGER, ValidateMaxConn}, {"options", "moronbanner", "Youre banned!", new ValueContainerChar (this->MoronBanner), DT_CHARPTR, NoValidation}, - {"server", "name", "", new ValueContainerChar (this->ServerName), DT_HOSTNAME, ValidateServerName}, + {"server", "name", "", new ValueContainerChar (this->ServerName), DT_HOSTNAME|DT_BOOTONLY, ValidateServerName}, {"server", "description", "Configure Me", new ValueContainerChar (this->ServerDesc), DT_CHARPTR, NoValidation}, {"server", "network", "Network", new ValueContainerChar (this->Network), DT_NOSPACES, NoValidation}, - {"server", "id", "", new ValueContainerChar (this->sid), DT_CHARPTR, ValidateSID}, + {"server", "id", "", new ValueContainerChar (this->sid), DT_CHARPTR|DT_BOOTONLY, 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}, @@ -950,7 +942,7 @@ void ServerConfig::Read(bool bail, User* user) /* Make a copy here so if it fails then we can carry on running with an unaffected config */ newconfig.clear(); - if (this->LoadConf(newconfig, ServerInstance->ConfigFileName, errstr)) + if (this->DoInclude(newconfig, ServerInstance->ConfigFileName, errstr)) { /* If we succeeded, set the ircd config to the new one */ ServerInstance->Threads->Mutex(true); @@ -980,8 +972,14 @@ void ServerConfig::Read(bool bail, User* user) int dt = Values[Index].datatype; bool allow_newlines = ((dt & DT_ALLOW_NEWLINE) > 0); bool allow_wild = ((dt & DT_ALLOW_WILD) > 0); + bool bootonly = ((dt & DT_BOOTONLY) > 0); dt &= ~DT_ALLOW_NEWLINE; dt &= ~DT_ALLOW_WILD; + dt &= ~DT_BOOTONLY; + + /* Silently ignore boot only values */ + if (bootonly && !bail) + continue; ConfValue(this->config_data, Values[Index].tag, Values[Index].value, Values[Index].default_value, 0, item, MAXBUF, allow_newlines); ValueItem vi(item); @@ -990,7 +988,7 @@ void ServerConfig::Read(bool bail, User* user) throw CoreException("One or more values in your configuration file failed to validate. Please see your ircd.log for more information."); ServerInstance->Threads->Mutex(true); - switch (Values[Index].datatype) + switch (dt) { case DT_NOSPACES: { @@ -1004,6 +1002,7 @@ void ServerConfig::Read(bool bail, User* user) ValueContainerChar* vcc = (ValueContainerChar*)Values[Index].val; this->ValidateHostname(vi.GetString(), Values[Index].tag, Values[Index].value); vcc->Set(vi.GetString(), strlen(vi.GetString()) + 1); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"Got %s", vi.GetString()); } break; case DT_IPADDRESS: @@ -1214,14 +1213,14 @@ void ServerConfig::Read(bool bail, User* user) ServerInstance->SNO->WriteToSnoMask('A', "*** REHASH UNLOADED MODULE: %s",removing->c_str()); if (user) - user->WriteServ("973 %s %s :Module %s successfully unloaded.",user->nick, removing->c_str(), removing->c_str()); + user->WriteNumeric(973, "%s %s :Module %s successfully unloaded.",user->nick, removing->c_str(), removing->c_str()); rem++; } else { if (user) - user->WriteServ("972 %s %s :Failed to unload module %s: %s",user->nick, removing->c_str(), removing->c_str(), ServerInstance->Modules->LastError().c_str()); + user->WriteNumeric(972, "%s %s :Failed to unload module %s: %s",user->nick, removing->c_str(), removing->c_str(), ServerInstance->Modules->LastError().c_str()); } } } @@ -1235,14 +1234,14 @@ void ServerConfig::Read(bool bail, User* user) ServerInstance->SNO->WriteToSnoMask('A', "*** REHASH LOADED MODULE: %s",adding->c_str()); if (user) - user->WriteServ("975 %s %s :Module %s successfully loaded.",user->nick, adding->c_str(), adding->c_str()); + user->WriteNumeric(975, "%s %s :Module %s successfully loaded.",user->nick, adding->c_str(), adding->c_str()); add++; } else { if (user) - user->WriteServ("974 %s %s :Failed to load module %s: %s",user->nick, adding->c_str(), adding->c_str(), ServerInstance->Modules->LastError().c_str()); + user->WriteNumeric(974, "%s %s :Failed to load module %s: %s",user->nick, adding->c_str(), adding->c_str(), ServerInstance->Modules->LastError().c_str()); } } } @@ -1266,9 +1265,8 @@ void ServerConfig::Read(bool bail, User* user) } -bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::ostringstream &errorstream) +bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* filename, std::ostringstream &errorstream) { - std::ifstream conf(filename); std::string line; char ch; long linenumber; @@ -1282,6 +1280,8 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o in_quote = false; in_comment = false; + ServerInstance->Logs->Log("CONFIG", DEBUG, "Reading %s", filename); + /* Check if the file open failed first */ if (!conf) { @@ -1289,9 +1289,6 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o return false; } - /* Fix the chmod of the file to restrict it to the current user and group */ - chmod(filename,0600); - for (unsigned int t = 0; t < include_stack.size(); t++) { if (std::string(filename) == include_stack[t]) @@ -1305,9 +1302,9 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o include_stack.push_back(filename); /* Start reading characters... */ - while (conf.get(ch)) + while (!feof(conf)) { - + ch = fgetc(conf); /* * Fix for moronic windows issue spotted by Adremelech. * Some windows editors save text files as utf-16, which is @@ -1364,8 +1361,9 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o { line += ch; char real_character; - if (conf.get(real_character)) + if (!feof(conf)) { + real_character = fgetc(conf); if (real_character == 'n') real_character = '\n'; line += real_character; @@ -1470,9 +1468,9 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, const char* filename, std::o } -bool ServerConfig::LoadConf(ConfigDataHash &target, const std::string &filename, std::ostringstream &errorstream) +bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const std::string &filename, std::ostringstream &errorstream) { - return this->LoadConf(target, filename.c_str(), errorstream); + return this->LoadConf(target, conf, filename.c_str(), errorstream); } bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &linenumber, std::ostringstream &errorstream) @@ -1577,6 +1575,12 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &li if (!this->DoInclude(target, current_value, errorstream)) return false; } + else if ((tagname == "include") && (current_key == "executable")) + { + /* Pipe an executable and use its stdout as config data */ + if (!this->DoPipe(target, current_value, errorstream)) + return false; + } current_key.clear(); current_value.clear(); @@ -1599,6 +1603,22 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, std::string &line, long &li return true; } +bool ServerConfig::DoPipe(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream) +{ + FILE* conf = popen(file.c_str(), "r"); + bool ret = false; + + if (conf) + { + ret = LoadConf(target, conf, file.c_str(), errorstream); + pclose(conf); + } + else + errorstream << "Couldn't execute: " << file << std::endl; + + return ret; +} + bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream) { std::string confpath; @@ -1625,7 +1645,18 @@ bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, st } } - return LoadConf(target, newfile, errorstream); + FILE* conf = fopen(newfile.c_str(), "r"); + bool ret = false; + + if (conf) + { + ret = LoadConf(target, conf, newfile, errorstream); + fclose(conf); + } + else + errorstream << "Couldn't open config file: " << file << std::endl; + + return ret; } bool ServerConfig::ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds) @@ -2193,5 +2224,8 @@ void ConfigReaderThread::Run() { /* TODO: TheUser may be invalid by the time we get here! Check its validity, or pass a UID would be better */ ServerInstance->Config->Read(do_bail, TheUser); + ServerInstance->Threads->Mutex(true); + this->SetExitFlag(); + ServerInstance->Threads->Mutex(false); }