From 29822a263b3b408559257e9ef2bd29167e7573fa Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Wed, 10 Jul 2013 18:11:48 +0100 Subject: [PATCH] Add keys for all of the compile-time paths. Also, make all paths in the config relative to their associated directory. This reverts a change in 2.0 which turned out to be a terrible idea, especially for system-wide installations. --- docs/conf/inspircd.conf.example | 20 +++++++++---- docs/conf/modules.conf.example | 8 ++--- include/configreader.h | 46 +++++++++++++++++++++++------ src/configparser.cpp | 18 ++++++----- src/configreader.cpp | 14 ++++++++- src/inspircd.cpp | 2 +- src/logger.cpp | 2 +- src/modmanager_dynamic.cpp | 4 +-- src/modules.cpp | 5 ++-- src/modules/extra/m_ssl_gnutls.cpp | 8 ++--- src/modules/extra/m_ssl_openssl.cpp | 8 ++--- src/modules/m_nationalchars.cpp | 2 +- src/modules/m_xline_db.cpp | 2 +- 13 files changed, 95 insertions(+), 44 deletions(-) diff --git a/docs/conf/inspircd.conf.example b/docs/conf/inspircd.conf.example index 0e5d40c08..036a3ebfc 100644 --- a/docs/conf/inspircd.conf.example +++ b/docs/conf/inspircd.conf.example @@ -439,11 +439,11 @@ # This file has all the information about oper classes, types and o:lines. # You *MUST* edit it. - + # This file has all the information about server links and ulined servers. # You *MUST* edit it if you intend to link servers. - + #-#-#-#-#-#-#-#-#-#- MISCELLANEOUS CONFIGURATION -#-#-#-#-#-#-#-#-#-# # # @@ -453,7 +453,7 @@ # motd - displayed on connect and when a user executes /MOTD # rules - displayed when the user executes /RULES # Modules can also define their own files - + # Example of an executable file include. Note this will be read on rehash, # not when the command is run. @@ -807,6 +807,14 @@ # maxaway: Maximum length of an away message. maxaway="200"> +#-#-#-#-#-#-#-#-#-#-#-#-# PATHS CONFIGURATION #-#-#-#-#-#-#-#-#-#-#-#-# +# # +# This configuration tag defines the location that InspIRCd stores # +# various types of files such as configuration files, log files and # +# modules. You will probably not need to change these from the values # +# set when InspIRCd was built unless you are using a binary package # +# where you do not have the ability to set build time configuration. # +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Logging @@ -976,7 +984,7 @@ # provide almost all the features of InspIRCd. :) # # # # The default does nothing -- we include it for simplicity for you. # - + # Here are some pre-built modules.conf files that closely match the # default configurations of some popular IRCd's. You still may want to @@ -988,10 +996,10 @@ # recommended that you make your own modules file based on modules.conf.example. # Settings similar to UnrealIRCd defaults. -# +# # Settings similar to Charybdis IRCd defaults. -# +# ######################################################################### diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 7e1a9f5ad..228d96312 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -314,7 +314,7 @@ # specify some censor tags. See also: # # http://wiki.inspircd.org/Modules/censor # # -# +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # CGI:IRC module: Adds support for automatic host changing in CGI:IRC @@ -730,7 +730,7 @@ # specfiy below the path to the filter.conf file, or define some # # tags. # # # -# +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Gecosban: Implements extended ban r:, which stops anyone matching @@ -783,7 +783,7 @@ # specify below the path to the helpop.conf file, or if you like to # # make a mess, define your helpop tags in this conf. # # # -# +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # HIDECHANS module: Allows opers to hide their channels list from non- @@ -1232,7 +1232,7 @@ # Read the comment above in # # inspircd.conf.example for details. # # # -# +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Override module: Adds support for oper override diff --git a/include/configreader.h b/include/configreader.h index 0d514e41d..bf5acbbc8 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -184,6 +184,32 @@ class CoreExport ServerConfig void CrossCheckConnectBlocks(ServerConfig* current); public: + class ServerPaths + { + public: + /** Config path */ + std::string Config; + + /** Data path */ + std::string Data; + + /** Log path */ + std::string Log; + + /** Module path */ + std::string Module; + + ServerPaths() + : Config(CONFIG_PATH) + , Data(DATA_PATH) + , Log(LOG_PATH) + , Module(MOD_PATH) { } + + std::string PrependConfig(const std::string& fn) const { return ServerConfig::ExpandPath(Config, fn); } + std::string PrependData(const std::string& fn) const { return ServerConfig::ExpandPath(Data, fn); } + std::string PrependLog(const std::string& fn) const { return ServerConfig::ExpandPath(Log, fn); } + std::string PrependModule(const std::string& fn) const { return ServerConfig::ExpandPath(Module, fn); } + }; /** Get a configuration tag * @param tag The name of the tag to get @@ -220,6 +246,9 @@ class CoreExport ServerConfig */ ServerLimits Limits; + /** Locations of various types of file (config, module, etc). */ + ServerPaths Paths; + /** Configuration parsed from the command line. */ CommandLineConf cmdline; @@ -333,13 +362,6 @@ class CoreExport ServerConfig */ char DisabledCModes[64]; - /** The full path to the modules directory. - * This is either set at compile time, or - * overridden in the configuration file via - * the \ tag. - */ - std::string ModPath; - /** If set to true, then all opers on this server are * shown with a generic 'is an IRC operator' line rather * than the oper type. Oper types are still used internally. @@ -508,7 +530,7 @@ class CoreExport ServerConfig /** Returns true if the given string starts with a windows drive letter */ - bool StartsWithWindowsDriveLetter(const std::string &path); + static bool StartsWithWindowsDriveLetter(const std::string& path); bool ApplyDisabledCommands(const std::string& data); @@ -523,7 +545,13 @@ class CoreExport ServerConfig * @return True if the file exists and is readable. */ static bool FileExists(const char* file); - + + /** Expands a path fragment to a full path. + * @param base The base path to expand from + * @param fragment The path fragment to expand on top of base. + */ + static std::string ExpandPath(const std::string& base, const std::string& fragment); + /** Escapes a value for storage in a configuration key. * @param str The string to escape. * @param xml Are we using the XML config format? diff --git a/src/configparser.cpp b/src/configparser.cpp index f3e79e2fd..1783e901e 100644 --- a/src/configparser.cpp +++ b/src/configparser.cpp @@ -323,9 +323,10 @@ void ParseStack::DoReadFile(const std::string& key, const std::string& name, int if (exec && (flags & FLAG_NO_EXEC)) throw CoreException("Invalid tag in file included with noexec=\"yes\""); - FileWrapper file(exec ? popen(name.c_str(), "r") : fopen(name.c_str(), "r"), exec); + std::string path = ServerInstance->Config->Paths.PrependConfig(name); + FileWrapper file(exec ? popen(name.c_str(), "r") : fopen(path.c_str(), "r"), exec); if (!file) - throw CoreException("Could not read \"" + name + "\" for \"" + key + "\" file"); + throw CoreException("Could not read \"" + path + "\" for \"" + key + "\" file"); file_cache& cache = FilesOutput[key]; cache.clear(); @@ -345,23 +346,24 @@ void ParseStack::DoReadFile(const std::string& key, const std::string& name, int bool ParseStack::ParseFile(const std::string& name, int flags, const std::string& mandatory_tag) { - ServerInstance->Logs->Log("CONFIG", LOG_DEBUG, "Reading file %s", name.c_str()); + std::string path = ServerInstance->Config->Paths.PrependConfig(name); + ServerInstance->Logs->Log("CONFIG", LOG_DEBUG, "Reading file %s", path.c_str()); for (unsigned int t = 0; t < reading.size(); t++) { if (std::string(name) == reading[t]) { - throw CoreException("File " + name + " is included recursively (looped inclusion)"); + throw CoreException("File " + path + " is included recursively (looped inclusion)"); } } /* It's not already included, add it to the list of files we've loaded */ - FileWrapper file(fopen(name.c_str(), "r")); + FileWrapper file(fopen(path.c_str(), "r")); if (!file) - throw CoreException("Could not read \"" + name + "\" for include"); + throw CoreException("Could not read \"" + path + "\" for include"); - reading.push_back(name); - Parser p(*this, flags, file, name, mandatory_tag); + reading.push_back(path); + Parser p(*this, flags, file, path, mandatory_tag); bool ok = p.outer_parse(); reading.pop_back(); return ok; diff --git a/src/configreader.cpp b/src/configreader.cpp index 27b9e5c77..af7a8ca59 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -383,7 +383,6 @@ void ServerConfig::Fill() AdminName = ConfValue("admin")->getString("name", ""); AdminEmail = ConfValue("admin")->getString("email", "null@example.com"); AdminNick = ConfValue("admin")->getString("nick", "admin"); - ModPath = ConfValue("path")->getString("moduledir", MOD_PATH); NetBufferSize = ConfValue("performance")->getInt("netbuffersize", 10240, 1024, 65534); dns_timeout = ConfValue("dns")->getInt("timeout", 5); DisabledCommands = ConfValue("disabled")->getString("commands", ""); @@ -417,6 +416,10 @@ void ServerConfig::Fill() Limits.MaxGecos = ConfValue("limits")->getInt("maxgecos", 128); Limits.MaxAway = ConfValue("limits")->getInt("maxaway", 200); Limits.MaxLine = ConfValue("limits")->getInt("maxline", 512); + Paths.Config = ConfValue("path")->getString("configdir", CONFIG_PATH); + Paths.Data = ConfValue("path")->getString("datadir", DATA_PATH); + Paths.Log = ConfValue("path")->getString("logdir", LOG_PATH); + Paths.Module = ConfValue("path")->getString("moduledir", MOD_PATH); InvBypassModes = options->getBool("invitebypassmodes", true); NoSnoticeStack = options->getBool("nosnoticestack", false); @@ -791,6 +794,15 @@ std::string ServerConfig::Escape(const std::string& str, bool xml) return escaped; } +std::string ServerConfig::ExpandPath(const std::string& base, const std::string& fragment) +{ + // The fragment is an absolute path, don't modify it. + if (fragment[0] == '/' || ServerConfig::StartsWithWindowsDriveLetter(fragment)) + return fragment; + + return base + '/' + fragment; +} + const char* ServerConfig::CleanFilename(const char* name) { const char* p = name + strlen(name); diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 59c65b931..f2095c4a2 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -207,7 +207,7 @@ void InspIRCd::WritePID(const std::string &filename) #ifndef _WIN32 std::string fname(filename); if (fname.empty()) - fname = DATA_PATH "/inspircd.pid"; + fname = ServerInstance->Config->Paths.PrependData("inspircd.pid"); std::ofstream outfile(fname.c_str()); if (outfile.is_open()) { diff --git a/src/logger.cpp b/src/logger.cpp index 47c726c51..61ac517c7 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -112,7 +112,7 @@ void LogManager::OpenFileLogs() loglevel = LOG_NONE; } FileWriter* fw; - std::string target = tag->getString("target"); + std::string target = ServerInstance->Config->Paths.PrependLog(tag->getString("target")); std::map::iterator fwi = logmap.find(target); if (fwi == logmap.end()) { diff --git a/src/modmanager_dynamic.cpp b/src/modmanager_dynamic.cpp index 92a7e0a32..750a1c448 100644 --- a/src/modmanager_dynamic.cpp +++ b/src/modmanager_dynamic.cpp @@ -37,7 +37,7 @@ bool ModuleManager::Load(const std::string& filename, bool defer) if (filename.find('/') != std::string::npos) return false; - const std::string moduleFile = ServerInstance->Config->ModPath + "/" + filename; + const std::string moduleFile = ServerInstance->Config->Paths.PrependModule(filename); if (!ServerConfig::FileExists(moduleFile.c_str())) { @@ -190,7 +190,7 @@ void ModuleManager::LoadAll() std::cout << std::endl << "Loading core commands"; fflush(stdout); - DIR* library = opendir(ServerInstance->Config->ModPath.c_str()); + DIR* library = opendir(ServerInstance->Config->Paths.Module.c_str()); if (library) { dirent* entry = NULL; diff --git a/src/modules.cpp b/src/modules.cpp index 5fc8ffc47..47c994088 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -577,7 +577,8 @@ FileReader::FileReader(const std::string& filename) void FileReader::Load(const std::string& filename) { // If the file is stored in the file cache then we used that version instead. - ConfigFileCache::iterator it = ServerInstance->Config->Files.find(filename); + std::string realName = ServerInstance->Config->Paths.PrependConfig(filename); + ConfigFileCache::iterator it = ServerInstance->Config->Files.find(realName); if (it != ServerInstance->Config->Files.end()) { this->lines = it->second; @@ -586,7 +587,7 @@ void FileReader::Load(const std::string& filename) { lines.clear(); - std::ifstream stream(filename.c_str()); + std::ifstream stream(realName.c_str()); if (!stream.is_open()) throw CoreException(filename + " does not exist or is not readable!"); diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index a3502a57b..28755f05e 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -684,10 +684,10 @@ class ModuleSSLGnuTLS : public Module ConfigTag* Conf = ServerInstance->Config->ConfValue("gnutls"); - cafile = Conf->getString("cafile", CONFIG_PATH "/ca.pem"); - crlfile = Conf->getString("crlfile", CONFIG_PATH "/crl.pem"); - certfile = Conf->getString("certfile", CONFIG_PATH "/cert.pem"); - keyfile = Conf->getString("keyfile", CONFIG_PATH "/key.pem"); + cafile = ServerInstance->Config->Paths.PrependConfig(Conf->getString("cafile", "ca.pem")); + crlfile = ServerInstance->Config->Paths.PrependConfig(Conf->getString("crlfile", "crl.pem")); + certfile = ServerInstance->Config->Paths.PrependConfig(Conf->getString("certfile", "cert.pem")); + keyfile = ServerInstance->Config->Paths.PrependConfig(Conf->getString("keyfile", "key.pem")); int dh_bits = Conf->getInt("dhbits"); std::string hashname = Conf->getString("hash", "md5"); diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 29f574fd0..c94527ab0 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -558,10 +558,10 @@ class ModuleSSLOpenSSL : public Module ConfigTag* conf = ServerInstance->Config->ConfValue("openssl"); - cafile = conf->getString("cafile", CONFIG_PATH "/ca.pem"); - certfile = conf->getString("certfile", CONFIG_PATH "/cert.pem"); - keyfile = conf->getString("keyfile", CONFIG_PATH "/key.pem"); - dhfile = conf->getString("dhfile", CONFIG_PATH "/dhparams.pem"); + cafile = ServerInstance->Config->Paths.PrependConfig(conf->getString("cafile", "ca.pem")); + certfile = ServerInstance->Config->Paths.PrependConfig(conf->getString("certfile", "cert.pem")); + keyfile = ServerInstance->Config->Paths.PrependConfig(conf->getString("keyfile", "key.pem")); + dhfile = ServerInstance->Config->Paths.PrependConfig(conf->getString("dhfile", "dhparams.pem")); std::string hash = conf->getString("hash", "md5"); iohook.digest = EVP_get_digestbyname(hash.c_str()); diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index 10347ac67..99e525398 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -298,7 +298,7 @@ class ModuleNationalChars : public Module /*so Bynets Unreal distribution stuff*/ void loadtables(std::string filename, unsigned char ** tables, unsigned char cnt, char faillimit) { - std::ifstream ifs(filename.c_str()); + std::ifstream ifs(ServerInstance->Config->Paths.PrependConfig(filename).c_str()); if (ifs.fail()) { ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "loadtables() called for missing file: %s", filename.c_str()); diff --git a/src/modules/m_xline_db.cpp b/src/modules/m_xline_db.cpp index df6f4c10c..63eb6d3ee 100644 --- a/src/modules/m_xline_db.cpp +++ b/src/modules/m_xline_db.cpp @@ -36,7 +36,7 @@ class ModuleXLineDB : public Module * ...and so is discarding all current in-memory XLines for the ones in the database. */ ConfigTag* Conf = ServerInstance->Config->ConfValue("xlinedb"); - xlinedbpath = Conf->getString("filename", DATA_PATH "/xline.db"); + xlinedbpath = ServerInstance->Config->Paths.PrependData(Conf->getString("filename", "xline.db")); // Read xlines before attaching to events ReadDatabase(); -- 2.39.5