aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Barbosa <joao.paulo.barbosa@gmail.com>2018-09-22 00:24:29 +0100
committerJoão Barbosa <joao.paulo.barbosa@gmail.com>2018-10-18 23:26:06 +0100
commitfc4db35bfd78d85d6b52d5da3d89696160658450 (patch)
tree666a877d77af91faa2306408012ba8b6078946e1
parent920c090f63f4990bf0f3b3d1a6d3d8a8bcd14ba0 (diff)
wallet: Add ListWalletDir utility
ListWalletDir returns all available wallets in the current wallet directory. Based on MeshCollider work in pull #11485.
-rw-r--r--src/wallet/walletutil.cpp50
-rw-r--r--src/wallet/walletutil.h8
2 files changed, 56 insertions, 2 deletions
diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp
index 34c76ec4c4..c0c9afe13e 100644
--- a/src/wallet/walletutil.cpp
+++ b/src/wallet/walletutil.cpp
@@ -4,6 +4,8 @@
#include <wallet/walletutil.h>
+#include <util.h>
+
fs::path GetWalletDir()
{
fs::path path;
@@ -25,3 +27,51 @@ fs::path GetWalletDir()
return path;
}
+
+static bool IsBerkeleyBtree(const fs::path& path)
+{
+ // A Berkeley DB Btree file has at least 4K.
+ // This check also prevents opening lock files.
+ boost::system::error_code ec;
+ if (fs::file_size(path, ec) < 4096) return false;
+
+ fs::ifstream file(path.string(), std::ios::binary);
+ if (!file.is_open()) return false;
+
+ file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
+ uint32_t data = 0;
+ file.read((char*) &data, sizeof(data)); // Read 4 bytes of file to compare against magic
+
+ // Berkeley DB Btree magic bytes, from:
+ // https://github.com/file/file/blob/5824af38469ec1ca9ac3ffd251e7afe9dc11e227/magic/Magdir/database#L74-L75
+ // - big endian systems - 00 05 31 62
+ // - little endian systems - 62 31 05 00
+ return data == 0x00053162 || data == 0x62310500;
+}
+
+std::vector<fs::path> ListWalletDir()
+{
+ const fs::path wallet_dir = GetWalletDir();
+ std::vector<fs::path> paths;
+
+ for (auto it = fs::recursive_directory_iterator(wallet_dir); it != end(it); ++it) {
+ if (it->status().type() == fs::directory_file && IsBerkeleyBtree(it->path() / "wallet.dat")) {
+ // Found a directory which contains wallet.dat btree file, add it as a wallet.
+ paths.emplace_back(fs::relative(it->path(), wallet_dir));
+ } else if (it.level() == 0 && it->symlink_status().type() == fs::regular_file && IsBerkeleyBtree(it->path())) {
+ if (it->path().filename() == "wallet.dat") {
+ // Found top-level wallet.dat btree file, add top level directory ""
+ // as a wallet.
+ paths.emplace_back();
+ } else {
+ // Found top-level btree file not called wallet.dat. Current bitcoin
+ // software will never create these files but will allow them to be
+ // opened in a shared database environment for backwards compatibility.
+ // Add it to the list of available wallets.
+ paths.emplace_back(fs::relative(it->path(), wallet_dir));
+ }
+ }
+ }
+
+ return paths;
+}
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
index 7c42954616..77f5ca428d 100644
--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -5,10 +5,14 @@
#ifndef BITCOIN_WALLET_WALLETUTIL_H
#define BITCOIN_WALLET_WALLETUTIL_H
-#include <chainparamsbase.h>
-#include <util.h>
+#include <fs.h>
+
+#include <vector>
//! Get the path of the wallet directory.
fs::path GetWalletDir();
+//! Get wallets in wallet directory.
+std::vector<fs::path> ListWalletDir();
+
#endif // BITCOIN_WALLET_WALLETUTIL_H