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:
parent
138910bcd4
commit
a8aff3535d
@ -31,6 +31,8 @@ pub struct DirectoryEntry {
|
|||||||
pub xattr: PxarAttributes,
|
pub xattr: PxarAttributes,
|
||||||
/// Payload size
|
/// Payload size
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
|
/// Target path for symbolic links
|
||||||
|
pub target: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait to create ReadSeek Decoder trait objects.
|
/// Trait to create ReadSeek Decoder trait objects.
|
||||||
@ -78,6 +80,7 @@ impl Decoder {
|
|||||||
entry,
|
entry,
|
||||||
xattr,
|
xattr,
|
||||||
size,
|
size,
|
||||||
|
target: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +138,10 @@ impl Decoder {
|
|||||||
PXAR_PAYLOAD => header.size - HEADER_SIZE,
|
PXAR_PAYLOAD => header.size - HEADER_SIZE,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
let target = match header.htype {
|
||||||
|
PXAR_SYMLINK => Some(self.inner.read_link(header.size)?),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
Ok(DirectoryEntry {
|
Ok(DirectoryEntry {
|
||||||
start: entry_start,
|
start: entry_start,
|
||||||
@ -143,6 +150,7 @@ impl Decoder {
|
|||||||
entry,
|
entry,
|
||||||
xattr,
|
xattr,
|
||||||
size,
|
size,
|
||||||
|
target,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,26 +378,4 @@ impl Decoder {
|
|||||||
|
|
||||||
Ok(data)
|
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::ffi::{CStr, CString, OsStr};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
@ -445,11 +445,8 @@ impl Session {
|
|||||||
|
|
||||||
extern "C" fn readlink(req: Request, inode: u64) {
|
extern "C" fn readlink(req: Request, inode: u64) {
|
||||||
Self::run_in_context(req, inode, |ctx| {
|
Self::run_in_context(req, inode, |ctx| {
|
||||||
let (target, _) = ctx
|
let target = ctx.entry.target.as_ref().ok_or_else(|| libc::EIO)?;
|
||||||
.decoder
|
let link = CString::new(target.as_os_str().as_bytes()).map_err(|_| libc::EIO)?;
|
||||||
.read_link(ctx.ino_offset)
|
|
||||||
.map_err(|_| libc::EIO)?;
|
|
||||||
let link = CString::new(target.into_os_string().into_vec()).map_err(|_| libc::EIO)?;
|
|
||||||
let _ret = unsafe { fuse_reply_readlink(req, link.as_ptr()) };
|
let _ret = unsafe { fuse_reply_readlink(req, link.as_ptr()) };
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user