On Wed, Jun 30, 2021 at 05:47:16PM +0200, Claudio Jeker wrote:
> Thge compare-dest option of rsync is something I would like to use in
> rpki-client. This implements just that and I think after that adding
> copy-dest and link-dest options should be somewhat easy to add as well.
> Lightly tested with my particular need.
There is some unveil issues with this diff that need to be worked out.
Until then it people can test by commenting the unveil calls in receiver.c
> --
> :wq Claudio
>
> Index: Makefile
> ===
> RCS file: /cvs/src/usr.bin/rsync/Makefile,v
> retrieving revision 1.10
> diff -u -p -r1.10 Makefile
> --- Makefile 8 May 2019 21:30:11 - 1.10
> +++ Makefile 30 Jun 2021 15:40:19 -
> @@ -1,14 +1,18 @@
> #$OpenBSD: Makefile,v 1.10 2019/05/08 21:30:11 benno Exp $
>
> PROG=openrsync
> -SRCS=blocks.c client.c downloader.c fargs.c flist.c hash.c ids.c \
> +SRCS=blocks.c client.c copy.c downloader.c fargs.c flist.c hash.c
> ids.c \
> io.c log.c mkpath.c mktemp.c receiver.c sender.c server.c session.c \
> socket.c symlinks.c uploader.c main.c misc.c
> LDADD+= -lcrypto -lm
> DPADD+= ${LIBCRYPTO} ${LIBM}
> MAN= openrsync.1
>
> -CFLAGS+=-g -W -Wall -Wextra
> +CFLAGS+= -Wall -Wextra
> +CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
> +CFLAGS+= -Wmissing-declarations
> +CFLAGS+= -Wshadow
> +
>
> openrsync.1: rsync.1
> ln -sf ${.CURDIR}/rsync.1 openrsync.1
> Index: copy.c
> ===
> RCS file: copy.c
> diff -N copy.c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ copy.c30 Jun 2021 15:40:19 -
> @@ -0,0 +1,90 @@
> +/* $OpenBSD$ */
> +/*
> + * Copyright (c) 2021 Claudio Jeker
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include/* for MAXBSIZE */
> +
> +#include
> +#include
> +#include
> +
> +#include "extern.h"
> +
> +/*
> + * Return true if all bytes in buffer are zero.
> + * A buffer of zero lenght is also considered a zero buffer.
> + */
> +static int
> +iszero(const void *b, size_t len)
> +{
> + const unsigned char *c = b;
> +
> + for (; len > 0; len--) {
> + if (*c++ != '\0')
> + return 0;
> + }
> + return 1;
> +}
> +
> +static int
> +copy_internal(int fromfd, int tofd)
> +{
> + char buf[MAXBSIZE];
> + ssize_t r, w;
> +
> + while ((r = read(fromfd, buf, sizeof(buf))) > 0) {
> + if (iszero(buf, sizeof(buf))) {
> + if (lseek(tofd, r, SEEK_CUR) == -1)
> + return -1;
> + } else {
> + w = write(tofd, buf, r);
> + if (r != w || w == -1)
> + return -1;
> + }
> + }
> + if (r == -1)
> + return -1;
> + if (ftruncate(tofd, lseek(tofd, 0, SEEK_CUR)) == -1)
> + return -1;
> + return 0;
> +}
> +
> +void
> +copy_file(int rootfd, const char *basedir, const struct flist *f)
> +{
> + int fromfd, tofd, dfd;
> +
> + dfd = openat(rootfd, basedir, O_RDONLY | O_DIRECTORY, 0);
> + if (dfd == -1)
> + err(ERR_FILE_IO, "%s: openat", basedir);
> +
> + fromfd = openat(dfd, f->path, O_RDONLY | O_NOFOLLOW, 0);
> + if (fromfd == -1)
> + err(ERR_FILE_IO, "%s/%s: openat", basedir, f->path);
> + close(dfd);
> +
> + tofd = openat(rootfd, f->path,
> + O_WRONLY | O_NOFOLLOW | O_TRUNC | O_CREAT | O_EXCL,
> + 0600);
> + if (tofd == -1)
> + err(ERR_FILE_IO, "%s: openat", f->path);
> +
> + if (copy_internal(fromfd, tofd) == -1)
> + err(ERR_FILE_IO, "%s: copy file", f->path);
> +
> + close(fromfd);
> + close(tofd);
> +}
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.bin/rsync/extern.h,v
> retrieving revision 1.39
> diff -u -p -r1.39 extern.h
> --- extern.h 30 Jun 2021 15:24:10 - 1.39
> +++ extern.h 30 Jun 2021 15:40:19 -
> @@ -34,6 +34,15 @@
> #define BLOCK_SIZE_MIN (700)
>
> /*
> + * Maximum number of base directories that can be used.
> + */
> +#define MAX_BASEDIR