diff options
author | Colin Watson <cjwatson@debian.org> | 2005-01-04 13:07:27 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2005-01-04 13:07:27 +0000 |
commit | fd0f611b70a83d80fe8793af785542ee5541b7cd (patch) | |
tree | bededd22bb7eeec52e20083237ab7e4113445a16 /sftp-client.c | |
parent | c44fe9a5b9d3db96a7249b04d915f17e4a3a3b04 (diff) | |
parent | ebd2ce335af5861020c79fddb1ae35c03bf036cf (diff) |
Merge 3.9p1 to the trunk.
Diffstat (limited to 'sftp-client.c')
-rw-r--r-- | sftp-client.c | 39 |
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" |
23 | RCSID("$OpenBSD: sftp-client.c,v 1.47 2004/03/03 09:30:42 djm Exp $"); | 23 | RCSID("$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 | ||
39 | extern volatile sig_atomic_t interrupted; | ||
39 | extern int showprogress; | 40 | extern 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 | ||