summaryrefslogtreecommitdiff
path: root/sftp-client.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2004-05-24 10:12:19 +1000
committerDarren Tucker <dtucker@zip.com.au>2004-05-24 10:12:19 +1000
commitcdf547afe4f7b6ad9b3143bb79163fa7a00f6721 (patch)
tree96deb3c736492199988f4e0632cb56619586fad5 /sftp-client.c
parentefec7c23b1d646578ddc47685496bdb9f1e9187f (diff)
- djm@cvs.openbsd.org 2004/05/19 12:17:33
[sftp-client.c sftp.c] gracefully abort transfers on receipt of SIGINT, also ignore SIGINT while waiting for a command; ok markus@
Diffstat (limited to 'sftp-client.c')
-rw-r--r--sftp-client.c35
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"
23RCSID("$OpenBSD: sftp-client.c,v 1.48 2004/03/30 12:41:56 djm Exp $"); 23RCSID("$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
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
@@ -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