Changeset View
Changeset View
Standalone View
Standalone View
src/util/system.cpp
Show First 20 Lines • Show All 238 Lines • ▼ Show 20 Lines | static bool CheckValid(const std::string &key, const util::SettingsValue &val, | ||||
if (val.isBool() && !(flags & ArgsManager::ALLOW_BOOL)) { | if (val.isBool() && !(flags & ArgsManager::ALLOW_BOOL)) { | ||||
error = strprintf( | error = strprintf( | ||||
"Negating of -%s is meaningless and therefore forbidden", key); | "Negating of -%s is meaningless and therefore forbidden", key); | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
namespace { | |||||
fs::path StripRedundantLastElementsOfPath(const fs::path &path) { | |||||
auto result = path; | |||||
while (result.filename().empty() || | |||||
fs::PathToString(result.filename()) == ".") { | |||||
result = result.parent_path(); | |||||
} | |||||
assert(fs::equivalent(result, path)); | |||||
return result; | |||||
} | |||||
} // namespace | |||||
// Define default constructor and destructor that are not inline, so code | // Define default constructor and destructor that are not inline, so code | ||||
// instantiating this class doesn't need to #include class definitions for all | // instantiating this class doesn't need to #include class definitions for all | ||||
// members. For example, m_settings has an internal dependency on univalue. | // members. For example, m_settings has an internal dependency on univalue. | ||||
ArgsManager::ArgsManager() {} | ArgsManager::ArgsManager() {} | ||||
ArgsManager::~ArgsManager() {} | ArgsManager::~ArgsManager() {} | ||||
const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const { | const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const { | ||||
std::set<std::string> unsuitables; | std::set<std::string> unsuitables; | ||||
▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | for (const auto &arg_map : m_available_args) { | ||||
const auto search = arg_map.second.find(name); | 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 std::nullopt; | return std::nullopt; | ||||
} | } | ||||
fs::path ArgsManager::GetPathArg(std::string pathlike_arg) const { | |||||
auto result = | |||||
fs::PathFromString(GetArg(pathlike_arg, "")).lexically_normal(); | |||||
// Remove trailing slash, if present. | |||||
return result.has_filename() ? result : result.parent_path(); | |||||
} | |||||
const fs::path &ArgsManager::GetBlocksDirPath() const { | const fs::path &ArgsManager::GetBlocksDirPath() const { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
fs::path &path = m_cached_blocks_path; | fs::path &path = m_cached_blocks_path; | ||||
// Cache the path to avoid calling fs::create_directories on every call of | // Cache the path to avoid calling fs::create_directories on every call of | ||||
// this function | // this function | ||||
if (!path.empty()) { | if (!path.empty()) { | ||||
return path; | return path; | ||||
} | } | ||||
if (IsArgSet("-blocksdir")) { | if (IsArgSet("-blocksdir")) { | ||||
path = fs::absolute(fs::PathFromString(GetArg("-blocksdir", ""))); | path = fs::absolute(GetPathArg("-blocksdir")); | ||||
if (!fs::is_directory(path)) { | if (!fs::is_directory(path)) { | ||||
path = ""; | path = ""; | ||||
return path; | return path; | ||||
} | } | ||||
} else { | } else { | ||||
path = GetDataDirBase(); | path = GetDataDirBase(); | ||||
} | } | ||||
path /= fs::PathFromString(BaseParams().DataDir()); | path /= fs::PathFromString(BaseParams().DataDir()); | ||||
path /= "blocks"; | path /= "blocks"; | ||||
fs::create_directories(path); | fs::create_directories(path); | ||||
return path; | return path; | ||||
} | } | ||||
const fs::path &ArgsManager::GetDataDir(bool net_specific) const { | const fs::path &ArgsManager::GetDataDir(bool net_specific) const { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
fs::path &path = | fs::path &path = | ||||
net_specific ? m_cached_network_datadir_path : m_cached_datadir_path; | net_specific ? m_cached_network_datadir_path : m_cached_datadir_path; | ||||
// Cache the path to avoid calling fs::create_directories on every call of | // Cache the path to avoid calling fs::create_directories on every call of | ||||
// this function | // this function | ||||
if (!path.empty()) { | if (!path.empty()) { | ||||
return path; | return path; | ||||
} | } | ||||
std::string datadir = GetArg("-datadir", ""); | |||||
const fs::path datadir{GetPathArg("-datadir")}; | |||||
if (!datadir.empty()) { | if (!datadir.empty()) { | ||||
path = fs::absolute( | path = fs::absolute(datadir); | ||||
StripRedundantLastElementsOfPath(fs::PathFromString(datadir))); | |||||
if (!fs::is_directory(path)) { | if (!fs::is_directory(path)) { | ||||
path = ""; | path = ""; | ||||
return path; | return path; | ||||
} | } | ||||
} else { | } else { | ||||
path = GetDefaultDataDir(); | path = GetDefaultDataDir(); | ||||
} | } | ||||
if (!fs::exists(path)) { | if (!fs::exists(path)) { | ||||
fs::create_directories(path / "wallets"); | fs::create_directories(path / "wallets"); | ||||
} | } | ||||
if (net_specific && !BaseParams().DataDir().empty()) { | if (net_specific && !BaseParams().DataDir().empty()) { | ||||
path /= fs::PathFromString(BaseParams().DataDir()); | path /= fs::PathFromString(BaseParams().DataDir()); | ||||
if (!fs::exists(path)) { | if (!fs::exists(path)) { | ||||
fs::create_directories(path / "wallets"); | fs::create_directories(path / "wallets"); | ||||
} | } | ||||
} | } | ||||
path = StripRedundantLastElementsOfPath(path); | |||||
return path; | return path; | ||||
} | } | ||||
void ArgsManager::ClearPathCache() { | void ArgsManager::ClearPathCache() { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
m_cached_datadir_path = fs::path(); | m_cached_datadir_path = fs::path(); | ||||
m_cached_network_datadir_path = fs::path(); | m_cached_network_datadir_path = fs::path(); | ||||
▲ Show 20 Lines • Show All 361 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
// Unix-like | // Unix-like | ||||
return pathRet / ".bitcoin"; | return pathRet / ".bitcoin"; | ||||
#endif | #endif | ||||
#endif | #endif | ||||
} | } | ||||
bool CheckDataDirOption() { | bool CheckDataDirOption() { | ||||
std::string datadir = gArgs.GetArg("-datadir", ""); | const fs::path datadir{gArgs.GetPathArg("-datadir")}; | ||||
return datadir.empty() || | return datadir.empty() || fs::is_directory(fs::absolute(datadir)); | ||||
fs::is_directory(fs::absolute(fs::PathFromString(datadir))); | |||||
} | } | ||||
fs::path GetConfigFile(const std::string &confPath) { | fs::path GetConfigFile(const std::string &confPath) { | ||||
return AbsPathForConfigVal(fs::PathFromString(confPath), false); | return AbsPathForConfigVal(fs::PathFromString(confPath), false); | ||||
} | } | ||||
static bool | static bool | ||||
GetConfigOptions(std::istream &stream, const std::string &filepath, | GetConfigOptions(std::istream &stream, const std::string &filepath, | ||||
▲ Show 20 Lines • Show All 564 Lines • Show Last 20 Lines |