mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-05 02:55:31 +00:00
feat: add password support for decompress and list
This commit is contained in:
parent
4ac8e2ba91
commit
512d2445b2
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1397,9 +1397,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unrar"
|
||||
version = "0.5.3"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4994bfae776d5c2ee22493a00742c77d58bfa5adbe10febe83d1ba7aff2ebdc"
|
||||
checksum = "c99d6a7735a222f2119ca4572e713fb468b5c3a17a4fb90b3cac3e28a8680c29"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"regex",
|
||||
@ -1409,9 +1409,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unrar_sys"
|
||||
version = "0.3.1"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f691c507016acf0a56fae074981ce30f13f8b035c8f80aa878f41905d96e390"
|
||||
checksum = "3f8325103479fffa0e31b41fd11267446b355037115ae184a63a9fd3f192f3da"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -32,7 +32,7 @@ snap = "1.1.1"
|
||||
tar = "0.4.41"
|
||||
tempfile = "3.10.1"
|
||||
time = { version = "0.3.36", default-features = false }
|
||||
unrar = { version = "0.5.3", optional = true }
|
||||
unrar = { version = "0.5.6", optional = true }
|
||||
xz2 = "0.1.7"
|
||||
zip = { version = "0.6.6", default-features = false, features = ["time"] }
|
||||
zstd = { version = "0.13.2", default-features = false, features = ["zstdmt"]}
|
||||
|
@ -8,10 +8,17 @@ use crate::{error::Error, list::FileInArchive, utils::logger::info};
|
||||
|
||||
/// Unpacks the archive given by `archive_path` into the folder given by `output_folder`.
|
||||
/// Assumes that output_folder is empty
|
||||
pub fn unpack_archive(archive_path: &Path, output_folder: &Path, quiet: bool) -> crate::Result<usize> {
|
||||
pub fn unpack_archive(archive_path: &Path, output_folder: &Path, password: Option<impl AsRef<[u8]>>, quiet: bool) -> crate::Result<usize> {
|
||||
assert!(output_folder.read_dir().expect("dir exists").count() == 0);
|
||||
|
||||
let mut archive = Archive::new(archive_path).open_for_processing()?;
|
||||
let password = password.as_ref().map(|p| p.as_ref());
|
||||
|
||||
let archive = match password {
|
||||
Some(password) => Archive::with_password(archive_path, password),
|
||||
None => Archive::new(archive_path),
|
||||
};
|
||||
|
||||
let mut archive = archive.open_for_processing()?;
|
||||
let mut unpacked = 0;
|
||||
|
||||
while let Some(header) = archive.read_header()? {
|
||||
@ -35,9 +42,13 @@ pub fn unpack_archive(archive_path: &Path, output_folder: &Path, quiet: bool) ->
|
||||
}
|
||||
|
||||
/// List contents of `archive_path`, returning a vector of archive entries
|
||||
pub fn list_archive(archive_path: &Path) -> impl Iterator<Item = crate::Result<FileInArchive>> {
|
||||
Archive::new(archive_path)
|
||||
.open_for_listing()
|
||||
pub fn list_archive(archive_path: &Path, password: Option<impl AsRef<[u8]>>) -> impl Iterator<Item = crate::Result<FileInArchive>> {
|
||||
let password = password.as_ref().map(|p| p.as_ref());
|
||||
let archive = match password {
|
||||
Some(password) => Archive::with_password(archive_path, password),
|
||||
None => Archive::new(archive_path),
|
||||
};
|
||||
archive.open_for_listing()
|
||||
.expect("cannot open archive")
|
||||
.map(|item| {
|
||||
let item = item?;
|
||||
|
@ -41,6 +41,10 @@ pub struct CliArgs {
|
||||
#[arg(short, long, global = true)]
|
||||
pub format: Option<OsString>,
|
||||
|
||||
/// decompress or list with password
|
||||
#[arg(short = 'p', long = "password", global = true)]
|
||||
pub password: Option<String>,
|
||||
|
||||
// Ouch and claps subcommands
|
||||
#[command(subcommand)]
|
||||
pub cmd: Subcommand,
|
||||
|
@ -36,6 +36,7 @@ pub fn decompress_file(
|
||||
output_file_path: PathBuf,
|
||||
question_policy: QuestionPolicy,
|
||||
quiet: bool,
|
||||
password: Option<&str>,
|
||||
) -> crate::Result<()> {
|
||||
assert!(output_dir.exists());
|
||||
let input_is_stdin = is_path_stdin(input_file_path);
|
||||
@ -172,9 +173,9 @@ pub fn decompress_file(
|
||||
let unpack_fn: Box<dyn FnOnce(&Path) -> UnpackResult> = if formats.len() > 1 || input_is_stdin {
|
||||
let mut temp_file = tempfile::NamedTempFile::new()?;
|
||||
io::copy(&mut reader, &mut temp_file)?;
|
||||
Box::new(move |output_dir| crate::archive::rar::unpack_archive(temp_file.path(), output_dir, quiet))
|
||||
Box::new(move |output_dir| crate::archive::rar::unpack_archive(temp_file.path(), output_dir, password, quiet))
|
||||
} else {
|
||||
Box::new(|output_dir| crate::archive::rar::unpack_archive(input_file_path, output_dir, quiet))
|
||||
Box::new(|output_dir| crate::archive::rar::unpack_archive(input_file_path, output_dir, password, quiet))
|
||||
};
|
||||
|
||||
if let ControlFlow::Continue(files) =
|
||||
|
@ -20,6 +20,7 @@ pub fn list_archive_contents(
|
||||
formats: Vec<CompressionFormat>,
|
||||
list_options: ListOptions,
|
||||
question_policy: QuestionPolicy,
|
||||
password: Option<&str>,
|
||||
) -> crate::Result<()> {
|
||||
let reader = fs::File::open(archive_path)?;
|
||||
|
||||
@ -86,9 +87,9 @@ pub fn list_archive_contents(
|
||||
if formats.len() > 1 {
|
||||
let mut temp_file = tempfile::NamedTempFile::new()?;
|
||||
io::copy(&mut reader, &mut temp_file)?;
|
||||
Box::new(crate::archive::rar::list_archive(temp_file.path()))
|
||||
Box::new(crate::archive::rar::list_archive(temp_file.path(), password))
|
||||
} else {
|
||||
Box::new(crate::archive::rar::list_archive(archive_path))
|
||||
Box::new(crate::archive::rar::list_archive(archive_path, password))
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "unrar"))]
|
||||
|
@ -188,6 +188,7 @@ pub fn run(
|
||||
output_file_path,
|
||||
question_policy,
|
||||
args.quiet,
|
||||
args.password.as_deref(),
|
||||
)
|
||||
})
|
||||
}
|
||||
@ -221,7 +222,7 @@ pub fn run(
|
||||
println!();
|
||||
}
|
||||
let formats = extension::flatten_compression_formats(&formats);
|
||||
list_archive_contents(archive_path, formats, list_options, question_policy)?;
|
||||
list_archive_contents(archive_path, formats, list_options, question_policy, args.password.as_deref())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
Loading…
x
Reference in New Issue
Block a user