Module Name: src Committed By: sborrill Date: Thu May 7 12:02:24 UTC 2020
Modified Files: src/bin/rcp [netbsd-7-0]: rcp.c Log Message: Pull up the following revisions(s) (requested by aymeric in ticket #1731): bin/rcp/rcp.c: revision 1.50 In sink(), upon error, avoid multiple replies to the source as this would lead to a desynchronization of the protocol and further files or directories to be ignored or corrupted. To generate a diff of this commit: cvs rdiff -u -r1.49 -r1.49.14.1 src/bin/rcp/rcp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/rcp/rcp.c diff -u src/bin/rcp/rcp.c:1.49 src/bin/rcp/rcp.c:1.49.14.1 --- src/bin/rcp/rcp.c:1.49 Mon May 7 15:22:54 2012 +++ src/bin/rcp/rcp.c Thu May 7 12:02:24 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: rcp.c,v 1.49 2012/05/07 15:22:54 chs Exp $ */ +/* $NetBSD: rcp.c,v 1.49.14.1 2020/05/07 12:02:24 sborrill Exp $ */ /* * Copyright (c) 1983, 1990, 1992, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19 #if 0 static char sccsid[] = "@(#)rcp.c 8.2 (Berkeley) 4/2/94"; #else -__RCSID("$NetBSD: rcp.c,v 1.49 2012/05/07 15:22:54 chs Exp $"); +__RCSID("$NetBSD: rcp.c,v 1.49.14.1 2020/05/07 12:02:24 sborrill Exp $"); #endif #endif /* not lint */ @@ -470,7 +470,6 @@ sink(int argc, char *argv[]) static BUF buffer; struct stat stb; struct timeval tv[2]; - enum { YES, NO, DISPLAYED } wrerr; BUF *bp; ssize_t j; off_t i; @@ -480,8 +479,9 @@ sink(int argc, char *argv[]) mode_t mask; mode_t mode; mode_t omode; - int setimes, targisdir; + int setimes, targisdir, wrerr; int wrerrno = 0; /* pacify gcc */ + const char *wrcontext = NULL; char ch, *cp, *np, *targ, *vect[1], buf[BUFSIZ]; const char *why; off_t size; @@ -624,9 +624,7 @@ sink(int argc, char *argv[]) sink(1, vect); if (setimes) { setimes = 0; - if (utimes(np, tv) < 0) - run_err("%s: set times: %s", - np, strerror(errno)); + (void) utimes(np, tv); } if (mod_flag) (void)chmod(np, mode); @@ -644,7 +642,20 @@ bad: run_err("%s: %s", np, strerror(er continue; } cp = bp->buf; - wrerr = NO; + wrerr = 0; + +/* + * Like run_err(), but don't send any message to the remote end. + * Instead, record the first error and send that in the end. + */ +#define RUN_ERR(w_context) do { \ + if (!wrerr) { \ + wrerrno = errno; \ + wrcontext = w_context; \ + wrerr = 1; \ + } \ +} while(0) + count = 0; for (i = 0; i < size; i += BUFSIZ) { amt = BUFSIZ; @@ -663,69 +674,56 @@ bad: run_err("%s: %s", np, strerror(er } while (amt > 0); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ - if (wrerr == NO) { + if (!wrerr) { j = write(ofd, bp->buf, (size_t)count); if (j != count) { - wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; + if (j >= 0) + errno = EIO; + RUN_ERR("write"); } } count = 0; cp = bp->buf; } } - if (count != 0 && wrerr == NO && + if (count != 0 && !wrerr && (j = write(ofd, bp->buf, (size_t)count)) != count) { - wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; - } - if (ftruncate(ofd, size)) { - run_err("%s: truncate: %s", np, strerror(errno)); - wrerr = DISPLAYED; + if (j >= 0) + errno = EIO; + RUN_ERR("write"); } + if (ftruncate(ofd, size)) + RUN_ERR("truncate"); + if (pflag) { if (exists || omode != mode) if (fchmod(ofd, omode)) - run_err("%s: set mode: %s", - np, strerror(errno)); + RUN_ERR("set mode"); } else { if (!exists && omode != mode) if (fchmod(ofd, omode & ~mask)) - run_err("%s: set mode: %s", - np, strerror(errno)); + RUN_ERR("set mode"); } #ifndef __SVR4 - if (setimes && wrerr == NO) { + if (setimes && !wrerr) { setimes = 0; - if (futimes(ofd, tv) < 0) { - run_err("%s: set times: %s", - np, strerror(errno)); - wrerr = DISPLAYED; - } + if (futimes(ofd, tv) < 0) + RUN_ERR("set times"); } #endif (void)close(ofd); #ifdef __SVR4 - if (setimes && wrerr == NO) { + if (setimes && !wrerr) { setimes = 0; - if (utimes(np, tv) < 0) { - run_err("%s: set times: %s", - np, strerror(errno)); - wrerr = DISPLAYED; - } + if (utimes(np, tv) < 0) + RUN_ERR("set times"); } #endif (void)response(); - switch(wrerr) { - case YES: - run_err("%s: write: %s", np, strerror(wrerrno)); - break; - case NO: + if (wrerr) + run_err("%s: %s: %s", np, wrcontext, strerror(wrerrno)); + else (void)write(rem, "", 1); - break; - case DISPLAYED: - break; - } } out: