From 9e3659dcf90e2cbb77d4e99dfae3b87509b1fa1a Mon Sep 17 00:00:00 2001 From: Jamie Winsor Date: Mon, 21 Mar 2016 15:58:09 -0700 Subject: [PATCH] expose ability to set/get filetype of archive entry --- libraries/libarchive/src/archive.rs | 48 +++++++++++++++++++++++++++-- libraries/libarchive/src/writer.rs | 2 +- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/libraries/libarchive/src/archive.rs b/libraries/libarchive/src/archive.rs index 4fa3172a..ff5a1dfb 100644 --- a/libraries/libarchive/src/archive.rs +++ b/libraries/libarchive/src/archive.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use std::str; use libarchive3_sys::ffi; -use error::{ArchiveResult, ErrCode}; +use error::ErrCode; pub enum ReadCompression { All, @@ -92,6 +92,17 @@ pub enum WriteFilter { Xz, } +pub enum FileType { + BlockDevice, + SymbolicLink, + Socket, + CharacterDevice, + Directory, + NamedPipe, + Mount, + RegularFile, +} + pub trait Handle { unsafe fn handle(&self) -> *mut ffi::Struct_archive; @@ -112,6 +123,22 @@ pub trait Handle { pub trait 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 pathname(&self) -> &str { let c_str: &CStr = unsafe { CStr::from_ptr(ffi::archive_entry_pathname(self.entry())) }; let buf: &[u8] = c_str.to_bytes(); @@ -122,12 +149,27 @@ pub trait Entry { unsafe { ffi::archive_entry_size(self.entry()) } } - fn set_pathname(&mut self, path: PathBuf) -> ArchiveResult<()> { + 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_pathname(&mut self, path: PathBuf) { unsafe { let c_str = CString::new(path.to_str().unwrap()).unwrap(); ffi::archive_entry_set_pathname(self.entry(), c_str.as_ptr()); } - Ok(()) } } diff --git a/libraries/libarchive/src/writer.rs b/libraries/libarchive/src/writer.rs index ca90e524..6b79b2fc 100644 --- a/libraries/libarchive/src/writer.rs +++ b/libraries/libarchive/src/writer.rs @@ -113,7 +113,7 @@ impl Disk { if let Some(entry) = reader.next_header() { if let Some(pfx) = prefix { let path = Path::new(pfx).join(entry.pathname()); - try!(entry.set_pathname(path)); + entry.set_pathname(path); } match self.write_header(entry) { Ok(()) => (),