Skip to main content

dump/
dump.rs

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    // Get last argument in command line
25
26    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}