use iso9660_simple::{Read as ISORead, ISO9660};
use std::{
fs::File,
io::{Read, Seek, SeekFrom},
};
struct FileDevice(File);
impl ISORead for FileDevice {
fn read(&mut self, position: usize, buffer: &mut [u8]) -> Option<()> {
if self.0.seek(SeekFrom::Start(position as u64)).is_err() {
return None;
}
if self.0.read_exact(buffer).is_ok() {
Some(())
} else {
None
}
}
}
fn main() {
let mut args = std::env::args();
if args.len() < 2 {
println!("Usage: {} <filename>", args.next().unwrap());
std::process::exit(1);
}
let filename = args.nth(args.len() - 1).unwrap();
let file = File::open(filename).unwrap();
let mut iso = match ISO9660::from_device(FileDevice(file)) {
Some(iso) => iso,
None => {
eprintln!("It's not an ISO9660 (*.iso) file!");
std::process::exit(1);
},
};
fn dump(reader: &mut ISO9660, lba: u32, level: usize) {
let data = reader.read_directory(lba as _);
for i in data.collect::<Vec<_>>() {
let size = i.record.data_length.get();
println!("{:<offset$}[{}] {} - {} bytes", "", if i.is_file() { "FILE" } else { "DIR" }, i.name, size, offset = level * 4);
if ![".", ".."].contains(&i.name.as_str()) && i.is_folder() {
dump(reader, i.record.lba.get(), level + 1);
}
}
}
let root_lba = iso.root().lba.get();
dump(&mut iso, root_lba, 0);
}