use std::fs::File;
use hadris_udf::UdfVolume;
use super::super::args::VerifyArgs;
use super::Result;
pub fn verify(args: VerifyArgs) -> Result<()> {
println!("Verifying: {}", args.input.display());
let file = File::open(&args.input)?;
let udf = match UdfVolume::open(file) {
Ok(fs) => {
println!(" [OK] Volume Recognition Sequence");
println!(" [OK] Anchor Volume Descriptor Pointer");
println!(" [OK] Volume Descriptor Sequence");
println!(" [OK] File Set Descriptor");
fs
}
Err(e) => {
println!(" [FAIL] Could not open UDF image: {e}");
return Err(e.into());
}
};
let info = udf.info();
println!(" Volume ID: {}", info.volume_id);
println!(" UDF revision: {}", info.udf_revision);
let root = match udf.root_dir() {
Ok(dir) => {
println!(" [OK] Root directory readable");
dir
}
Err(e) => {
println!(" [FAIL] Root directory: {e}");
return Err(e.into());
}
};
if args.verbose {
let mut files = 0usize;
let mut dirs = 0usize;
let mut errors = 0usize;
walk_tree(&udf, &root, &mut files, &mut dirs, &mut errors);
println!(" Directory tree: {files} files, {dirs} directories, {errors} errors");
if errors > 0 {
println!(" [WARN] {errors} directories could not be read");
} else {
println!(" [OK] Directory tree fully traversable");
}
}
println!("Verification complete.");
Ok(())
}
fn walk_tree(
udf: &UdfVolume<File>,
dir: &hadris_udf::UdfDir,
files: &mut usize,
dirs: &mut usize,
errors: &mut usize,
) {
for entry in dir.entries() {
if entry.is_dir() {
*dirs += 1;
let icb = entry.icb;
match udf.read_directory(&icb) {
Ok(subdir) => walk_tree(udf, &subdir, files, dirs, errors),
Err(_) => *errors += 1,
}
} else {
*files += 1;
}
}
}