diff options
author | Christian Weisgerber <naddy@cvs.openbsd.org> | 2019-03-31 08:47:47 +0000 |
---|---|---|
committer | Christian Weisgerber <naddy@cvs.openbsd.org> | 2019-03-31 08:47:47 +0000 |
commit | 62eba8762a949ea3eb27048ce89d4eded14d72e4 (patch) | |
tree | c40ac103f781bc6f1844de3c0272b6ea85ee8843 /usr.bin | |
parent | 9115d231b1a1c4bf35f8969f4d0c61b7eff1ae55 (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.h | 8 | ||||
-rw-r--r-- | usr.bin/rsync/fargs.c | 8 | ||||
-rw-r--r-- | usr.bin/rsync/main.c | 20 | ||||
-rw-r--r-- | usr.bin/rsync/socket.c | 77 |
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; } |