catalog: decoder and shell: fix incorrect logic in find matching
The find matching was incorrectly performed starting from the parent directroy and not as intended from the entries of the parent directory. Further, the match pattern passed from the catalog shell contains the absolute path of the search entry point as prefix, so find() must always start from the archive root. This is because the match pattern has to be stored in the selected list for a subsequent restore-selected command in the shell. All matching paths are shown as absolute paths with all contents in the subdir, equal to what would be restored by the given pattern. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
8af272fd14
commit
38d9a69875
|
@ -546,44 +546,35 @@ impl <R: Read + Seek> CatalogReader<R> {
|
|||
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),
|
||||
_ => {}
|
||||
}
|
||||
let parent = entry.last().unwrap();
|
||||
if !parent.is_directory() {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
for e in self.read_dir(parent)? {
|
||||
match MatchPatternSlice::match_filename_include(
|
||||
&CString::new(node.name.clone())?,
|
||||
node.is_directory(),
|
||||
&CString::new(e.name.clone())?,
|
||||
e.is_directory(),
|
||||
pattern,
|
||||
)? {
|
||||
(MatchType::Positive, _) => {
|
||||
entry.push(e);
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -495,7 +495,7 @@ fn restore_command(target: String, pattern: Option<String>) -> Result<(), Error>
|
|||
/// Find entries in the catalog matching the given match pattern.
|
||||
fn find_command(path: String, pattern: String, select: Option<bool>) -> Result<(), Error> {
|
||||
Context::with(|ctx| {
|
||||
let mut path = ctx.canonical_path(&path)?;
|
||||
let path = ctx.canonical_path(&path)?;
|
||||
if !path.last().unwrap().is_directory() {
|
||||
bail!("path should be a directory, not a file!");
|
||||
}
|
||||
|
@ -517,8 +517,12 @@ fn find_command(path: String, pattern: String, select: Option<bool>) -> Result<(
|
|||
.ok_or_else(|| format_err!("invalid match pattern"))?;
|
||||
let slice = vec![pattern.as_slice()];
|
||||
|
||||
// The match pattern all contain the prefix of the entry path in order to
|
||||
// store them if selected, so the entry point for find is always the root
|
||||
// directory.
|
||||
let mut dir_stack = ctx.root.clone();
|
||||
ctx.catalog.find(
|
||||
&mut path,
|
||||
&mut dir_stack,
|
||||
&slice,
|
||||
&Box::new(|path: &[DirEntry]| println!("{:?}", Context::generate_cstring(path).unwrap()))
|
||||
)?;
|
||||
|
|
Loading…
Reference in New Issue