Skip to content

Commit fc4db35

Browse files
committed
wallet: Add ListWalletDir utility
ListWalletDir returns all available wallets in the current wallet directory. Based on MeshCollider work in pull bitcoin#11485.
1 parent 920c090 commit fc4db35

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

src/wallet/walletutil.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include <wallet/walletutil.h>
66

7+
#include <util.h>
8+
79
fs::path GetWalletDir()
810
{
911
fs::path path;
@@ -25,3 +27,51 @@ fs::path GetWalletDir()
2527

2628
return path;
2729
}
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+
std::vector<fs::path> paths;
56+
57+
for (auto it = fs::recursive_directory_iterator(wallet_dir); it != end(it); ++it) {
58+
if (it->status().type() == fs::directory_file && IsBerkeleyBtree(it->path() / "wallet.dat")) {
59+
// Found a directory which contains wallet.dat btree file, add it as a wallet.
60+
paths.emplace_back(fs::relative(it->path(), wallet_dir));
61+
} else if (it.level() == 0 && it->symlink_status().type() == fs::regular_file && IsBerkeleyBtree(it->path())) {
62+
if (it->path().filename() == "wallet.dat") {
63+
// Found top-level wallet.dat btree file, add top level directory ""
64+
// as a wallet.
65+
paths.emplace_back();
66+
} else {
67+
// Found top-level btree file not called wallet.dat. Current bitcoin
68+
// software will never create these files but will allow them to be
69+
// opened in a shared database environment for backwards compatibility.
70+
// Add it to the list of available wallets.
71+
paths.emplace_back(fs::relative(it->path(), wallet_dir));
72+
}
73+
}
74+
}
75+
76+
return paths;
77+
}

src/wallet/walletutil.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
#ifndef BITCOIN_WALLET_WALLETUTIL_H
66
#define BITCOIN_WALLET_WALLETUTIL_H
77

8-
#include <chainparamsbase.h>
9-
#include <util.h>
8+
#include <fs.h>
9+
10+
#include <vector>
1011

1112
//! Get the path of the wallet directory.
1213
fs::path GetWalletDir();
1314

15+
//! Get wallets in wallet directory.
16+
std::vector<fs::path> ListWalletDir();
17+
1418
#endif // BITCOIN_WALLET_WALLETUTIL_H

0 commit comments

Comments
 (0)