diff options
author | Karl-Johan Alm <karljohan-alm@garage.co.jp> | 2018-04-18 14:35:44 +0900 |
---|---|---|
committer | Karl-Johan Alm <karljohan-alm@garage.co.jp> | 2018-04-26 12:46:28 +0900 |
commit | 629ff8c35845af95c95e24cfdda25f9991f95ae5 (patch) | |
tree | 9c2cfc75b67631be7c21cb19a81fe63d750edf03 | |
parent | a0079d4b6dc67be3889af9a16eda89b3c4b33bc5 (diff) |
-includeconf=<path> support in config handler, for including external configuration files
-rw-r--r-- | src/bitcoin-cli.cpp | 2 | ||||
-rw-r--r-- | src/bitcoind.cpp | 2 | ||||
-rw-r--r-- | src/init.cpp | 1 | ||||
-rw-r--r-- | src/interfaces/node.cpp | 2 | ||||
-rw-r--r-- | src/interfaces/node.h | 2 | ||||
-rw-r--r-- | src/qt/bitcoin.cpp | 2 | ||||
-rw-r--r-- | src/util.cpp | 35 | ||||
-rw-r--r-- | src/util.h | 2 |
8 files changed, 41 insertions, 7 deletions
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 26a9231308..c1f6c2294d 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -107,7 +107,7 @@ static int AppInitRPC(int argc, char* argv[]) return EXIT_FAILURE; } try { - gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + gArgs.ReadConfigFiles(); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return EXIT_FAILURE; diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 0dc2dfbf7d..38d5bb7aa1 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -92,7 +92,7 @@ bool AppInit(int argc, char* argv[]) } try { - gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + gArgs.ReadConfigFiles(); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; diff --git a/src/init.cpp b/src/init.cpp index f403f90b08..1bd2e4c992 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -361,6 +361,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf(_("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (default: %s)"), DEFAULT_DEBUGLOGFILE)); if (showDebug) strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER)); + strUsage += HelpMessageOpt("-includeconf=<file>", _("Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)")); strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup")); strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE)); strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 55786c807f..14af44f924 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -52,7 +52,7 @@ class NodeImpl : public Node { gArgs.ParseParameters(argc, argv); } - void readConfigFile(const std::string& conf_path) override { gArgs.ReadConfigFile(conf_path); } + void readConfigFiles() override { gArgs.ReadConfigFiles(); } bool softSetArg(const std::string& arg, const std::string& value) override { return gArgs.SoftSetArg(arg, value); } bool softSetBoolArg(const std::string& arg, bool value) override { return gArgs.SoftSetBoolArg(arg, value); } void selectParams(const std::string& network) override { SelectParams(network); } diff --git a/src/interfaces/node.h b/src/interfaces/node.h index 3cebe53eb0..d9a48e2563 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -48,7 +48,7 @@ public: virtual bool softSetBoolArg(const std::string& arg, bool value) = 0; //! Load settings from configuration file. - virtual void readConfigFile(const std::string& conf_path) = 0; + virtual void readConfigFiles() = 0; //! Choose network parameters. virtual void selectParams(const std::string& network) = 0; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 57fe4552a1..c0fb641b1c 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -616,7 +616,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } try { - node->readConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + node->readConfigFiles(); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); diff --git a/src/util.cpp b/src/util.cpp index 9a3067259f..58ef27b94f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -445,6 +445,17 @@ void ArgsManager::ParseParameters(int argc, const char* const argv[]) m_override_args[key].push_back(val); } } + + // we do not allow -includeconf from command line, so we clear it here + auto it = m_override_args.find("-includeconf"); + if (it != m_override_args.end()) { + if (it->second.size() > 0) { + for (const auto& ic : it->second) { + fprintf(stderr, "warning: -includeconf cannot be used from commandline; ignoring -includeconf=%s\n", ic.c_str()); + } + m_override_args.erase(it); + } + } } std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg) const @@ -706,18 +717,40 @@ void ArgsManager::ReadConfigStream(std::istream& stream) } } -void ArgsManager::ReadConfigFile(const std::string& confPath) +void ArgsManager::ReadConfigFiles() { { LOCK(cs_args); m_config_args.clear(); } + const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME); fs::ifstream stream(GetConfigFile(confPath)); // ok to not have a config file if (stream.good()) { ReadConfigStream(stream); + // if there is an -includeconf in the override args, but it is empty, that means the user + // passed '-noincludeconf' on the command line, in which case we should not include anything + if (m_override_args.count("-includeconf") == 0) { + std::vector<std::string> includeconf(GetArgs("-includeconf")); + { + // We haven't set m_network yet (that happens in SelectParams()), so manually check + // for network.includeconf args. + std::vector<std::string> includeconf_net(GetArgs(std::string("-") + GetChainName() + ".includeconf")); + includeconf.insert(includeconf.end(), includeconf_net.begin(), includeconf_net.end()); + } + + for (const std::string& to_include : includeconf) { + fs::ifstream include_config(GetConfigFile(to_include)); + if (include_config.good()) { + ReadConfigStream(include_config); + LogPrintf("Included configuration file %s\n", to_include.c_str()); + } else { + fprintf(stderr, "Failed to include configuration file %s\n", to_include.c_str()); + } + } + } } // If datadir is changed in .conf file: diff --git a/src/util.h b/src/util.h index ce94f396af..420ce7a1ea 100644 --- a/src/util.h +++ b/src/util.h @@ -140,7 +140,7 @@ public: void SelectConfigNetwork(const std::string& network); void ParseParameters(int argc, const char*const argv[]); - void ReadConfigFile(const std::string& confPath); + void ReadConfigFiles(); /** * Log warnings for options in m_section_only_args when |