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 <c.ebner@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						parent
						
							138910bcd4
						
					
				
				
					commit
					a8aff3535d
				
			@ -31,6 +31,8 @@ pub struct DirectoryEntry {
 | 
			
		||||
    pub xattr: PxarAttributes,
 | 
			
		||||
    /// Payload size
 | 
			
		||||
    pub size: u64,
 | 
			
		||||
    /// Target path for symbolic links
 | 
			
		||||
    pub target: Option<PathBuf>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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::<PxarEntry>(&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))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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(())
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user