src/pxar/decoder.rs: impl lookup for Decoder
				
					
				
			Allows to lookup an entry in a directory based on the provided `DirectoryEntry`. This is needed to navigate the filesystem based on `DirectoryEntry`s and similar to the find_goodbye_entry() function in src/pxar/fuse.rs Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						parent
						
							fb2554de29
						
					
				
				
					commit
					e66621182b
				
			@ -3,9 +3,10 @@
 | 
			
		||||
//! This module contain the code to decode *pxar* archive files.
 | 
			
		||||
 | 
			
		||||
use std::convert::TryFrom;
 | 
			
		||||
use std::ffi::OsString;
 | 
			
		||||
use std::ffi::{OsString, OsStr};
 | 
			
		||||
use std::io::{Read, Seek, SeekFrom};
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
use std::os::unix::ffi::OsStrExt;
 | 
			
		||||
 | 
			
		||||
use failure::*;
 | 
			
		||||
use libc;
 | 
			
		||||
@ -253,6 +254,52 @@ impl<R: Read + Seek, F: Fn(&Path) -> Result<(), Error>> Decoder<R, F> {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Lookup the item identified by `filename` in the provided `DirectoryEntry`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Calculates the hash of the filename and searches for matching entries in
 | 
			
		||||
    /// the goodbye table of the provided `DirectoryEntry`.
 | 
			
		||||
    /// If found, also the filename is compared to avoid hash collision.
 | 
			
		||||
    /// If the filename does not match, the search resumes with the next entry in
 | 
			
		||||
    /// the goodbye table.
 | 
			
		||||
    /// If there is no entry with matching `filename`, `Ok(None)` is returned.
 | 
			
		||||
    pub fn lookup(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        dir: &DirectoryEntry,
 | 
			
		||||
        filename: &OsStr,
 | 
			
		||||
    ) -> Result<Option<(DirectoryEntry, PxarAttributes)>, Error> {
 | 
			
		||||
        let gbt = self.goodbye_table(Some(dir.start), dir.end)?;
 | 
			
		||||
        let hash = compute_goodbye_hash(filename.as_bytes());
 | 
			
		||||
 | 
			
		||||
        let mut iterator = gbt.iter();
 | 
			
		||||
        loop {
 | 
			
		||||
            // Search for the next goodbye entry with matching hash.
 | 
			
		||||
            let (start, end) = match iterator.find(|(i, _, _)| i.hash == hash) {
 | 
			
		||||
                Some((_item, start, end)) => (start, end),
 | 
			
		||||
                None => return Ok(None),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // At this point it is not clear if the item is a directory or not,
 | 
			
		||||
            // this has to be decided based on the entry mode.
 | 
			
		||||
            // `Decoder`s attributes function accepts both, offsets pointing to
 | 
			
		||||
            // 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)?;
 | 
			
		||||
 | 
			
		||||
            // Possible hash collision, need to check if the found entry is indeed
 | 
			
		||||
            // the filename to lookup.
 | 
			
		||||
            if entry_name == filename {
 | 
			
		||||
                let dir_entry = DirectoryEntry {
 | 
			
		||||
                    start: *start + HEADER_SIZE + entry_name.len() as u64 + 1,
 | 
			
		||||
                    end: *end,
 | 
			
		||||
                    filename: entry_name,
 | 
			
		||||
                    entry,
 | 
			
		||||
                };
 | 
			
		||||
                return Ok(Some((dir_entry, attr)));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Get attributes for the archive item located at `offset`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Returns the entry, attributes and the payload size for the item.
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user