Changeset View
Changeset View
Standalone View
Standalone View
src/util/system.cpp
Show First 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | static bool InterpretBool(const std::string &strValue) { | ||||
} | } | ||||
return (atoi(strValue) != 0); | return (atoi(strValue) != 0); | ||||
} | } | ||||
static std::string SettingName(const std::string &arg) { | static std::string SettingName(const std::string &arg) { | ||||
return arg.size() > 0 && arg[0] == '-' ? arg.substr(1) : arg; | return arg.size() > 0 && arg[0] == '-' ? arg.substr(1) : arg; | ||||
} | } | ||||
/** Internal helper functions for ArgsManager */ | |||||
class ArgsManagerHelper { | |||||
public: | |||||
/** Determine whether to use config settings in the default section, | |||||
* See also comments around ArgsManager::ArgsManager() below. */ | |||||
static inline bool UseDefaultSection(const ArgsManager &am, | |||||
const std::string &arg) | |||||
EXCLUSIVE_LOCKS_REQUIRED(am.cs_args) { | |||||
return (am.m_network == CBaseChainParams::MAIN || | |||||
am.m_network_only_args.count(arg) == 0); | |||||
} | |||||
static util::SettingsValue Get(const ArgsManager &am, | |||||
const std::string &arg) { | |||||
LOCK(am.cs_args); | |||||
return GetSetting(am.m_settings, am.m_network, SettingName(arg), | |||||
!UseDefaultSection(am, arg), | |||||
/* get_chain_name= */ false); | |||||
} | |||||
}; | |||||
/** | /** | ||||
* Interpret -nofoo as if the user supplied -foo=0. | * Interpret -nofoo as if the user supplied -foo=0. | ||||
* | * | ||||
* This method also tracks when the -no form was supplied, and if so, checks | * This method also tracks when the -no form was supplied, and if so, checks | ||||
* whether there was a double-negative (-nofoo=0 -> -foo=1). | * whether there was a double-negative (-nofoo=0 -> -foo=1). | ||||
* | * | ||||
* If there was not a double negative, it removes the "no" from the key | * If there was not a double negative, it removes the "no" from the key | ||||
* and returns false. | * and returns false. | ||||
▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | for (int i = 1; i < argc; i++) { | ||||
if (!ParseKeyValue(key, val)) { | if (!ParseKeyValue(key, val)) { | ||||
break; | break; | ||||
} | } | ||||
// Transform -foo to foo | // Transform -foo to foo | ||||
key.erase(0, 1); | key.erase(0, 1); | ||||
std::string section; | std::string section; | ||||
util::SettingsValue value = InterpretOption(section, key, val); | util::SettingsValue value = InterpretOption(section, key, val); | ||||
const unsigned int flags = FlagsOfKnownArg(key); | Optional<unsigned int> flags = GetArgFlags('-' + key); | ||||
if (flags) { | if (flags) { | ||||
if (!CheckValid(key, value, flags, error)) { | if (!CheckValid(key, value, *flags, error)) { | ||||
return false; | return false; | ||||
} | } | ||||
// Weird behavior preserved for backwards compatibility: command | // Weird behavior preserved for backwards compatibility: command | ||||
// line options with section prefixes are allowed but ignored. It | // line options with section prefixes are allowed but ignored. It | ||||
// would be better if these options triggered the Invalid parameter | // would be better if these options triggered the Invalid parameter | ||||
// error below. | // error below. | ||||
if (section.empty()) { | if (section.empty()) { | ||||
m_settings.command_line_options[key].push_back(value); | m_settings.command_line_options[key].push_back(value); | ||||
} | } | ||||
} else { | } else { | ||||
error = strprintf("Invalid parameter -%s", key); | error = strprintf("Invalid parameter -%s", key); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// we do not allow -includeconf from command line, so we clear it here | // we do not allow -includeconf from command line | ||||
bool success = true; | bool success = true; | ||||
if (auto *includes = | if (auto *includes = | ||||
util::FindKey(m_settings.command_line_options, "includeconf")) { | util::FindKey(m_settings.command_line_options, "includeconf")) { | ||||
for (const auto &include : util::SettingsSpan(*includes)) { | for (const auto &include : util::SettingsSpan(*includes)) { | ||||
error += | error += | ||||
"-includeconf cannot be used from commandline; -includeconf=" + | "-includeconf cannot be used from commandline; -includeconf=" + | ||||
include.get_str() + "\n"; | include.get_str() + "\n"; | ||||
success = false; | success = false; | ||||
} | } | ||||
} | } | ||||
return success; | return success; | ||||
} | } | ||||
unsigned int ArgsManager::FlagsOfKnownArg(const std::string &key) const { | Optional<unsigned int> ArgsManager::GetArgFlags(const std::string &name) const { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
for (const auto &arg_map : m_available_args) { | for (const auto &arg_map : m_available_args) { | ||||
const auto search = arg_map.second.find('-' + key); | const auto search = arg_map.second.find(name); | ||||
if (search != arg_map.second.end()) { | if (search != arg_map.second.end()) { | ||||
return search->second.m_flags; | return search->second.m_flags; | ||||
} | } | ||||
} | } | ||||
return ArgsManager::NONE; | return nullopt; | ||||
} | } | ||||
std::vector<std::string> ArgsManager::GetArgs(const std::string &strArg) const { | std::vector<std::string> ArgsManager::GetArgs(const std::string &strArg) const { | ||||
LOCK(cs_args); | |||||
bool ignore_default_section_config = | |||||
!ArgsManagerHelper::UseDefaultSection(*this, strArg); | |||||
std::vector<std::string> result; | std::vector<std::string> result; | ||||
for (const util::SettingsValue &value : | for (const util::SettingsValue &value : GetSettingsList(strArg)) { | ||||
util::GetSettingsList(m_settings, m_network, SettingName(strArg), | |||||
ignore_default_section_config)) { | |||||
result.push_back( | result.push_back( | ||||
value.isFalse() ? "0" : value.isTrue() ? "1" : value.get_str()); | value.isFalse() ? "0" : value.isTrue() ? "1" : value.get_str()); | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
bool ArgsManager::IsArgSet(const std::string &strArg) const { | bool ArgsManager::IsArgSet(const std::string &strArg) const { | ||||
return !ArgsManagerHelper::Get(*this, strArg).isNull(); | return !GetSetting(strArg).isNull(); | ||||
} | } | ||||
bool ArgsManager::IsArgNegated(const std::string &strArg) const { | bool ArgsManager::IsArgNegated(const std::string &strArg) const { | ||||
return ArgsManagerHelper::Get(*this, strArg).isFalse(); | return GetSetting(strArg).isFalse(); | ||||
} | } | ||||
std::string ArgsManager::GetArg(const std::string &strArg, | std::string ArgsManager::GetArg(const std::string &strArg, | ||||
const std::string &strDefault) const { | const std::string &strDefault) const { | ||||
const util::SettingsValue value = ArgsManagerHelper::Get(*this, strArg); | const util::SettingsValue value = GetSetting(strArg); | ||||
return value.isNull() | return value.isNull() | ||||
? strDefault | ? strDefault | ||||
: value.isFalse() ? "0" : value.isTrue() ? "1" : value.get_str(); | : value.isFalse() ? "0" : value.isTrue() ? "1" : value.get_str(); | ||||
} | } | ||||
int64_t ArgsManager::GetArg(const std::string &strArg, int64_t nDefault) const { | int64_t ArgsManager::GetArg(const std::string &strArg, int64_t nDefault) const { | ||||
const util::SettingsValue value = ArgsManagerHelper::Get(*this, strArg); | const util::SettingsValue value = GetSetting(strArg); | ||||
return value.isNull() | return value.isNull() | ||||
? nDefault | ? nDefault | ||||
: value.isFalse() | : value.isFalse() | ||||
? 0 | ? 0 | ||||
: value.isTrue() ? 1 | : value.isTrue() ? 1 | ||||
: value.isNum() ? value.get_int64() | : value.isNum() ? value.get_int64() | ||||
: atoi64(value.get_str()); | : atoi64(value.get_str()); | ||||
} | } | ||||
bool ArgsManager::GetBoolArg(const std::string &strArg, bool fDefault) const { | bool ArgsManager::GetBoolArg(const std::string &strArg, bool fDefault) const { | ||||
const util::SettingsValue value = ArgsManagerHelper::Get(*this, strArg); | const util::SettingsValue value = GetSetting(strArg); | ||||
return value.isNull() ? fDefault | return value.isNull() ? fDefault | ||||
: value.isBool() ? value.get_bool() | : value.isBool() ? value.get_bool() | ||||
: InterpretBool(value.get_str()); | : InterpretBool(value.get_str()); | ||||
} | } | ||||
bool ArgsManager::SoftSetArg(const std::string &strArg, | bool ArgsManager::SoftSetArg(const std::string &strArg, | ||||
const std::string &strValue) { | const std::string &strValue) { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
▲ Show 20 Lines • Show All 379 Lines • ▼ Show 20 Lines | if (!GetConfigOptions(stream, filepath, error, options, | ||||
m_config_sections)) { | m_config_sections)) { | ||||
return false; | return false; | ||||
} | } | ||||
for (const std::pair<std::string, std::string> &option : options) { | for (const std::pair<std::string, std::string> &option : options) { | ||||
std::string section; | std::string section; | ||||
std::string key = option.first; | std::string key = option.first; | ||||
util::SettingsValue value = | util::SettingsValue value = | ||||
InterpretOption(section, key, option.second); | InterpretOption(section, key, option.second); | ||||
const unsigned int flags = FlagsOfKnownArg(key); | Optional<unsigned int> flags = GetArgFlags('-' + key); | ||||
if (flags) { | if (flags) { | ||||
if (!CheckValid(key, value, flags, error)) { | if (!CheckValid(key, value, *flags, error)) { | ||||
return false; | return false; | ||||
} | } | ||||
m_settings.ro_config[section][key].push_back(value); | m_settings.ro_config[section][key].push_back(value); | ||||
} else { | } else { | ||||
if (ignore_invalid_keys) { | if (ignore_invalid_keys) { | ||||
LogPrintf("Ignoring unknown configuration value %s\n", | LogPrintf("Ignoring unknown configuration value %s\n", | ||||
option.first); | option.first); | ||||
} else { | } else { | ||||
Show All 18 Lines | bool ArgsManager::ReadConfigFiles(std::string &error, | ||||
fsbridge::ifstream stream(GetConfigFile(confPath)); | fsbridge::ifstream stream(GetConfigFile(confPath)); | ||||
// ok to not have a config file | // ok to not have a config file | ||||
if (stream.good()) { | if (stream.good()) { | ||||
if (!ReadConfigStream(stream, confPath, error, ignore_invalid_keys)) { | if (!ReadConfigStream(stream, confPath, error, ignore_invalid_keys)) { | ||||
return false; | return false; | ||||
} | } | ||||
// `-includeconf` cannot be included in the command line arguments | // `-includeconf` cannot be included in the command line arguments | ||||
// except as `-noincludeconf` (which indicates that no conf file should | // except as `-noincludeconf` (which indicates that no included conf | ||||
// be used). | // file should be used). | ||||
bool use_conf_file{true}; | bool use_conf_file{true}; | ||||
{ | { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
if (auto *includes = util::FindKey(m_settings.command_line_options, | if (auto *includes = util::FindKey(m_settings.command_line_options, | ||||
"includeconf")) { | "includeconf")) { | ||||
// ParseParameters() fails if a non-negated -includeconf is | // ParseParameters() fails if a non-negated -includeconf is | ||||
// passed on the command-line | // passed on the command-line | ||||
assert(util::SettingsSpan(*includes).last_negated()); | assert(util::SettingsSpan(*includes).last_negated()); | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | bool ArgsManager::ReadConfigFiles(std::string &error, | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
std::string ArgsManager::GetChainName() const { | std::string ArgsManager::GetChainName() const { | ||||
auto get_net = [&](const std::string &arg) { | auto get_net = [&](const std::string &arg) { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
util::SettingsValue value = | util::SettingsValue value = | ||||
GetSetting(m_settings, /* section= */ "", SettingName(arg), | util::GetSetting(m_settings, /* section= */ "", SettingName(arg), | ||||
/* ignore_default_section_config= */ false, | /* ignore_default_section_config= */ false, | ||||
/* get_chain_name= */ true); | /* get_chain_name= */ true); | ||||
return value.isNull() ? false | return value.isNull() ? false | ||||
: value.isBool() ? value.get_bool() | : value.isBool() ? value.get_bool() | ||||
: InterpretBool(value.get_str()); | : InterpretBool(value.get_str()); | ||||
}; | }; | ||||
const bool fRegTest = get_net("-regtest"); | const bool fRegTest = get_net("-regtest"); | ||||
const bool fTestNet = get_net("-testnet"); | const bool fTestNet = get_net("-testnet"); | ||||
const bool is_chain_arg_set = IsArgSet("-chain"); | const bool is_chain_arg_set = IsArgSet("-chain"); | ||||
if (int(is_chain_arg_set) + int(fRegTest) + int(fTestNet) > 1) { | if (int(is_chain_arg_set) + int(fRegTest) + int(fTestNet) > 1) { | ||||
throw std::runtime_error("Invalid combination of -regtest, -testnet " | throw std::runtime_error("Invalid combination of -regtest, -testnet " | ||||
"and -chain. Can use at most one."); | "and -chain. Can use at most one."); | ||||
} | } | ||||
if (fRegTest) { | if (fRegTest) { | ||||
return CBaseChainParams::REGTEST; | return CBaseChainParams::REGTEST; | ||||
} | } | ||||
if (fTestNet) { | if (fTestNet) { | ||||
return CBaseChainParams::TESTNET; | return CBaseChainParams::TESTNET; | ||||
} | } | ||||
return GetArg("-chain", CBaseChainParams::MAIN); | return GetArg("-chain", CBaseChainParams::MAIN); | ||||
} | } | ||||
bool ArgsManager::UseDefaultSection(const std::string &arg) const { | |||||
return m_network == CBaseChainParams::MAIN || | |||||
m_network_only_args.count(arg) == 0; | |||||
} | |||||
util::SettingsValue ArgsManager::GetSetting(const std::string &arg) const { | |||||
LOCK(cs_args); | |||||
return util::GetSetting(m_settings, m_network, SettingName(arg), | |||||
!UseDefaultSection(arg), | |||||
/* get_chain_name= */ false); | |||||
} | |||||
std::vector<util::SettingsValue> | |||||
ArgsManager::GetSettingsList(const std::string &arg) const { | |||||
LOCK(cs_args); | |||||
return util::GetSettingsList(m_settings, m_network, SettingName(arg), | |||||
!UseDefaultSection(arg)); | |||||
} | |||||
bool RenameOver(fs::path src, fs::path dest) { | bool RenameOver(fs::path src, fs::path dest) { | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
return MoveFileExA(src.string().c_str(), dest.string().c_str(), | return MoveFileExA(src.string().c_str(), dest.string().c_str(), | ||||
MOVEFILE_REPLACE_EXISTING) != 0; | MOVEFILE_REPLACE_EXISTING) != 0; | ||||
#else | #else | ||||
int rc = std::rename(src.string().c_str(), dest.string().c_str()); | int rc = std::rename(src.string().c_str(), dest.string().c_str()); | ||||
return (rc == 0); | return (rc == 0); | ||||
#endif /* WIN32 */ | #endif /* WIN32 */ | ||||
▲ Show 20 Lines • Show All 278 Lines • Show Last 20 Lines |