diff options
-rw-r--r-- | src/inspircd.cpp | 2 | ||||
-rw-r--r-- | src/inspircd_io.cpp | 33 | ||||
-rw-r--r-- | src/modules.cpp | 3 |
3 files changed, 33 insertions, 5 deletions
diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 9dc99857b..37c98bb1b 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -120,6 +120,7 @@ int ep, lep, sep; #endif bool has_been_netsplit = false; +extern std::vector<std::string> include_stack; typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, irc::StrHashComp> user_hash; typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, irc::StrHashComp> chan_hash; @@ -263,6 +264,7 @@ void ReadConfig(bool bail, userrec* user) char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF],thold[MAXBUF],sqmax[MAXBUF],rqmax[MAXBUF]; ConnectClass c; std::stringstream errstr; + include_stack.clear(); if (!LoadConf(CONFIG_FILE,&config_f,&errstr)) { diff --git a/src/inspircd_io.cpp b/src/inspircd_io.cpp index e28290ec5..de3d23689 100644 --- a/src/inspircd_io.cpp +++ b/src/inspircd_io.cpp @@ -37,6 +37,7 @@ extern int openSockfd[MAXSOCKS]; extern time_t TIME; extern bool unlimitcore; extern int MaxConn; +std::vector<std::string> include_stack; void WriteOpers(char* text, ...); @@ -298,6 +299,15 @@ bool LoadConf(const char* filename, std::stringstream *target, std::stringstream } // Fix the chmod of the file to restrict it to the current user and group chmod(filename,0600); + for (int t = 0; t < include_stack.size(); t++) + { + if (std::string(filename) == include_stack[t]) + { + *errorstream << "File " << filename << " is included recursively (looped inclusion)." << endl; + return false; + } + } + include_stack.push_back(filename); // now open it FILE* conf = fopen(filename,"r"); char buffer[MAXBUF]; @@ -314,6 +324,7 @@ bool LoadConf(const char* filename, std::stringstream *target, std::stringstream if (!strncmp(buffer,"<include file=\"",15)) { char* buf = buffer; + char confpath[10240],newconf[10240]; // include file directive buf += 15; // advance to filename for (int j = 0; j < strlen(buffer); j++) @@ -325,13 +336,25 @@ bool LoadConf(const char* filename, std::stringstream *target, std::stringstream } } log(DEFAULT,"Opening included file '%s'",buf); + if (*buf != '/') + { + strlcpy(confpath,CONFIG_FILE,10240); + if (strstr(confpath,"/inspircd.conf")) + { + // leaves us with just the path + *(strstr(confpath,"/inspircd.conf")) = '\0'; + } + snprintf(newconf,10240,"%s/%s",confpath,buf); + } + else snprintf(newconf,10240,"%s",buf); std::stringstream merge(stringstream::in | stringstream::out); // recursively call LoadConf and get the new data, use the same errorstream - LoadConf(buf, &merge, errorstream); - // append &merge to the end of the file - std::string newstuff = merge.str(); - // append the new stuff to the end of the line - *target << newstuff; + if (LoadConf(newconf, &merge, errorstream)) + { + // append to the end of the file + std::string newstuff = merge.str(); + *target << newstuff; + } } else { diff --git a/src/modules.cpp b/src/modules.cpp index 14b2abb3e..964cd2b74 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -72,6 +72,8 @@ extern int MODCOUNT; extern std::vector<Module*> modules; extern std::vector<ircd_module*> factory; +extern std::vector<std::string> include_stack; + extern time_t TIME; extern int LogLevel; @@ -818,6 +820,7 @@ Module* Server::FindModule(std::string name) ConfigReader::ConfigReader() { + include_stack.clear(); this->cache = new std::stringstream(std::stringstream::in | std::stringstream::out); this->errorlog = new std::stringstream(std::stringstream::in | std::stringstream::out); this->readerror = LoadConf(CONFIG_FILE,this->cache,this->errorlog); |