summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2008-01-21 19:20:18 +0000
committerDamien Miller <djm@cvs.openbsd.org>2008-01-21 19:20:18 +0000
commit0af8b844099628a21ffc6740a3dc7c76e1b3cb9f (patch)
tree493b4f52706bf39d03fffdca939a91c965d6d1d2 /usr.bin
parentdd33d768f22fd7735689ab6c1b328b7816d51f62 (diff)
when a remote write error occurs during an upload, ensure that ACKs for all
issued requests are properly drained. patch from t8m AT centrum.cz
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/sftp-client.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/usr.bin/ssh/sftp-client.c b/usr.bin/ssh/sftp-client.c
index 3a50f6994b6..e8ffb30fb78 100644
--- a/usr.bin/ssh/sftp-client.c
+++ b/usr.bin/ssh/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.79 2008/01/19 22:04:57 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.80 2008/01/21 19:20:17 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -987,7 +987,8 @@ int
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
int pflag)
{
- int local_fd, status;
+ int local_fd;
+ int status = SSH2_FX_OK;
u_int handle_len, id, type;
off_t offset;
char *handle, *data;
@@ -1049,7 +1050,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
if (handle == NULL) {
close(local_fd);
buffer_free(&msg);
- return(-1);
+ return -1;
}
startid = ackid = id + 1;
@@ -1069,7 +1070,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
* Simulate an EOF on interrupt, allowing ACKs from the
* server to drain.
*/
- if (interrupted)
+ if (interrupted || status != SSH2_FX_OK)
len = 0;
else do
len = read(local_fd, data, conn->transfer_buflen);
@@ -1125,19 +1126,6 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
if (ack == NULL)
fatal("Can't find request for ID %u", r_id);
TAILQ_REMOVE(&acks, ack, tq);
-
- if (status != SSH2_FX_OK) {
- error("Couldn't write to remote file \"%s\": %s",
- remote_path, fx2txt(status));
- if (showprogress)
- stop_progress_meter();
- do_close(conn, handle, handle_len);
- close(local_fd);
- xfree(data);
- xfree(ack);
- status = -1;
- goto done;
- }
debug3("In write loop, ack for %u %u bytes at %lld",
ack->id, ack->len, (long long)ack->offset);
++ackid;
@@ -1147,26 +1135,31 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
if (offset < 0)
fatal("%s: offset < 0", __func__);
}
+ buffer_free(&msg);
+
if (showprogress)
stop_progress_meter();
xfree(data);
+ if (status != SSH2_FX_OK) {
+ error("Couldn't write to remote file \"%s\": %s",
+ remote_path, fx2txt(status));
+ status = -1;
+ }
+
if (close(local_fd) == -1) {
error("Couldn't close local file \"%s\": %s", local_path,
strerror(errno));
- do_close(conn, handle, handle_len);
status = -1;
- goto done;
}
/* Override umask and utimes if asked */
if (pflag)
do_fsetstat(conn, handle, handle_len, &a);
- status = do_close(conn, handle, handle_len);
-
-done:
+ if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
+ status = -1;
xfree(handle);
- buffer_free(&msg);
- return(status);
+
+ return status;
}