summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorChristian Weisgerber <naddy@cvs.openbsd.org>2019-03-31 08:47:47 +0000
committerChristian Weisgerber <naddy@cvs.openbsd.org>2019-03-31 08:47:47 +0000
commit62eba8762a949ea3eb27048ce89d4eded14d72e4 (patch)
treec40ac103f781bc6f1844de3c0272b6ea85ee8843 /usr.bin
parent9115d231b1a1c4bf35f8969f4d0c61b7eff1ae55 (diff)
Add ability to combine rsync:// and -e by splitting rsync_socket()
into two functions, rsync_connect() to establish a TCP connection to the remote daemon, and rsync_socket() to run the actual protocol. E.g.: rsync -av --del -e 'ssh -W localhost:rsync -lanoncvs' \ rsync://anoncvs.spacehopper.org/OpenBSD-CVS/ /cvs ok deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/rsync/extern.h8
-rw-r--r--usr.bin/rsync/fargs.c8
-rw-r--r--usr.bin/rsync/main.c20
-rw-r--r--usr.bin/rsync/socket.c77
4 files changed, 71 insertions, 42 deletions
diff --git a/usr.bin/rsync/extern.h b/usr.bin/rsync/extern.h
index c4c2d5b478b..86eea421236 100644
--- a/usr.bin/rsync/extern.h
+++ b/usr.bin/rsync/extern.h
@@ -1,4 +1,4 @@
-/* $Id: extern.h,v 1.24 2019/03/06 18:37:22 deraadt Exp $ */
+/* $Id: extern.h,v 1.25 2019/03/31 08:47:46 naddy Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -266,7 +266,7 @@ int flist_gen_dels(struct sess *, const char *,
struct flist **, size_t *,
const struct flist *, size_t);
-char **fargs_cmdline(struct sess *, const struct fargs *);
+char **fargs_cmdline(struct sess *, const struct fargs *, size_t *);
int io_read_buf(struct sess *, int, void *, size_t);
int io_read_byte(struct sess *, int, uint8_t *);
@@ -304,7 +304,9 @@ void io_unbuffer_buf(struct sess *, const void *,
int rsync_receiver(struct sess *, int, int, const char *);
int rsync_sender(struct sess *, int, int, size_t, char **);
int rsync_client(const struct opts *, int, const struct fargs *);
-int rsync_socket(const struct opts *, const struct fargs *);
+int rsync_connect(const struct opts *, int *,
+ const struct fargs *);
+int rsync_socket(const struct opts *, int, const struct fargs *);
int rsync_server(const struct opts *, size_t, char *[]);
int rsync_downloader(struct download *, struct sess *, int *);
int rsync_set_metadata(struct sess *, int, int,
diff --git a/usr.bin/rsync/fargs.c b/usr.bin/rsync/fargs.c
index 4cc68c5980b..9e4a61aeb7d 100644
--- a/usr.bin/rsync/fargs.c
+++ b/usr.bin/rsync/fargs.c
@@ -1,4 +1,4 @@
-/* $Id: fargs.c,v 1.13 2019/02/21 22:06:26 benno Exp $ */
+/* $Id: fargs.c,v 1.14 2019/03/31 08:47:46 naddy Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -26,7 +26,7 @@
#define RSYNC_PATH "rsync"
char **
-fargs_cmdline(struct sess *sess, const struct fargs *f)
+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;
@@ -52,8 +52,6 @@ fargs_cmdline(struct sess *sess, const struct fargs *f)
goto out;
if (f->host != NULL) {
- assert(f->host != NULL);
-
/*
* Splice arguments from -e "foo bar baz" into array
* elements required for execve(2).
@@ -89,6 +87,8 @@ fargs_cmdline(struct sess *sess, const struct fargs *f)
args[i++] = f->host;
args[i++] = rsync_path;
+ if (skip)
+ *skip = i;
args[i++] = "--server";
if (f->mode == FARGS_RECEIVER)
args[i++] = "--sender";
diff --git a/usr.bin/rsync/main.c b/usr.bin/rsync/main.c
index 0ec61ee951c..9f2de25f97f 100644
--- a/usr.bin/rsync/main.c
+++ b/usr.bin/rsync/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.40 2019/03/30 23:48:24 schwarze Exp $ */
+/* $Id: main.c,v 1.41 2019/03/31 08:47:46 naddy Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -269,7 +269,7 @@ main(int argc, char *argv[])
{
struct opts opts;
pid_t child;
- int fds[2], rc, c, st, i;
+ int fds[2], sd, rc, c, st, i;
struct sess sess;
struct fargs *fargs;
char **args;
@@ -417,12 +417,15 @@ main(int argc, char *argv[])
/*
* If we're contacting an rsync:// daemon, then we don't need to
* fork, because we won't start a server ourselves.
- * Route directly into the socket code, in that case.
+ * Route directly into the socket code, unless a remote shell
+ * has explicitly been specified.
*/
- if (fargs->remote) {
+ if (fargs->remote && opts.ssh_prog == NULL) {
assert(fargs->mode == FARGS_RECEIVER);
- exit(rsync_socket(&opts, fargs));
+ if ((rc = rsync_connect(&opts, &sd, fargs)) == 0)
+ rc = rsync_socket(&opts, sd, fargs);
+ exit(rc);
}
/* Drop the dns/inet possibility. */
@@ -447,7 +450,7 @@ main(int argc, char *argv[])
memset(&sess, 0, sizeof(struct sess));
sess.opts = &opts;
- if ((args = fargs_cmdline(&sess, fargs)) == NULL) {
+ if ((args = fargs_cmdline(&sess, fargs, NULL)) == NULL) {
ERRX1(&sess, "fargs_cmdline");
_exit(1);
}
@@ -469,7 +472,10 @@ main(int argc, char *argv[])
/* NOTREACHED */
default:
close(fds[1]);
- rc = rsync_client(&opts, fds[0], fargs);
+ if (!fargs->remote)
+ rc = rsync_client(&opts, fds[0], fargs);
+ else
+ rc = rsync_socket(&opts, fds[0], fargs);
break;
}
diff --git a/usr.bin/rsync/socket.c b/usr.bin/rsync/socket.c
index 0f36b883541..36384d063a0 100644
--- a/usr.bin/rsync/socket.c
+++ b/usr.bin/rsync/socket.c
@@ -1,4 +1,4 @@
-/* $Id: socket.c,v 1.21 2019/03/23 16:04:28 deraadt Exp $ */
+/* $Id: socket.c,v 1.22 2019/03/31 08:47:46 naddy Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -232,41 +232,30 @@ protocol_line(struct sess *sess, const char *host, const char *cp)
}
/*
- * Talk to a remote rsync://-enabled server sender.
- * Returns exit code 0 on success, 1 on failure, 2 on failure with
- * incompatible protocols.
+ * Connect to a remote rsync://-enabled server sender.
+ * Returns exit code 0 on success, 1 on failure.
*/
int
-rsync_socket(const struct opts *opts, const struct fargs *f)
+rsync_connect(const struct opts *opts, int *sd, const struct fargs *f)
{
struct sess sess;
struct source *src = NULL;
size_t i, srcsz = 0;
- int sd = -1, rc = 1, c;
- char **args, buf[BUFSIZ];
- uint8_t byte;
+ int c, rc = 1;
if (pledge("stdio unix rpath wpath cpath dpath inet fattr chown dns getpw unveil",
NULL) == -1)
err(1, "pledge");
memset(&sess, 0, sizeof(struct sess));
- sess.lver = RSYNC_PROTOCOL;
sess.opts = opts;
assert(f->host != NULL);
- assert(f->module != NULL);
-
- if ((args = fargs_cmdline(&sess, f)) == NULL) {
- ERRX1(&sess, "fargs_cmdline");
- exit(1);
- }
/* Resolve all IP addresses from the host. */
if ((src = inet_resolve(&sess, f->host, &srcsz)) == NULL) {
ERRX1(&sess, "inet_resolve");
- free(args);
exit(1);
}
@@ -285,7 +274,7 @@ rsync_socket(const struct opts *opts, const struct fargs *f)
assert(srcsz);
for (i = 0; i < srcsz; i++) {
- c = inet_connect(&sess, &sd, &src[i], f->host);
+ c = inet_connect(&sess, sd, &src[i], f->host);
if (c < 0) {
ERRX1(&sess, "inet_connect");
goto out;
@@ -305,10 +294,49 @@ rsync_socket(const struct opts *opts, const struct fargs *f)
goto out;
}
- /* Initiate with the rsyncd version and module request. */
-
LOG2(&sess, "connected: %s, %s", src[i].ip, f->host);
+ free(src);
+ return 0;
+out:
+ free(src);
+ if (*sd != -1)
+ close(*sd);
+ return rc;
+}
+
+/*
+ * Talk to a remote rsync://-enabled server sender.
+ * Returns exit code 0 on success, 1 on failure, 2 on failure with
+ * incompatible protocols.
+ */
+int
+rsync_socket(const struct opts *opts, int sd, const struct fargs *f)
+{
+ struct sess sess;
+ size_t i, skip;
+ int c, rc = 1;
+ char **args, buf[BUFSIZ];
+ uint8_t byte;
+
+ if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw unveil",
+ NULL) == -1)
+ err(1, "pledge");
+
+ memset(&sess, 0, sizeof(struct sess));
+ sess.lver = RSYNC_PROTOCOL;
+ sess.opts = opts;
+
+ assert(f->host != NULL);
+ assert(f->module != NULL);
+
+ if ((args = fargs_cmdline(&sess, f, &skip)) == NULL) {
+ ERRX1(&sess, "fargs_cmdline");
+ exit(1);
+ }
+
+ /* Initiate with the rsyncd version and module request. */
+
(void)snprintf(buf, sizeof(buf), "@RSYNCD: %d", sess.lver);
if (!io_write_line(&sess, sd, buf)) {
ERRX1(&sess, "io_write_line");
@@ -372,12 +400,7 @@ rsync_socket(const struct opts *opts, const struct fargs *f)
* Emit a standalone newline afterward.
*/
- if (f->mode == FARGS_RECEIVER || f->mode == FARGS_SENDER)
- i = 3; /* ssh host rsync... */
- else
- i = 1; /* rsync... */
-
- for ( ; args[i] != NULL; i++)
+ for (i = skip ; args[i] != NULL; i++)
if (!io_write_line(&sess, sd, args[i])) {
ERRX1(&sess, "io_write_line");
goto out;
@@ -431,9 +454,7 @@ rsync_socket(const struct opts *opts, const struct fargs *f)
rc = 0;
out:
- free(src);
free(args);
- if (sd != -1)
- close(sd);
+ close(sd);
return rc;
}