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:
		
				
					committed by
					
						
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						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).
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user