Files
RedBear-OS/initfs/tools/src/bin/dump.rs
T
bjorn3 0e0287cb6d initfs: Use fixed modes for inode types
This also ensures that the write bit is never set and the execute bit
is always set for directories.
2026-02-17 20:57:10 +01:00

113 lines
3.5 KiB
Rust

use std::{ffi::OsStr, path::Path};
use anyhow::{Context, Result};
use clap::{Arg, Command};
use redox_initfs::{InitFs, InodeKind};
fn main() -> Result<()> {
let matches = Command::new("redox-initfs-dump")
.about("dump initfs metadata")
.version(clap::crate_version!())
.author(clap::crate_authors!())
.arg(
Arg::new("IMAGE")
.required(true)
.help("specify the image to dump"),
)
.get_matches();
// TODO: support non-utf8 paths
let source = matches
.get_one::<String>("IMAGE")
.expect("expected the required arg IMAGE to exist");
let bytes = std::fs::read(source).context("failed to read image into memory")?;
let initfs = InitFs::new(&bytes, None).context("failed to parse initfs header")?;
println!("{:#?}", initfs.header());
for inode in initfs.all_inodes() {
print!("{:?}: ", inode);
let inode_struct = match initfs.get_inode(inode) {
Some(s) => s,
None => {
println!("failed to obtain.");
continue;
}
};
match inode_struct.kind() {
InodeKind::Unknown => println!("(unknown)"),
InodeKind::Dir(dir) => {
print!("dir{{");
let ec = match dir.entry_count().ok() {
Some(c) => c,
None => {
println!("(failed to get entry count)}}");
continue;
}
};
println!("entries=[");
for entry in 0..ec {
let entry = match dir.get_entry(entry).ok().flatten() {
Some(e) => e,
None => {
println!("\t(unknown),");
continue;
}
};
let name = match entry.name().ok() {
Some(name) => name,
None => {
println!("\t(unknown name),");
continue;
}
};
println!(
"\t`{}` => {:?},",
String::from_utf8_lossy(name),
entry.inode()
);
}
println!("]}}");
}
InodeKind::File(file) => {
print!("file{{");
match file.data().ok() {
Some(d) => {
use std::hash::Hasher;
let mut hasher = twox_hash::XxHash64::with_seed(0);
hasher.write(d);
print!("len={}, hash={:#0x}", d.len(), hasher.finish());
}
None => {
print!("(failed to get data)");
}
}
println!("}}");
}
InodeKind::Link(link) => {
print!("link{{");
match link.data().ok() {
Some(d) => {
use std::os::unix::ffi::OsStrExt;
print!("dst={}", Path::new(OsStr::from_bytes(d)).display());
}
None => {
print!("(failed to get data)");
}
}
println!("}}");
}
}
}
Ok(())
}