diff options
author | Damien Miller <djm@mindrot.org> | 2008-02-10 22:27:24 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2008-02-10 22:27:24 +1100 |
commit | acdf25b31f02c010ed2b5f655bbae0f5b75f07f6 (patch) | |
tree | 0c07fe211654f61ebc0ed3e1bd21fde7c75a35da | |
parent | 3397d0e0c5820464bea4c96e91b5e02cca98330a (diff) |
- 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
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | sftp-client.c | 41 |
2 files changed, 22 insertions, 25 deletions
@@ -54,6 +54,10 @@ | |||
54 | Remove the fixed 100 handle limit in sftp-server and allocate as many | 54 | Remove the fixed 100 handle limit in sftp-server and allocate as many |
55 | as we have available file descriptors. Patch from miklos AT szeredi.hu; | 55 | as we have available file descriptors. Patch from miklos AT szeredi.hu; |
56 | ok dtucker@ markus@ | 56 | ok dtucker@ markus@ |
57 | - djm@cvs.openbsd.org 2008/01/21 19:20:17 | ||
58 | [sftp-client.c] | ||
59 | when a remote write error occurs during an upload, ensure that ACKs for | ||
60 | all issued requests are properly drained. patch from t8m AT centrum.cz | ||
57 | 61 | ||
58 | 20080119 | 62 | 20080119 |
59 | - (djm) Silence noice from expr in ssh-copy-id; patch from | 63 | - (djm) Silence noice from expr in ssh-copy-id; patch from |
@@ -3582,4 +3586,4 @@ | |||
3582 | OpenServer 6 and add osr5bigcrypt support so when someone migrates | 3586 | OpenServer 6 and add osr5bigcrypt support so when someone migrates |
3583 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ | 3587 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ |
3584 | 3588 | ||
3585 | $Id: ChangeLog,v 1.4830 2008/02/10 11:26:51 djm Exp $ | 3589 | $Id: ChangeLog,v 1.4831 2008/02/10 11:27:24 djm Exp $ |
diff --git a/sftp-client.c b/sftp-client.c index e8cdb96ac..b189422d4 100644 --- a/sftp-client.c +++ b/sftp-client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-client.c,v 1.79 2008/01/19 22:04:57 djm Exp $ */ | 1 | /* $OpenBSD: sftp-client.c,v 1.80 2008/01/21 19:20:17 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -997,7 +997,8 @@ int | |||
997 | do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | 997 | do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
998 | int pflag) | 998 | int pflag) |
999 | { | 999 | { |
1000 | int local_fd, status; | 1000 | int local_fd; |
1001 | int status = SSH2_FX_OK; | ||
1001 | u_int handle_len, id, type; | 1002 | u_int handle_len, id, type; |
1002 | off_t offset; | 1003 | off_t offset; |
1003 | char *handle, *data; | 1004 | char *handle, *data; |
@@ -1059,7 +1060,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1059 | if (handle == NULL) { | 1060 | if (handle == NULL) { |
1060 | close(local_fd); | 1061 | close(local_fd); |
1061 | buffer_free(&msg); | 1062 | buffer_free(&msg); |
1062 | return(-1); | 1063 | return -1; |
1063 | } | 1064 | } |
1064 | 1065 | ||
1065 | startid = ackid = id + 1; | 1066 | startid = ackid = id + 1; |
@@ -1079,7 +1080,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1079 | * Simulate an EOF on interrupt, allowing ACKs from the | 1080 | * Simulate an EOF on interrupt, allowing ACKs from the |
1080 | * server to drain. | 1081 | * server to drain. |
1081 | */ | 1082 | */ |
1082 | if (interrupted) | 1083 | if (interrupted || status != SSH2_FX_OK) |
1083 | len = 0; | 1084 | len = 0; |
1084 | else do | 1085 | else do |
1085 | len = read(local_fd, data, conn->transfer_buflen); | 1086 | len = read(local_fd, data, conn->transfer_buflen); |
@@ -1135,19 +1136,6 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1135 | if (ack == NULL) | 1136 | if (ack == NULL) |
1136 | fatal("Can't find request for ID %u", r_id); | 1137 | fatal("Can't find request for ID %u", r_id); |
1137 | TAILQ_REMOVE(&acks, ack, tq); | 1138 | TAILQ_REMOVE(&acks, ack, tq); |
1138 | |||
1139 | if (status != SSH2_FX_OK) { | ||
1140 | error("Couldn't write to remote file \"%s\": %s", | ||
1141 | remote_path, fx2txt(status)); | ||
1142 | if (showprogress) | ||
1143 | stop_progress_meter(); | ||
1144 | do_close(conn, handle, handle_len); | ||
1145 | close(local_fd); | ||
1146 | xfree(data); | ||
1147 | xfree(ack); | ||
1148 | status = -1; | ||
1149 | goto done; | ||
1150 | } | ||
1151 | debug3("In write loop, ack for %u %u bytes at %lld", | 1139 | debug3("In write loop, ack for %u %u bytes at %lld", |
1152 | ack->id, ack->len, (long long)ack->offset); | 1140 | ack->id, ack->len, (long long)ack->offset); |
1153 | ++ackid; | 1141 | ++ackid; |
@@ -1157,26 +1145,31 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1157 | if (offset < 0) | 1145 | if (offset < 0) |
1158 | fatal("%s: offset < 0", __func__); | 1146 | fatal("%s: offset < 0", __func__); |
1159 | } | 1147 | } |
1148 | buffer_free(&msg); | ||
1149 | |||
1160 | if (showprogress) | 1150 | if (showprogress) |
1161 | stop_progress_meter(); | 1151 | stop_progress_meter(); |
1162 | xfree(data); | 1152 | xfree(data); |
1163 | 1153 | ||
1154 | if (status != SSH2_FX_OK) { | ||
1155 | error("Couldn't write to remote file \"%s\": %s", | ||
1156 | remote_path, fx2txt(status)); | ||
1157 | status = -1; | ||
1158 | } | ||
1159 | |||
1164 | if (close(local_fd) == -1) { | 1160 | if (close(local_fd) == -1) { |
1165 | error("Couldn't close local file \"%s\": %s", local_path, | 1161 | error("Couldn't close local file \"%s\": %s", local_path, |
1166 | strerror(errno)); | 1162 | strerror(errno)); |
1167 | do_close(conn, handle, handle_len); | ||
1168 | status = -1; | 1163 | status = -1; |
1169 | goto done; | ||
1170 | } | 1164 | } |
1171 | 1165 | ||
1172 | /* Override umask and utimes if asked */ | 1166 | /* Override umask and utimes if asked */ |
1173 | if (pflag) | 1167 | if (pflag) |
1174 | do_fsetstat(conn, handle, handle_len, &a); | 1168 | do_fsetstat(conn, handle, handle_len, &a); |
1175 | 1169 | ||
1176 | status = do_close(conn, handle, handle_len); | 1170 | if (do_close(conn, handle, handle_len) != SSH2_FX_OK) |
1177 | 1171 | status = -1; | |
1178 | done: | ||
1179 | xfree(handle); | 1172 | xfree(handle); |
1180 | buffer_free(&msg); | 1173 | |
1181 | return(status); | 1174 | return status; |
1182 | } | 1175 | } |