bnd: do not overwrite existing files unless -f

This commit is contained in:
dece 2020-05-08 17:31:31 +02:00
parent 75ff6ddc7f
commit 0f9ac5330e
2 changed files with 30 additions and 7 deletions

View file

@ -67,7 +67,12 @@ fn main() {
.short("o") .short("o")
.long("output") .long("output")
.takes_value(true) .takes_value(true)
.required(true))) .required(true))
.arg(Arg::with_name("overwrite")
.short("f")
.long("force")
.takes_value(false)
.required(false)))
.get_matches(); .get_matches();
process::exit(match matches.subcommand() { process::exit(match matches.subcommand() {
@ -201,7 +206,8 @@ fn cmd_dcx(args: &ArgMatches) -> i32 {
fn cmd_bnd(args: &ArgMatches) -> i32 { fn cmd_bnd(args: &ArgMatches) -> i32 {
let file_path: &str = args.value_of("file").unwrap(); let file_path: &str = args.value_of("file").unwrap();
let output_path: &str = args.value_of("output").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 } Err(e) => { eprintln!("Failed to extract BND: {:?}", e); return 1 }
_ => { 0 } _ => { 0 }
} }

View file

@ -11,9 +11,13 @@ use crate::utils::fs as fs_utils;
/// Extract BND file contents to disk. /// Extract BND file contents to disk.
/// ///
/// Wraps around `extract_bnd` to load the BND from 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)?; let (bnd, data) = load_bnd_file(bnd_path)?;
extract_bnd(&bnd, &data, output_dir)?; extract_bnd(&bnd, &data, output_dir, overwrite)?;
Ok(()) 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 /// 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. /// 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. /// If it does not have IDs, consecutive integers will be used.
pub fn extract_bnd(bnd: &bnd::Bnd, bnd_data: &Vec<u8>, output_dir: &str) -> Result<(), UnpackError> { pub fn extract_bnd(
bnd: &bnd::Bnd,
bnd_data: &Vec<u8>,
output_dir: &str,
overwrite: bool
) -> Result<(), UnpackError> {
let output_dir = path::Path::new(output_dir); let output_dir = path::Path::new(output_dir);
fs_utils::ensure_dir_exists(output_dir)?; fs_utils::ensure_dir_exists(output_dir)?;
for file_info in &bnd.file_infos { 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(()) Ok(())
} }
@ -37,7 +50,8 @@ pub fn extract_bnd(bnd: &bnd::Bnd, bnd_data: &Vec<u8>, output_dir: &str) -> Resu
fn extract_bnd_entry( fn extract_bnd_entry(
file_info: &bnd::BndFileInfo, file_info: &bnd::BndFileInfo,
bnd_data: &Vec<u8>, bnd_data: &Vec<u8>,
output_dir: &path::Path output_dir: &path::Path,
overwrite: bool,
) -> Result<(), UnpackError> { ) -> Result<(), UnpackError> {
if file_info.path.is_none() { if file_info.path.is_none() {
return Err(UnpackError::Naming("No path for BND entry.".to_owned())); 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(); let mut file_path = output_dir.to_path_buf();
file_path.push(file_name); 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)?; let mut output_file = fs::File::create(file_path)?;
output_file.write_all(&data)?; output_file.write_all(&data)?;
Ok(()) Ok(())