diff options
Diffstat (limited to 'sftp-client.c')
-rw-r--r-- | sftp-client.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/sftp-client.c b/sftp-client.c index bf2eb43ac..6dcd5de74 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.48 2004/03/30 12:41:56 djm Exp $"); | 23 | RCSID("$OpenBSD: sftp-client.c,v 1.49 2004/05/19 12:17:33 djm 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.48 2004/03/30 12:41:56 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 | ||
@@ -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 | } |
@@ -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 | ||