summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2022-01-13 11:50:30 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2022-01-13 11:50:30 +0000
commit1439c6c7681037304bcbebf74c587b35b3e0c8a6 (patch)
tree8337797624431dc27d563390006e925a74dd2000 /usr.sbin
parentbd521eb9aa086f628e20c93b6f27a77c18e5c58d (diff)
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@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/rpki-client/main.c3
-rw-r--r--usr.sbin/rpki-client/rsync.c40
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 <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -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 <kristaps@bsd.lv>
*
@@ -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. */