aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-13 20:33:46 +0000
committertv <tv@krebsco.de>2026-11-13 22:01:12 +0100
commit53eb98c0b2f808ca456717111facf21ca4a50015 (patch)
tree6b9231e6255d7b55b650a2cfeb9c68f3997258d5 /pkgs
parenta39ddee552a3955d1655fe89620daa31d9875d16 (diff)
populate: fail if find fails looking for .rsync-filter files
Looking for .rsync-filter files that apply to a file source, a failing find counted as finding none, and only happened with rsync 3.5.0 and later. Like in the shell implementation, find runs before each transfer with filter files, and its failure stops populate with find's message, e.g. for a source that's missing, or contains a directory find can't read, which would also have switched off the check of insecureLinks. A signal during find takes effect right after it.
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/populate/src/rsync.rs21
1 files changed, 11 insertions, 10 deletions
diff --git a/pkgs/populate/src/rsync.rs b/pkgs/populate/src/rsync.rs
index 78022ab..0ab92e6 100644
--- a/pkgs/populate/src/rsync.rs
+++ b/pkgs/populate/src/rsync.rs
@@ -150,7 +150,10 @@ fn insecure_links(context: &Context, config: &Config, source: &str) -> Result<bo
.and_then(|line| line.split_whitespace().nth(2))
.unwrap_or("")
.to_string();
- if !version_at_least(&version, "3.5.0") || !filtered(source) {
+ // Also with older versions of rsync, so a source that's missing, or
+ // that contains a directory find can't read, fails before rsync runs.
+ let filtered = filtered(source)?;
+ if !version_at_least(&version, "3.5.0") || !filtered {
return Ok(false);
}
// A dry run of the same transfer, as far as filtering goes.
@@ -215,26 +218,24 @@ fn insecure_links(context: &Context, config: &Config, source: &str) -> Result<bo
}
/// Whether a .rsync-filter file applies to source: one therein, or in a
-/// directory above it.
-fn filtered(source: &str) -> bool {
+/// directory above it. Fails, with find's message, if find fails.
+fn filtered(source: &str) -> Result<bool> {
let found = run::output(Command::new("find").arg(source).args([
"-name",
".rsync-filter",
"-print",
"-quit",
- ]))
- .map(|out| !out.is_empty())
- .unwrap_or(false);
- if found {
- return true;
+ ]))?;
+ if !found.is_empty() {
+ return Ok(true);
}
let mut above = parent(source);
loop {
if Path::new(&above).join(".rsync-filter").exists() {
- return true;
+ return Ok(true);
}
if above == "/" || above == "." {
- return false;
+ return Ok(false);
}
above = parent(&above);
}