crate::ix!();
#[cfg(target_os = "windows")]
pub fn get_default_data_dir() -> PathBuf {
let mut path: PathBuf = get_special_folder_path(csidl_appdata);
path.push("Bitcoin");
path
}
#[cfg(target_os = "macos")]
pub fn get_default_data_dir() -> PathBuf {
let mut path_ret = get_home_dir();
path_ret.push("Library/Application Support/Bitcoin");
path_ret
}
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
pub fn get_default_data_dir() -> PathBuf {
let mut path_ret = get_home_dir();
path_ret.push(".bitcoin");
path_ret
}
#[cfg(not(target_os = "windows"))]
pub fn get_home_dir() -> PathBuf {
let psz_home = env::var("HOME");
if psz_home.is_err() || psz_home.as_ref().unwrap().is_empty() {
PathBuf::from("/")
} else {
PathBuf::from(psz_home.unwrap())
}
}
impl ArgsManagerInner {
pub fn get_data_dir_base(&self) -> PathBuf {
self.get_data_dir(false)
}
pub fn get_data_dir_net(&self) -> PathBuf {
self.get_data_dir(true)
}
pub fn get_data_dir(&self, net_specific: bool) -> PathBuf {
let maybe_cached = match net_specific {
true => self.cached_network_datadir_path.as_ref(),
false => self.cached_datadir_path.as_ref()
};
if let Some(path) = maybe_cached {
return path.to_path_buf();
}
let mut buf: PathBuf = PathBuf::new();
let datadir: String = self.get_arg("-datadir","");
if !datadir.is_empty() {
buf.push(Path::new(&datadir));
if !buf.as_path().is_dir() {
buf.clear();
return buf;
}
} else {
buf.push(get_default_data_dir());
}
if net_specific {
buf.push(base_params().data_dir());
}
if std::fs::create_dir_all(&buf).is_ok() {
let mut subdir = buf.clone();
subdir.push("wallets");
let _ = std::fs::create_dir_all(subdir);
}
strip_redundant_last_elements_of_path(&mut buf);
buf
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
use std::fs;
use std::sync::{Mutex, OnceLock};
static M: OnceLock<Mutex<()>> = OnceLock::new();
fn lock() -> std::sync::MutexGuard<'static,()> { M.get_or_init(|| Mutex::new(())).lock().unwrap() }
#[test]
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
fn default_data_dir_is_in_home_bitcoin_on_unix() {
let _g = lock();
let tmp = tempfile::tempdir().unwrap();
env::set_var("HOME", tmp.path());
let d = get_default_data_dir();
assert!(d.ends_with(".bitcoin"));
}
#[test]
fn get_data_dir_uses_datadir_and_creates_subdirs() {
let _g = lock();
let tmp = tempfile::tempdir().unwrap();
let datadir = tmp.path().join("dd");
fs::create_dir_all(&datadir).unwrap();
let mut inner = ArgsManagerInner::default();
inner.force_set_arg("-datadir", datadir.to_str().unwrap());
select_base_params(base_chain_params::TESTNET);
let base = inner.get_data_dir_base();
assert_eq!(base, datadir);
let net = inner.get_data_dir_net();
assert!(net.ends_with("testnet3"));
assert!(net.join("wallets").exists(), "wallets/ should be created on first run");
}
}