* add support for xferbuf', which sets both sndbuf' and `rcvbuf'

* document the above three commands
* rototill the way the sndbuf and rcvbuf work. remove resetsockbufsize()
* use the appropriate socket buffer size as the size of the buffer that
  the read()/write() loops use. speeds up things in some cases.
This commit is contained in:
lukem 1999-09-22 07:18:31 +00:00
parent 313488aee7
commit 700e3c1ec7
9 changed files with 136 additions and 149 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cmds.c,v 1.57 1999/09/22 03:01:53 lukem Exp $ */
/* $NetBSD: cmds.c,v 1.58 1999/09/22 07:18:31 lukem Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@ -107,7 +107,7 @@
#if 0
static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
#else
__RCSID("$NetBSD: cmds.c,v 1.57 1999/09/22 03:01:53 lukem Exp $");
__RCSID("$NetBSD: cmds.c,v 1.58 1999/09/22 07:18:31 lukem Exp $");
#endif
#endif /* not lint */
@ -762,6 +762,9 @@ status(argc, argv)
fprintf(ttyout,
"Put transfer rate throttle: %s; maximum: %d; increment %d.\n",
onoff(rate_put), rate_put, rate_put_incr);
fprintf(ttyout,
"Socket buffer sizes: send %d, receive %d.\n",
sndbuf_size, rcvbuf_size);
fprintf(ttyout, "Use of PORT cmds: %s.\n", onoff(sendport));
fprintf(ttyout, "Use of EPSV/EPRT cmds for IPv4: %s.\n", onoff(epsv4));
#ifndef NO_EDITCOMPLETE
@ -1669,8 +1672,6 @@ disconnect(argc, argv)
if (!proxy) {
macnum = 0;
}
resetsockbufsize();
}
void
@ -2418,62 +2419,46 @@ page(argc, argv)
}
/*
* Set the socket send buffer size.
* Set the socket send or receive buffer size.
*/
void
sndbuf(argc, argv)
setxferbuf(argc, argv)
int argc;
char *argv[];
{
int size;
int size, dir;
if (argc != 2) {
printf("usage: %s size\n", argv[0]);
usage:
fprintf(ttyout, "usage: %s size\n", argv[0]);
code = -1;
return;
}
if ((size = strsuftoi(argv[1])) == -1) {
printf("invalid socket buffer size: %s\n", argv[1]);
code = -1;
return;
}
sndbuf_size = size;
if (sndbuf_size)
sndbuf_manual = 1;
if (strcasecmp(argv[0], "sndbuf") == 0)
dir = RATE_PUT;
else if (strcasecmp(argv[0], "rcvbuf") == 0)
dir = RATE_GET;
else if (strcasecmp(argv[0], "xferbuf") == 0)
dir = RATE_ALL;
else
sndbuf_manual = 0;
goto usage;
if ((size = strsuftoi(argv[1])) == -1)
goto usage;
if (size == 0) {
fprintf(ttyout, "%s: size must be positive.\n", argv[0]);
goto usage;
}
if (dir & RATE_PUT)
sndbuf_size = size;
if (dir & RATE_GET)
rcvbuf_size = size;
fprintf(ttyout, "Socket buffer sizes: send %d, receive %d.\n",
sndbuf_size, rcvbuf_size);
}
/*
* Set the socket receive buffer size.
*/
void
rcvbuf(argc, argv)
int argc;
char *argv[];
{
int size;
if (argc != 2) {
printf("usage: %s size\n", argv[0]);
code = -1;
return;
}
if ((size = strsuftoi(argv[1])) == -1) {
printf("invalid socket buffer size: %s\n", argv[1]);
code = -1;
return;
}
rcvbuf_size = size;
if (rcvbuf_size)
rcvbuf_manual = 1;
else
rcvbuf_manual = 0;
}
void
setepsv4(argc, argv)

View File

@ -1,4 +1,4 @@
/* $NetBSD: cmdtab.c,v 1.25 1999/07/11 20:37:39 itojun Exp $ */
/* $NetBSD: cmdtab.c,v 1.26 1999/09/22 07:18:32 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)cmdtab.c 8.4 (Berkeley) 10/9/94";
#else
__RCSID("$NetBSD: cmdtab.c,v 1.25 1999/07/11 20:37:39 itojun Exp $");
__RCSID("$NetBSD: cmdtab.c,v 1.26 1999/09/22 07:18:32 lukem Exp $");
#endif
#endif /* not lint */
@ -104,7 +104,6 @@ char pwdhelp[] = "print working directory on remote machine";
char quithelp[] = "terminate ftp session and exit";
char quotehelp[] = "send arbitrary ftp command";
char ratehelp[] = "set transfer rate limit";
char rcvbufhelp[] = "set socket receive buffer size";
char receivehelp[] = "receive file";
char regethelp[] = "get file restarting at end of local file";
char remotehelp[] = "get help from remote server";
@ -120,7 +119,6 @@ char sitehelp[] = "send site specific command to remote server\n"
"\t\tTry \"rhelp site\" or \"site help\" "
"for more information";
char sizecmdhelp[] = "show size of remote file";
char sndbufhelp[] = "set socket send buffer size";
char statushelp[] = "show current status";
char structhelp[] = "set file transfer structure";
char suniquehelp[] = "toggle store unique on remote machine";
@ -131,6 +129,7 @@ char typehelp[] = "set file transfer type";
char umaskhelp[] = "get (set) umask on remote side";
char userhelp[] = "send new user information";
char verbosehelp[] = "toggle verbose mode";
char xferbufhelp[] = "set socket send/receive buffer size";
#ifdef NO_EDITCOMPLETE
#define CMPL(x)
@ -204,7 +203,7 @@ struct cmd cmdtab[] = {
{ "quit", quithelp, 0, 0, 0, CMPL0 quit },
{ "quote", quotehelp, 1, 1, 1, CMPL0 quote },
{ "rate", ratehelp, 0, 0, 0, CMPL0 setrate },
{ "rcvbuf", rcvbufhelp, 0, 0, 0, CMPL0 rcvbuf },
{ "rcvbuf", xferbufhelp, 0, 0, 0, CMPL0 setxferbuf },
{ "recv", receivehelp, 1, 1, 1, CMPL(rl) get },
{ "reget", regethelp, 1, 1, 1, CMPL(rl) reget },
{ "rename", renamehelp, 0, 1, 1, CMPL(rr) renamefile },
@ -218,7 +217,7 @@ struct cmd cmdtab[] = {
{ "sendport", porthelp, 0, 0, 0, CMPL0 setport },
{ "site", sitehelp, 0, 1, 1, CMPL0 site },
{ "size", sizecmdhelp, 1, 1, 1, CMPL(r) sizecmd },
{ "sndbuf", sndbufhelp, 0, 0, 0, CMPL0 sndbuf },
{ "sndbuf", xferbufhelp, 0, 0, 0, CMPL0 setxferbuf },
{ "status", statushelp, 0, 0, 1, CMPL0 status },
{ "struct", structhelp, 0, 1, 1, CMPL0 setstruct },
{ "sunique", suniquehelp, 0, 0, 1, CMPL0 setsunique },
@ -230,6 +229,7 @@ struct cmd cmdtab[] = {
{ "umask", umaskhelp, 0, 1, 1, CMPL0 do_umask },
{ "user", userhelp, 0, 1, 1, CMPL0 user },
{ "verbose", verbosehelp, 0, 0, 0, CMPL0 setverbose },
{ "xferbuf", xferbufhelp, 0, 0, 0, CMPL0 setxferbuf },
{ "?", helphelp, 0, 0, 1, CMPL(C) help },
{ 0 },
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.34 1999/07/12 13:20:34 lukem Exp $ */
/* $NetBSD: extern.h,v 1.35 1999/09/22 07:18:32 lukem Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@ -144,7 +144,6 @@ void pwd __P((int, char **));
void quit __P((int, char **));
void quote __P((int, char **));
void quote1 __P((const char *, int, char **));
void rcvbuf __P((int, char **));
void recvrequest __P((const char *, const char *, const char *,
const char *, int, int));
void reget __P((int, char **));
@ -154,7 +153,6 @@ time_t remotemodtime __P((const char *, int));
void removedir __P((int, char **));
void renamefile __P((int, char **));
void reset __P((int, char **));
void resetsockbufsize __P((void));
void restart __P((int, char **));
void rmthelp __P((int, char **));
void rmtstatus __P((int, char **));
@ -192,11 +190,11 @@ void setttywidth __P((int));
void settype __P((int, char **));
void setupsockbufsize __P((int));
void setverbose __P((int, char **));
void setxferbuf __P((int, char **));
void shell __P((int, char **));
void site __P((int, char **));
void sizecmd __P((int, char **));
char *slurpstring __P((void));
void sndbuf __P((int, char **));
void status __P((int, char **));
int strsuftoi __P((const char *));
void syst __P((int, char **));

View File

@ -1,4 +1,4 @@
/* $NetBSD: fetch.c,v 1.72 1999/09/22 03:01:53 lukem Exp $ */
/* $NetBSD: fetch.c,v 1.73 1999/09/22 07:18:33 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fetch.c,v 1.72 1999/09/22 03:01:53 lukem Exp $");
__RCSID("$NetBSD: fetch.c,v 1.73 1999/09/22 07:18:33 lukem Exp $");
#endif /* not lint */
/*
@ -445,6 +445,8 @@ fetch_url(url, proxyenv, proxyauth, wwwauth)
volatile int s;
int ischunked, isproxy, rval, hcode;
size_t len;
static size_t bufsize;
static char *xferbuf;
char *cp, *ep, *buf, *savefile;
char *auth, *location, *message;
char *user, *pass, *host, *port, *path, *decodedpath;
@ -1048,23 +1050,31 @@ fetch_url(url, proxyenv, proxyauth, wwwauth)
}
oldintr = signal(SIGINT, aborthttp);
if (rcvbuf_size > bufsize) {
if (xferbuf)
(void)free(xferbuf);
bufsize = rcvbuf_size;
xferbuf = xmalloc(bufsize);
}
if (debug)
fprintf(ttyout, "using a buffer size of %d\n", (int)bufsize);
bytes = 0;
hashbytes = mark;
progressmeter(-1);
/* Finally, suck down the file. */
buf = xmalloc(BUFSIZ + 1);
do {
ssize_t chunksize;
chunksize = 0;
/* read chunksize */
if (ischunked) {
if (fgets(buf, BUFSIZ, fin) == NULL) {
if (fgets(xferbuf, bufsize, fin) == NULL) {
warnx("Unexpected EOF reading chunksize");
goto cleanup_fetch_url;
}
chunksize = strtol(buf, &ep, 16);
chunksize = strtol(xferbuf, &ep, 16);
if (strcmp(ep, "\r\n") != 0) {
warnx("Unexpected data following chunksize");
goto cleanup_fetch_url;
@ -1088,16 +1098,16 @@ fetch_url(url, proxyenv, proxyauth, wwwauth)
if (rate_get)
(void)gettimeofday(&then, NULL);
bufrem = rate_get ? rate_get : BUFSIZ;
bufrem = rate_get ? rate_get : bufsize;
while (bufrem > 0) {
len = fread(buf, sizeof(char),
ischunked ? MIN(chunksize, bufrem) : BUFSIZ,
fin);
len = fread(xferbuf, sizeof(char),
ischunked ? MIN(chunksize, bufrem)
: bufsize, fin);
if (len <= 0)
goto chunkdone;
bytes += len;
bufrem -= len;
if (fwrite(buf, sizeof(char), len, fout)
if (fwrite(xferbuf, sizeof(char), len, fout)
!= len) {
warn("Writing `%s'", savefile);
goto cleanup_fetch_url;
@ -1128,9 +1138,9 @@ fetch_url(url, proxyenv, proxyauth, wwwauth)
/* read CRLF after chunk*/
chunkdone:
if (ischunked) {
if (fgets(buf, BUFSIZ, fin) == NULL)
if (fgets(xferbuf, bufsize, fin) == NULL)
break;
if (strcmp(buf, "\r\n") != 0) {
if (strcmp(xferbuf, "\r\n") != 0) {
warnx("Unexpected data following chunk");
goto cleanup_fetch_url;
}
@ -1175,7 +1185,6 @@ improper:
warnx("Improper response from `%s'", host);
cleanup_fetch_url:
resetsockbufsize();
if (fin != NULL)
fclose(fin);
else if (s != -1)

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ftp.1,v 1.46 1999/07/12 13:20:34 lukem Exp $
.\" $NetBSD: ftp.1,v 1.47 1999/09/22 07:18:34 lukem Exp $
.\"
.\" Copyright (c) 1985, 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -35,7 +35,7 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
.Dd July 12, 1999
.Dd September 22, 1999
.Dt FTP 1
.Os
.Sh NAME
@ -977,6 +977,9 @@ is not supplied, the current throttle rates are displayed.
Note:
.Ic rate
is not yet implemented for ascii mode transfers.
.It Ic rcvbuf Ar size
Set the size of the socket receive buffer to
.Ar size .
.It Ic recv Ar remote-file Op Ar local-file
A synonym for
.Ic get .
@ -1088,6 +1091,9 @@ for certain
implementations which do ignore
.Dv PORT
commands but, incorrectly, indicate they've been accepted.
.It Ic sndbuf Ar size
Set the size of the socket send buffer to
.Ar size .
.It Ic site Ar arg1 arg2 ...
The arguments specified are sent, verbatim, to the remote
.Tn FTP
@ -1186,6 +1192,9 @@ if verbose is on, when a file transfer completes, statistics
regarding the efficiency of the transfer are reported.
By default,
verbose is on.
.It Ic xferbuf Ar size
Set the size of the socket send and receive buffers to
.Ar size .
.It Ic ? Op Ar command
A synonym for
.Ic help .
@ -1202,9 +1211,10 @@ argument to force the setting appropriately.
.Pp
Commands which take a byte count as an argument
(e.g.,
.Ic hash
.Ic hash ,
.Ic rate ,
and
.Ic rate )
.Ic xferbuf )
support an optional suffix on the argument which changes the
interpretation of the argument.
Supported suffixes are:
@ -1711,8 +1721,7 @@ and transfer rate throttling
were implemented in
.Nx 1.3
(and later releases)
by Luke Mewburn,
with the original code for HTTP retrieval supplied by Jason Thorpe.
by Luke Mewburn.
.Pp
IPv6 support was added by the WIDE/KAME project.
.Sh BUGS

View File

@ -1,4 +1,4 @@
/* $NetBSD: ftp.c,v 1.63 1999/09/22 03:01:54 lukem Exp $ */
/* $NetBSD: ftp.c,v 1.64 1999/09/22 07:18:34 lukem Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@ -67,7 +67,7 @@
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
__RCSID("$NetBSD: ftp.c,v 1.63 1999/09/22 03:01:54 lukem Exp $");
__RCSID("$NetBSD: ftp.c,v 1.64 1999/09/22 07:18:34 lukem Exp $");
#endif
#endif /* not lint */
@ -633,7 +633,9 @@ sendrequest(cmd, local, remote, printnames)
int (*closefunc) __P((FILE *));
sig_t oldinti, oldintr, oldintp;
volatile off_t hashbytes;
char *lmode, buf[BUFSIZ], *bufp;
char *lmode, *bufp;
static size_t bufsize;
static char *buf;
int oprogress;
#ifdef __GNUC__ /* to shut up gcc warnings */
@ -792,17 +794,27 @@ sendrequest(cmd, local, remote, printnames)
dout = dataconn(lmode);
if (dout == NULL)
goto abort;
if (sndbuf_size > bufsize) {
if (buf)
(void)free(buf);
bufsize = sndbuf_size;
buf = xmalloc(bufsize);
}
if (debug)
fprintf(ttyout, "using a buffer size of %d\n", (int)bufsize);
progressmeter(-1);
oldintp = signal(SIGPIPE, SIG_IGN);
switch (curtype) {
case TYPE_I:
case TYPE_L:
while (1) {
struct timeval then, now, td;
off_t bufrem, bufsize;
off_t bufrem;
bufsize = sizeof(buf);
if (rate_put)
(void)gettimeofday(&then, NULL);
errno = c = d = 0;
@ -1124,24 +1136,21 @@ recvrequest(cmd, local, remote, lmode, printnames, ignorespecial)
closefunc = fclose;
}
/*
* XXX: look at punting and just using sndbuf_* for
* the buffer size, since st.st_blksize ~= 512
* and BUFSIZ ~= 4K
*/
if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
st.st_blksize = BUFSIZ;
if (st.st_blksize > bufsize) {
if (buf)
(void)free(buf);
bufsize = st.st_blksize;
buf = xmalloc(bufsize);
}
if (!S_ISREG(st.st_mode)) {
if (fstat(fileno(fout), &st) != -1 && !S_ISREG(st.st_mode)) {
progress = 0;
preserve = 0;
}
if (rcvbuf_size > bufsize) {
if (buf)
(void)free(buf);
bufsize = rcvbuf_size;
buf = xmalloc(bufsize);
}
if (debug)
fprintf(ttyout, "using a buffer size of %d\n", (int)bufsize);
progressmeter(-1);
switch (curtype) {
case TYPE_I:

View File

@ -1,4 +1,4 @@
/* $NetBSD: ftp_var.h,v 1.35 1999/07/11 20:37:39 itojun Exp $ */
/* $NetBSD: ftp_var.h,v 1.36 1999/09/22 07:18:36 lukem Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@ -214,11 +214,7 @@ int mflag; /* flag: if != 0, then active multi command */
int options; /* used during socket creation */
int sndbuf_size; /* socket send buffer size */
int sndbuf_manual; /* sndbuf_size was set manually; override
conf file */
int rcvbuf_size; /* socket receive buffer size */
int rcvbuf_manual; /* rcvbuf_size was set manually; override
conf file */
/*
* Format of command table.

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.49 1999/09/21 10:11:56 lukem Exp $ */
/* $NetBSD: main.c,v 1.50 1999/09/22 07:18:36 lukem Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@ -72,7 +72,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94";
#else
__RCSID("$NetBSD: main.c,v 1.49 1999/09/21 10:11:56 lukem Exp $");
__RCSID("$NetBSD: main.c,v 1.50 1999/09/22 07:18:36 lukem Exp $");
#endif
#endif /* not lint */
@ -109,7 +109,7 @@ main(argc, argv)
int ch, top, rval;
struct passwd *pw = NULL;
char *cp, *ep, homedir[MAXPATHLEN];
int dumbterm;
int dumbterm, s, len;
ftpport = "ftp";
httpport = "http";
@ -149,6 +149,25 @@ main(argc, argv)
epsv4 = 0;
#endif
/*
* Get the default socket buffer sizes if we don't already have them.
* It doesn't matter which socket we do this to, because on the first
* call no socket buffer sizes will have been modified, so we are
* guaranteed to get the system defaults.
*/
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
err(1, "can't create socket");
len = sizeof(sndbuf_size);
if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, (void *) &sndbuf_size, &len)
< 0)
err(1, "unable to get default sndbuf size");
len = sizeof(rcvbuf_size);
if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (void *) &rcvbuf_size, &len)
< 0)
err(1, "unable to get default rcvbuf size");
close(s);
marg_sl = sl_init();
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = _PATH_TMP;

View File

@ -1,4 +1,4 @@
/* $NetBSD: util.c,v 1.57 1999/09/22 03:01:54 lukem Exp $ */
/* $NetBSD: util.c,v 1.58 1999/09/22 07:18:37 lukem Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -75,7 +75,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: util.c,v 1.57 1999/09/22 03:01:54 lukem Exp $");
__RCSID("$NetBSD: util.c,v 1.58 1999/09/22 07:18:37 lukem Exp $");
#endif /* not lint */
/*
@ -1232,52 +1232,14 @@ void
setupsockbufsize(sock)
int sock;
{
static int sndbuf_default, rcvbuf_default;
int len, size;
/*
* Get the default socket buffer sizes if we don't already
* have them. It doesn't matter which socket we do this
* to, because on the first call no socket buffer sizes
* will have been modified, so we are guaranteed to get
* the system defaults.
*/
if (sndbuf_default == 0) {
len = sizeof(sndbuf_default);
if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF,
(void *) &sndbuf_default, &len) < 0)
err(1, "unable to get default sndbuf size");
len = sizeof(rcvbuf_default);
if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(void *) &rcvbuf_default, &len) < 0)
err(1, "unable to get default rcvbuf size");
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *) &sndbuf_size,
sizeof(rcvbuf_size)) < 0)
warn("unable to set sndbuf size %d", sndbuf_size);
}
size = sndbuf_size ? sndbuf_size : sndbuf_default;
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *) &size,
sizeof(size)) < 0)
warn("unable to set sndbuf size %d", size);
size = rcvbuf_size ? rcvbuf_size : rcvbuf_default;
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *) &size,
sizeof(size)) < 0)
warn("unable to set rcvbuf size %d", size);
}
/*
* If the socket buffer sizes were not set manually (i.e. came from a
* configuration file), reset them so the right thing will happen on
* subsequent connections.
*/
void
resetsockbufsize()
{
if (sndbuf_manual == 0)
sndbuf_size = 0;
if (rcvbuf_manual == 0)
rcvbuf_size = 0;
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *) &rcvbuf_size,
sizeof(rcvbuf_size)) < 0)
warn("unable to set rcvbuf size %d", rcvbuf_size);
}
void