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