From b435c97d1085bceb4b19a5f331eff57b0067d6e5 Mon Sep 17 00:00:00 2001 From: claudio Date: Thu, 13 Jan 2022 11:50:29 +0000 Subject: [PATCH] Implement but don't use code to use rsync's --compare-dest feature. One gotcha is that the path passed to --compare-dest needs to be relative to the dst directory. rsync_fixup_dest() will prepend the necessary ../ for that by counting number of '/' in dst. OK tb@ --- usr.sbin/rpki-client/main.c | 3 ++- usr.sbin/rpki-client/rsync.c | 40 +++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index fa8d2841330..1a976d8064b 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.173 2022/01/11 13:06:07 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.174 2022/01/13 11:50:29 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -261,6 +261,7 @@ rsync_fetch(unsigned int id, const char *uri, const char *local) b = io_new_buffer(); io_simple_buffer(b, &id, sizeof(id)); io_str_buffer(b, local); + io_str_buffer(b, NULL); io_str_buffer(b, uri); io_close_buffer(&rsyncq, b); } diff --git a/usr.sbin/rpki-client/rsync.c b/usr.sbin/rpki-client/rsync.c index 58d22764368..c4e6f917435 100644 --- a/usr.sbin/rpki-client/rsync.c +++ b/usr.sbin/rpki-client/rsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rsync.c,v 1.31 2021/12/22 09:35:14 claudio Exp $ */ +/* $OpenBSD: rsync.c,v 1.32 2022/01/13 11:50:29 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -99,6 +99,31 @@ rsync_base_uri(const char *uri) return base_uri; } +/* + * The directory passed as --compare-dest needs to be relative to + * the destination directory. This function takes care of that. + */ +static char * +rsync_fixup_dest(char *destdir, char *compdir) +{ + const char *dotdot = "../../../../../../"; /* should be enough */ + int dirs = 1; + char *fn; + char c; + + while ((c = *destdir++) != '\0') + if (c == '/') + dirs++; + + if (dirs > 6) + /* too deep for us */ + return NULL; + + if ((asprintf(&fn, "%.*s%s", dirs * 3, dotdot, compdir)) == -1) + err(1, NULL); + return fn; +} + static void proc_child(int signal) { @@ -181,7 +206,7 @@ proc_rsync(char *prog, char *bind_addr, int fd) err(1, NULL); for (;;) { - char *uri = NULL, *dst = NULL; + char *uri, *dst, *compdst; unsigned int id; pid_t pid; int st; @@ -209,7 +234,8 @@ proc_rsync(char *prog, char *bind_addr, int fd) for (i = 0; i < idsz; i++) if (ids[i].pid == pid) break; - assert(i < idsz); + if (i >= idsz) + errx(1, "waitpid: %d unexpected", pid); if (!WIFEXITED(st)) { warnx("rsync %s terminated abnormally", @@ -261,6 +287,7 @@ proc_rsync(char *prog, char *bind_addr, int fd) /* Read host and module. */ io_read_buf(b, &id, sizeof(id)); io_read_str(b, &dst); + io_read_str(b, &compdst); io_read_str(b, &uri); ibuf_free(b); @@ -275,6 +302,7 @@ proc_rsync(char *prog, char *bind_addr, int fd) if (pid == 0) { char *args[32]; + char *reldst; if (pledge("stdio exec", NULL) == -1) err(1, "pledge"); @@ -295,6 +323,11 @@ proc_rsync(char *prog, char *bind_addr, int fd) args[i++] = "--address"; args[i++] = (char *)bind_addr; } + if (compdst != NULL && + (reldst = rsync_fixup_dest(dst, compdst)) != NULL) { + args[i++] = "--compare-dest"; + args[i++] = reldst; + } args[i++] = uri; args[i++] = dst; args[i] = NULL; @@ -323,6 +356,7 @@ proc_rsync(char *prog, char *bind_addr, int fd) /* Clean up temporary values. */ free(dst); + free(compdst); } /* No need for these to be hanging around. */ -- 2.20.1