From 0f9ac5330ea63cb3896694deed4b37552291fb78 Mon Sep 17 00:00:00 2001 From: dece Date: Fri, 8 May 2020 17:31:31 +0200 Subject: [PATCH] bnd: do not overwrite existing files unless -f --- src/bin/ironring.rs | 10 ++++++++-- src/unpackers/bnd.rs | 27 ++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/bin/ironring.rs b/src/bin/ironring.rs index b0cd407..7086b33 100644 --- a/src/bin/ironring.rs +++ b/src/bin/ironring.rs @@ -67,7 +67,12 @@ fn main() { .short("o") .long("output") .takes_value(true) - .required(true))) + .required(true)) + .arg(Arg::with_name("overwrite") + .short("f") + .long("force") + .takes_value(false) + .required(false))) .get_matches(); process::exit(match matches.subcommand() { @@ -201,7 +206,8 @@ fn cmd_dcx(args: &ArgMatches) -> i32 { fn cmd_bnd(args: &ArgMatches) -> i32 { let file_path: &str = args.value_of("file").unwrap(); let output_path: &str = args.value_of("output").unwrap(); - match unpackers::bnd::extract_bnd_file(file_path, output_path) { + let overwrite: bool = args.is_present("overwrite"); + match unpackers::bnd::extract_bnd_file(file_path, output_path, overwrite) { Err(e) => { eprintln!("Failed to extract BND: {:?}", e); return 1 } _ => { 0 } } diff --git a/src/unpackers/bnd.rs b/src/unpackers/bnd.rs index 7c56db2..d252ac9 100644 --- a/src/unpackers/bnd.rs +++ b/src/unpackers/bnd.rs @@ -11,9 +11,13 @@ use crate::utils::fs as fs_utils; /// Extract BND file contents to disk. /// /// Wraps around `extract_bnd` to load the BND from disk. -pub fn extract_bnd_file(bnd_path: &str, output_dir: &str) -> Result<(), UnpackError> { +pub fn extract_bnd_file( + bnd_path: &str, + output_dir: &str, + overwrite: bool +) -> Result<(), UnpackError> { let (bnd, data) = load_bnd_file(bnd_path)?; - extract_bnd(&bnd, &data, output_dir)?; + extract_bnd(&bnd, &data, output_dir, overwrite)?; Ok(()) } @@ -22,11 +26,20 @@ pub fn extract_bnd_file(bnd_path: &str, output_dir: &str) -> Result<(), UnpackEr /// Files in the BND are written in the output_path directory, creating it if needed, without /// preserving directory structure. If the BND do not contain paths, it will be named after its ID. /// If it does not have IDs, consecutive integers will be used. -pub fn extract_bnd(bnd: &bnd::Bnd, bnd_data: &Vec, output_dir: &str) -> Result<(), UnpackError> { +pub fn extract_bnd( + bnd: &bnd::Bnd, + bnd_data: &Vec, + output_dir: &str, + overwrite: bool +) -> Result<(), UnpackError> { let output_dir = path::Path::new(output_dir); fs_utils::ensure_dir_exists(output_dir)?; for file_info in &bnd.file_infos { - extract_bnd_entry(file_info, bnd_data, output_dir)?; + // Extract all entries, print but ignore path errors. + match extract_bnd_entry(file_info, bnd_data, output_dir, overwrite) { + Err(UnpackError::Naming(e)) => { eprintln!("{}", e) } + _ => {} + } } Ok(()) } @@ -37,7 +50,8 @@ pub fn extract_bnd(bnd: &bnd::Bnd, bnd_data: &Vec, output_dir: &str) -> Resu fn extract_bnd_entry( file_info: &bnd::BndFileInfo, bnd_data: &Vec, - output_dir: &path::Path + output_dir: &path::Path, + overwrite: bool, ) -> Result<(), UnpackError> { if file_info.path.is_none() { return Err(UnpackError::Naming("No path for BND entry.".to_owned())); @@ -57,6 +71,9 @@ fn extract_bnd_entry( let mut file_path = output_dir.to_path_buf(); file_path.push(file_name); + if !overwrite && file_path.exists() { + return Err(UnpackError::Naming(format!("File already exists: {:?}", file_path))); + } let mut output_file = fs::File::create(file_path)?; output_file.write_all(&data)?; Ok(())