Repository: wcampbell0x2a/backhand (language: rust)

Issue:
Add `replace` binary



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1df2b674..ddbdc220 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ## Unreleased
 ### Added
 - Fuzz testing with `cargo fuzz`. Mostly fuzz bytes as bytes/image input into this library.
+- `unsquashfs`: Add `-o, --out <OUT>` flag for output squashfs image destination
+- `replace`: Add binary to replace file in squashfs filesystems
+
 ### Fixed
 - Fixed many issues found with fuzz testing related to legal images.
   Checks are now added at every stop possible to prevent many soundness issues.
diff --git a/README.md b/README.md
index ba52e73c..87099e40 100644
--- a/README.md
+++ b/README.md
@@ -51,8 +51,8 @@ These are currently under development and are missing features, MR's welcome!
 
 To install, run `cargo install backhand --locked`.
 
-### unsquashfs
-```console
+### unsquashfs-backhand
+```no_test
 tool to uncompress, extract and list squashfs filesystems
 
 Usage: unsquashfs [OPTIONS] <FILESYSTEM>
@@ -70,20 +70,38 @@ Options:
   -h, --help             Print help information
   -V, --version          Print version information
 ```
-### add
-```console
+### add-backhand
+```no_test
 tool to add files to squashfs filesystems
 
-Usage: add <FILESYSTEM> <FILE> <FILE_PATH>
+Usage: add [OPTIONS] <FILESYSTEM> <FILE> <FILE_PATH>
 
 Arguments:
-  <FILESYSTEM>  Squashfs file
-  <FILE>
-  <FILE_PATH>
+  <FILESYSTEM>  Squashfs input image
+  <FILE>        Path of file to read, to write into squashfs
+  <FILE_PATH>   Path of file inserted into squashfs
+
+Options:
+  -o, --out <OUT>  Squashfs output image [default: added.squashfs]
+  -h, --help       Print help
+  -V, --version    Print version
+```
+
+### replace-backhand
+```no_test
+tool to replace files in squashfs filesystems
+
+Usage: replace [OPTIONS] <FILESYSTEM> <FILE> <FILE_PATH>
+
+Arguments:
+  <FILESYSTEM>  Squashfs input image
+  <FILE>        Path of file to read, to write into squashfs
+  <FILE_PATH>   Path of file replaced in image
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -o, --out <OUT>  Squashfs output image [default: replaced.squashfs]
+  -h, --help       Print help
+  -V, --version    Print version
 ```
 
 ## Testing
diff --git a/src/bin/add.rs b/src/bin/add.rs
index 2c32dd35..c8903e88 100644
--- a/src/bin/add.rs
+++ b/src/bin/add.rs
@@ -8,14 +8,18 @@ use clap::Parser;
 #[derive(Parser, Debug)]
 #[command(author, version, name = "add-backhand")]
 struct Args {
-    /// Squashfs file
+    /// Squashfs input image
     filesystem: PathBuf,
 
-    // Path of file to read, to write into squashfs
+    /// Path of file to read, to write into squashfs
     file: PathBuf,
 
-    // Path of file inserted into squashfs
+    /// Path of file inserted into squashfs
     file_path: PathBuf,
+
+    /// Squashfs output image
+    #[clap(short, long, default_value = "added.squashfs")]
+    out: PathBuf,
 }
 
 fn main() {
@@ -33,7 +37,7 @@ fn main() {
     filesystem.push_file(new_file, args.file_path, NodeHeader::default());
 
     // write new file
-    let mut output = File::create("added.squashfs").unwrap();
+    let mut output = File::create(&args.out).unwrap();
     filesystem.write(&mut output).unwrap();
-    println!("added file and wrote to added.squashfs");
+    println!("added file and wrote to {}", args.out.display());
 }
diff --git a/src/bin/replace.rs b/src/bin/replace.rs
new file mode 100644
index 00000000..8710b201
--- /dev/null
+++ b/src/bin/replace.rs
@@ -0,0 +1,43 @@
+use std::fs::File;
+use std::path::PathBuf;
+
+use backhand::{FilesystemReader, FilesystemWriter};
+use clap::Parser;
+
+/// tool to replace files in squashfs filesystems
+#[derive(Parser, Debug)]
+#[command(author, version, name = "replace-backhand")]
+struct Args {
+    /// Squashfs input image
+    filesystem: PathBuf,
+
+    /// Path of file to read, to write into squashfs
+    file: PathBuf,
+
+    /// Path of file replaced in image
+    file_path: PathBuf,
+
+    /// Squashfs output image
+    #[clap(short, long, default_value = "replaced.squashfs")]
+    out: PathBuf,
+}
+
+fn main() {
+    tracing_subscriber::fmt::init();
+
+    let args = Args::parse();
+
+    // read of squashfs
+    let file = File::open(args.filesystem).unwrap();
+    let filesystem = FilesystemReader::from_reader(file).unwrap();
+    let mut filesystem = FilesystemWriter::from_fs_reader(&filesystem).unwrap();
+
+    // Modify file
+    let new_file = File::open(&args.file).unwrap();
+    filesystem.replace_file(args.file_path, new_file).unwrap();
+
+    // write new file
+    let mut output = File::create(&args.out).unwrap();
+    filesystem.write(&mut output).unwrap();
+    println!("replaced file and wrote to {}", args.out.display());
+}


Test patch: