Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/rcp In sink(), upon error, avoid multiple replies to the...
details: https://anonhg.NetBSD.org/src/rev/b16b1d31f195
branches: trunk
changeset: 932397:b16b1d31f195
user: aymeric <aymeric%NetBSD.org@localhost>
date: Wed May 06 18:15:40 2020 +0000
description:
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.
Reported by Daniel Goujot, Georges-Axel Jaloyan, Ryan Lahfa, and David Naccache.
diffstat:
bin/rcp/rcp.c | 84 ++++++++++++++++++++++++++++------------------------------
1 files changed, 41 insertions(+), 43 deletions(-)
diffs (162 lines):
diff -r b3ec447b3705 -r b16b1d31f195 bin/rcp/rcp.c
--- a/bin/rcp/rcp.c Wed May 06 17:28:26 2020 +0000
+++ b/bin/rcp/rcp.c Wed May 06 18:15:40 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rcp.c,v 1.49 2012/05/07 15:22:54 chs Exp $ */
+/* $NetBSD: rcp.c,v 1.50 2020/05/06 18:15:40 aymeric Exp $ */
/*
* Copyright (c) 1983, 1990, 1992, 1993
@@ -39,7 +39,7 @@
#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.50 2020/05/06 18:15:40 aymeric Exp $");
#endif
#endif /* not lint */
@@ -470,7 +470,6 @@
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 @@
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(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 @@
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 @@
} 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 (j >= 0)
+ errno = EIO;
+ RUN_ERR("write");
}
- if (ftruncate(ofd, size)) {
- run_err("%s: truncate: %s", np, strerror(errno));
- wrerr = DISPLAYED;
- }
+ 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:
Home |
Main Index |
Thread Index |
Old Index