summaryrefslogtreecommitdiff
path: root/sftp-client.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2005-01-04 13:07:27 +0000
committerColin Watson <cjwatson@debian.org>2005-01-04 13:07:27 +0000
commitfd0f611b70a83d80fe8793af785542ee5541b7cd (patch)
treebededd22bb7eeec52e20083237ab7e4113445a16 /sftp-client.c
parentc44fe9a5b9d3db96a7249b04d915f17e4a3a3b04 (diff)
parentebd2ce335af5861020c79fddb1ae35c03bf036cf (diff)
Merge 3.9p1 to the trunk.
Diffstat (limited to 'sftp-client.c')
-rw-r--r--sftp-client.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/sftp-client.c b/sftp-client.c
index 781d9827a..0ffacbccc 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -20,7 +20,7 @@
20/* XXX: copy between two remote sites */ 20/* XXX: copy between two remote sites */
21 21
22#include "includes.h" 22#include "includes.h"
23RCSID("$OpenBSD: sftp-client.c,v 1.47 2004/03/03 09:30:42 djm Exp $"); 23RCSID("$OpenBSD: sftp-client.c,v 1.51 2004/07/11 17:48:47 deraadt Exp $");
24 24
25#include "openbsd-compat/sys-queue.h" 25#include "openbsd-compat/sys-queue.h"
26 26
@@ -36,6 +36,7 @@ RCSID("$OpenBSD: sftp-client.c,v 1.47 2004/03/03 09:30:42 djm Exp $");
36#include "sftp-common.h" 36#include "sftp-common.h"
37#include "sftp-client.h" 37#include "sftp-client.h"
38 38
39extern volatile sig_atomic_t interrupted;
39extern int showprogress; 40extern int showprogress;
40 41
41/* Minimum amount of data to read at at time */ 42/* Minimum amount of data to read at at time */
@@ -330,7 +331,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
330 (*dir)[0] = NULL; 331 (*dir)[0] = NULL;
331 } 332 }
332 333
333 for (;;) { 334 for (; !interrupted;) {
334 int count; 335 int count;
335 336
336 id = expected_id = conn->msg_id++; 337 id = expected_id = conn->msg_id++;
@@ -407,6 +408,13 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
407 do_close(conn, handle, handle_len); 408 do_close(conn, handle, handle_len);
408 xfree(handle); 409 xfree(handle);
409 410
411 /* Don't return partial matches on interrupt */
412 if (interrupted && dir != NULL && *dir != NULL) {
413 free_sftp_dirents(*dir);
414 *dir = xmalloc(sizeof(**dir));
415 **dir = NULL;
416 }
417
410 return(0); 418 return(0);
411} 419}
412 420
@@ -643,7 +651,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
643 651
644 buffer_init(&msg); 652 buffer_init(&msg);
645 653
646 /* Send rename request */ 654 /* Send symlink request */
647 id = conn->msg_id++; 655 id = conn->msg_id++;
648 buffer_put_char(&msg, SSH2_FXP_SYMLINK); 656 buffer_put_char(&msg, SSH2_FXP_SYMLINK);
649 buffer_put_int(&msg, id); 657 buffer_put_int(&msg, id);
@@ -812,6 +820,16 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
812 char *data; 820 char *data;
813 u_int len; 821 u_int len;
814 822
823 /*
824 * Simulate EOF on interrupt: stop sending new requests and
825 * allow outstanding requests to drain gracefully
826 */
827 if (interrupted) {
828 if (num_req == 0) /* If we haven't started yet... */
829 break;
830 max_req = 0;
831 }
832
815 /* Send some more requests */ 833 /* Send some more requests */
816 while (num_req < max_req) { 834 while (num_req < max_req) {
817 debug3("Request range %llu -> %llu (%d/%d)", 835 debug3("Request range %llu -> %llu (%d/%d)",
@@ -899,8 +917,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
899 (unsigned long long)offset, 917 (unsigned long long)offset,
900 num_req); 918 num_req);
901 max_req = 1; 919 max_req = 1;
902 } 920 } else if (max_req <= conn->num_requests) {
903 else if (max_req < conn->num_requests + 1) {
904 ++max_req; 921 ++max_req;
905 } 922 }
906 } 923 }
@@ -975,7 +992,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
975 TAILQ_ENTRY(outstanding_ack) tq; 992 TAILQ_ENTRY(outstanding_ack) tq;
976 }; 993 };
977 TAILQ_HEAD(ackhead, outstanding_ack) acks; 994 TAILQ_HEAD(ackhead, outstanding_ack) acks;
978 struct outstanding_ack *ack; 995 struct outstanding_ack *ack = NULL;
979 996
980 TAILQ_INIT(&acks); 997 TAILQ_INIT(&acks);
981 998
@@ -1036,10 +1053,14 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1036 int len; 1053 int len;
1037 1054
1038 /* 1055 /*
1039 * Can't use atomicio here because it returns 0 on EOF, thus losing 1056 * Can't use atomicio here because it returns 0 on EOF,
1040 * the last block of the file 1057 * thus losing the last block of the file.
1058 * Simulate an EOF on interrupt, allowing ACKs from the
1059 * server to drain.
1041 */ 1060 */
1042 do 1061 if (interrupted)
1062 len = 0;
1063 else do
1043 len = read(local_fd, data, conn->transfer_buflen); 1064 len = read(local_fd, data, conn->transfer_buflen);
1044 while ((len == -1) && (errno == EINTR || errno == EAGAIN)); 1065 while ((len == -1) && (errno == EINTR || errno == EAGAIN));
1045 1066