diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2008-01-21 19:20:18 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2008-01-21 19:20:18 +0000 |
commit | 0af8b844099628a21ffc6740a3dc7c76e1b3cb9f (patch) | |
tree | 493b4f52706bf39d03fffdca939a91c965d6d1d2 /usr.bin | |
parent | dd33d768f22fd7735689ab6c1b328b7816d51f62 (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.c | 41 |
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; } |