pxar::decoder::Decoder: include xattrs and payload size in DirectoryEntry
.
By reading and including xattrs and payload size in struct `DirectoryEntry`, the tuple of return types is avoided and the code is simpler. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
6fc053ed85
commit
90fc97af6a
@ -309,12 +309,12 @@ fn stat_command(path: String) -> Result<(), Error> {
|
||||
// This is done by calling canonical_path(), which returns the full path
|
||||
// if it exists, error otherwise.
|
||||
let path = ctx.canonical_path(&path)?;
|
||||
let (item, _attr, size) = ctx.lookup(&path)?;
|
||||
let item = ctx.lookup(&path)?;
|
||||
let mut out = std::io::stdout();
|
||||
out.write_all(b"File: ")?;
|
||||
out.write_all(item.filename.as_bytes())?;
|
||||
out.write_all(&[b'\n'])?;
|
||||
out.write_all(format!("Size: {}\n", size).as_bytes())?;
|
||||
out.write_all(format!("Size: {}\n", item.size).as_bytes())?;
|
||||
out.write_all(b"Type: ")?;
|
||||
match item.entry.mode as u32 & libc::S_IFMT {
|
||||
libc::S_IFDIR => out.write_all(b"directory\n")?,
|
||||
@ -463,8 +463,7 @@ fn restore_command(target: String, pattern: Option<String>) -> Result<(), Error>
|
||||
// Get the directory corresponding to the working directory from the
|
||||
// archive.
|
||||
let cwd = ctx.current.clone();
|
||||
let (dir, _, _) = ctx.lookup(&cwd)?;
|
||||
dir
|
||||
ctx.lookup(&cwd)?
|
||||
};
|
||||
|
||||
ctx.decoder
|
||||
@ -681,27 +680,19 @@ impl Context {
|
||||
///
|
||||
/// This will actively navigate the archive by calling the corresponding
|
||||
/// decoder functionalities and is therefore very expensive.
|
||||
fn lookup(
|
||||
&mut self,
|
||||
absolute_path: &[DirEntry],
|
||||
) -> Result<(DirectoryEntry, PxarAttributes, u64), Error> {
|
||||
fn lookup(&mut self, absolute_path: &[DirEntry]) -> Result<DirectoryEntry, Error> {
|
||||
let mut current = self.decoder.root()?;
|
||||
let (_, _, mut attr, mut size) = self.decoder.attributes(0)?;
|
||||
// Ignore the archive root, don't need it.
|
||||
for item in absolute_path.iter().skip(1) {
|
||||
match self
|
||||
.decoder
|
||||
.lookup(¤t, &OsStr::from_bytes(&item.name))?
|
||||
{
|
||||
Some((item, item_attr, item_size)) => {
|
||||
current = item;
|
||||
attr = item_attr;
|
||||
size = item_size;
|
||||
}
|
||||
Some(item) => current = item,
|
||||
// This should not happen if catalog an archive are consistent.
|
||||
None => bail!("no such file or directory in archive - inconsistent catalog"),
|
||||
}
|
||||
}
|
||||
Ok((current, attr, size))
|
||||
Ok(current)
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,14 @@ pub struct DirectoryEntry {
|
||||
start: u64,
|
||||
/// Points past the goodbye table tail
|
||||
end: u64,
|
||||
/// Filename of entry
|
||||
pub filename: OsString,
|
||||
/// Entry (mode, permissions)
|
||||
pub entry: PxarEntry,
|
||||
/// Extended attributes
|
||||
pub xattr: PxarAttributes,
|
||||
/// Payload size
|
||||
pub size: u64,
|
||||
}
|
||||
|
||||
/// Trait to create ReadSeek Decoder trait objects.
|
||||
@ -59,11 +65,19 @@ impl Decoder {
|
||||
let header: PxarHeader = self.inner.read_item()?;
|
||||
check_ca_header::<PxarEntry>(&header, PXAR_ENTRY)?;
|
||||
let entry: PxarEntry = self.inner.read_item()?;
|
||||
let (header, xattr) = self.inner.read_attributes()?;
|
||||
let size = match header.htype {
|
||||
PXAR_PAYLOAD => header.size - HEADER_SIZE,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
Ok(DirectoryEntry {
|
||||
start: self.root_start,
|
||||
end: self.root_end,
|
||||
filename: OsString::new(), // Empty
|
||||
entry,
|
||||
xattr,
|
||||
size,
|
||||
})
|
||||
}
|
||||
|
||||
@ -116,12 +130,19 @@ impl Decoder {
|
||||
}
|
||||
check_ca_header::<PxarEntry>(&head, PXAR_ENTRY)?;
|
||||
let entry: PxarEntry = self.inner.read_item()?;
|
||||
let (header, xattr) = self.inner.read_attributes()?;
|
||||
let size = match header.htype {
|
||||
PXAR_PAYLOAD => header.size - HEADER_SIZE,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
Ok(DirectoryEntry {
|
||||
start: entry_start,
|
||||
end,
|
||||
filename,
|
||||
entry,
|
||||
xattr,
|
||||
size,
|
||||
})
|
||||
}
|
||||
|
||||
@ -273,7 +294,7 @@ impl Decoder {
|
||||
&mut self,
|
||||
dir: &DirectoryEntry,
|
||||
filename: &OsStr,
|
||||
) -> Result<Option<(DirectoryEntry, PxarAttributes, u64)>, Error> {
|
||||
) -> Result<Option<DirectoryEntry>, Error> {
|
||||
let gbt = self.goodbye_table(Some(dir.start), dir.end)?;
|
||||
let hash = compute_goodbye_hash(filename.as_bytes());
|
||||
|
||||
@ -298,7 +319,7 @@ impl Decoder {
|
||||
// the start of an item (PXAR_FILENAME) or the GOODBYE_TAIL_MARKER in
|
||||
// case of directories, so the use of start offset is fine for both
|
||||
// cases.
|
||||
let (entry_name, entry, attr, payload_size) = self.attributes(*start)?;
|
||||
let (entry_name, entry, xattr, size) = self.attributes(*start)?;
|
||||
|
||||
// Possible hash collision, need to check if the found entry is indeed
|
||||
// the filename to lookup.
|
||||
@ -308,8 +329,10 @@ impl Decoder {
|
||||
end: *end,
|
||||
filename: entry_name,
|
||||
entry,
|
||||
xattr,
|
||||
size,
|
||||
};
|
||||
return Ok(Some((dir_entry, attr, payload_size)));
|
||||
return Ok(Some(dir_entry));
|
||||
}
|
||||
// Hash collision, check the next entry in the goodbye table by starting
|
||||
// from given index but skipping one more match (so hash at index itself).
|
||||
|
Loading…
Reference in New Issue
Block a user