summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2002-02-08 22:04:05 +1100
committerDamien Miller <djm@mindrot.org>2002-02-08 22:04:05 +1100
commit8829d3669d154dbd06f9ee2cc779f14e2af8e15f (patch)
tree06c5dc3d5c2352c1466d76512d2d9cd5e6b6513a
parente8c9ed436a23d0fdbad1881092a3f9d2e7d5f822 (diff)
- djm@cvs.openbsd.org 2002/02/05 00:00:46
[sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c] Add "-B" option to specify copy buffer length (default 32k); ok markus@
-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 aa1a6fe2..d3a6be9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,9 @@
- stevesk@cvs.openbsd.org 2002/02/04 20:41:16
[ssh-agent.1]
more sync for default ssh-add identities; ok markus@
+ - djm@cvs.openbsd.org 2002/02/05 00:00:46
+ [sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c]
+ Add "-B" option to specify copy buffer length (default 32k); ok markus@
20020205
- (djm) Cleanup after sync:
@@ -7513,4 +7516,4 @@
- Wrote replacements for strlcpy and mkdtemp
- Released 1.0pre1
-$Id: ChangeLog,v 1.1829 2002/02/08 11:02:16 djm Exp $
+$Id: ChangeLog,v 1.1830 2002/02/08 11:04:05 djm Exp $
diff --git a/sftp-client.c b/sftp-client.c
index ca5a4859..362814d4 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -29,7 +29,7 @@
/* XXX: copy between two remote sites */
#include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.20 2002/02/05 00:00:46 djm Exp $");
#include "buffer.h"
#include "bufaux.h"
@@ -42,10 +42,6 @@ RCSID("$OpenBSD: sftp-client.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $");
#include "sftp-common.h"
#include "sftp-client.h"
-/* How much data to read/write at at time during copies */
-/* XXX: what should this be? */
-#define COPY_SIZE 8192
-
/* Message ID */
static u_int msg_id = 1;
@@ -670,15 +666,14 @@ do_readlink(int fd_in, int fd_out, char *path)
int
do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
- int pflag)
+ int pflag, size_t buflen)
{
- int local_fd;
+ int local_fd, status;
u_int expected_id, handle_len, mode, type, id;
u_int64_t offset;
char *handle;
Buffer msg;
Attrib junk, *a;
- int status;
a = do_stat(fd_in, fd_out, remote_path, 0);
if (a == NULL)
@@ -736,10 +731,10 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
buffer_put_int(&msg, id);
buffer_put_string(&msg, handle, handle_len);
buffer_put_int64(&msg, offset);
- buffer_put_int(&msg, COPY_SIZE);
+ buffer_put_int(&msg, buflen);
send_msg(fd_out, &msg);
debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u",
- id, (u_int64_t)offset, COPY_SIZE);
+ id, (u_int64_t)offset, buflen);
buffer_clear(&msg);
@@ -767,9 +762,9 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
}
data = buffer_get_string(&msg, &len);
- if (len > COPY_SIZE)
+ if (len > buflen)
fatal("Received more data than asked for %d > %d",
- len, COPY_SIZE);
+ len, buflen);
debug3("In read loop, got %d offset %llu", len,
(u_int64_t)offset);
@@ -814,16 +809,15 @@ done:
int
do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
- int pflag)
+ int pflag, size_t buflen)
{
- int local_fd;
+ int local_fd, status;
u_int handle_len, id;
u_int64_t offset;
- char *handle;
+ char *handle, *data;
Buffer msg;
struct stat sb;
Attrib a;
- int status;
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
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,
return(-1);
}
+ data = xmalloc(buflen);
+
/* Read from local and write to remote */
offset = 0;
for (;;) {
int len;
- char data[COPY_SIZE];
/*
* Can't use atomicio here because it returns 0 on EOF, thus losing
* the last block of the file
*/
do
- len = read(local_fd, data, COPY_SIZE);
+ len = read(local_fd, data, buflen);
while ((len == -1) && (errno == EINTR || errno == EAGAIN));
if (len == -1)
@@ -908,6 +903,7 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
offset += len;
}
+ xfree(data);
if (close(local_fd) == -1) {
error("Couldn't close local file \"%s\": %s", local_path,
diff --git a/sftp-client.h b/sftp-client.h
index a322b257..20350701 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: sftp-client.h,v 1.6 2001/06/26 06:33:01 itojun Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.7 2002/02/05 00:00:46 djm Exp $ */
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001-2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -94,10 +94,10 @@ char *do_readlink(int, int, char *);
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_download(int, int, char *, char *, int);
+int do_download(int, int, char *, char *, int, size_t);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_upload(int, int, char *, char *, int);
+int do_upload(int, int, char *, char *, int , size_t);
diff --git a/sftp-int.c b/sftp-int.c
index d8eec3f3..f86922d0 100644
--- a/sftp-int.c
+++ b/sftp-int.c
@@ -26,7 +26,7 @@
/* XXX: recursive operations */
#include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.41 2001/12/19 07:18:56 deraadt Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.42 2002/02/05 00:00:46 djm Exp $");
#include "buffer.h"
#include "xmalloc.h"
@@ -42,6 +42,9 @@ RCSID("$OpenBSD: sftp-int.c,v 1.41 2001/12/19 07:18:56 deraadt Exp $");
/* File to read commands from */
extern FILE *infile;
+/* Size of buffer used when copying files */
+extern size_t copy_buffer_len;
+
/* Version of server we are speaking to */
int version;
@@ -381,7 +384,8 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
goto out;
}
printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
- err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag);
+ err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag,
+ copy_buffer_len);
goto out;
}
@@ -405,7 +409,8 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
abs_dst = tmp;
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
- if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
+ if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag,
+ copy_buffer_len) == -1)
err = -1;
xfree(abs_dst);
abs_dst = NULL;
@@ -463,7 +468,8 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
abs_dst = make_absolute(abs_dst, pwd);
}
printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
- err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag);
+ err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag,
+ copy_buffer_len);
goto out;
}
@@ -487,7 +493,8 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
abs_dst = make_absolute(tmp, pwd);
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
- if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
+ if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag,
+ copy_buffer_len) == -1)
err = -1;
}
diff --git a/sftp.1 b/sftp.1
index 2a256032..49d4af57 100644
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.27 2002/02/04 21:53:11 djm Exp $
+.\" $OpenBSD: sftp.1,v 1.28 2002/02/05 00:00:46 djm Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@@ -31,6 +31,7 @@
.Sh SYNOPSIS
.Nm sftp
.Op Fl 1Cv
+.Op Fl B Ar buffer_size
.Op Fl b Ar batchfile
.Op Fl F Ar ssh_config
.Op Fl o Ar ssh_option
@@ -66,6 +67,11 @@ The options are as follows:
.Bl -tag -width Ds
.It Fl 1
Specify the use of protocol version 1.
+.It Fl B Ar buffer_size
+Specify the size of the buffer that
+.Nm
+uses when transferring files. Larger buffers require fewer round trips at
+the cost of higher memory consumption. The default is 32768 bytes.
.It Fl P Ar sftp_server path
Connect directly to a local
.Nm sftp-server
diff --git a/sftp.c b/sftp.c
index 3748d055..c2282b50 100644
--- a/sftp.c
+++ b/sftp.c
@@ -24,7 +24,7 @@
#include "includes.h"
-RCSID("$OpenBSD: sftp.c,v 1.23 2002/02/04 21:53:12 djm Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.24 2002/02/05 00:00:46 djm Exp $");
/* XXX: short-form remote directory listings (like 'ls -C') */
@@ -46,6 +46,7 @@ char *__progname;
#endif
FILE* infile;
+size_t copy_buffer_len = 32768;
static void
connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid)
@@ -93,7 +94,8 @@ usage(void)
{
fprintf(stderr,
"usage: sftp [-1Cv] [-b batchfile] [-F config] [-o option] [-s subsystem|path]\n"
- " [-S program] [user@]host[:file [file]]\n");
+ " [-P direct server path] [-S program] \n"
+ " [-B buffer_size] [user@]host[:file [file]]\n");
exit(1);
}
@@ -121,7 +123,7 @@ main(int argc, char **argv)
ll = SYSLOG_LEVEL_INFO;
infile = stdin; /* Read from STDIN unless changed by -b */
- while ((ch = getopt(argc, argv, "1hvCo:s:S:b:F:P:")) != -1) {
+ while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:")) != -1) {
switch (ch) {
case 'C':
addargs(&args, "-C");
@@ -159,6 +161,11 @@ main(int argc, char **argv)
case 'P':
sftp_direct = optarg;
break;
+ case 'B':
+ copy_buffer_len = strtol(optarg, &cp, 10);
+ if (copy_buffer_len == 0 || *cp != '\0')
+ fatal("Invalid buffer size \"%s\"", optarg);
+ break;
case 'h':
default:
usage();