From a8aff3535d9cd75815409ecad4b890288ca9614b Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Fri, 17 Jan 2020 11:21:44 +0100 Subject: [PATCH] pxar: Include symlink target in DirectoryEntry This allows to read the target path of a symbolic link in the Decoder::read_directory_entry() function and stores it in the DirectoryEntry. By this the Decoder::read_link() function becomes obsolete and is therefore removed. Signed-off-by: Christian Ebner --- src/pxar/decoder.rs | 30 ++++++++---------------------- src/pxar/fuse.rs | 9 +++------ 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/pxar/decoder.rs b/src/pxar/decoder.rs index 46871b5e..c7cdce19 100644 --- a/src/pxar/decoder.rs +++ b/src/pxar/decoder.rs @@ -31,6 +31,8 @@ pub struct DirectoryEntry { pub xattr: PxarAttributes, /// Payload size pub size: u64, + /// Target path for symbolic links + pub target: Option, } /// Trait to create ReadSeek Decoder trait objects. @@ -78,6 +80,7 @@ impl Decoder { entry, xattr, size, + target: None, }) } @@ -135,6 +138,10 @@ impl Decoder { PXAR_PAYLOAD => header.size - HEADER_SIZE, _ => 0, }; + let target = match header.htype { + PXAR_SYMLINK => Some(self.inner.read_link(header.size)?), + _ => None, + }; Ok(DirectoryEntry { start: entry_start, @@ -143,6 +150,7 @@ impl Decoder { entry, xattr, size, + target, }) } @@ -370,26 +378,4 @@ impl Decoder { Ok(data) } - - /// Read the target of a hardlink in the archive. - pub fn read_link(&mut self, offset: u64) -> Result<(PathBuf, PxarEntry), Error> { - self.seek(SeekFrom::Start(offset))?; - let mut header: PxarHeader = self.inner.read_item()?; - if header.htype != PXAR_FILENAME { - bail!("Expected PXAR_FILENAME, encountered 0x{:x?}", header.htype); - } - let _filename = self.inner.read_filename(header.size)?; - - header = self.inner.read_item()?; - check_ca_header::(&header, PXAR_ENTRY)?; - let entry: PxarEntry = self.inner.read_item()?; - - header = self.inner.read_item()?; - if header.htype != PXAR_SYMLINK { - bail!("Expected PXAR_SYMLINK, encountered 0x{:x?}", header.htype); - } - let target = self.inner.read_link(header.size)?; - - Ok((target, entry)) - } } diff --git a/src/pxar/fuse.rs b/src/pxar/fuse.rs index 31e67eb3..139ff036 100644 --- a/src/pxar/fuse.rs +++ b/src/pxar/fuse.rs @@ -7,7 +7,7 @@ use std::convert::TryFrom; use std::ffi::{CStr, CString, OsStr}; use std::fs::File; use std::io::BufReader; -use std::os::unix::ffi::{OsStrExt, OsStringExt}; +use std::os::unix::ffi::OsStrExt; use std::path::Path; use std::sync::Mutex; @@ -445,11 +445,8 @@ impl Session { extern "C" fn readlink(req: Request, inode: u64) { Self::run_in_context(req, inode, |ctx| { - let (target, _) = ctx - .decoder - .read_link(ctx.ino_offset) - .map_err(|_| libc::EIO)?; - let link = CString::new(target.into_os_string().into_vec()).map_err(|_| libc::EIO)?; + let target = ctx.entry.target.as_ref().ok_or_else(|| libc::EIO)?; + let link = CString::new(target.as_os_str().as_bytes()).map_err(|_| libc::EIO)?; let _ret = unsafe { fuse_reply_readlink(req, link.as_ptr()) }; Ok(())