mirror of
https://github.com/Drop-OSS/drop.git
synced 2026-07-27 02:04:39 +10:00
Merge pull request #1 from chef/extract-bug
Various fixes for restoring files on disk from archive
This commit is contained in:
@@ -4,7 +4,7 @@ use std::path::PathBuf;
|
|||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use libarchive3_sys::ffi;
|
use libarchive3_sys::ffi;
|
||||||
use error::{ArchiveResult, ErrCode};
|
use error::ErrCode;
|
||||||
|
|
||||||
pub enum ReadCompression {
|
pub enum ReadCompression {
|
||||||
All,
|
All,
|
||||||
@@ -92,6 +92,17 @@ pub enum WriteFilter {
|
|||||||
Xz,
|
Xz,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FileType {
|
||||||
|
BlockDevice,
|
||||||
|
SymbolicLink,
|
||||||
|
Socket,
|
||||||
|
CharacterDevice,
|
||||||
|
Directory,
|
||||||
|
NamedPipe,
|
||||||
|
Mount,
|
||||||
|
RegularFile,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Handle {
|
pub trait Handle {
|
||||||
unsafe fn handle(&self) -> *mut ffi::Struct_archive;
|
unsafe fn handle(&self) -> *mut ffi::Struct_archive;
|
||||||
|
|
||||||
@@ -112,6 +123,34 @@ pub trait Handle {
|
|||||||
pub trait Entry {
|
pub trait Entry {
|
||||||
unsafe fn entry(&self) -> *mut ffi::Struct_archive_entry;
|
unsafe fn entry(&self) -> *mut ffi::Struct_archive_entry;
|
||||||
|
|
||||||
|
fn filetype(&self) -> FileType {
|
||||||
|
unsafe {
|
||||||
|
match ffi::archive_entry_filetype(self.entry()) as u32 {
|
||||||
|
ffi::AE_IFBLK => FileType::BlockDevice,
|
||||||
|
ffi::AE_IFCHR => FileType::CharacterDevice,
|
||||||
|
ffi::AE_IFLNK => FileType::SymbolicLink,
|
||||||
|
ffi::AE_IFDIR => FileType::Directory,
|
||||||
|
ffi::AE_IFIFO => FileType::NamedPipe,
|
||||||
|
ffi::AE_IFMT => FileType::Mount,
|
||||||
|
ffi::AE_IFREG => FileType::RegularFile,
|
||||||
|
ffi::AE_IFSOCK => FileType::Socket,
|
||||||
|
code => unreachable!("undefined filetype: {}", code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hardlink(&self) -> Option<&str> {
|
||||||
|
let c_str: &CStr = unsafe {
|
||||||
|
let ptr = ffi::archive_entry_hardlink(self.entry());
|
||||||
|
if ptr.is_null() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
CStr::from_ptr(ptr)
|
||||||
|
};
|
||||||
|
let buf: &[u8] = c_str.to_bytes();
|
||||||
|
Some(str::from_utf8(buf).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
fn pathname(&self) -> &str {
|
fn pathname(&self) -> &str {
|
||||||
let c_str: &CStr = unsafe { CStr::from_ptr(ffi::archive_entry_pathname(self.entry())) };
|
let c_str: &CStr = unsafe { CStr::from_ptr(ffi::archive_entry_pathname(self.entry())) };
|
||||||
let buf: &[u8] = c_str.to_bytes();
|
let buf: &[u8] = c_str.to_bytes();
|
||||||
@@ -122,12 +161,40 @@ pub trait Entry {
|
|||||||
unsafe { ffi::archive_entry_size(self.entry()) }
|
unsafe { ffi::archive_entry_size(self.entry()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_pathname(&mut self, path: PathBuf) -> ArchiveResult<()> {
|
fn symlink(&self) -> &str {
|
||||||
|
let c_str: &CStr = unsafe { CStr::from_ptr(ffi::archive_entry_symlink(self.entry())) };
|
||||||
|
let buf: &[u8] = c_str.to_bytes();
|
||||||
|
str::from_utf8(buf).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_filetype(&mut self, file_type: FileType) {
|
||||||
|
unsafe {
|
||||||
|
let file_type = match file_type {
|
||||||
|
FileType::BlockDevice => ffi::AE_IFBLK,
|
||||||
|
FileType::CharacterDevice => ffi::AE_IFCHR,
|
||||||
|
FileType::SymbolicLink => ffi::AE_IFLNK,
|
||||||
|
FileType::Directory => ffi::AE_IFDIR,
|
||||||
|
FileType::NamedPipe => ffi::AE_IFIFO,
|
||||||
|
FileType::Mount => ffi::AE_IFMT,
|
||||||
|
FileType::RegularFile => ffi::AE_IFREG,
|
||||||
|
FileType::Socket => ffi::AE_IFSOCK,
|
||||||
|
};
|
||||||
|
ffi::archive_entry_set_filetype(self.entry(), file_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_link(&mut self, path: &PathBuf) {
|
||||||
|
unsafe {
|
||||||
|
let c_str = CString::new(path.to_str().unwrap()).unwrap();
|
||||||
|
ffi::archive_entry_set_link(self.entry(), c_str.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_pathname(&mut self, path: &PathBuf) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_str = CString::new(path.to_str().unwrap()).unwrap();
|
let c_str = CString::new(path.to_str().unwrap()).unwrap();
|
||||||
ffi::archive_entry_set_pathname(self.entry(), c_str.as_ptr());
|
ffi::archive_entry_set_pathname(self.entry(), c_str.as_ptr());
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ impl FileReader {
|
|||||||
let c_file = CString::new(file.as_ref().to_string_lossy().as_bytes()).unwrap();
|
let c_file = CString::new(file.as_ref().to_string_lossy().as_bytes()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
match ffi::archive_read_open_filename(builder.handle(), c_file.as_ptr(), BLOCK_SIZE) {
|
match ffi::archive_read_open_filename(builder.handle(), c_file.as_ptr(), BLOCK_SIZE) {
|
||||||
0 => {
|
ffi::ARCHIVE_OK => {
|
||||||
builder.consume();
|
builder.consume();
|
||||||
Ok(Self::new(builder.handle()))
|
Ok(Self::new(builder.handle()))
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,6 @@ impl Reader for FileReader {
|
|||||||
impl Drop for FileReader {
|
impl Drop for FileReader {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_read_close(self.handle()); // jw todo: close here?
|
|
||||||
ffi::archive_read_free(self.handle());
|
ffi::archive_read_free(self.handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,7 +154,7 @@ impl StreamReader {
|
|||||||
None,
|
None,
|
||||||
Some(stream_read_callback),
|
Some(stream_read_callback),
|
||||||
None) {
|
None) {
|
||||||
0 => {
|
ffi::ARCHIVE_OK => {
|
||||||
let reader = StreamReader {
|
let reader = StreamReader {
|
||||||
handle: builder.handle(),
|
handle: builder.handle(),
|
||||||
entry: ReaderEntry::default(),
|
entry: ReaderEntry::default(),
|
||||||
@@ -188,7 +187,6 @@ impl Reader for StreamReader {
|
|||||||
impl Drop for StreamReader {
|
impl Drop for StreamReader {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_read_close(self.handle()); // jw todo: close here?
|
|
||||||
ffi::archive_read_free(self.handle());
|
ffi::archive_read_free(self.handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,84 +198,63 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn support_compression(&mut self, compression: ReadCompression) -> ArchiveResult<()> {
|
pub fn support_compression(&mut self, compression: ReadCompression) -> ArchiveResult<()> {
|
||||||
match compression {
|
let result = match compression {
|
||||||
ReadCompression::All => unsafe {
|
ReadCompression::All => unsafe {
|
||||||
ffi::archive_read_support_compression_all(self.handle);
|
ffi::archive_read_support_compression_all(self.handle)
|
||||||
},
|
},
|
||||||
ReadCompression::Bzip2 => unsafe {
|
ReadCompression::Bzip2 => unsafe {
|
||||||
ffi::archive_read_support_compression_bzip2(self.handle);
|
ffi::archive_read_support_compression_bzip2(self.handle)
|
||||||
},
|
},
|
||||||
ReadCompression::Compress => unsafe {
|
ReadCompression::Compress => unsafe {
|
||||||
ffi::archive_read_support_compression_compress(self.handle);
|
ffi::archive_read_support_compression_compress(self.handle)
|
||||||
},
|
},
|
||||||
ReadCompression::Gzip => unsafe {
|
ReadCompression::Gzip => unsafe {
|
||||||
ffi::archive_read_support_compression_gzip(self.handle);
|
ffi::archive_read_support_compression_gzip(self.handle)
|
||||||
},
|
},
|
||||||
ReadCompression::Lzip => unsafe {
|
ReadCompression::Lzip => unsafe {
|
||||||
ffi::archive_read_support_compression_lzip(self.handle);
|
ffi::archive_read_support_compression_lzip(self.handle)
|
||||||
},
|
},
|
||||||
ReadCompression::Lzma => unsafe {
|
ReadCompression::Lzma => unsafe {
|
||||||
ffi::archive_read_support_compression_lzma(self.handle);
|
ffi::archive_read_support_compression_lzma(self.handle)
|
||||||
},
|
},
|
||||||
ReadCompression::None => unsafe {
|
ReadCompression::None => unsafe {
|
||||||
ffi::archive_read_support_compression_none(self.handle);
|
ffi::archive_read_support_compression_none(self.handle)
|
||||||
},
|
},
|
||||||
ReadCompression::Program(prog) => {
|
ReadCompression::Program(prog) => {
|
||||||
let c_prog = CString::new(prog).unwrap();
|
let c_prog = CString::new(prog).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_read_support_compression_program(self.handle, c_prog.as_ptr());
|
ffi::archive_read_support_compression_program(self.handle, c_prog.as_ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReadCompression::Rpm => unsafe {
|
ReadCompression::Rpm => unsafe {
|
||||||
ffi::archive_read_support_compression_rpm(self.handle);
|
ffi::archive_read_support_compression_rpm(self.handle)
|
||||||
},
|
|
||||||
ReadCompression::Uu => unsafe {
|
|
||||||
ffi::archive_read_support_compression_uu(self.handle);
|
|
||||||
},
|
|
||||||
ReadCompression::Xz => unsafe {
|
|
||||||
ffi::archive_read_support_compression_xz(self.handle);
|
|
||||||
},
|
},
|
||||||
|
ReadCompression::Uu => unsafe { ffi::archive_read_support_compression_uu(self.handle) },
|
||||||
|
ReadCompression::Xz => unsafe { ffi::archive_read_support_compression_xz(self.handle) },
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn support_filter(&mut self, filter: ReadFilter) -> ArchiveResult<()> {
|
pub fn support_filter(&mut self, filter: ReadFilter) -> ArchiveResult<()> {
|
||||||
match filter {
|
let result = match filter {
|
||||||
ReadFilter::All => unsafe {
|
ReadFilter::All => unsafe { ffi::archive_read_support_filter_all(self.handle) },
|
||||||
ffi::archive_read_support_filter_all(self.handle);
|
ReadFilter::Bzip2 => unsafe { ffi::archive_read_support_filter_bzip2(self.handle) },
|
||||||
},
|
|
||||||
ReadFilter::Bzip2 => unsafe {
|
|
||||||
ffi::archive_read_support_filter_bzip2(self.handle);
|
|
||||||
},
|
|
||||||
ReadFilter::Compress => unsafe {
|
ReadFilter::Compress => unsafe {
|
||||||
ffi::archive_read_support_filter_compress(self.handle);
|
ffi::archive_read_support_filter_compress(self.handle)
|
||||||
},
|
|
||||||
ReadFilter::Grzip => unsafe {
|
|
||||||
ffi::archive_read_support_filter_grzip(self.handle);
|
|
||||||
},
|
|
||||||
ReadFilter::Gzip => unsafe {
|
|
||||||
ffi::archive_read_support_filter_gzip(self.handle);
|
|
||||||
},
|
|
||||||
ReadFilter::Lrzip => unsafe {
|
|
||||||
ffi::archive_read_support_filter_lrzip(self.handle);
|
|
||||||
},
|
|
||||||
ReadFilter::Lzip => unsafe {
|
|
||||||
ffi::archive_read_support_filter_lzip(self.handle);
|
|
||||||
},
|
|
||||||
ReadFilter::Lzma => unsafe {
|
|
||||||
ffi::archive_read_support_filter_lzma(self.handle);
|
|
||||||
},
|
|
||||||
ReadFilter::Lzop => unsafe {
|
|
||||||
ffi::archive_read_support_filter_lzop(self.handle);
|
|
||||||
},
|
|
||||||
ReadFilter::None => unsafe {
|
|
||||||
ffi::archive_read_support_filter_none(self.handle);
|
|
||||||
},
|
},
|
||||||
|
ReadFilter::Grzip => unsafe { ffi::archive_read_support_filter_grzip(self.handle) },
|
||||||
|
ReadFilter::Gzip => unsafe { ffi::archive_read_support_filter_gzip(self.handle) },
|
||||||
|
ReadFilter::Lrzip => unsafe { ffi::archive_read_support_filter_lrzip(self.handle) },
|
||||||
|
ReadFilter::Lzip => unsafe { ffi::archive_read_support_filter_lzip(self.handle) },
|
||||||
|
ReadFilter::Lzma => unsafe { ffi::archive_read_support_filter_lzma(self.handle) },
|
||||||
|
ReadFilter::Lzop => unsafe { ffi::archive_read_support_filter_lzop(self.handle) },
|
||||||
|
ReadFilter::None => unsafe { ffi::archive_read_support_filter_none(self.handle) },
|
||||||
ReadFilter::Program(prog) => {
|
ReadFilter::Program(prog) => {
|
||||||
let c_prog = CString::new(prog).unwrap();
|
let c_prog = CString::new(prog).unwrap();
|
||||||
unsafe {
|
unsafe { ffi::archive_read_support_filter_program(self.handle, c_prog.as_ptr()) }
|
||||||
ffi::archive_read_support_filter_program(self.handle, c_prog.as_ptr());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ReadFilter::ProgramSignature(prog, cb, size) => {
|
ReadFilter::ProgramSignature(prog, cb, size) => {
|
||||||
let c_prog = CString::new(prog).unwrap();
|
let c_prog = CString::new(prog).unwrap();
|
||||||
@@ -285,71 +262,43 @@ impl Builder {
|
|||||||
ffi::archive_read_support_filter_program_signature(self.handle,
|
ffi::archive_read_support_filter_program_signature(self.handle,
|
||||||
c_prog.as_ptr(),
|
c_prog.as_ptr(),
|
||||||
mem::transmute(cb),
|
mem::transmute(cb),
|
||||||
size);
|
size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReadFilter::Rpm => unsafe {
|
ReadFilter::Rpm => unsafe { ffi::archive_read_support_filter_rpm(self.handle) },
|
||||||
ffi::archive_read_support_filter_rpm(self.handle);
|
ReadFilter::Uu => unsafe { ffi::archive_read_support_filter_uu(self.handle) },
|
||||||
},
|
ReadFilter::Xz => unsafe { ffi::archive_read_support_filter_xz(self.handle) },
|
||||||
ReadFilter::Uu => unsafe {
|
};
|
||||||
ffi::archive_read_support_filter_uu(self.handle);
|
match result {
|
||||||
},
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
ReadFilter::Xz => unsafe {
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
ffi::archive_read_support_filter_xz(self.handle);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn support_format(&self, format: ReadFormat) -> ArchiveResult<()> {
|
pub fn support_format(&self, format: ReadFormat) -> ArchiveResult<()> {
|
||||||
match format {
|
let result = match format {
|
||||||
ReadFormat::SevenZip => unsafe {
|
ReadFormat::SevenZip => unsafe { ffi::archive_read_support_format_7zip(self.handle()) },
|
||||||
ffi::archive_read_support_format_7zip(self.handle());
|
ReadFormat::All => unsafe { ffi::archive_read_support_format_all(self.handle()) },
|
||||||
},
|
ReadFormat::Ar => unsafe { ffi::archive_read_support_format_ar(self.handle()) },
|
||||||
ReadFormat::All => unsafe {
|
ReadFormat::Cab => unsafe { ffi::archive_read_support_format_cab(self.handle()) },
|
||||||
ffi::archive_read_support_format_all(self.handle());
|
ReadFormat::Cpio => unsafe { ffi::archive_read_support_format_cpio(self.handle()) },
|
||||||
},
|
ReadFormat::Empty => unsafe { ffi::archive_read_support_format_empty(self.handle()) },
|
||||||
ReadFormat::Ar => unsafe {
|
ReadFormat::Gnutar => unsafe { ffi::archive_read_support_format_gnutar(self.handle()) },
|
||||||
ffi::archive_read_support_format_ar(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Cab => unsafe {
|
|
||||||
ffi::archive_read_support_format_cab(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Cpio => unsafe {
|
|
||||||
ffi::archive_read_support_format_cpio(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Empty => unsafe {
|
|
||||||
ffi::archive_read_support_format_empty(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Gnutar => unsafe {
|
|
||||||
ffi::archive_read_support_format_gnutar(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Iso9660 => unsafe {
|
ReadFormat::Iso9660 => unsafe {
|
||||||
ffi::archive_read_support_format_iso9660(self.handle());
|
ffi::archive_read_support_format_iso9660(self.handle())
|
||||||
},
|
|
||||||
ReadFormat::Lha => unsafe {
|
|
||||||
ffi::archive_read_support_format_lha(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Mtree => unsafe {
|
|
||||||
ffi::archive_read_support_format_mtree(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Rar => unsafe {
|
|
||||||
ffi::archive_read_support_format_rar(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Raw => unsafe {
|
|
||||||
ffi::archive_read_support_format_raw(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Tar => unsafe {
|
|
||||||
ffi::archive_read_support_format_tar(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Xar => unsafe {
|
|
||||||
ffi::archive_read_support_format_xar(self.handle());
|
|
||||||
},
|
|
||||||
ReadFormat::Zip => unsafe {
|
|
||||||
ffi::archive_read_support_format_zip(self.handle());
|
|
||||||
},
|
},
|
||||||
|
ReadFormat::Lha => unsafe { ffi::archive_read_support_format_lha(self.handle()) },
|
||||||
|
ReadFormat::Mtree => unsafe { ffi::archive_read_support_format_mtree(self.handle()) },
|
||||||
|
ReadFormat::Rar => unsafe { ffi::archive_read_support_format_rar(self.handle()) },
|
||||||
|
ReadFormat::Raw => unsafe { ffi::archive_read_support_format_raw(self.handle()) },
|
||||||
|
ReadFormat::Tar => unsafe { ffi::archive_read_support_format_tar(self.handle()) },
|
||||||
|
ReadFormat::Xar => unsafe { ffi::archive_read_support_format_xar(self.handle()) },
|
||||||
|
ReadFormat::Zip => unsafe { ffi::archive_read_support_format_zip(self.handle()) },
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_file<T: AsRef<Path>>(self, file: T) -> ArchiveResult<FileReader> {
|
pub fn open_file<T: AsRef<Path>>(self, file: T) -> ArchiveResult<FileReader> {
|
||||||
|
|||||||
@@ -62,24 +62,30 @@ impl Disk {
|
|||||||
|
|
||||||
pub fn set_bytes_per_block(&mut self, count: i32) -> ArchiveResult<()> {
|
pub fn set_bytes_per_block(&mut self, count: i32) -> ArchiveResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_write_set_bytes_per_block(self.handle, count);
|
match ffi::archive_write_set_bytes_per_block(self.handle, count) {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bytes_in_last_block(&mut self, count: i32) -> ArchiveResult<()> {
|
pub fn set_bytes_in_last_block(&mut self, count: i32) -> ArchiveResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_write_set_bytes_in_last_block(self.handle, count);
|
match ffi::archive_write_set_bytes_in_last_block(self.handle, count) {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set options for extraction built from `ExtractOptions`
|
// Set options for extraction built from `ExtractOptions`
|
||||||
pub fn set_options(&self, eopt: &ExtractOptions) -> ArchiveResult<()> {
|
pub fn set_options(&self, eopt: &ExtractOptions) -> ArchiveResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_write_disk_set_options(self.handle, eopt.flags);
|
match ffi::archive_write_disk_set_options(self.handle, eopt.flags) {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This convenience function installs a standard set of user and group lookup functions. These
|
// This convenience function installs a standard set of user and group lookup functions. These
|
||||||
@@ -88,9 +94,11 @@ impl Disk {
|
|||||||
// reduce the number of calls to getpwnam(3) and getgrnam(3).
|
// reduce the number of calls to getpwnam(3) and getgrnam(3).
|
||||||
pub fn set_standard_lookup(&self) -> ArchiveResult<()> {
|
pub fn set_standard_lookup(&self) -> ArchiveResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_write_disk_set_standard_lookup(self.handle);
|
match ffi::archive_write_disk_set_standard_lookup(self.handle) {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// * Failures - HeaderPosition
|
// * Failures - HeaderPosition
|
||||||
@@ -105,7 +113,11 @@ impl Disk {
|
|||||||
if let Some(entry) = reader.next_header() {
|
if let Some(entry) = reader.next_header() {
|
||||||
if let Some(pfx) = prefix {
|
if let Some(pfx) = prefix {
|
||||||
let path = Path::new(pfx).join(entry.pathname());
|
let path = Path::new(pfx).join(entry.pathname());
|
||||||
try!(entry.set_pathname(path));
|
entry.set_pathname(&path);
|
||||||
|
if entry.hardlink().is_some() {
|
||||||
|
let path = Path::new(pfx).join(entry.hardlink().unwrap());
|
||||||
|
entry.set_link(&path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
match self.write_header(entry) {
|
match self.write_header(entry) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
@@ -133,9 +145,11 @@ impl Disk {
|
|||||||
|
|
||||||
pub fn close(&self) -> ArchiveResult<()> {
|
pub fn close(&self) -> ArchiveResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_write_close(self.handle());
|
match ffi::archive_write_close(self.handle()) {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_data<T: Reader>(&self, reader: &T) -> ArchiveResult<usize> {
|
fn write_data<T: Reader>(&self, reader: &T) -> ArchiveResult<usize> {
|
||||||
@@ -164,9 +178,11 @@ impl Disk {
|
|||||||
|
|
||||||
fn write_header(&self, entry: &ReaderEntry) -> ArchiveResult<()> {
|
fn write_header(&self, entry: &ReaderEntry) -> ArchiveResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_write_header(self.handle, entry.entry());
|
match ffi::archive_write_header(self.handle, entry.entry()) {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +206,6 @@ impl Default for Disk {
|
|||||||
|
|
||||||
impl Drop for Disk {
|
impl Drop for Disk {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.close().unwrap();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::archive_write_free(self.handle());
|
ffi::archive_write_free(self.handle());
|
||||||
}
|
}
|
||||||
@@ -203,107 +218,64 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_filter(&mut self, filter: WriteFilter) -> ArchiveResult<()> {
|
pub fn add_filter(&mut self, filter: WriteFilter) -> ArchiveResult<()> {
|
||||||
match filter {
|
let result = match filter {
|
||||||
WriteFilter::B64Encode => unsafe {
|
WriteFilter::B64Encode => unsafe {
|
||||||
ffi::archive_write_add_filter_b64encode(self.handle);
|
ffi::archive_write_add_filter_b64encode(self.handle)
|
||||||
},
|
|
||||||
WriteFilter::Bzip2 => unsafe {
|
|
||||||
ffi::archive_write_add_filter_bzip2(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::Compress => unsafe {
|
|
||||||
ffi::archive_write_add_filter_compress(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::Grzip => unsafe {
|
|
||||||
ffi::archive_write_add_filter_grzip(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::Gzip => unsafe {
|
|
||||||
ffi::archive_write_add_filter_gzip(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::Lrzip => unsafe {
|
|
||||||
ffi::archive_write_add_filter_lrzip(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::Lzip => unsafe {
|
|
||||||
ffi::archive_write_add_filter_lzip(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::Lzma => unsafe {
|
|
||||||
ffi::archive_write_add_filter_lzma(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::Lzop => unsafe {
|
|
||||||
ffi::archive_write_add_filter_lzop(self.handle);
|
|
||||||
},
|
|
||||||
WriteFilter::None => unsafe {
|
|
||||||
ffi::archive_write_add_filter_none(self.handle);
|
|
||||||
},
|
},
|
||||||
|
WriteFilter::Bzip2 => unsafe { ffi::archive_write_add_filter_bzip2(self.handle) },
|
||||||
|
WriteFilter::Compress => unsafe { ffi::archive_write_add_filter_compress(self.handle) },
|
||||||
|
WriteFilter::Grzip => unsafe { ffi::archive_write_add_filter_grzip(self.handle) },
|
||||||
|
WriteFilter::Gzip => unsafe { ffi::archive_write_add_filter_gzip(self.handle) },
|
||||||
|
WriteFilter::Lrzip => unsafe { ffi::archive_write_add_filter_lrzip(self.handle) },
|
||||||
|
WriteFilter::Lzip => unsafe { ffi::archive_write_add_filter_lzip(self.handle) },
|
||||||
|
WriteFilter::Lzma => unsafe { ffi::archive_write_add_filter_lzma(self.handle) },
|
||||||
|
WriteFilter::Lzop => unsafe { ffi::archive_write_add_filter_lzop(self.handle) },
|
||||||
|
WriteFilter::None => unsafe { ffi::archive_write_add_filter_none(self.handle) },
|
||||||
WriteFilter::Program(prog) => {
|
WriteFilter::Program(prog) => {
|
||||||
let c_prog = CString::new(prog).unwrap();
|
let c_prog = CString::new(prog).unwrap();
|
||||||
unsafe { ffi::archive_write_add_filter_program(self.handle, c_prog.as_ptr()) };
|
unsafe { ffi::archive_write_add_filter_program(self.handle, c_prog.as_ptr()) }
|
||||||
|
|
||||||
}
|
}
|
||||||
WriteFilter::UuEncode => unsafe {
|
WriteFilter::UuEncode => unsafe { ffi::archive_write_add_filter_uuencode(self.handle) },
|
||||||
ffi::archive_write_add_filter_uuencode(self.handle);
|
WriteFilter::Xz => unsafe { ffi::archive_write_add_filter_xz(self.handle) },
|
||||||
},
|
};
|
||||||
WriteFilter::Xz => unsafe {
|
match result {
|
||||||
ffi::archive_write_add_filter_xz(self.handle);
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
},
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_format(&self, format: WriteFormat) -> ArchiveResult<()> {
|
pub fn set_format(&self, format: WriteFormat) -> ArchiveResult<()> {
|
||||||
match format {
|
let result = match format {
|
||||||
WriteFormat::SevenZip => unsafe {
|
WriteFormat::SevenZip => unsafe { ffi::archive_write_set_format_7zip(self.handle) },
|
||||||
ffi::archive_write_set_format_7zip(self.handle);
|
WriteFormat::ArBsd => unsafe { ffi::archive_write_set_format_ar_bsd(self.handle) },
|
||||||
},
|
WriteFormat::ArSvr4 => unsafe { ffi::archive_write_set_format_ar_svr4(self.handle) },
|
||||||
WriteFormat::ArBsd => unsafe {
|
WriteFormat::Cpio => unsafe { ffi::archive_write_set_format_cpio(self.handle) },
|
||||||
ffi::archive_write_set_format_ar_bsd(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::ArSvr4 => unsafe {
|
|
||||||
ffi::archive_write_set_format_ar_svr4(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::Cpio => unsafe {
|
|
||||||
ffi::archive_write_set_format_cpio(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::CpioNewc => unsafe {
|
WriteFormat::CpioNewc => unsafe {
|
||||||
ffi::archive_write_set_format_cpio_newc(self.handle);
|
ffi::archive_write_set_format_cpio_newc(self.handle)
|
||||||
},
|
|
||||||
WriteFormat::Gnutar => unsafe {
|
|
||||||
ffi::archive_write_set_format_gnutar(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::Iso9660 => unsafe {
|
|
||||||
ffi::archive_write_set_format_iso9660(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::Mtree => unsafe {
|
|
||||||
ffi::archive_write_set_format_mtree(self.handle);
|
|
||||||
},
|
},
|
||||||
|
WriteFormat::Gnutar => unsafe { ffi::archive_write_set_format_gnutar(self.handle) },
|
||||||
|
WriteFormat::Iso9660 => unsafe { ffi::archive_write_set_format_iso9660(self.handle) },
|
||||||
|
WriteFormat::Mtree => unsafe { ffi::archive_write_set_format_mtree(self.handle) },
|
||||||
WriteFormat::MtreeClassic => unsafe {
|
WriteFormat::MtreeClassic => unsafe {
|
||||||
ffi::archive_write_set_format_mtree_classic(self.handle);
|
ffi::archive_write_set_format_mtree_classic(self.handle)
|
||||||
},
|
|
||||||
WriteFormat::Pax => unsafe {
|
|
||||||
ffi::archive_write_set_format_pax(self.handle);
|
|
||||||
},
|
},
|
||||||
|
WriteFormat::Pax => unsafe { ffi::archive_write_set_format_pax(self.handle) },
|
||||||
WriteFormat::PaxRestricted => unsafe {
|
WriteFormat::PaxRestricted => unsafe {
|
||||||
ffi::archive_write_set_format_pax_restricted(self.handle);
|
ffi::archive_write_set_format_pax_restricted(self.handle)
|
||||||
},
|
|
||||||
WriteFormat::Shar => unsafe {
|
|
||||||
ffi::archive_write_set_format_shar(self.handle);
|
|
||||||
},
|
},
|
||||||
|
WriteFormat::Shar => unsafe { ffi::archive_write_set_format_shar(self.handle) },
|
||||||
WriteFormat::SharDump => unsafe {
|
WriteFormat::SharDump => unsafe {
|
||||||
ffi::archive_write_set_format_shar_dump(self.handle);
|
ffi::archive_write_set_format_shar_dump(self.handle)
|
||||||
},
|
|
||||||
WriteFormat::Ustar => unsafe {
|
|
||||||
ffi::archive_write_set_format_ustar(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::V7tar => unsafe {
|
|
||||||
ffi::archive_write_set_format_v7tar(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::Xar => unsafe {
|
|
||||||
ffi::archive_write_set_format_xar(self.handle);
|
|
||||||
},
|
|
||||||
WriteFormat::Zip => unsafe {
|
|
||||||
ffi::archive_write_set_format_zip(self.handle);
|
|
||||||
},
|
},
|
||||||
|
WriteFormat::Ustar => unsafe { ffi::archive_write_set_format_ustar(self.handle) },
|
||||||
|
WriteFormat::V7tar => unsafe { ffi::archive_write_set_format_v7tar(self.handle) },
|
||||||
|
WriteFormat::Xar => unsafe { ffi::archive_write_set_format_xar(self.handle) },
|
||||||
|
WriteFormat::Zip => unsafe { ffi::archive_write_set_format_zip(self.handle) },
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
ffi::ARCHIVE_OK => Ok(()),
|
||||||
|
_ => ArchiveResult::from(self as &Handle),
|
||||||
}
|
}
|
||||||
ArchiveResult::from(self as &Handle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_file<T: AsRef<Path>>(mut self, file: T) -> ArchiveResult<Writer> {
|
pub fn open_file<T: AsRef<Path>>(mut self, file: T) -> ArchiveResult<Writer> {
|
||||||
@@ -313,7 +285,7 @@ impl Builder {
|
|||||||
let c_file = CString::new(file.as_ref().to_string_lossy().as_bytes()).unwrap();
|
let c_file = CString::new(file.as_ref().to_string_lossy().as_bytes()).unwrap();
|
||||||
let res = unsafe { ffi::archive_write_open_filename(self.handle, c_file.as_ptr()) };
|
let res = unsafe { ffi::archive_write_open_filename(self.handle, c_file.as_ptr()) };
|
||||||
match res {
|
match res {
|
||||||
0 => {
|
ffi::ARCHIVE_OK => {
|
||||||
self.consumed = true;
|
self.consumed = true;
|
||||||
Ok(Writer::new(self.handle))
|
Ok(Writer::new(self.handle))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user