From 56e370fbb9413260723c598048392219b1055ad0 Mon Sep 17 00:00:00 2001 From: willcl-ark Date: Thu, 9 Feb 2023 14:42:02 +0000 Subject: util: add ArgsManager datadir helper functions * Add ArgsManager::EnsureDataDir() Creates data directory if it doesn't exist * Add ArgsManager::GetConfigFilePath() Return config file path (read-only) --- src/util/system.cpp | 26 ++++++++++++++++++++++++++ src/util/system.h | 11 +++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/util/system.cpp b/src/util/system.cpp index e72c970157..d104d0d3f8 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -446,6 +446,27 @@ const fs::path& ArgsManager::GetDataDir(bool net_specific) const return path; } +void ArgsManager::EnsureDataDir() const +{ + /** + * "/wallets" subdirectories are created in all **new** + * datadirs, because wallet code will create new wallets in the "wallets" + * subdirectory only if exists already, otherwise it will create them in + * the top-level datadir where they could interfere with other files. + * Wallet init code currently avoids creating "wallets" directories itself + * for backwards compatibility, but this be changed in the future and + * wallet code here could go away (#16220). + */ + auto path{GetDataDir(false)}; + if (!fs::exists(path)) { + fs::create_directories(path / "wallets"); + } + path = GetDataDir(true); + if (!fs::exists(path)) { + fs::create_directories(path / "wallets"); + } +} + void ArgsManager::ClearPathCache() { LOCK(cs_args); @@ -965,6 +986,11 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& file return true; } +fs::path ArgsManager::GetConfigFilePath() const +{ + return GetConfigFile(GetPathArg("-conf", BITCOIN_CONF_FILENAME)); +} + bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys) { { diff --git a/src/util/system.h b/src/util/system.h index c053adf8c3..49fcd751fc 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -242,6 +242,11 @@ protected: void SelectConfigNetwork(const std::string& network); [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error); + + /** + * Return config file path (read-only) + */ + fs::path GetConfigFilePath() const; [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false); /** @@ -475,6 +480,12 @@ protected: */ void LogArgs() const; + /** + * If datadir does not exist, create it along with wallets/ + * subdirectory(s). + */ + void EnsureDataDir() const; + private: /** * Get data directory path -- cgit v1.2.3 From 64c105442ce8c10900ea6fbecdbcfebe42f2d387 Mon Sep 17 00:00:00 2001 From: willcl-ark Date: Thu, 9 Feb 2023 19:51:41 +0000 Subject: util: make GetDataDir read-only & create datadir.. .. only in bitcoind and bitcoin-qt This changes behaviour of GetConfigFilePath which now always returns the absolute path of the provided -conf argument. --- src/qt/bitcoin.cpp | 1 + src/util/system.cpp | 15 ++++----------- src/util/system.h | 1 - 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 59f433749d..c383c8bd58 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -167,6 +167,7 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans static bool InitSettings() { + gArgs.EnsureDataDir(); if (!gArgs.GetSettingsPath()) { return true; // Do nothing if settings file disabled. } diff --git a/src/util/system.cpp b/src/util/system.cpp index d104d0d3f8..77b659df7e 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -417,8 +417,7 @@ const fs::path& ArgsManager::GetDataDir(bool net_specific) const LOCK(cs_args); fs::path& 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 - // this function + // Used cached path if available if (!path.empty()) return path; const fs::path datadir{GetPathArg("-datadir")}; @@ -432,15 +431,8 @@ const fs::path& ArgsManager::GetDataDir(bool net_specific) const path = GetDefaultDataDir(); } - if (!fs::exists(path)) { - fs::create_directories(path / "wallets"); - } - if (net_specific && !BaseParams().DataDir().empty()) { path /= fs::PathFromString(BaseParams().DataDir()); - if (!fs::exists(path)) { - fs::create_directories(path / "wallets"); - } } return path; @@ -512,6 +504,7 @@ bool ArgsManager::IsArgSet(const std::string& strArg) const bool ArgsManager::InitSettings(std::string& error) { + EnsureDataDir(); if (!GetSettingsPath()) { return true; // Do nothing if settings file disabled. } @@ -999,8 +992,8 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys) m_config_sections.clear(); } - const fs::path conf_path = GetPathArg("-conf", BITCOIN_CONF_FILENAME); - std::ifstream stream{GetConfigFile(conf_path)}; + const auto conf_path{GetConfigFilePath()}; + std::ifstream stream{conf_path}; // not ok to have a config file specified that cannot be opened if (IsArgSet("-conf") && !stream.good()) { diff --git a/src/util/system.h b/src/util/system.h index 49fcd751fc..14f093501a 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -492,7 +492,6 @@ private: * * @param net_specific Append network identifier to the returned path * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned - * @post Returned directory path is created unless it is empty */ const fs::path& GetDataDir(bool net_specific) const; -- cgit v1.2.3