Skip to content

Commit

Permalink
Add functions to list all file names in a archive
Browse files Browse the repository at this point in the history
Signed-off-by: asakiz <asakizin@gmail.com>
  • Loading branch information
Asakiz committed Jun 27, 2020
1 parent 7defb36 commit 85f66ec
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
17 changes: 17 additions & 0 deletions examples/uncompress.rs
Expand Up @@ -16,6 +16,7 @@ struct TopLevel {
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum CmdLine {
ListArchiveFiles(SubCommandListArchiveFiles),
UncompressData(SubCommandUncompressData),
UncompressArchiveFile(SubCommandUncompressArchiveFile),
UncompressArchive(SubCommandUncompressArchive),
Expand Down Expand Up @@ -68,10 +69,26 @@ struct SubCommandUncompressArchive {
preserve_ownership: bool,
}

#[derive(FromArgs, PartialEq, Debug)]
/// List archive files subcommand.
#[argh(subcommand, name = "list-archive-files")]
struct SubCommandListArchiveFiles {
/// source path
#[argh(positional)]
source_path: String,
}

fn main() -> compress_tools::Result<()> {
let cmd: TopLevel = argh::from_env();

match cmd.nested {
CmdLine::ListArchiveFiles(input) => {
let filename = std::fs::File::open(input.source_path)?;

let file_list = list_archive_files(filename)?;
println!("{:#?}", file_list);
}

CmdLine::UncompressData(input) => {
let mut source = std::fs::File::open(input.source_path)?;
let mut target = std::fs::File::open(input.target_path)?;
Expand Down
40 changes: 40 additions & 0 deletions src/lib.rs
Expand Up @@ -83,6 +83,46 @@ enum Mode {
WriteDisk { ownership: Ownership },
}

/// Get all files in a archive using `source` as a reader.
/// # Example
///
/// ```no_run
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// use compress_tools::*;
/// use std::fs::File;
///
/// let mut source = File::open("tree.tar")?;
///
/// let file_list = list_archive_files(&mut source)?;
/// # Ok(())
/// # }
/// ```
pub fn list_archive_files<R>(source: R) -> Result<Vec<String>>
where
R: Read,
{
run_with_archive(
Mode::AllFormat,
source,
|archive_reader, _, mut entry| unsafe {
let mut file_list = Vec::new();
loop {
match ffi::archive_read_next_header(archive_reader, &mut entry) {
ffi::ARCHIVE_OK => {
file_list.push(
CStr::from_ptr(ffi::archive_entry_pathname(entry))
.to_str()?
.to_string(),
);
}
ffi::ARCHIVE_EOF => return Ok(file_list),
_ => return Err(Error::from(archive_reader)),
}
}
},
)
}

/// Uncompress a file using the `source` need as reader and the `target` as a
/// writer.
///
Expand Down

0 comments on commit 85f66ec

Please sign in to comment.