catalog: impl find() for file search by match pattern.
find() iterates over the file tree and matches each node against a list of match patterns provided at function call. For each matching node, a callback function with the current directroy stack is called. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						parent
						
							a333b4ccea
						
					
				
				
					commit
					90dfd0a71d
				
			@ -10,6 +10,7 @@ use chrono::offset::{TimeZone, Local};
 | 
			
		||||
use proxmox::tools::io::ReadExt;
 | 
			
		||||
 | 
			
		||||
use crate::pxar::catalog::BackupCatalogWriter;
 | 
			
		||||
use crate::pxar::{MatchPattern, MatchPatternSlice, MatchType};
 | 
			
		||||
use crate::backup::file_formats::PROXMOX_CATALOG_FILE_MAGIC_1_0;
 | 
			
		||||
 | 
			
		||||
#[repr(u8)]
 | 
			
		||||
@ -536,6 +537,55 @@ impl <R: Read + Seek> CatalogReader<R> {
 | 
			
		||||
            Ok(true)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Finds all entries matching the given match patterns and calls the
 | 
			
		||||
    /// provided callback on them.
 | 
			
		||||
    pub fn find(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        mut entry: &mut Vec<DirEntry>,
 | 
			
		||||
        pattern: &[MatchPatternSlice],
 | 
			
		||||
        callback: &Box<fn(&[DirEntry])>,
 | 
			
		||||
    ) -> Result<(), Error> {
 | 
			
		||||
        let node = entry.last().unwrap();
 | 
			
		||||
        if !node.is_directory() {
 | 
			
		||||
            match MatchPatternSlice::match_filename_include(
 | 
			
		||||
                &CString::new(node.name.clone())?,
 | 
			
		||||
                false,
 | 
			
		||||
                pattern,
 | 
			
		||||
            )? {
 | 
			
		||||
                (MatchType::Positive, _) => callback(&entry),
 | 
			
		||||
                _ => {}
 | 
			
		||||
            }
 | 
			
		||||
            return Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        match MatchPatternSlice::match_filename_include(
 | 
			
		||||
            &CString::new(node.name.clone())?,
 | 
			
		||||
            node.is_directory(),
 | 
			
		||||
            pattern,
 | 
			
		||||
        )? {
 | 
			
		||||
            (MatchType::Positive, _) => {
 | 
			
		||||
                callback(&entry);
 | 
			
		||||
                let pattern = MatchPattern::from_line(b"**/*").unwrap().unwrap();
 | 
			
		||||
                let child_pattern = vec![pattern.as_slice()];
 | 
			
		||||
                for e in self.read_dir(node)?  {
 | 
			
		||||
                    entry.push(e);
 | 
			
		||||
                    self.find(&mut entry, &child_pattern, callback)?;
 | 
			
		||||
                    entry.pop();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            (MatchType::PartialPositive, child_pattern)
 | 
			
		||||
            | (MatchType::PartialNegative, child_pattern) => {
 | 
			
		||||
                for e in self.read_dir(node)?  {
 | 
			
		||||
                    entry.push(e);
 | 
			
		||||
                    self.find(&mut entry, &child_pattern, callback)?;
 | 
			
		||||
                    entry.pop();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            _ => {}
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Serialize u64 as short, variable length byte sequence
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user