Changeset View
Changeset View
Standalone View
Standalone View
src/util.cpp
Show First 20 Lines • Show All 438 Lines • ▼ Show 20 Lines | for (const auto &arg : m_network_only_args) { | ||||
arg, m_network, m_network); | arg, m_network, m_network); | ||||
} | } | ||||
} | } | ||||
void ArgsManager::SelectConfigNetwork(const std::string &network) { | void ArgsManager::SelectConfigNetwork(const std::string &network) { | ||||
m_network = network; | m_network = network; | ||||
} | } | ||||
void ArgsManager::ParseParameters(int argc, const char *const argv[]) { | bool ArgsManager::ParseParameters(int argc, const char *const argv[], | ||||
std::string &error) { | |||||
LOCK(cs_args); | LOCK(cs_args); | ||||
m_override_args.clear(); | m_override_args.clear(); | ||||
for (int i = 1; i < argc; i++) { | for (int i = 1; i < argc; i++) { | ||||
std::string key(argv[i]); | std::string key(argv[i]); | ||||
std::string val; | std::string val; | ||||
size_t is_index = key.find('='); | size_t is_index = key.find('='); | ||||
if (is_index != std::string::npos) { | if (is_index != std::string::npos) { | ||||
Show All 17 Lines | #endif | ||||
} | } | ||||
// Check for -nofoo | // Check for -nofoo | ||||
if (InterpretNegatedOption(key, val)) { | if (InterpretNegatedOption(key, val)) { | ||||
m_override_args[key].clear(); | m_override_args[key].clear(); | ||||
} else { | } else { | ||||
m_override_args[key].push_back(val); | m_override_args[key].push_back(val); | ||||
} | } | ||||
// Check that the arg is known | |||||
if (!(IsSwitchChar(key[0]) && key.size() == 1)) { | |||||
if (!IsArgKnown(key, error)) { | |||||
error = strprintf("Invalid parameter %s", key.c_str()); | |||||
return false; | |||||
} | |||||
} | |||||
} | } | ||||
// we do not allow -includeconf from command line, so we clear it here | // we do not allow -includeconf from command line, so we clear it here | ||||
auto it = m_override_args.find("-includeconf"); | auto it = m_override_args.find("-includeconf"); | ||||
if (it != m_override_args.end()) { | if (it != m_override_args.end()) { | ||||
if (it->second.size() > 0) { | if (it->second.size() > 0) { | ||||
for (const auto &ic : it->second) { | for (const auto &ic : it->second) { | ||||
fprintf(stderr, | fprintf(stderr, | ||||
"warning: -includeconf cannot be used from " | "warning: -includeconf cannot be used from " | ||||
"commandline; ignoring -includeconf=%s\n", | "commandline; ignoring -includeconf=%s\n", | ||||
ic.c_str()); | ic.c_str()); | ||||
} | } | ||||
m_override_args.erase(it); | m_override_args.erase(it); | ||||
} | } | ||||
} | } | ||||
return true; | |||||
} | |||||
bool ArgsManager::IsArgKnown(const std::string &key, std::string &error) { | |||||
size_t option_index = key.find('.'); | |||||
std::string arg_no_net; | |||||
if (option_index == std::string::npos) { | |||||
arg_no_net = key; | |||||
} else { | |||||
arg_no_net = | |||||
std::string("-") + key.substr(option_index + 1, std::string::npos); | |||||
} | |||||
for (const auto &arg_map : m_available_args) { | |||||
if (arg_map.second.count(arg_no_net)) { | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | } | ||||
std::vector<std::string> ArgsManager::GetArgs(const std::string &strArg) const { | std::vector<std::string> ArgsManager::GetArgs(const std::string &strArg) const { | ||||
std::vector<std::string> result = {}; | std::vector<std::string> result = {}; | ||||
// special case | // special case | ||||
if (IsArgNegated(strArg)) { | if (IsArgNegated(strArg)) { | ||||
return result; | return result; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 366 Lines • ▼ Show 20 Lines | fs::path GetConfigFile(const std::string &confPath) { | ||||
fs::path pathConfigFile(confPath); | fs::path pathConfigFile(confPath); | ||||
if (!pathConfigFile.is_complete()) { | if (!pathConfigFile.is_complete()) { | ||||
pathConfigFile = GetDataDir(false) / pathConfigFile; | pathConfigFile = GetDataDir(false) / pathConfigFile; | ||||
} | } | ||||
return pathConfigFile; | return pathConfigFile; | ||||
} | } | ||||
void ArgsManager::ReadConfigStream(std::istream &stream) { | bool ArgsManager::ReadConfigStream(std::istream &stream, std::string &error, | ||||
bool ignore_invalid_keys) { | |||||
LOCK(cs_args); | LOCK(cs_args); | ||||
std::set<std::string> setOptions; | std::set<std::string> setOptions; | ||||
setOptions.insert("*"); | setOptions.insert("*"); | ||||
for (boost::program_options::detail::config_file_iterator | for (boost::program_options::detail::config_file_iterator | ||||
it(stream, setOptions), | it(stream, setOptions), | ||||
end; | end; | ||||
it != end; ++it) { | it != end; ++it) { | ||||
std::string strKey = std::string("-") + it->string_key; | std::string strKey = std::string("-") + it->string_key; | ||||
std::string strValue = it->value[0]; | std::string strValue = it->value[0]; | ||||
if (InterpretNegatedOption(strKey, strValue)) { | if (InterpretNegatedOption(strKey, strValue)) { | ||||
m_config_args[strKey].clear(); | m_config_args[strKey].clear(); | ||||
} else { | } else { | ||||
m_config_args[strKey].push_back(strValue); | m_config_args[strKey].push_back(strValue); | ||||
} | } | ||||
// Check that the arg is known | |||||
if (!IsArgKnown(strKey, error) && !ignore_invalid_keys) { | |||||
error = strprintf("Invalid configuration value %s", | |||||
it->string_key.c_str()); | |||||
return false; | |||||
} | |||||
} | } | ||||
return true; | |||||
} | } | ||||
void ArgsManager::ReadConfigFiles() { | bool ArgsManager::ReadConfigFiles(std::string &error, | ||||
bool ignore_invalid_keys) { | |||||
{ | { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
m_config_args.clear(); | m_config_args.clear(); | ||||
} | } | ||||
const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME); | const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME); | ||||
fs::ifstream stream(GetConfigFile(confPath)); | fs::ifstream stream(GetConfigFile(confPath)); | ||||
// ok to not have a config file | // ok to not have a config file | ||||
if (stream.good()) { | if (stream.good()) { | ||||
ReadConfigStream(stream); | if (!ReadConfigStream(stream, error, ignore_invalid_keys)) { | ||||
return false; | |||||
} | |||||
// if there is an -includeconf in the override args, but it is empty, | // if there is an -includeconf in the override args, but it is empty, | ||||
// that means the user passed '-noincludeconf' on the command line, in | // that means the user passed '-noincludeconf' on the command line, in | ||||
// which case we should not include anything | // which case we should not include anything | ||||
bool emptyIncludeConf; | bool emptyIncludeConf; | ||||
{ | { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
emptyIncludeConf = m_override_args.count("-includeconf") == 0; | emptyIncludeConf = m_override_args.count("-includeconf") == 0; | ||||
} | } | ||||
if (emptyIncludeConf) { | if (emptyIncludeConf) { | ||||
std::vector<std::string> includeconf(GetArgs("-includeconf")); | std::vector<std::string> includeconf(GetArgs("-includeconf")); | ||||
{ | { | ||||
// We haven't set m_network yet (that happens in | // We haven't set m_network yet (that happens in | ||||
// SelectParams()), so manually check for network.includeconf | // SelectParams()), so manually check for network.includeconf | ||||
// args. | // args. | ||||
std::vector<std::string> includeconf_net(GetArgs( | std::vector<std::string> includeconf_net(GetArgs( | ||||
std::string("-") + GetChainName() + ".includeconf")); | std::string("-") + GetChainName() + ".includeconf")); | ||||
includeconf.insert(includeconf.end(), includeconf_net.begin(), | includeconf.insert(includeconf.end(), includeconf_net.begin(), | ||||
includeconf_net.end()); | includeconf_net.end()); | ||||
} | } | ||||
for (const std::string &to_include : includeconf) { | for (const std::string &to_include : includeconf) { | ||||
fs::ifstream include_config(GetConfigFile(to_include)); | fs::ifstream include_config(GetConfigFile(to_include)); | ||||
if (include_config.good()) { | if (include_config.good()) { | ||||
ReadConfigStream(include_config); | if (!ReadConfigStream(include_config, error, | ||||
ignore_invalid_keys)) { | |||||
return false; | |||||
} | |||||
LogPrintf("Included configuration file %s\n", | LogPrintf("Included configuration file %s\n", | ||||
to_include.c_str()); | to_include.c_str()); | ||||
} else { | } else { | ||||
fprintf(stderr, "Failed to include configuration file %s\n", | fprintf(stderr, "Failed to include configuration file %s\n", | ||||
to_include.c_str()); | to_include.c_str()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// If datadir is changed in .conf file: | // If datadir is changed in .conf file: | ||||
ClearDatadirCache(); | ClearDatadirCache(); | ||||
if (!fs::is_directory(GetDataDir(false))) { | if (!fs::is_directory(GetDataDir(false))) { | ||||
throw std::runtime_error( | error = strprintf("specified data directory \"%s\" does not exist.", | ||||
strprintf("specified data directory \"%s\" does not exist.", | gArgs.GetArg("-datadir", "").c_str()); | ||||
gArgs.GetArg("-datadir", "").c_str())); | return false; | ||||
} | } | ||||
return true; | |||||
} | } | ||||
std::string ArgsManager::GetChainName() const { | std::string ArgsManager::GetChainName() const { | ||||
bool fRegTest = ArgsManagerHelper::GetNetBoolArg(*this, "-regtest"); | bool fRegTest = ArgsManagerHelper::GetNetBoolArg(*this, "-regtest"); | ||||
bool fTestNet = ArgsManagerHelper::GetNetBoolArg(*this, "-testnet"); | bool fTestNet = ArgsManagerHelper::GetNetBoolArg(*this, "-testnet"); | ||||
if (fTestNet && fRegTest) { | if (fTestNet && fRegTest) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
▲ Show 20 Lines • Show All 284 Lines • Show Last 20 Lines |