forked from devaultcrypto/devault
/
walletutil.cpp
144 lines (126 loc) · 4.45 KB
/
walletutil.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright (c) 2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <util/system.h>
#include <wallet/walletutil.h>
#include <util/system.h>
fs::path GetWalletDir() {
fs::path path;
if (gArgs.IsArgSet("-walletdir")) {
path = gArgs.GetArg("-walletdir", "");
if (!fs::is_directory(path)) {
// If the path specified doesn't exist, we return the deliberately
// invalid empty string.
path = "";
}
} else {
path = GetDataDir();
// Always use a wallets directory
path /= "wallets";
}
return path;
}
fs::path GetWalletDirNoCreate(fs::path& added_dir) {
fs::path path;
if (gArgs.IsArgSet("-walletdir")) {
path = gArgs.GetArg("-walletdir", "");
if (!fs::is_directory(path)) {
// If the path specified doesn't exist, we return the deliberately
// invalid empty string.
path = "";
}
} else {
path = GetDataDirNoCreate();
// This will be Net specific addition
if (added_dir != "") {
path /= added_dir;
}
// Always assume a wallets directory
path /= "wallets";
}
return path;
}
fs::path GetWalletPathNoCreate(fs::path& added, const std::string& file) {
#ifdef NO_BOOST_FILESYSTEM
return GetWalletDirNoCreate(added) / file;
#else
return fs::absolute(file, GetWalletDirNoCreate(added));
#endif
}
static bool IsBerkeleyBtree(const fs::path &path) {
#ifndef NO_BOOST_FILESYSTEM
// 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;
}
// Magic bytes start at offset 12
file.seekg(12, std::ios::beg);
uint32_t data = 0;
// Read 4 bytes of file to compare against magic
file.read((char *)&data, sizeof(data));
// 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;
#else
return true;
#endif
}
std::vector<fs::path> ListWalletDir() {
const fs::path wallet_dir = GetWalletDir();
const size_t offset = wallet_dir.string().size() + 1;
std::vector<fs::path> paths;
#ifndef NO_BOOST_FILESYSTEM
for (auto it = fs::recursive_directory_iterator(wallet_dir);
it != fs::recursive_directory_iterator(); ++it) {
// Get wallet path relative to walletdir by removing walletdir from the
// wallet path. This can be replaced by
// boost::filesystem::lexically_relative once boost is bumped to 1.60.
const fs::path path = it->path().string().substr(offset);
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(path);
} 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(path);
}
}
}
#endif
return paths;
}
WalletLocation::WalletLocation(const std::string &name)
: m_name(name) {
#ifdef NO_BOOST_FILESYSTEM
m_path = fs::absolute( GetWalletDir() / name );
#else
m_path = fs::absolute( name, GetWalletDir() );
#endif
}
bool WalletLocation::Exists() const {
#ifdef NO_BOOST_FILESYSTEM
return fs::symlink_status(m_path).type() != fs::file_type::not_found;
#else
return fs::symlink_status(m_path).type() != fs::file_not_found;
#endif
}