summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2019-04-02 05:32:08 +0000
committerderaadt <deraadt@openbsd.org>2019-04-02 05:32:08 +0000
commit4d864e8f52ad6c20b788491457196299e3ae7454 (patch)
tree407ef4d40c3d22ca8dc929454645777fd9756fbe
parentvmm(4): Fix some broken event injection code for SVM (diff)
downloadwireguard-openbsd-4d864e8f52ad6c20b788491457196299e3ae7454.tar.xz
wireguard-openbsd-4d864e8f52ad6c20b788491457196299e3ae7454.zip
Pull in addargs() API from ssh to replace complicated hand-rolled argument
composition code for the remote process. ok florian naddy
-rw-r--r--usr.bin/rsync/Makefile4
-rw-r--r--usr.bin/rsync/extern.h12
-rw-r--r--usr.bin/rsync/fargs.c98
-rw-r--r--usr.bin/rsync/misc.c77
4 files changed, 128 insertions, 63 deletions
diff --git a/usr.bin/rsync/Makefile b/usr.bin/rsync/Makefile
index 3e8c28dac50..8bb82588520 100644
--- a/usr.bin/rsync/Makefile
+++ b/usr.bin/rsync/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.8 2019/03/18 04:32:31 deraadt Exp $
+# $OpenBSD: Makefile,v 1.9 2019/04/02 05:32:08 deraadt Exp $
PROG= openrsync
SRCS= blocks.c client.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
+ socket.c symlinks.c uploader.c main.c misc.c
LDADD+= -lcrypto -lm
DPADD+= ${LIBCRYPTO} ${LIBM}
MAN= openrsync.1
diff --git a/usr.bin/rsync/extern.h b/usr.bin/rsync/extern.h
index 12aceae566c..9ae08e7515e 100644
--- a/usr.bin/rsync/extern.h
+++ b/usr.bin/rsync/extern.h
@@ -1,4 +1,4 @@
-/* $Id: extern.h,v 1.26 2019/03/31 09:26:05 deraadt Exp $ */
+/* $Id: extern.h,v 1.27 2019/04/02 05:32:08 deraadt Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -199,6 +199,16 @@ struct ident {
char *name; /* resolved name */
};
+typedef struct arglist arglist;
+struct arglist {
+ char **list;
+ u_int num;
+ u_int nalloc;
+};
+void addargs(arglist *, char *, ...)
+ __attribute__((format(printf, 2, 3)));
+void freeargs(arglist *);
+
struct download;
struct upload;
diff --git a/usr.bin/rsync/fargs.c b/usr.bin/rsync/fargs.c
index 9e4a61aeb7d..55bf1b4b8af 100644
--- a/usr.bin/rsync/fargs.c
+++ b/usr.bin/rsync/fargs.c
@@ -1,4 +1,4 @@
-/* $Id: fargs.c,v 1.14 2019/03/31 08:47:46 naddy Exp $ */
+/* $Id: fargs.c,v 1.15 2019/04/02 05:32:08 deraadt Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -28,9 +28,11 @@
char **
fargs_cmdline(struct sess *sess, const struct fargs *f, size_t *skip)
{
- char **args = NULL, **new;
- size_t i = 0, n = 1, j, argsz = 0;
- char *rsync_path, *ap;
+ arglist args;
+ size_t j;
+ char *rsync_path, *ap, *arg;
+
+ memset(&args, 0, sizeof args);
assert(f != NULL);
assert(f->sourcesz > 0);
@@ -38,19 +40,6 @@ fargs_cmdline(struct sess *sess, const struct fargs *f, size_t *skip)
if ((rsync_path = sess->opts->rsync_path) == NULL)
rsync_path = RSYNC_PATH;
- /* Be explicit with array size. */
-
- argsz += 1; /* dot separator */
- argsz += 1; /* sink file */
- argsz += 5; /* per-mode maximum */
- argsz += 15; /* shared args */
- argsz += 1; /* NULL pointer */
- argsz += f->sourcesz;
-
- args = calloc(argsz, sizeof(char *));
- if (args == NULL)
- goto out;
-
if (f->host != NULL) {
/*
* Splice arguments from -e "foo bar baz" into array
@@ -64,89 +53,78 @@ fargs_cmdline(struct sess *sess, const struct fargs *f, size_t *skip)
if (ap == NULL)
goto out;
- while ((args[i] = strsep(&ap, " \t")) != NULL) {
- if (args[i][0] == '\0') {
+ while ((arg = strsep(&ap, " \t")) != NULL) {
+ if (arg[0] == '\0') {
ap++; /* skip seperators */
continue;
}
- /* Grow command-area of array */
-
- if (i++ < n)
- continue;
- n += 10;
- new = reallocarray(args,
- argsz + n, sizeof(char *));
- if (new == NULL)
- goto out;
- args = new;
- argsz += n;
+ addargs(&args, "%s", arg);
}
} else
- args[i++] = "ssh";
+ addargs(&args, "ssh");
- args[i++] = f->host;
- args[i++] = rsync_path;
+ addargs(&args, "%s", f->host);
+ addargs(&args, "%s", rsync_path);
if (skip)
- *skip = i;
- args[i++] = "--server";
+ *skip = args.num;
+ addargs(&args, "--server");
if (f->mode == FARGS_RECEIVER)
- args[i++] = "--sender";
+ addargs(&args, "--sender");
} else {
- args[i++] = rsync_path;
- args[i++] = "--server";
+ addargs(&args, "%s", rsync_path);
+ addargs(&args, "--server");
}
/* Shared arguments. */
if (sess->opts->del)
- args[i++] = "--delete";
+ addargs(&args, "--delete");
if (sess->opts->numeric_ids)
- args[i++] = "--numeric-ids";
+ addargs(&args, "--numeric-ids");
if (sess->opts->preserve_gids)
- args[i++] = "-g";
+ addargs(&args, "-g");
if (sess->opts->preserve_links)
- args[i++] = "-l";
+ addargs(&args, "-l");
if (sess->opts->dry_run)
- args[i++] = "-n";
+ addargs(&args, "-n");
if (sess->opts->preserve_uids)
- args[i++] = "-o";
+ addargs(&args, "-o");
if (sess->opts->preserve_perms)
- args[i++] = "-p";
+ addargs(&args, "-p");
if (sess->opts->devices)
- args[i++] = "-D";
+ addargs(&args, "-D");
if (sess->opts->recursive)
- args[i++] = "-r";
+ addargs(&args, "-r");
if (sess->opts->preserve_times)
- args[i++] = "-t";
+ addargs(&args, "-t");
if (sess->opts->verbose > 3)
- args[i++] = "-v";
+ addargs(&args, "-v");
if (sess->opts->verbose > 2)
- args[i++] = "-v";
+ addargs(&args, "-v");
if (sess->opts->verbose > 1)
- args[i++] = "-v";
+ addargs(&args, "-v");
if (sess->opts->verbose > 0)
- args[i++] = "-v";
+ addargs(&args, "-v");
if (sess->opts->specials && !sess->opts->devices)
- args[i++] = "--specials";
+ addargs(&args, "--specials");
if (!sess->opts->specials && sess->opts->devices)
/* --devices is sent as -D --no-specials */
- args[i++] = "--no-specials";
+ addargs(&args, "--no-specials");
/* Terminate with a full-stop for reasons unknown. */
- args[i++] = ".";
+ addargs(&args, ".");
if (f->mode == FARGS_RECEIVER) {
for (j = 0; j < f->sourcesz; j++)
- args[i++] = f->sources[j];
+ addargs(&args, "%s", f->sources[j]);
} else
- args[i++] = f->sink;
+ addargs(&args, "%s", f->sink);
- args[i] = NULL;
- return args;
+ return args.list;
out:
- free(args);
+ freeargs(&args);
ERR(sess, "calloc");
return NULL;
}
diff --git a/usr.bin/rsync/misc.c b/usr.bin/rsync/misc.c
new file mode 100644
index 00000000000..2886f85f645
--- /dev/null
+++ b/usr.bin/rsync/misc.c
@@ -0,0 +1,77 @@
+/* $OpenBSD: misc.c,v 1.1 2019/04/02 05:32:08 deraadt Exp $ */
+/*
+ * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <err.h>
+
+#include "extern.h"
+
+/* function to assist building execv() arguments */
+void
+addargs(arglist *args, char *fmt, ...)
+{
+ va_list ap;
+ char *cp;
+ u_int nalloc;
+ int r;
+
+ va_start(ap, fmt);
+ r = vasprintf(&cp, fmt, ap);
+ va_end(ap);
+ if (r == -1)
+ err(1, "addargs: argument too long");
+
+ nalloc = args->nalloc;
+ if (args->list == NULL) {
+ nalloc = 32;
+ args->num = 0;
+ } else if (args->num+2 >= nalloc)
+ nalloc *= 2;
+
+ args->list = recallocarray(args->list, args->nalloc, nalloc, sizeof(char *));
+ if (!args->list)
+ err(1, "malloc");
+ args->nalloc = nalloc;
+ args->list[args->num++] = cp;
+ args->list[args->num] = NULL;
+}
+
+void
+freeargs(arglist *args)
+{
+ u_int i;
+
+ if (args->list != NULL) {
+ for (i = 0; i < args->num; i++)
+ free(args->list[i]);
+ free(args->list);
+ args->nalloc = args->num = 0;
+ args->list = NULL;
+ }
+}