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:
Christian Ebner 2019-12-16 12:13:47 +01:00 committed by Dietmar Maurer
parent a333b4ccea
commit 90dfd0a71d
1 changed files with 50 additions and 0 deletions

View File

@ -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