From 375f867e0616a23f19d1386dc1b03b70e10a8237 Mon Sep 17 00:00:00 2001 From: djm Date: Fri, 8 Feb 2002 11:04:05 +0000 Subject: [PATCH] - 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@ --- ChangeLog | 3 +++ sftp-client.c | 32 ++++++++++++++------------------ sftp-client.h | 8 ++++---- sftp-int.c | 17 ++++++++++++----- sftp.1 | 8 +++++++- sftp.c | 13 ++++++++++--- 6 files changed, 50 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d415d96..d16e369d 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: 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(); -- 2.45.2