#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
use crate::ported::errors;
use crate::ported::request::common::normalizePasswordStorePath;
use crate::ported::request::process::request;
use crate::ported::response;
use std::ffi::OsStr;
use std::fs;
pub fn listDirectories(request: &request) {
let mut responseData = response::MakeTreeResponse();
for store in request.Settings.Stores.values() { let mut store = store.clone();
let normalizedStorePath = match normalizePasswordStorePath(&store.Path) { Ok(p) => p,
Err(e) => { eprintln!(
"The password store '{:?}' is not accessible at its location: {}",
store, e
);
response::SendErrorAndExit( errors::Code::InaccessiblePasswordStore,
Some(response::params_of(&[
(errors::field::MESSAGE, "The password store is not accessible"),
(errors::field::ACTION, "tree"),
(errors::field::ERROR, &e),
(errors::field::STORE_ID, &store.ID),
(errors::field::STORE_NAME, &store.Name),
(errors::field::STORE_PATH, &store.Path),
])),
);
}
};
store.Path = normalizedStorePath.to_string_lossy().into_owned();
let mut directories: Vec<String> = Vec::new(); if let Err(e) = collect_dirs(&normalizedStorePath, &normalizedStorePath, &mut directories) {
eprintln!(
"Unable to list the directory tree in the password store '{:?}' at its location: {}",
store, e
);
response::SendErrorAndExit( errors::Code::UnableToListDirectoriesInPasswordStore,
Some(response::params_of(&[
(errors::field::MESSAGE, "Unable to list the directory tree in the password store"),
(errors::field::ACTION, "tree"),
(errors::field::ERROR, &e),
(errors::field::STORE_ID, &store.ID),
(errors::field::STORE_NAME, &store.Name),
(errors::field::STORE_PATH, &store.Path),
])),
);
}
for directory in directories.iter_mut() { *directory = directory.replace('\\', "/"); }
directories.sort(); responseData.Directories.insert(store.ID.clone(), directories); }
response::SendOk(responseData); }
fn collect_dirs(root: &std::path::Path, dir: &std::path::Path, out: &mut Vec<String>) -> Result<(), String> {
let rd = fs::read_dir(dir).map_err(|e| format!("{e}"))?;
for entry in rd {
let entry = entry.map_err(|e| format!("{e}"))?;
let path = entry.path();
let ft = entry.file_type().map_err(|e| format!("{e}"))?;
if !ft.is_dir() {
continue;
}
if path.file_name() == Some(OsStr::new(".git")) { continue;
}
let rel = path
.strip_prefix(root)
.map_err(|e| format!("{e}"))?
.to_string_lossy()
.into_owned();
if !rel.is_empty() {
out.push(rel);
}
collect_dirs(root, &path, out)?;
}
Ok(())
}
#[allow(non_snake_case)]
const _: () = ();