BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
walletutil.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2018 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 <util.h>
8 
9 fs::path GetWalletDir()
10 {
11  fs::path path;
12 
13  if (gArgs.IsArgSet("-walletdir")) {
14  path = gArgs.GetArg("-walletdir", "");
15  if (!fs::is_directory(path)) {
16  // If the path specified doesn't exist, we return the deliberately
17  // invalid empty string.
18  path = "";
19  }
20  } else {
21  path = GetDataDir();
22  // If a wallets directory exists, use that, otherwise default to GetDataDir
23  if (fs::is_directory(path / "wallets")) {
24  path /= "wallets";
25  }
26  }
27 
28  return path;
29 }
30 
31 static bool IsBerkeleyBtree(const fs::path& path)
32 {
33  // A Berkeley DB Btree file has at least 4K.
34  // This check also prevents opening lock files.
35  boost::system::error_code ec;
36  if (fs::file_size(path, ec) < 4096) return false;
37 
38  fs::ifstream file(path.string(), std::ios::binary);
39  if (!file.is_open()) return false;
40 
41  file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
42  uint32_t data = 0;
43  file.read((char*) &data, sizeof(data)); // Read 4 bytes of file to compare against magic
44 
45  // Berkeley DB Btree magic bytes, from:
46  // https://github.com/file/file/blob/5824af38469ec1ca9ac3ffd251e7afe9dc11e227/magic/Magdir/database#L74-L75
47  // - big endian systems - 00 05 31 62
48  // - little endian systems - 62 31 05 00
49  return data == 0x00053162 || data == 0x62310500;
50 }
51 
52 std::vector<fs::path> ListWalletDir()
53 {
54  const fs::path wallet_dir = GetWalletDir();
55  const size_t offset = wallet_dir.string().size() + 1;
56  std::vector<fs::path> paths;
57 
58  for (auto it = fs::recursive_directory_iterator(wallet_dir); it != fs::recursive_directory_iterator(); ++it) {
59  // Get wallet path relative to walletdir by removing walletdir from the wallet path.
60  // This can be replaced by boost::filesystem::lexically_relative once boost is bumped to 1.60.
61  const fs::path path = it->path().string().substr(offset);
62 
63  if (it->status().type() == fs::directory_file && IsBerkeleyBtree(it->path() / "wallet.dat")) {
64  // Found a directory which contains wallet.dat btree file, add it as a wallet.
65  paths.emplace_back(path);
66  } else if (it.level() == 0 && it->symlink_status().type() == fs::regular_file && IsBerkeleyBtree(it->path())) {
67  if (it->path().filename() == "wallet.dat") {
68  // Found top-level wallet.dat btree file, add top level directory ""
69  // as a wallet.
70  paths.emplace_back();
71  } else {
72  // Found top-level btree file not called wallet.dat. Current bitcoin
73  // software will never create these files but will allow them to be
74  // opened in a shared database environment for backwards compatibility.
75  // Add it to the list of available wallets.
76  paths.emplace_back(path);
77  }
78  }
79  }
80 
81  return paths;
82 }
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: util.cpp:502
fs::ifstream ifstream
Definition: fs.h:90
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:9
ArgsManager gArgs
Definition: util.cpp:88
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:526
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:766
std::vector< fs::path > ListWalletDir()
Get wallets in wallet directory.
Definition: walletutil.cpp:52