- djm@cvs.openbsd.org 2008/01/21 19:20:17

[sftp-client.c]
     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
This commit is contained in:
Damien Miller 2008-02-10 22:27:24 +11:00
parent 3397d0e0c5
commit acdf25b31f
2 changed files with 22 additions and 25 deletions

View File

@ -54,6 +54,10 @@
Remove the fixed 100 handle limit in sftp-server and allocate as many Remove the fixed 100 handle limit in sftp-server and allocate as many
as we have available file descriptors. Patch from miklos AT szeredi.hu; as we have available file descriptors. Patch from miklos AT szeredi.hu;
ok dtucker@ markus@ ok dtucker@ markus@
- djm@cvs.openbsd.org 2008/01/21 19:20:17
[sftp-client.c]
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
20080119 20080119
- (djm) Silence noice from expr in ssh-copy-id; patch from - (djm) Silence noice from expr in ssh-copy-id; patch from
@ -3582,4 +3586,4 @@
OpenServer 6 and add osr5bigcrypt support so when someone migrates OpenServer 6 and add osr5bigcrypt support so when someone migrates
passwords between UnixWare and OpenServer they will still work. OK dtucker@ passwords between UnixWare and OpenServer they will still work. OK dtucker@
$Id: ChangeLog,v 1.4830 2008/02/10 11:26:51 djm Exp $ $Id: ChangeLog,v 1.4831 2008/02/10 11:27:24 djm Exp $

View File

@ -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> * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
* *
@ -997,7 +997,8 @@ int
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
int pflag) int pflag)
{ {
int local_fd, status; int local_fd;
int status = SSH2_FX_OK;
u_int handle_len, id, type; u_int handle_len, id, type;
off_t offset; off_t offset;
char *handle, *data; char *handle, *data;
@ -1059,7 +1060,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
if (handle == NULL) { if (handle == NULL) {
close(local_fd); close(local_fd);
buffer_free(&msg); buffer_free(&msg);
return(-1); return -1;
} }
startid = ackid = id + 1; startid = ackid = id + 1;
@ -1079,7 +1080,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
* Simulate an EOF on interrupt, allowing ACKs from the * Simulate an EOF on interrupt, allowing ACKs from the
* server to drain. * server to drain.
*/ */
if (interrupted) if (interrupted || status != SSH2_FX_OK)
len = 0; len = 0;
else do else do
len = read(local_fd, data, conn->transfer_buflen); len = read(local_fd, data, conn->transfer_buflen);
@ -1135,19 +1136,6 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
if (ack == NULL) if (ack == NULL)
fatal("Can't find request for ID %u", r_id); fatal("Can't find request for ID %u", r_id);
TAILQ_REMOVE(&acks, ack, tq); 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", debug3("In write loop, ack for %u %u bytes at %lld",
ack->id, ack->len, (long long)ack->offset); ack->id, ack->len, (long long)ack->offset);
++ackid; ++ackid;
@ -1157,26 +1145,31 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
if (offset < 0) if (offset < 0)
fatal("%s: offset < 0", __func__); fatal("%s: offset < 0", __func__);
} }
buffer_free(&msg);
if (showprogress) if (showprogress)
stop_progress_meter(); stop_progress_meter();
xfree(data); 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) { if (close(local_fd) == -1) {
error("Couldn't close local file \"%s\": %s", local_path, error("Couldn't close local file \"%s\": %s", local_path,
strerror(errno)); strerror(errno));
do_close(conn, handle, handle_len);
status = -1; status = -1;
goto done;
} }
/* Override umask and utimes if asked */ /* Override umask and utimes if asked */
if (pflag) if (pflag)
do_fsetstat(conn, handle, handle_len, &a); do_fsetstat(conn, handle, handle_len, &a);
status = do_close(conn, handle, handle_len); if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
status = -1;
done:
xfree(handle); xfree(handle);
buffer_free(&msg);
return(status); return status;
} }