Skip to main content
Version: 3.0.0-rc.2

Read and extract files from UDF

[dependencies.hadris]
version = "3.0.0-rc.2"
default-features = false
features = ["std", "sync", "udf"]

UdfFs opens a volume on any hadris_storage block device, such as a host file, and implements the hadris-fs FileSystem trait, so Volume, its handles and the host helpers work on it.

use std::io::Read;

use hadris::fs::{MountOptions, OpenOptions};
use hadris::fs::sync::Volume;
use hadris::udf::UdfId;
use hadris::udf::sync::UdfFs;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let udf = UdfFs::mount(hadris::storage::host::FileDevice::open("disc.udf")?, MountOptions::new())?;
println!("volume: {}", udf.info().id(UdfId::LogicalVolume));
let vol = Volume::new(udf);

for entry in vol.read_dir("/")? {
let entry = entry?;
let kind = if entry.file_type().is_dir() { "dir " } else { "file" };
println!("{kind} {}", String::from_utf8_lossy(entry.name().as_bytes()));
}

let mut readme = Vec::new();
vol.open("/README.TXT", OpenOptions::new().read())?
.read_to_end(&mut readme)?;
std::fs::write("README.TXT", readme)?;
let tree = hadris::fs::sync::read_tree(&vol, "/")?;
hadris::fs::host::write_tree("out", &tree)?;
Ok(())
}

host::write_tree refuses names with separators or .. components and never writes through an existing host symlink, so an untrusted image cannot escape the target directory.

For an unknown ISO/UDF image, hadris::sync::detect lists a bridge as IsoUdfBridge, Iso and Udf, and hadris::sync::open mounts its UDF side. The hadris udf command provides listing and extraction for hosted workflows.