Add 'initfs/' from commit 'd0802237d7894881df7ddd338dfc64220d0646ff'
git-subtree-dir: initfs git-subtree-mainline:bb25f45f43git-subtree-split:d0802237d7
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::{Arg, Command};
|
||||
|
||||
use archive_common::{self as archive, Args, DEFAULT_MAX_SIZE};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let matches = Command::new("redox-initfs-ar")
|
||||
.about("create an initfs image from a directory")
|
||||
.version(clap::crate_version!())
|
||||
.author(clap::crate_authors!())
|
||||
.arg(
|
||||
Arg::new("MAX_SIZE")
|
||||
.long("max-size")
|
||||
.short('m')
|
||||
.required(false)
|
||||
.help("Set the upper limit for how large the image can become (default 64 MiB)."),
|
||||
)
|
||||
// TODO: support non-utf8 paths (applies to other paths as well)
|
||||
.arg(
|
||||
Arg::new("SOURCE")
|
||||
.required(true)
|
||||
.help("Specify the source directory to build the image from."),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("BOOTSTRAP_CODE")
|
||||
.required(false)
|
||||
.help("Specify the bootstrap ELF file to include in the image."),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("OUTPUT")
|
||||
.required(true)
|
||||
.long("output")
|
||||
.short('o')
|
||||
.help("Specify the path of the new image file."),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
env_logger::init();
|
||||
|
||||
let max_size = if let Some(max_size_str) = matches.get_one::<String>("MAX_SIZE") {
|
||||
max_size_str
|
||||
.parse::<u64>()
|
||||
.context("expected an integer for MAX_SIZE")?
|
||||
} else {
|
||||
DEFAULT_MAX_SIZE
|
||||
};
|
||||
|
||||
let source = matches
|
||||
.get_one::<String>("SOURCE")
|
||||
.expect("expected the required arg SOURCE to exist");
|
||||
|
||||
let bootstrap_code = matches.get_one::<String>("BOOTSTRAP_CODE");
|
||||
|
||||
let destination = matches
|
||||
.get_one::<String>("OUTPUT")
|
||||
.expect("expected the required arg OUTPUT to exist");
|
||||
|
||||
let args = Args {
|
||||
source: Path::new(source),
|
||||
bootstrap_code: bootstrap_code.map(Path::new),
|
||||
destination_path: Path::new(destination),
|
||||
max_size,
|
||||
};
|
||||
archive::archive(&args)
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
use std::{ffi::OsStr, path::Path};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::{Arg, Command};
|
||||
|
||||
use redox_initfs::InitFs;
|
||||
|
||||
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).context("failed to parse initfs header")?;
|
||||
|
||||
dbg!(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;
|
||||
}
|
||||
};
|
||||
print!(
|
||||
"mode={:#0o}, uid={}, gid={}, kind=",
|
||||
inode_struct.mode(),
|
||||
inode_struct.uid(),
|
||||
inode_struct.gid()
|
||||
);
|
||||
|
||||
use redox_initfs::InodeKind;
|
||||
|
||||
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(())
|
||||
}
|
||||
Reference in New Issue
Block a user