diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sftp-client.c | 32 | ||||
-rw-r--r-- | sftp-client.h | 8 | ||||
-rw-r--r-- | sftp-int.c | 17 | ||||
-rw-r--r-- | sftp.1 | 8 | ||||
-rw-r--r-- | sftp.c | 13 |
6 files changed, 51 insertions, 32 deletions
@@ -7,6 +7,9 @@ | |||
7 | - stevesk@cvs.openbsd.org 2002/02/04 20:41:16 | 7 | - stevesk@cvs.openbsd.org 2002/02/04 20:41:16 |
8 | [ssh-agent.1] | 8 | [ssh-agent.1] |
9 | more sync for default ssh-add identities; ok markus@ | 9 | more sync for default ssh-add identities; ok markus@ |
10 | - djm@cvs.openbsd.org 2002/02/05 00:00:46 | ||
11 | [sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c] | ||
12 | Add "-B" option to specify copy buffer length (default 32k); ok markus@ | ||
10 | 13 | ||
11 | 20020205 | 14 | 20020205 |
12 | - (djm) Cleanup after sync: | 15 | - (djm) Cleanup after sync: |
@@ -7513,4 +7516,4 @@ | |||
7513 | - Wrote replacements for strlcpy and mkdtemp | 7516 | - Wrote replacements for strlcpy and mkdtemp |
7514 | - Released 1.0pre1 | 7517 | - Released 1.0pre1 |
7515 | 7518 | ||
7516 | $Id: ChangeLog,v 1.1829 2002/02/08 11:02:16 djm Exp $ | 7519 | $Id: ChangeLog,v 1.1830 2002/02/08 11:04:05 djm Exp $ |
diff --git a/sftp-client.c b/sftp-client.c index ca5a48597..362814d42 100644 --- a/sftp-client.c +++ b/sftp-client.c | |||
@@ -29,7 +29,7 @@ | |||
29 | /* XXX: copy between two remote sites */ | 29 | /* XXX: copy between two remote sites */ |
30 | 30 | ||
31 | #include "includes.h" | 31 | #include "includes.h" |
32 | RCSID("$OpenBSD: sftp-client.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $"); | 32 | RCSID("$OpenBSD: sftp-client.c,v 1.20 2002/02/05 00:00:46 djm Exp $"); |
33 | 33 | ||
34 | #include "buffer.h" | 34 | #include "buffer.h" |
35 | #include "bufaux.h" | 35 | #include "bufaux.h" |
@@ -42,10 +42,6 @@ RCSID("$OpenBSD: sftp-client.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $"); | |||
42 | #include "sftp-common.h" | 42 | #include "sftp-common.h" |
43 | #include "sftp-client.h" | 43 | #include "sftp-client.h" |
44 | 44 | ||
45 | /* How much data to read/write at at time during copies */ | ||
46 | /* XXX: what should this be? */ | ||
47 | #define COPY_SIZE 8192 | ||
48 | |||
49 | /* Message ID */ | 45 | /* Message ID */ |
50 | static u_int msg_id = 1; | 46 | static u_int msg_id = 1; |
51 | 47 | ||
@@ -670,15 +666,14 @@ do_readlink(int fd_in, int fd_out, char *path) | |||
670 | 666 | ||
671 | int | 667 | int |
672 | do_download(int fd_in, int fd_out, char *remote_path, char *local_path, | 668 | do_download(int fd_in, int fd_out, char *remote_path, char *local_path, |
673 | int pflag) | 669 | int pflag, size_t buflen) |
674 | { | 670 | { |
675 | int local_fd; | 671 | int local_fd, status; |
676 | u_int expected_id, handle_len, mode, type, id; | 672 | u_int expected_id, handle_len, mode, type, id; |
677 | u_int64_t offset; | 673 | u_int64_t offset; |
678 | char *handle; | 674 | char *handle; |
679 | Buffer msg; | 675 | Buffer msg; |
680 | Attrib junk, *a; | 676 | Attrib junk, *a; |
681 | int status; | ||
682 | 677 | ||
683 | a = do_stat(fd_in, fd_out, remote_path, 0); | 678 | a = do_stat(fd_in, fd_out, remote_path, 0); |
684 | if (a == NULL) | 679 | if (a == NULL) |
@@ -736,10 +731,10 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path, | |||
736 | buffer_put_int(&msg, id); | 731 | buffer_put_int(&msg, id); |
737 | buffer_put_string(&msg, handle, handle_len); | 732 | buffer_put_string(&msg, handle, handle_len); |
738 | buffer_put_int64(&msg, offset); | 733 | buffer_put_int64(&msg, offset); |
739 | buffer_put_int(&msg, COPY_SIZE); | 734 | buffer_put_int(&msg, buflen); |
740 | send_msg(fd_out, &msg); | 735 | send_msg(fd_out, &msg); |
741 | debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u", | 736 | debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u", |
742 | id, (u_int64_t)offset, COPY_SIZE); | 737 | id, (u_int64_t)offset, buflen); |
743 | 738 | ||
744 | buffer_clear(&msg); | 739 | buffer_clear(&msg); |
745 | 740 | ||
@@ -767,9 +762,9 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path, | |||
767 | } | 762 | } |
768 | 763 | ||
769 | data = buffer_get_string(&msg, &len); | 764 | data = buffer_get_string(&msg, &len); |
770 | if (len > COPY_SIZE) | 765 | if (len > buflen) |
771 | fatal("Received more data than asked for %d > %d", | 766 | fatal("Received more data than asked for %d > %d", |
772 | len, COPY_SIZE); | 767 | len, buflen); |
773 | 768 | ||
774 | debug3("In read loop, got %d offset %llu", len, | 769 | debug3("In read loop, got %d offset %llu", len, |
775 | (u_int64_t)offset); | 770 | (u_int64_t)offset); |
@@ -814,16 +809,15 @@ done: | |||
814 | 809 | ||
815 | int | 810 | int |
816 | do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, | 811 | do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, |
817 | int pflag) | 812 | int pflag, size_t buflen) |
818 | { | 813 | { |
819 | int local_fd; | 814 | int local_fd, status; |
820 | u_int handle_len, id; | 815 | u_int handle_len, id; |
821 | u_int64_t offset; | 816 | u_int64_t offset; |
822 | char *handle; | 817 | char *handle, *data; |
823 | Buffer msg; | 818 | Buffer msg; |
824 | struct stat sb; | 819 | struct stat sb; |
825 | Attrib a; | 820 | Attrib a; |
826 | int status; | ||
827 | 821 | ||
828 | if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { | 822 | if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { |
829 | error("Couldn't open local file \"%s\" for reading: %s", | 823 | error("Couldn't open local file \"%s\" for reading: %s", |
@@ -865,18 +859,19 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, | |||
865 | return(-1); | 859 | return(-1); |
866 | } | 860 | } |
867 | 861 | ||
862 | data = xmalloc(buflen); | ||
863 | |||
868 | /* Read from local and write to remote */ | 864 | /* Read from local and write to remote */ |
869 | offset = 0; | 865 | offset = 0; |
870 | for (;;) { | 866 | for (;;) { |
871 | int len; | 867 | int len; |
872 | char data[COPY_SIZE]; | ||
873 | 868 | ||
874 | /* | 869 | /* |
875 | * Can't use atomicio here because it returns 0 on EOF, thus losing | 870 | * Can't use atomicio here because it returns 0 on EOF, thus losing |
876 | * the last block of the file | 871 | * the last block of the file |
877 | */ | 872 | */ |
878 | do | 873 | do |
879 | len = read(local_fd, data, COPY_SIZE); | 874 | len = read(local_fd, data, buflen); |
880 | while ((len == -1) && (errno == EINTR || errno == EAGAIN)); | 875 | while ((len == -1) && (errno == EINTR || errno == EAGAIN)); |
881 | 876 | ||
882 | if (len == -1) | 877 | if (len == -1) |
@@ -908,6 +903,7 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, | |||
908 | 903 | ||
909 | offset += len; | 904 | offset += len; |
910 | } | 905 | } |
906 | xfree(data); | ||
911 | 907 | ||
912 | if (close(local_fd) == -1) { | 908 | if (close(local_fd) == -1) { |
913 | error("Couldn't close local file \"%s\": %s", local_path, | 909 | error("Couldn't close local file \"%s\": %s", local_path, |
diff --git a/sftp-client.h b/sftp-client.h index a322b2571..20350701c 100644 --- a/sftp-client.h +++ b/sftp-client.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* $OpenBSD: sftp-client.h,v 1.6 2001/06/26 06:33:01 itojun Exp $ */ | 1 | /* $OpenBSD: sftp-client.h,v 1.7 2002/02/05 00:00:46 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2001-2002 Damien Miller. All rights reserved. |
5 | * | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions |
@@ -94,10 +94,10 @@ char *do_readlink(int, int, char *); | |||
94 | * Download 'remote_path' to 'local_path'. Preserve permissions and times | 94 | * Download 'remote_path' to 'local_path'. Preserve permissions and times |
95 | * if 'pflag' is set | 95 | * if 'pflag' is set |
96 | */ | 96 | */ |
97 | int do_download(int, int, char *, char *, int); | 97 | int do_download(int, int, char *, char *, int, size_t); |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * Upload 'local_path' to 'remote_path'. Preserve permissions and times | 100 | * Upload 'local_path' to 'remote_path'. Preserve permissions and times |
101 | * if 'pflag' is set | 101 | * if 'pflag' is set |
102 | */ | 102 | */ |
103 | int do_upload(int, int, char *, char *, int); | 103 | int do_upload(int, int, char *, char *, int , size_t); |
diff --git a/sftp-int.c b/sftp-int.c index d8eec3f3d..f86922d0c 100644 --- a/sftp-int.c +++ b/sftp-int.c | |||
@@ -26,7 +26,7 @@ | |||
26 | /* XXX: recursive operations */ | 26 | /* XXX: recursive operations */ |
27 | 27 | ||
28 | #include "includes.h" | 28 | #include "includes.h" |
29 | RCSID("$OpenBSD: sftp-int.c,v 1.41 2001/12/19 07:18:56 deraadt Exp $"); | 29 | RCSID("$OpenBSD: sftp-int.c,v 1.42 2002/02/05 00:00:46 djm Exp $"); |
30 | 30 | ||
31 | #include "buffer.h" | 31 | #include "buffer.h" |
32 | #include "xmalloc.h" | 32 | #include "xmalloc.h" |
@@ -42,6 +42,9 @@ RCSID("$OpenBSD: sftp-int.c,v 1.41 2001/12/19 07:18:56 deraadt Exp $"); | |||
42 | /* File to read commands from */ | 42 | /* File to read commands from */ |
43 | extern FILE *infile; | 43 | extern FILE *infile; |
44 | 44 | ||
45 | /* Size of buffer used when copying files */ | ||
46 | extern size_t copy_buffer_len; | ||
47 | |||
45 | /* Version of server we are speaking to */ | 48 | /* Version of server we are speaking to */ |
46 | int version; | 49 | int version; |
47 | 50 | ||
@@ -381,7 +384,8 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag) | |||
381 | goto out; | 384 | goto out; |
382 | } | 385 | } |
383 | printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst); | 386 | printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst); |
384 | err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag); | 387 | err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag, |
388 | copy_buffer_len); | ||
385 | goto out; | 389 | goto out; |
386 | } | 390 | } |
387 | 391 | ||
@@ -405,7 +409,8 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag) | |||
405 | abs_dst = tmp; | 409 | abs_dst = tmp; |
406 | 410 | ||
407 | printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); | 411 | printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); |
408 | if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1) | 412 | if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag, |
413 | copy_buffer_len) == -1) | ||
409 | err = -1; | 414 | err = -1; |
410 | xfree(abs_dst); | 415 | xfree(abs_dst); |
411 | abs_dst = NULL; | 416 | abs_dst = NULL; |
@@ -463,7 +468,8 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag) | |||
463 | abs_dst = make_absolute(abs_dst, pwd); | 468 | abs_dst = make_absolute(abs_dst, pwd); |
464 | } | 469 | } |
465 | printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst); | 470 | printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst); |
466 | err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag); | 471 | err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag, |
472 | copy_buffer_len); | ||
467 | goto out; | 473 | goto out; |
468 | } | 474 | } |
469 | 475 | ||
@@ -487,7 +493,8 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag) | |||
487 | abs_dst = make_absolute(tmp, pwd); | 493 | abs_dst = make_absolute(tmp, pwd); |
488 | 494 | ||
489 | printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); | 495 | printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); |
490 | if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1) | 496 | if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag, |
497 | copy_buffer_len) == -1) | ||
491 | err = -1; | 498 | err = -1; |
492 | } | 499 | } |
493 | 500 | ||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: sftp.1,v 1.27 2002/02/04 21:53:11 djm Exp $ | 1 | .\" $OpenBSD: sftp.1,v 1.28 2002/02/05 00:00:46 djm Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright (c) 2001 Damien Miller. All rights reserved. | 3 | .\" Copyright (c) 2001 Damien Miller. All rights reserved. |
4 | .\" | 4 | .\" |
@@ -31,6 +31,7 @@ | |||
31 | .Sh SYNOPSIS | 31 | .Sh SYNOPSIS |
32 | .Nm sftp | 32 | .Nm sftp |
33 | .Op Fl 1Cv | 33 | .Op Fl 1Cv |
34 | .Op Fl B Ar buffer_size | ||
34 | .Op Fl b Ar batchfile | 35 | .Op Fl b Ar batchfile |
35 | .Op Fl F Ar ssh_config | 36 | .Op Fl F Ar ssh_config |
36 | .Op Fl o Ar ssh_option | 37 | .Op Fl o Ar ssh_option |
@@ -66,6 +67,11 @@ The options are as follows: | |||
66 | .Bl -tag -width Ds | 67 | .Bl -tag -width Ds |
67 | .It Fl 1 | 68 | .It Fl 1 |
68 | Specify the use of protocol version 1. | 69 | Specify the use of protocol version 1. |
70 | .It Fl B Ar buffer_size | ||
71 | Specify the size of the buffer that | ||
72 | .Nm | ||
73 | uses when transferring files. Larger buffers require fewer round trips at | ||
74 | the cost of higher memory consumption. The default is 32768 bytes. | ||
69 | .It Fl P Ar sftp_server path | 75 | .It Fl P Ar sftp_server path |
70 | Connect directly to a local | 76 | Connect directly to a local |
71 | .Nm sftp-server | 77 | .Nm sftp-server |
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | 26 | ||
27 | RCSID("$OpenBSD: sftp.c,v 1.23 2002/02/04 21:53:12 djm Exp $"); | 27 | RCSID("$OpenBSD: sftp.c,v 1.24 2002/02/05 00:00:46 djm Exp $"); |
28 | 28 | ||
29 | /* XXX: short-form remote directory listings (like 'ls -C') */ | 29 | /* XXX: short-form remote directory listings (like 'ls -C') */ |
30 | 30 | ||
@@ -46,6 +46,7 @@ char *__progname; | |||
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | FILE* infile; | 48 | FILE* infile; |
49 | size_t copy_buffer_len = 32768; | ||
49 | 50 | ||
50 | static void | 51 | static void |
51 | connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid) | 52 | connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid) |
@@ -93,7 +94,8 @@ usage(void) | |||
93 | { | 94 | { |
94 | fprintf(stderr, | 95 | fprintf(stderr, |
95 | "usage: sftp [-1Cv] [-b batchfile] [-F config] [-o option] [-s subsystem|path]\n" | 96 | "usage: sftp [-1Cv] [-b batchfile] [-F config] [-o option] [-s subsystem|path]\n" |
96 | " [-S program] [user@]host[:file [file]]\n"); | 97 | " [-P direct server path] [-S program] \n" |
98 | " [-B buffer_size] [user@]host[:file [file]]\n"); | ||
97 | exit(1); | 99 | exit(1); |
98 | } | 100 | } |
99 | 101 | ||
@@ -121,7 +123,7 @@ main(int argc, char **argv) | |||
121 | ll = SYSLOG_LEVEL_INFO; | 123 | ll = SYSLOG_LEVEL_INFO; |
122 | infile = stdin; /* Read from STDIN unless changed by -b */ | 124 | infile = stdin; /* Read from STDIN unless changed by -b */ |
123 | 125 | ||
124 | while ((ch = getopt(argc, argv, "1hvCo:s:S:b:F:P:")) != -1) { | 126 | while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:")) != -1) { |
125 | switch (ch) { | 127 | switch (ch) { |
126 | case 'C': | 128 | case 'C': |
127 | addargs(&args, "-C"); | 129 | addargs(&args, "-C"); |
@@ -159,6 +161,11 @@ main(int argc, char **argv) | |||
159 | case 'P': | 161 | case 'P': |
160 | sftp_direct = optarg; | 162 | sftp_direct = optarg; |
161 | break; | 163 | break; |
164 | case 'B': | ||
165 | copy_buffer_len = strtol(optarg, &cp, 10); | ||
166 | if (copy_buffer_len == 0 || *cp != '\0') | ||
167 | fatal("Invalid buffer size \"%s\"", optarg); | ||
168 | break; | ||
162 | case 'h': | 169 | case 'h': |
163 | default: | 170 | default: |
164 | usage(); | 171 | usage(); |