Skip to content

Commit

Permalink
Fix unpacking empty directories; Print error instead of panic (#16)
Browse files Browse the repository at this point in the history
* Fix unpacking empty directories; Print error instead of panic

* Fix lints
  • Loading branch information
antangelo authored Apr 18, 2023
1 parent 007a005 commit 8ed40be
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 32 deletions.
29 changes: 26 additions & 3 deletions xdvdfs-cli/src/cmd_read.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fs::File, io::Write, path::Path};
use std::{fs::File, io::Write, path::PathBuf, str::FromStr};

pub fn cmd_ls(img_path: &str, dir_path: &str) -> Result<(), String> {
let mut img = File::options()
Expand Down Expand Up @@ -58,7 +58,15 @@ pub fn cmd_tree(img_path: &str) -> Result<(), String> {
Ok(())
}

pub fn cmd_unpack(img_path: &str, target_dir: &Path) -> Result<(), String> {
pub fn cmd_unpack(img_path: &str, target_dir: &Option<String>) -> Result<(), String> {
let target_dir = match target_dir {
Some(path) => PathBuf::from_str(path).unwrap(),
None => {
let os_path = PathBuf::from_str(img_path).unwrap();
PathBuf::from(os_path.file_name().unwrap()).with_extension("")
}
};

let mut img = File::options()
.read(true)
.open(img_path)
Expand All @@ -73,10 +81,25 @@ pub fn cmd_unpack(img_path: &str, target_dir: &Path) -> Result<(), String> {
let dir = dir.trim_start_matches('/');
let dirname = target_dir.join(dir);
let file_path = dirname.join(dirent.get_name());
let is_dir = dirent.node.dirent.is_directory();

println!("Extracting file {}", file_path.display());
println!(
"Extracting {} {}",
if is_dir { "directory" } else { "file" },
file_path.display()
);

std::fs::create_dir_all(dirname).map_err(|e| e.to_string())?;
if dirent.node.dirent.is_directory() {
std::fs::create_dir(file_path).map_err(|e| e.to_string())?;
continue;
}

if dirent.node.dirent.filename_length == 0 {
eprintln!("WARNING: {:?} has an empty file name, skipping", file_path);
continue;
}

let mut file = File::options()
.write(true)
.truncate(true)
Expand Down
44 changes: 17 additions & 27 deletions xdvdfs-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::{path::PathBuf, str::FromStr};

use clap::{Parser, Subcommand};

mod cmd_info;
Expand Down Expand Up @@ -37,14 +35,6 @@ enum Cmd {
#[arg(help = "Target file within image")]
path: Option<String>,
},
#[command(about = "Unpack an entire image to a directory")]
Unpack {
#[arg(help = "Path to XISO image")]
image_path: String,

#[arg(help = "Output directory")]
path: Option<String>,
},
#[command(
about = "Print information about image metadata",
long_about = "\
Expand All @@ -59,6 +49,14 @@ enum Cmd {
#[arg(help = "Path to file/directory within image")]
file_entry: Option<String>,
},
#[command(about = "Unpack an entire image to a directory")]
Unpack {
#[arg(help = "Path to XISO image")]
image_path: String,

#[arg(help = "Output directory")]
path: Option<String>,
},
#[command(about = "Pack an image from a given directory")]
Pack {
#[arg(help = "Path to source directory")]
Expand All @@ -69,39 +67,31 @@ enum Cmd {
},
}

fn run_command(cmd: &Cmd) {
fn run_command(cmd: &Cmd) -> Result<(), String> {
use Cmd::*;
let res = match cmd {
match cmd {
Ls { image_path, path } => cmd_read::cmd_ls(image_path, path),
Tree { image_path } => cmd_read::cmd_tree(image_path),
Md5 { image_path, path } => cmd_md5::cmd_md5(image_path, path.clone().as_deref()),
Unpack { image_path, path } => {
let path = match path {
Some(path) => PathBuf::from_str(path).unwrap(),
None => {
let os_path = PathBuf::from_str(image_path).unwrap();
PathBuf::from(os_path.file_name().unwrap()).with_extension("")
}
};

cmd_read::cmd_unpack(image_path, &path)
}
Info {
image_path,
file_entry,
} => cmd_info::cmd_info(image_path, file_entry.as_ref()),
Unpack { image_path, path } => cmd_read::cmd_unpack(image_path, path),
Pack {
source_path,
image_path,
} => cmd_pack::cmd_pack(source_path, image_path),
};

res.unwrap();
}
}

fn main() {
let cli = Args::parse();
if let Some(cmd) = cli.command {
run_command(&cmd);
let res = run_command(&cmd);
if let Err(err) = res {
eprintln!("Error: {}", err);
std::process::exit(1);
}
}
}
4 changes: 2 additions & 2 deletions xdvdfs-core/src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ impl DirectoryEntryTable {
let child_name = core::str::from_utf8(child.name_slice())
.map_err(|e| util::Error::UTFError(e))?;
stack.push((format!("{}/{}", parent, child_name), dirent_table));
} else {
dirents.push((parent.clone(), *child));
}

dirents.push((parent.clone(), *child));
}
}

Expand Down

0 comments on commit 8ed40be

Please sign in to comment.