1use iso9660_simple::{Read as ISORead, ISO9660};
2use std::{
3 fs::File,
4 io::{Read, Seek, SeekFrom},
5};
6
7struct FileDevice(File);
8
9impl ISORead for FileDevice {
10 fn read(&mut self, position: usize, buffer: &mut [u8]) -> Option<()> {
11 if self.0.seek(SeekFrom::Start(position as u64)).is_err() {
12 return None;
13 }
14
15 if self.0.read_exact(buffer).is_ok() {
16 Some(())
17 } else {
18 None
19 }
20 }
21}
22
23fn main() {
24 let mut args = std::env::args();
27
28 if args.len() < 2 {
29 println!("Usage: {} <filename>", args.next().unwrap());
30 std::process::exit(1);
31 }
32
33 let filename = args.nth(args.len() - 1).unwrap();
34
35 let file = File::open(filename).unwrap();
36 let mut iso = match ISO9660::from_device(FileDevice(file)) {
37 Some(iso) => iso,
38 None => {
39 eprintln!("It's not an ISO9660 (*.iso) file!");
40 std::process::exit(1);
41 },
42 };
43
44 fn dump(reader: &mut ISO9660, lba: u32, level: usize) {
45 let data = reader.read_directory(lba as _);
46
47 for i in data.collect::<Vec<_>>() {
48 let size = i.record.data_length.get();
49
50 println!("{:<offset$}[{}] {} - {} bytes", "", if i.is_file() { "FILE" } else { "DIR" }, i.name, size, offset = level * 4);
51
52 if ![".", ".."].contains(&i.name.as_str()) && i.is_folder() {
53 dump(reader, i.record.lba.get(), level + 1);
54 }
55 }
56 }
57
58 let root_lba = iso.root().lba.get();
59 dump(&mut iso, root_lba, 0);
60}