summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--sftp-client.c32
-rw-r--r--sftp-client.h8
-rw-r--r--sftp-int.c17
-rw-r--r--sftp.18
-rw-r--r--sftp.c13
6 files changed, 51 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index aa1a6fe22..d3a6be9c3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
1120020205 1420020205
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"
32RCSID("$OpenBSD: sftp-client.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $"); 32RCSID("$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 */
50static u_int msg_id = 1; 46static u_int msg_id = 1;
51 47
@@ -670,15 +666,14 @@ do_readlink(int fd_in, int fd_out, char *path)
670 666
671int 667int
672do_download(int fd_in, int fd_out, char *remote_path, char *local_path, 668do_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
815int 810int
816do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, 811do_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 */
97int do_download(int, int, char *, char *, int); 97int 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 */
103int do_upload(int, int, char *, char *, int); 103int 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"
29RCSID("$OpenBSD: sftp-int.c,v 1.41 2001/12/19 07:18:56 deraadt Exp $"); 29RCSID("$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 */
43extern FILE *infile; 43extern FILE *infile;
44 44
45/* Size of buffer used when copying files */
46extern size_t copy_buffer_len;
47
45/* Version of server we are speaking to */ 48/* Version of server we are speaking to */
46int version; 49int 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
diff --git a/sftp.1 b/sftp.1
index 2a2560320..49d4af574 100644
--- a/sftp.1
+++ b/sftp.1
@@ -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
68Specify the use of protocol version 1. 69Specify the use of protocol version 1.
70.It Fl B Ar buffer_size
71Specify the size of the buffer that
72.Nm
73uses when transferring files. Larger buffers require fewer round trips at
74the 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
70Connect directly to a local 76Connect directly to a local
71.Nm sftp-server 77.Nm sftp-server
diff --git a/sftp.c b/sftp.c
index 3748d055d..c2282b502 100644
--- a/sftp.c
+++ b/sftp.c
@@ -24,7 +24,7 @@
24 24
25#include "includes.h" 25#include "includes.h"
26 26
27RCSID("$OpenBSD: sftp.c,v 1.23 2002/02/04 21:53:12 djm Exp $"); 27RCSID("$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
48FILE* infile; 48FILE* infile;
49size_t copy_buffer_len = 32768;
49 50
50static void 51static void
51connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid) 52connect_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();