diff --git a/pbs-client/src/pxar/tools.rs b/pbs-client/src/pxar/tools.rs index 25500f74..68207cd3 100644 --- a/pbs-client/src/pxar/tools.rs +++ b/pbs-client/src/pxar/tools.rs @@ -299,30 +299,12 @@ pub async fn pxar_metadata_catalog_lookup( while let Some(entry) = entries_iter.next().await { let entry = entry?.decode_entry().await?; - let entry_attr = match entry.kind() { - EntryKind::Version(_) | EntryKind::Prelude(_) | EntryKind::GoodbyeTable => continue, - EntryKind::Directory => DirEntryAttribute::Directory { - start: entry.entry_range_info().entry_range.start, - }, - EntryKind::File { size, .. } => { - let mtime = match entry.metadata().mtime_as_duration() { - SignedDuration::Positive(val) => i64::try_from(val.as_secs())?, - SignedDuration::Negative(val) => -i64::try_from(val.as_secs())?, - }; - DirEntryAttribute::File { size: *size, mtime } - } - EntryKind::Device(_) => match entry.metadata().file_type() { - mode::IFBLK => DirEntryAttribute::BlockDevice, - mode::IFCHR => DirEntryAttribute::CharDevice, - _ => bail!("encountered unknown device type"), - }, - EntryKind::Symlink(_) => DirEntryAttribute::Symlink, - EntryKind::Hardlink(_) => DirEntryAttribute::Hardlink, - EntryKind::Fifo => DirEntryAttribute::Fifo, - EntryKind::Socket => DirEntryAttribute::Socket, + let entry_attr = match DirEntryAttribute::try_from(&entry) { + Ok(attr) => attr, + Err(_) => continue, }; - let entry_path = entry_path_with_prefix(&entry, path_prefix); + let entry_path = crate::pxar::tools::entry_path_with_prefix(&entry, path_prefix); entries.push(ArchiveEntry::new( entry_path.as_os_str().as_bytes(), Some(&entry_attr), diff --git a/pbs-datastore/src/catalog.rs b/pbs-datastore/src/catalog.rs index eb531837..f0589f88 100644 --- a/pbs-datastore/src/catalog.rs +++ b/pbs-datastore/src/catalog.rs @@ -7,6 +7,10 @@ use anyhow::{bail, format_err, Error}; use serde::{Deserialize, Serialize}; use pathpatterns::{MatchList, MatchType}; +use pxar::accessor::aio::FileEntry; +use pxar::accessor::ReadAt; +use pxar::format::SignedDuration; +use pxar::{mode, EntryKind}; use proxmox_io::ReadExt; use proxmox_schema::api; @@ -104,6 +108,42 @@ pub enum DirEntryAttribute { Socket, } +impl TryFrom<&FileEntry> for DirEntryAttribute +where + T: Clone + ReadAt, +{ + type Error = Error; + + fn try_from(entry: &FileEntry) -> Result { + let attr = match entry.kind() { + EntryKind::Version(_) | EntryKind::Prelude(_) | EntryKind::GoodbyeTable => bail!( + "cannot convert pxar entry kind {:?} to catalog directory entry attribute", + entry.kind(), + ), + EntryKind::Directory => DirEntryAttribute::Directory { + start: entry.entry_range_info().entry_range.start, + }, + EntryKind::File { size, .. } => { + let mtime = match entry.metadata().mtime_as_duration() { + SignedDuration::Positive(val) => i64::try_from(val.as_secs())?, + SignedDuration::Negative(val) => -i64::try_from(val.as_secs())?, + }; + DirEntryAttribute::File { size: *size, mtime } + } + EntryKind::Device(_) => match entry.metadata().file_type() { + mode::IFBLK => DirEntryAttribute::BlockDevice, + mode::IFCHR => DirEntryAttribute::CharDevice, + _ => bail!("encountered unknown device type"), + }, + EntryKind::Symlink(_) => DirEntryAttribute::Symlink, + EntryKind::Hardlink(_) => DirEntryAttribute::Hardlink, + EntryKind::Fifo => DirEntryAttribute::Fifo, + EntryKind::Socket => DirEntryAttribute::Socket, + }; + Ok(attr) + } +} + impl DirEntry { fn new(etype: CatalogEntryType, name: Vec, start: u64, size: u64, mtime: i64) -> Self { match etype {