Line data Source code
1 : // Copyright (c) 2017-2019 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #include <wallet/walletutil.h> 6 : 7 : #include <logging.h> 8 : #include <util/system.h> 9 : 10 : bool ExistsBerkeleyDatabase(const fs::path& path); 11 : bool ExistsSQLiteDatabase(const fs::path& path); 12 : 13 1830 : fs::path GetWalletDir() 14 : { 15 1830 : fs::path path; 16 : 17 1830 : if (gArgs.IsArgSet("-walletdir")) { 18 35 : path = gArgs.GetArg("-walletdir", ""); 19 35 : if (!fs::is_directory(path)) { 20 : // If the path specified doesn't exist, we return the deliberately 21 : // invalid empty string. 22 0 : path = ""; 23 : } 24 : } else { 25 1795 : path = GetDataDir(); 26 : // If a wallets directory exists, use that, otherwise default to GetDataDir 27 1795 : if (fs::is_directory(path / "wallets")) { 28 1275 : path /= "wallets"; 29 : } 30 : } 31 : 32 : return path; 33 1830 : } 34 : 35 8 : std::vector<fs::path> ListWalletDir() 36 : { 37 8 : const fs::path wallet_dir = GetWalletDir(); 38 8 : const size_t offset = wallet_dir.string().size() + 1; 39 8 : std::vector<fs::path> paths; 40 8 : boost::system::error_code ec; 41 : 42 308 : for (auto it = fs::recursive_directory_iterator(wallet_dir, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) { 43 300 : if (ec) { 44 0 : LogPrintf("%s: %s %s\n", __func__, ec.message(), it->path().string()); 45 0 : continue; 46 : } 47 : 48 : // Get wallet path relative to walletdir by removing walletdir from the wallet path. 49 : // This can be replaced by boost::filesystem::lexically_relative once boost is bumped to 1.60. 50 300 : const fs::path path = it->path().string().substr(offset); 51 : 52 398 : if (it->status().type() == fs::directory_file && 53 98 : (ExistsBerkeleyDatabase(it->path()) || ExistsSQLiteDatabase(it->path()))) { 54 : // Found a directory which contains wallet.dat btree file, add it as a wallet. 55 44 : paths.emplace_back(path); 56 256 : } else if (it.level() == 0 && it->symlink_status().type() == fs::regular_file && ExistsBerkeleyDatabase(it->path())) { 57 18 : if (it->path().filename() == "wallet.dat") { 58 : // Found top-level wallet.dat btree file, add top level directory "" 59 : // as a wallet. 60 8 : paths.emplace_back(); 61 : } else { 62 : // Found top-level btree file not called wallet.dat. Current bitcoin 63 : // software will never create these files but will allow them to be 64 : // opened in a shared database environment for backwards compatibility. 65 : // Add it to the list of available wallets. 66 10 : paths.emplace_back(path); 67 : } 68 : } 69 300 : } 70 : 71 : return paths; 72 8 : }