summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Traina <pst@FreeBSD.org>1997-12-13 20:38:21 +0000
committerPaul Traina <pst@FreeBSD.org>1997-12-13 20:38:21 +0000
commitb62081305ab334cee7b23e179ea854c66e31ca38 (patch)
tree2970c392cbb587321233b9ac30aac8fb173245dd
parentf2c90b95385de064f438eccbfa3e49935975201d (diff)
downloadsrc-test2-b62081305ab334cee7b23e179ea854c66e31ca38.tar.gz
src-test2-b62081305ab334cee7b23e179ea854c66e31ca38.zip
Notes
-rw-r--r--usr.bin/ftp/Makefile14
-rw-r--r--usr.bin/ftp/cmds.c258
-rw-r--r--usr.bin/ftp/cmdtab.c10
-rw-r--r--usr.bin/ftp/complete.c24
-rw-r--r--usr.bin/ftp/domacro.c8
-rw-r--r--usr.bin/ftp/extern.h13
-rw-r--r--usr.bin/ftp/fetch.c115
-rw-r--r--usr.bin/ftp/ftp.143
-rw-r--r--usr.bin/ftp/ftp.c141
-rw-r--r--usr.bin/ftp/ftp_var.h34
-rw-r--r--usr.bin/ftp/main.c63
-rw-r--r--usr.bin/ftp/pathnames.h2
-rw-r--r--usr.bin/ftp/ruserpass.c32
-rw-r--r--usr.bin/ftp/util.c159
14 files changed, 613 insertions, 303 deletions
diff --git a/usr.bin/ftp/Makefile b/usr.bin/ftp/Makefile
index acf31c159814..225d10ec3397 100644
--- a/usr.bin/ftp/Makefile
+++ b/usr.bin/ftp/Makefile
@@ -1,7 +1,11 @@
-# $Id: Makefile,v 1.6 1997/06/25 08:56:33 msmith Exp $
-# $NetBSD: Makefile,v 1.11 1997/03/24 21:59:36 christos Exp $
+# $Id: Makefile,v 1.7 1997/10/05 09:39:55 jkh Exp $
+# $NetBSD: Makefile,v 1.15 1997/10/18 15:31:20 lukem Exp $
# from: @(#)Makefile 8.2 (Berkeley) 4/3/94
+# Uncomment the following to provide defaults for gate-ftp operation
+#
+#CFLAGS+=-DGATE_SERVER=\"ftp-gw.host\" # -DGATE_PORT=21
+
PROG= ftp
SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c ruserpass.c \
util.c
@@ -10,7 +14,9 @@ CFLAGS+=-I${.CURDIR}/../../contrib-crypto/telnet
LDADD+= -ledit -ltermcap
DPADD+= ${LIBEDIT} ${LIBTERMCAP}
-LINKS= ${BINDIR}/ftp ${BINDIR}/pftp
-MLINKS= ftp.1 pftp.1
+LINKS= ${BINDIR}/ftp ${BINDIR}/pftp \
+ ${BINDIR}/ftp ${BINDIR}/gate-ftp
+MLINKS= ftp.1 pftp.1 \
+ ftp.1 gate-ftp.1
.include <bsd.prog.mk>
diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c
index 893bdf74504d..7576537398b3 100644
--- a/usr.bin/ftp/cmds.c
+++ b/usr.bin/ftp/cmds.c
@@ -1,5 +1,5 @@
-/* $Id: cmds.c,v 1.10 1997/11/17 19:29:16 guido Exp $ */
-/* $NetBSD: cmds.c,v 1.24 1997/05/17 19:44:36 pk Exp $ */
+/* $Id$ */
+/* $NetBSD: cmds.c,v 1.30.2.1 1997/11/18 00:58:26 mellon Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@@ -34,11 +34,13 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
#else
-static char rcsid[] = "$Id: cmds.c,v 1.10 1997/11/17 19:29:16 guido Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: cmds.c,v 1.30.2.1 1997/11/18 00:58:26 mellon Exp $");
#endif
#endif /* not lint */
@@ -299,6 +301,8 @@ usage:
}
sendrequest(cmd, argv[1], argv[2],
argv[1] != oldargv1 || argv[2] != oldargv2);
+ if (oldargv1 != argv[1]) /* free up after globulize() */
+ free(argv[1]);
}
/*
@@ -452,16 +456,12 @@ getit(argc, argv, restartit, mode)
const char *mode;
{
int loc = 0;
- char *oldargv1, *oldargv2;
+ int rval = 0;
+ char *oldargv1, *oldargv2, *globargv2;
if (argc == 2) {
argc++;
argv[2] = argv[1];
- if (*argv[1] == '|' && !another(&argc, &argv,
- "(warning: remote file starts with '|') local-file")) {
- code = -1;
- return (0);
- }
loc++;
}
if (argc < 2 && !another(&argc, &argv, "remote-file"))
@@ -478,6 +478,7 @@ usage:
code = -1;
return (0);
}
+ globargv2 = argv[2];
if (loc && mcase) {
char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
@@ -488,8 +489,9 @@ usage:
tp = argv[2];
tp2 = tmpbuf;
while ((*tp2 = *tp) != '\0') {
- if (isupper((unsigned char)*tp2))
+ if (isupper((unsigned char)*tp2)) {
*tp2 = tolower((unsigned char)*tp2);
+ }
tp++;
tp2++;
}
@@ -508,7 +510,7 @@ usage:
if (restartit == 1) {
if (ret < 0) {
warn("local: %s", argv[2]);
- return (0);
+ goto freegetit;
}
restart_point = stbuf.st_size;
} else {
@@ -517,17 +519,22 @@ usage:
mtime = remotemodtime(argv[1], 0);
if (mtime == -1)
- return (0);
- if (stbuf.st_mtime >= mtime)
- return (1);
+ goto freegetit;
+ if (stbuf.st_mtime >= mtime) {
+ rval = 1;
+ goto freegetit;
+ }
}
}
}
recvrequest("RETR", argv[2], argv[1], mode,
- argv[1] != oldargv1 || argv[2] != oldargv2);
+ argv[1] != oldargv1 || argv[2] != oldargv2, loc);
restart_point = 0;
- return (0);
+freegetit:
+ if (oldargv2 != globargv2) /* free up after globulize() */
+ free(globargv2);
+ return (rval);
}
/* ARGSUSED */
@@ -583,19 +590,13 @@ mget(argc, argv)
mflag = 0;
continue;
}
- if (!interactive && *cp == '|') {
- printf("skipping %s for security reasons\n", cp);
- sleep(2);
- continue;
- }
- if (*cp == '|')
- printf(
- "note: next file starts with '|', which runs it through a pipe\n");
if (mflag && confirm(argv[0], cp)) {
tp = cp;
if (mcase) {
- for (tp2 = tmpbuf; (ch = (unsigned char)*tp++) != 0; )
- *tp2++ = isupper(ch) ? tolower(ch) : ch;
+ for (tp2 = tmpbuf; (ch = *tp++) != 0; )
+ *tp2++ = isupper((unsigned char)ch) ?
+ tolower((unsigned char)ch) :
+ ch;
*tp2 = '\0';
tp = tmpbuf;
}
@@ -606,7 +607,7 @@ mget(argc, argv)
tp = domap(tp);
}
recvrequest("RETR", tp, cp, "w",
- tp != cp || !interactive);
+ tp != cp || !interactive, 1);
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
@@ -656,6 +657,8 @@ status(argc, argv)
}
pswitch(0);
}
+ printf("Gate ftp: %s, server %s, port %d.\n", onoff(gatemode),
+ *gateserver ? gateserver : "(none)", ntohs(gateport));
printf("Passive mode: %s.\n", onoff(passivemode));
printf("Mode: %s; Type: %s; Form: %s; Structure: %s.\n",
modename, typename, formname, structname);
@@ -780,9 +783,12 @@ sethash(argc, argv)
else if (strcasecmp(argv[1], "off") == 0)
hash = 0;
else {
- int nmark = atol(argv[1]);
- if (nmark < 1) {
- printf("%s: bad bytecount value.\n", argv[1]);
+ int nmark;
+ char *ep;
+
+ nmark = strtol(argv[1], &ep, 10);
+ if (nmark < 1 || *ep != '\0') {
+ printf("mark: bad bytecount value `%s'.\n", argv[1]);
code = -1;
return;
}
@@ -836,8 +842,7 @@ setprogress(argc, argv)
}
/*
- * Turn on interactive prompting
- * during mget, mput, and mdelete.
+ * Turn on interactive prompting during mget, mput, and mdelete.
*/
/*VARARGS*/
void
@@ -850,8 +855,61 @@ setprompt(argc, argv)
}
/*
- * Toggle metacharacter interpretation
- * on local file names.
+ * Toggle gate-ftp mode, or set gate-ftp server
+ */
+/*VARARGS*/
+void
+setgate(argc, argv)
+ int argc;
+ char *argv[];
+{
+ static char gsbuf[MAXHOSTNAMELEN];
+
+ if (argc > 3) {
+ printf("usage: %s [ on | off | gateserver [ port ] ]\n",
+ argv[0]);
+ code = -1;
+ return;
+ } else if (argc < 2) {
+ gatemode = !gatemode;
+ } else {
+ if (argc == 2 && strcasecmp(argv[1], "on") == 0)
+ gatemode = 1;
+ else if (argc == 2 && strcasecmp(argv[1], "off") == 0)
+ gatemode = 0;
+ else {
+ if (argc == 3) {
+ char *ep;
+ long port;
+
+ port = strtol(argv[2], &ep, 10);
+ if (port < 0 || port > 0xffff || *ep != '\0') {
+ printf("%s: bad gateport value.\n",
+ argv[2]);
+ code = -1;
+ return;
+ }
+ gateport = htons(port);
+ }
+ strncpy(gsbuf, argv[1], sizeof(gsbuf) - 1);
+ gsbuf[sizeof(gsbuf) - 1] = '\0';
+ gateserver = gsbuf;
+ gatemode = 1;
+ }
+ }
+ if (gatemode && (gateserver == NULL || *gateserver == '\0')) {
+ printf(
+ "Disabling gate-ftp mode - no gate-ftp server defined.\n");
+ gatemode = 0;
+ } else {
+ printf("Gate ftp: %s, server %s, port %d.\n", onoff(gatemode),
+ *gateserver ? gateserver : "(none)", ntohs(gateport));
+ }
+ code = gatemode;
+}
+
+/*
+ * Toggle metacharacter interpretation on local file names.
*/
/*VARARGS*/
void
@@ -877,8 +935,7 @@ setpreserve(argc, argv)
}
/*
- * Set debugging mode on/off and/or
- * set level of debugging.
+ * Set debugging mode on/off and/or set level of debugging.
*/
/*VARARGS*/
void
@@ -886,8 +943,6 @@ setdebug(argc, argv)
int argc;
char *argv[];
{
- int val;
-
if (argc > 2) {
printf("usage: %s [ on | off | debuglevel ]\n", argv[0]);
code = -1;
@@ -898,13 +953,16 @@ setdebug(argc, argv)
else if (strcasecmp(argv[1], "off") == 0)
debug = 0;
else {
- val = atoi(argv[1]);
- if (val < 0) {
+ char *ep;
+ long val;
+
+ val = strtol(argv[1], &ep, 10);
+ if (val < 0 || val > INT_MAX || *ep != '\0') {
printf("%s: bad debugging value.\n", argv[1]);
code = -1;
return;
}
- debug = val;
+ debug = (int)val;
}
} else
debug = !debug;
@@ -917,8 +975,7 @@ setdebug(argc, argv)
}
/*
- * Set current working directory
- * on remote machine.
+ * Set current working directory on remote machine.
*/
void
cd(argc, argv)
@@ -944,8 +1001,7 @@ cd(argc, argv)
}
/*
- * Set current working directory
- * on local machine.
+ * Set current working directory on local machine.
*/
void
lcd(argc, argv)
@@ -953,6 +1009,7 @@ lcd(argc, argv)
char *argv[];
{
char buf[MAXPATHLEN];
+ char *oldargv1;
if (argc < 2)
argc++, argv[1] = home;
@@ -961,6 +1018,7 @@ lcd(argc, argv)
code = -1;
return;
}
+ oldargv1 = argv[1];
if (!globulize(&argv[1])) {
code = -1;
return;
@@ -968,13 +1026,15 @@ lcd(argc, argv)
if (chdir(argv[1]) < 0) {
warn("local: %s", argv[1]);
code = -1;
- return;
+ } else {
+ if (getcwd(buf, sizeof(buf)) != NULL)
+ printf("Local directory now %s\n", buf);
+ else
+ warn("getcwd: %s", argv[1]);
+ code = 0;
}
- if (getcwd(buf, sizeof(buf)) != NULL)
- printf("Local directory now %s\n", buf);
- else
- warn("getcwd: %s", argv[1]);
- code = 0;
+ if (oldargv1 != argv[1]) /* free up after globulize() */
+ free(argv[1]);
}
/*
@@ -1058,8 +1118,7 @@ usage:
}
/*
- * Get a directory listing
- * of remote files.
+ * Get a directory listing of remote files.
*/
void
ls(argc, argv)
@@ -1067,6 +1126,7 @@ ls(argc, argv)
char *argv[];
{
const char *cmd;
+ char *oldargv2, *globargv2;
if (argc < 2)
argc++, argv[1] = NULL;
@@ -1078,25 +1138,31 @@ ls(argc, argv)
return;
}
cmd = strcmp(argv[0], "dir") == 0 ? "LIST" : "NLST";
+ oldargv2 = argv[2];
if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
code = -1;
return;
}
+ globargv2 = argv[2];
if (strcmp(argv[2], "-") && *argv[2] != '|')
if (!globulize(&argv[2]) || !confirm("output to local-file:",
argv[2])) {
code = -1;
- return;
+ goto freels;
}
- recvrequest(cmd, argv[2], argv[1], "w", 0);
+ recvrequest(cmd, argv[2], argv[1], "w", 0, 0);
/* flush results in case commands are coming from a pipe */
fflush(stdout);
+freels:
+ if (argv[2] != globargv2) /* free up after globulize() */
+ free(argv[2]);
+ if (globargv2 != oldargv2)
+ free(globargv2);
}
/*
- * Get a directory listing
- * of multiple remote files.
+ * Get a directory listing of multiple remote files.
*/
void
mls(argc, argv)
@@ -1105,8 +1171,8 @@ mls(argc, argv)
{
sig_t oldintr;
int ointer, i;
- const char *cmd;
- char mode[1], *dest;
+ int dolist;
+ char mode[1], *dest, *odest;
if (argc < 2 && !another(&argc, &argv, "remote-files"))
goto usage;
@@ -1116,7 +1182,7 @@ usage:
code = -1;
return;
}
- dest = argv[argc - 1];
+ odest = dest = argv[argc - 1];
argv[argc - 1] = NULL;
if (strcmp(dest, "-") && *dest != '|')
if (!globulize(&dest) ||
@@ -1124,14 +1190,15 @@ usage:
code = -1;
return;
}
- cmd = strcmp(argv[0], "mls") == 0 ? "NLST" : "LIST";
+ dolist = strcmp(argv[0], "mls");
mname = argv[0];
mflag = 1;
oldintr = signal(SIGINT, mabort);
(void)setjmp(jabort);
for (i = 1; mflag && i < argc-1; ++i) {
*mode = (i == 1) ? 'w' : 'a';
- recvrequest(cmd, dest, argv[i], mode, 0);
+ recvrequest(dolist ? "LIST" : "NLST", dest, argv[i], mode,
+ 0, 0);
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
@@ -1143,6 +1210,8 @@ usage:
}
(void)signal(SIGINT, oldintr);
mflag = 0;
+ if (dest != odest) /* free up after globulize() */
+ free(dest);
}
/*
@@ -1157,7 +1226,7 @@ shell(argc, argv)
pid_t pid;
sig_t old1, old2;
char shellnam[MAXPATHLEN], *shell, *namep;
- union wait status;
+ int wait_status;
old1 = signal (SIGINT, SIG_IGN);
old2 = signal (SIGQUIT, SIG_IGN);
@@ -1192,7 +1261,7 @@ shell(argc, argv)
exit(1);
}
if (pid > 0)
- while (wait((int *)&status) != pid)
+ while (wait(&wait_status) != pid)
;
(void)signal(SIGINT, old1);
(void)signal(SIGQUIT, old2);
@@ -1765,7 +1834,8 @@ domap(name)
break;
case '[':
LOOP:
- if (*++cp2 == '$' && isdigit((unsigned char)*(cp2+1))) {
+ if (*++cp2 == '$' &&
+ isdigit((unsigned char)*(cp2+1))) {
if (*++cp2 == '0') {
char *cp3 = name;
@@ -1790,7 +1860,7 @@ LOOP:
cp2++;
}
else if (*cp2 == '$' &&
- isdigit((unsigned char)*(cp2+1))) {
+ isdigit((unsigned char)*(cp2+1))) {
if (*++cp2 == '0') {
char *cp3 = name;
@@ -1921,23 +1991,40 @@ cdup(argc, argv)
dirchange = 1;
}
-/* restart transfer at specific point */
+/*
+ * Restart transfer at specific point
+ */
void
restart(argc, argv)
int argc;
char *argv[];
{
- if (argc != 2)
- puts("restart: offset not specified.");
- else {
- restart_point = atol(argv[1]);
- printf("Restarting at %qd. Execute get, put or append to"
- "initiate transfer\n", restart_point);
+ if (argc > 2) {
+ printf("usage: %s [restart_point]\n", argv[0]);
+ code = -1;
+ return;
}
+ if (argc == 2) {
+ quad_t rp;
+ char *ep;
+
+ rp = strtoq(argv[1], &ep, 10);
+ if (rp < 0 || *ep != '\0')
+ printf("restart: Invalid offset `%s'\n", argv[1]);
+ else
+ restart_point = rp;
+ }
+ if (restart_point == 0)
+ puts("No restart point defined");
+ else
+ printf("Restarting at %qd for next get, put or append\n",
+ (long long)restart_point);
}
-/* show remote system type */
+/*
+ * Show remote system type
+ */
void
syst(argc, argv)
int argc;
@@ -2021,7 +2108,7 @@ setrestrict(argc, argv)
}
/*
- * get size of file on remote machine
+ * Get size of file on remote machine
*/
void
sizecmd(argc, argv)
@@ -2037,12 +2124,12 @@ sizecmd(argc, argv)
}
size = remotesize(argv[1], 1);
if (size != -1)
- printf("%s\t%qd\n", argv[1], size);
+ printf("%s\t%qd\n", argv[1], (long long)size);
code = size;
}
/*
- * get last modification time of file on remote machine
+ * Get last modification time of file on remote machine
*/
void
modtime(argc, argv)
@@ -2063,7 +2150,7 @@ modtime(argc, argv)
}
/*
- * show status on remote machine
+ * Show status on remote machine
*/
void
rmtstatus(argc, argv)
@@ -2075,7 +2162,7 @@ rmtstatus(argc, argv)
}
/*
- * get file if modtime is more recent than current file
+ * Get file if modtime is more recent than current file
*/
void
newer(argc, argv)
@@ -2096,14 +2183,15 @@ page(argc, argv)
int argc;
char *argv[];
{
- int orestart_point, ohash, overbose;
- char *p, *pager;
+ int ohash, overbose;
+ char *p, *pager, *oldargv1;
if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) {
printf("usage: %s filename\n", argv[0]);
code = -1;
return;
}
+ oldargv1 = argv[1];
if (!globulize(&argv[1])) {
code = -1;
return;
@@ -2115,13 +2203,13 @@ page(argc, argv)
errx(1, "Can't allocate memory for $PAGER");
(void)sprintf(pager, "|%s", p);
- orestart_point = restart_point;
ohash = hash;
overbose = verbose;
- restart_point = hash = verbose = 0;
- recvrequest("RETR", pager, argv[1], "r+w", 1);
+ hash = verbose = 0;
+ recvrequest("RETR", pager, argv[1], "r+w", 1, 0);
(void)free(pager);
- restart_point = orestart_point;
hash = ohash;
verbose = overbose;
+ if (oldargv1 != argv[1]) /* free up after globulize() */
+ free(argv[1]);
}
diff --git a/usr.bin/ftp/cmdtab.c b/usr.bin/ftp/cmdtab.c
index f67eeb02c929..37920e7d8bca 100644
--- a/usr.bin/ftp/cmdtab.c
+++ b/usr.bin/ftp/cmdtab.c
@@ -1,5 +1,5 @@
-/* $Id$ */
-/* $NetBSD: cmdtab.c,v 1.15 1997/04/05 03:27:33 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: cmdtab.c,v 1.17 1997/08/18 10:20:17 lukem Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@@ -34,11 +34,13 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cmdtab.c 8.4 (Berkeley) 10/9/94";
#else
-static char rcsid[] = "$Id$";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: cmdtab.c,v 1.17 1997/08/18 10:20:17 lukem Exp $");
#endif
#endif /* not lint */
@@ -69,6 +71,7 @@ char domachelp[] = "execute macro";
char edithelp[] = "toggle command line editing";
#endif /* !SMALL */
char formhelp[] = "set file transfer format";
+char gatehelp[] = "toggle gate-ftp; specify host[:port] to change proxy";
char globhelp[] = "toggle metacharacter expansion of local file names";
char hashhelp[] = "toggle printing `#' marks; specify number to set size";
char helphelp[] = "print local help information";
@@ -161,6 +164,7 @@ struct cmd cmdtab[] = {
{ "form", formhelp, 0, 1, 1, CMPL0 setform },
{ "ftp", connecthelp, 0, 0, 1, CMPL0 setpeer },
{ "get", receivehelp, 1, 1, 1, CMPL(rl) get },
+ { "gate", gatehelp, 0, 0, 0, CMPL0 setgate },
{ "glob", globhelp, 0, 0, 0, CMPL0 setglob },
{ "hash", hashhelp, 0, 0, 0, CMPL0 sethash },
{ "help", helphelp, 0, 0, 1, CMPL(C) help },
diff --git a/usr.bin/ftp/complete.c b/usr.bin/ftp/complete.c
index 689c1f84f010..901a916d7bab 100644
--- a/usr.bin/ftp/complete.c
+++ b/usr.bin/ftp/complete.c
@@ -1,5 +1,5 @@
-/* $Id: complete.c,v 1.2 1997/06/27 09:30:04 ache Exp $ */
-/* $NetBSD: complete.c,v 1.8 1997/05/24 16:34:30 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: complete.c,v 1.11 1997/09/13 09:05:53 lukem Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -27,8 +27,8 @@
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
@@ -38,8 +38,11 @@
*/
#ifndef SMALL
+
+#include <sys/cdefs.h>
#ifndef lint
-static char rcsid[] = "$Id: complete.c,v 1.2 1997/06/27 09:30:04 ache Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: complete.c,v 1.11 1997/09/13 09:05:53 lukem Exp $");
#endif /* not lint */
/*
@@ -81,7 +84,8 @@ complete_ambiguous(word, list, words)
{
char insertstr[MAXPATHLEN];
char *lastmatch;
- int i, j, matchlen, wordlen;
+ int i, j;
+ size_t matchlen, wordlen;
wordlen = strlen(word);
if (words->sl_cur == 0)
@@ -135,7 +139,7 @@ complete_command(word, list)
{
struct cmd *c;
StringList *words;
- int wordlen;
+ size_t wordlen;
unsigned char rv;
words = sl_init();
@@ -302,7 +306,8 @@ complete(el, ch)
struct cmd *c;
const LineInfo *lf;
- int len, celems, dolist;
+ int celems, dolist;
+ size_t len;
lf = el_line(el);
len = lf->lastchar - lf->buffer;
@@ -364,4 +369,5 @@ complete(el, ch)
return (CC_ERROR);
}
-#endif
+
+#endif /* !SMALL */
diff --git a/usr.bin/ftp/domacro.c b/usr.bin/ftp/domacro.c
index a28d068a3afd..c5ddc92061d7 100644
--- a/usr.bin/ftp/domacro.c
+++ b/usr.bin/ftp/domacro.c
@@ -1,5 +1,5 @@
-/* $Id: domacro.c,v 1.3 1997/06/27 09:30:09 ache Exp $ */
-/* $NetBSD: domacro.c,v 1.9 1997/03/13 06:23:14 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: domacro.c,v 1.10 1997/07/20 09:45:45 lukem Exp $ */
/*
* Copyright (c) 1985, 1993, 1994
@@ -34,11 +34,13 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)domacro.c 8.3 (Berkeley) 4/2/94";
#else
-static char rcsid[] = "$Id: domacro.c,v 1.3 1997/06/27 09:30:09 ache Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: domacro.c,v 1.10 1997/07/20 09:45:45 lukem Exp $");
#endif
#endif /* not lint */
diff --git a/usr.bin/ftp/extern.h b/usr.bin/ftp/extern.h
index 3acc6714a521..b6e42666462b 100644
--- a/usr.bin/ftp/extern.h
+++ b/usr.bin/ftp/extern.h
@@ -1,5 +1,5 @@
-/* $Id$ */
-/* $NetBSD: extern.h,v 1.15 1997/04/14 09:09:17 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: extern.h,v 1.17.2.1 1997/11/18 00:59:50 mellon Exp $ */
/*-
* Copyright (c) 1994 The Regents of the University of California.
@@ -42,7 +42,6 @@ void abort_remote __P((FILE *));
void abortpt __P((int));
void abortrecv __P((int));
void abortsend __P((int));
-void aborthttp __P((int));
void account __P((int, char **));
void alarmtimer __P((int));
int another __P((int *, char ***, const char *));
@@ -112,7 +111,7 @@ void quit __P((int, char **));
void quote __P((int, char **));
void quote1 __P((const char *, int, char **));
void recvrequest __P((const char *, const char *, const char *,
- const char *, int));
+ const char *, int, int));
void reget __P((int, char **));
char *remglob __P((char **, int, char **));
off_t remotesize __P((const char *, int));
@@ -134,6 +133,7 @@ void setdebug __P((int, char **));
void setedit __P((int, char **));
void setform __P((int, char **));
void setftmode __P((int, char **));
+void setgate __P((int, char **));
void setglob __P((int, char **));
void sethash __P((int, char **));
void setnmap __P((int, char **));
@@ -163,17 +163,12 @@ int togglevar __P((int, char **, int *, const char *));
void usage __P((void));
void user __P((int, char **));
-
-extern jmp_buf abortprox;
-extern int abrtflag;
extern struct cmd cmdtab[];
extern FILE *cout;
extern int data;
extern char *home;
-extern jmp_buf jabort;
extern int proxy;
extern char reply_string[];
-extern off_t restart_point;
extern int NCMDS;
extern char *__progname; /* from crt0.o */
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index e79c0a76c4aa..4283b3539df6 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -1,5 +1,4 @@
-/* $Id: fetch.c,v 1.1 1997/06/25 08:56:39 msmith Exp $ */
-/* $NetBSD: fetch.c,v 1.10 1997/05/23 18:54:18 lukem Exp $ */
+/* $NetBSD: fetch.c,v 1.16.2.1 1997/11/18 01:00:22 mellon Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -27,8 +26,8 @@
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
@@ -37,8 +36,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
-static char rcsid[] = "$Id: fetch.c,v 1.1 1997/06/25 08:56:39 msmith Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: fetch.c,v 1.16.2.1 1997/11/18 01:00:22 mellon Exp $");
#endif /* not lint */
/*
@@ -66,6 +67,10 @@ static char rcsid[] = "$Id: fetch.c,v 1.1 1997/06/25 08:56:39 msmith Exp $";
#include "ftp_var.h"
+static int url_get __P((const char *, const char *));
+void aborthttp __P((int));
+
+
#define FTP_URL "ftp://" /* ftp URL prefix */
#define HTTP_URL "http://" /* http URL prefix */
#define FTP_PROXY "ftp_proxy" /* env var with ftp proxy location */
@@ -81,40 +86,54 @@ jmp_buf httpabort;
* Modifies the string argument given.
* Returns -1 on failure, 0 on success
*/
-int
+static int
url_get(origline, proxyenv)
const char *origline;
const char *proxyenv;
{
struct sockaddr_in sin;
- int i, out, port, s;
- size_t buflen, len;
- char c, *cp, *cp2, *savefile, *portnum, *path, buf[4096];
+ int i, out, isftpurl;
+ u_int16_t port;
+ volatile int s;
+ size_t len;
+ char c, *cp, *ep, *portnum, *path, buf[4096];
+ const char *savefile;
char *line, *proxy, *host;
- sig_t oldintr;
+ volatile sig_t oldintr;
off_t hashbytes;
s = -1;
proxy = NULL;
+ isftpurl = 0;
+
+#ifdef __GNUC__ /* XXX: to shut up gcc warnings */
+ (void)&savefile;
+ (void)&proxy;
+#endif
line = strdup(origline);
if (line == NULL)
errx(1, "Can't allocate memory to parse URL");
if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
host = line + sizeof(HTTP_URL) - 1;
- else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0)
+ else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
host = line + sizeof(FTP_URL) - 1;
- else
+ isftpurl = 1;
+ } else
errx(1, "url_get: Invalid URL '%s'", line);
path = strchr(host, '/'); /* find path */
if (EMPTYSTRING(path)) {
- warnx("Invalid URL: %s", origline);
+ if (isftpurl)
+ goto noftpautologin;
+ warnx("Invalid URL (no `/' after host): %s", origline);
goto cleanup_url_get;
}
*path++ = '\0';
if (EMPTYSTRING(path)) {
- warnx("Invalid URL: %s", origline);
+ if (isftpurl)
+ goto noftpautologin;
+ warnx("Invalid URL (no file after host): %s", origline);
goto cleanup_url_get;
}
@@ -124,7 +143,9 @@ url_get(origline, proxyenv)
else
savefile = path;
if (EMPTYSTRING(savefile)) {
- warnx("Invalid URL: %s", origline);
+ if (isftpurl)
+ goto noftpautologin;
+ warnx("Invalid URL (no file after directory): %s", origline);
goto cleanup_url_get;
}
@@ -162,7 +183,7 @@ url_get(origline, proxyenv)
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- if (isdigit((unsigned char)host[0])) {
+ if (isdigit(host[0])) {
if (inet_aton(host, &sin.sin_addr) == 0) {
warnx("Invalid IP address: %s", host);
goto cleanup_url_get;
@@ -183,12 +204,15 @@ url_get(origline, proxyenv)
}
if (! EMPTYSTRING(portnum)) {
- port = atoi(portnum);
- if (port < 1 || (port & 0xffff) != port) {
+ char *ep;
+ long nport;
+
+ nport = strtol(portnum, &ep, 10);
+ if (nport < 1 || nport > 0xffff || *ep != '\0') {
warnx("Invalid port: %s", portnum);
goto cleanup_url_get;
}
- port = htons(port);
+ port = htons(nport);
} else
port = httpport;
sin.sin_port = port;
@@ -212,23 +236,23 @@ url_get(origline, proxyenv)
printf("Requesting %s\n", origline);
else
printf("Requesting %s (via %s)\n", origline, proxyenv);
- snprintf(buf, sizeof(buf), "GET %s%s HTTP/1.0\n\n",
+ len = snprintf(buf, sizeof(buf), "GET %s%s HTTP/1.0\r\n\r\n",
proxy ? "" : "/", path);
- buflen = strlen(buf);
- if (write(s, buf, buflen) < buflen) {
+ if (write(s, buf, len) < len) {
warn("Writing HTTP request");
goto cleanup_url_get;
}
memset(buf, 0, sizeof(buf));
- for (i = 0, buflen = sizeof(buf), cp = buf; i < buflen; cp++, i++) {
+ for (cp = buf; cp < buf + sizeof(buf); ) {
if (read(s, cp, 1) != 1)
goto improper;
if (*cp == '\r')
continue;
if (*cp == '\n')
break;
+ cp++;
}
- buf[buflen - 1] = '\0'; /* sanity */
+ buf[sizeof(buf) - 1] = '\0'; /* sanity */
cp = strchr(buf, ' ');
if (cp == NULL)
goto improper;
@@ -244,7 +268,7 @@ url_get(origline, proxyenv)
*/
memset(buf, 0, sizeof(buf));
c = '\0';
- for (i = 0, buflen = sizeof(buf), cp = buf; i < buflen; cp++, i++) {
+ for (cp = buf; cp < buf + sizeof(buf); ) {
if (read(s, cp, 1) != 1)
goto improper;
if (*cp == '\r')
@@ -252,29 +276,31 @@ url_get(origline, proxyenv)
if (*cp == '\n' && c == '\n')
break;
c = *cp;
+ cp++;
}
- buf[buflen - 1] = '\0'; /* sanity */
+ buf[sizeof(buf) - 1] = '\0'; /* sanity */
/*
* Look for the "Content-length: " header.
*/
#define CONTENTLEN "Content-Length: "
for (cp = buf; *cp != '\0'; cp++) {
- if (tolower((unsigned char)*cp) == 'c' &&
+ if (tolower(*cp) == 'c' &&
strncasecmp(cp, CONTENTLEN, sizeof(CONTENTLEN) - 1) == 0)
break;
}
- if (*cp == '\0')
- goto improper;
- cp += sizeof(CONTENTLEN) - 1;
- cp2 = strchr(cp, '\n');
- if (cp2 == NULL)
- goto improper;
- else
- *cp2 = '\0';
- filesize = atoi(cp);
- if (filesize < 1)
- goto improper;
+ if (*cp != '\0') {
+ cp += sizeof(CONTENTLEN) - 1;
+ ep = strchr(cp, '\n');
+ if (ep == NULL)
+ goto improper;
+ else
+ *ep = '\0';
+ filesize = strtol(cp, &ep, 10);
+ if (filesize < 1 || *ep != '\0')
+ goto improper;
+ } else
+ filesize = -1;
/* Open the output file. */
out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
@@ -338,8 +364,14 @@ url_get(origline, proxyenv)
free(line);
return (0);
+noftpautologin:
+ warnx(
+ "Auto-login using ftp URLs isn't supported when using $ftp_proxy");
+ goto cleanup_url_get;
+
improper:
warnx("Improper response from %s", host);
+
cleanup_url_get:
if (s != -1)
close(s);
@@ -387,7 +419,8 @@ auto_fetch(argc, argv)
char *cp, *line, *host, *dir, *file, *portnum;
char *user, *pass;
char *ftpproxy, *httpproxy;
- int rval, xargc, argpos;
+ int rval, xargc;
+ volatile int argpos;
int dirhasglob, filehasglob;
char rempath[MAXPATHLEN];
@@ -472,17 +505,17 @@ bad_ftp_url:
portnum = strchr(host, ':');
if (portnum != NULL)
*portnum++ = '\0';
-parsed_url:
} else { /* classic style `host:file' */
dir = strchr(host, ':');
}
+parsed_url:
if (EMPTYSTRING(host)) {
rval = argpos + 1;
continue;
}
/*
- * If cp is NULL, the file wasn't specified
+ * If dir is NULL, the file wasn't specified
* (URL looked something like ftp://host)
*/
if (dir != NULL)
diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1
index 49336d2fb3d6..8da42f8a9378 100644
--- a/usr.bin/ftp/ftp.1
+++ b/usr.bin/ftp/ftp.1
@@ -1,4 +1,4 @@
-.\" $Id: ftp.1,v 1.5 1997/06/25 08:56:40 msmith Exp $
+.\" $Id: ftp.1,v 1.6 1997/12/08 22:09:44 roberto Exp $
.\" $NetBSD: ftp.1,v 1.21 1997/06/10 21:59:58 lukem Exp $
.\"
.\" Copyright (c) 1985, 1989, 1990, 1993
@@ -34,11 +34,11 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
-.Dd February 23, 1997
+.Dd August 18, 1997
.Dt FTP 1
.Os BSD 4.2
.Sh NAME
-.Nm ftp , pftp
+.Nm ftp , pftp , gate-ftp
.Nd
.Tn ARPANET
file transfer program
@@ -333,6 +333,21 @@ The current settings for
and
.Ic structure
are used while transferring the file.
+.It Ic gate Op Ar host Op Ar port
+Toggle gate-ftp mode.
+This will not be permitted if the gate-ftp server hasn't been set
+(either explicitly by the user, or from the
+.Ev FTPSERVER
+environment variable).
+If
+.Ar host
+is given,
+then gate-ftp mode will be enabled, and the gate-ftp server will be set to
+.Ar host .
+If
+.Ar port
+is also given, that will be used as the port to connect to on the
+gate-ftp server.
.It Ic glob
Toggle filename expansion for
.Ic mdelete ,
@@ -1332,7 +1347,21 @@ By default, this is bound to the TAB key.
.Sh ENVIRONMENT
.Nm
utilizes the following environment variables.
-.Bl -tag -width "http_proxy"
+.Bl -tag -width "FTP_PASSIVE_MODE"
+.It Ev FTP_PASSIVE_MODE
+Use passive mode FTP by default.
+.It Ev FTPSERVER
+Host to use as gate-ftp server when
+.Ic gate
+is enabled.
+.It Ev FTPSERVERPORT
+Port to use when connecting to gate-ftp server when
+.Ic gate
+is enabled.
+Default is port returned by a
+.Fn getservbyname
+lookup of
+.Dq ftpgate/tcp .
.It Ev HOME
For default location of a
.Pa .netrc
@@ -1350,12 +1379,16 @@ URL of FTP proxy to use when making FTP URL requests
URL of HTTP proxy to use when making HTTP URL requests.
.El
.Sh SEE ALSO
+.Xr getservbyname 3 ,
.Xr editrc 5 ,
+.Xr services 5 ,
.Xr ftpd 8
.Sh NOTES
The
.Xr pftp 1
-command is only a link to
+and
+.Xr gate-ftp 1
+commands are links to
.Nm ftp .
.Sh HISTORY
The
diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c
index f3914c1a7433..60482d0ff34d 100644
--- a/usr.bin/ftp/ftp.c
+++ b/usr.bin/ftp/ftp.c
@@ -1,5 +1,5 @@
-/* $Id$ */
-/* $NetBSD: ftp.c,v 1.25 1997/04/14 09:09:22 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: ftp.c,v 1.29.2.1 1997/11/18 01:01:04 mellon Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@@ -34,11 +34,13 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
-static char rcsid[] = "$Id$";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: ftp.c,v 1.29.2.1 1997/11/18 01:01:04 mellon Exp $");
#endif
#endif /* not lint */
@@ -77,7 +79,6 @@ jmp_buf ptabort;
int ptabflg;
int ptflag = 0;
struct sockaddr_in myctladdr;
-off_t restart_point = 0;
FILE *cin, *cout;
@@ -87,7 +88,7 @@ hookup(host, port)
const char *host;
int port;
{
- struct hostent *hp = 0;
+ struct hostent *hp = NULL;
int s, len, tos;
static char hostnamebuf[MAXHOSTNAMELEN];
@@ -412,15 +413,26 @@ sendrequest(cmd, local, remote, printnames)
{
struct stat st;
int c, d;
- FILE *fin, *dout = 0;
+ FILE *fin, *dout;
int (*closefunc) __P((FILE *));
sig_t oldinti, oldintr, oldintp;
- off_t hashbytes;
+ volatile off_t hashbytes;
char *lmode, buf[BUFSIZ], *bufp;
int oprogress;
+#ifdef __GNUC__ /* XXX: to shut up gcc warnings */
+ (void)&fin;
+ (void)&dout;
+ (void)&closefunc;
+ (void)&oldinti;
+ (void)&oldintr;
+ (void)&oldintp;
+ (void)&lmode;
+#endif
+
hashbytes = mark;
direction = "sent";
+ dout = NULL;
bytes = 0;
filesize = -1;
oprogress = progress;
@@ -455,9 +467,8 @@ sendrequest(cmd, local, remote, printnames)
(void)signal(SIGPIPE, oldintp);
if (oldinti)
(void)signal(SIGINFO, oldinti);
- progress = oprogress;
code = -1;
- return;
+ goto cleanupsend;
}
oldintr = signal(SIGINT, abortsend);
oldinti = signal(SIGINFO, psummary);
@@ -473,7 +484,7 @@ sendrequest(cmd, local, remote, printnames)
(void)signal(SIGPIPE, oldintp);
(void)signal(SIGINFO, oldinti);
code = -1;
- return;
+ goto cleanupsend;
}
progress = 0;
closefunc = pclose;
@@ -484,17 +495,16 @@ sendrequest(cmd, local, remote, printnames)
(void)signal(SIGINT, oldintr);
(void)signal(SIGINFO, oldinti);
code = -1;
- return;
+ goto cleanupsend;
}
closefunc = fclose;
- if (fstat(fileno(fin), &st) < 0 ||
- (st.st_mode & S_IFMT) != S_IFREG) {
+ if (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode)) {
printf("%s: not a plain file.\n", local);
(void)signal(SIGINT, oldintr);
(void)signal(SIGINFO, oldinti);
fclose(fin);
code = -1;
- return;
+ goto cleanupsend;
}
filesize = st.st_size;
}
@@ -504,10 +514,9 @@ sendrequest(cmd, local, remote, printnames)
if (oldintp)
(void)signal(SIGPIPE, oldintp);
code = -1;
- progress = oprogress;
if (closefunc != NULL)
(*closefunc)(fin);
- return;
+ goto cleanupsend;
}
if (setjmp(sendabort))
goto abort;
@@ -528,44 +537,37 @@ sendrequest(cmd, local, remote, printnames)
}
if (rc < 0) {
warn("local: %s", local);
- restart_point = 0;
- progress = oprogress;
if (closefunc != NULL)
(*closefunc)(fin);
- return;
+ goto cleanupsend;
}
- if (command("REST %ld", (long) restart_point)
- != CONTINUE) {
- restart_point = 0;
- progress = oprogress;
+ if (command("REST %qd", (long long) restart_point) !=
+ CONTINUE) {
if (closefunc != NULL)
(*closefunc)(fin);
- return;
+ goto cleanupsend;
}
- restart_point = 0;
lmode = "r+w";
}
if (remote) {
if (command("%s %s", cmd, remote) != PRELIM) {
(void)signal(SIGINT, oldintr);
(void)signal(SIGINFO, oldinti);
- progress = oprogress;
if (oldintp)
(void)signal(SIGPIPE, oldintp);
if (closefunc != NULL)
(*closefunc)(fin);
- return;
+ goto cleanupsend;
}
} else
if (command("%s", cmd) != PRELIM) {
(void)signal(SIGINT, oldintr);
(void)signal(SIGINFO, oldinti);
- progress = oprogress;
if (oldintp)
(void)signal(SIGPIPE, oldintp);
if (closefunc != NULL)
(*closefunc)(fin);
- return;
+ goto cleanupsend;
}
dout = dataconn(lmode);
if (dout == NULL)
@@ -644,7 +646,6 @@ sendrequest(cmd, local, remote, printnames)
break;
}
progressmeter(1);
- progress = oprogress;
if (closefunc != NULL)
(*closefunc)(fin);
(void)fclose(dout);
@@ -655,11 +656,10 @@ sendrequest(cmd, local, remote, printnames)
(void)signal(SIGPIPE, oldintp);
if (bytes > 0)
ptransfer(0);
- return;
+ goto cleanupsend;
abort:
(void)signal(SIGINT, oldintr);
(void)signal(SIGINFO, oldinti);
- progress = oprogress;
if (oldintp)
(void)signal(SIGPIPE, oldintp);
if (!cpend) {
@@ -678,6 +678,9 @@ abort:
(*closefunc)(fin);
if (bytes > 0)
ptransfer(0);
+cleanupsend:
+ progress = oprogress;
+ restart_point = 0;
}
jmp_buf recvabort;
@@ -696,32 +699,47 @@ abortrecv(notused)
}
void
-recvrequest(cmd, local, remote, lmode, printnames)
+recvrequest(cmd, local, remote, lmode, printnames, ignorespecial)
const char *cmd, *local, *remote, *lmode;
- int printnames;
+ int printnames, ignorespecial;
{
- FILE *fout, *din = 0;
+ FILE *fout, *din;
int (*closefunc) __P((FILE *));
sig_t oldinti, oldintr, oldintp;
- int c, d, is_retr, tcrflag, bare_lfs = 0;
- static int bufsize;
+ int c, d;
+ volatile int is_retr, tcrflag, bare_lfs;
+ static size_t bufsize;
static char *buf;
- off_t hashbytes;
+ volatile off_t hashbytes;
struct stat st;
time_t mtime;
struct timeval tval[2];
int oprogress;
int opreserve;
+#ifdef __GNUC__ /* XXX: to shut up gcc warnings */
+ (void)&local;
+ (void)&fout;
+ (void)&din;
+ (void)&closefunc;
+ (void)&oldinti;
+ (void)&oldintr;
+ (void)&oldintp;
+#endif
+
+ fout = NULL;
+ din = NULL;
+ oldinti = NULL;
hashbytes = mark;
direction = "received";
bytes = 0;
+ bare_lfs = 0;
filesize = -1;
oprogress = progress;
opreserve = preserve;
- is_retr = strcmp(cmd, "RETR") == 0;
+ is_retr = (strcmp(cmd, "RETR") == 0);
if (is_retr && verbose && printnames) {
- if (local && *local != '-')
+ if (local && (ignorespecial || *local != '-'))
printf("local: %s ", local);
if (remote)
printf("remote: %s\n", remote);
@@ -753,8 +771,8 @@ recvrequest(cmd, local, remote, lmode, printnames)
}
oldintr = signal(SIGINT, abortrecv);
oldinti = signal(SIGINFO, psummary);
- if (strcmp(local, "-") && *local != '|') {
- if (access(local, 2) < 0) {
+ if (ignorespecial || (strcmp(local, "-") && *local != '|')) {
+ if (access(local, W_OK) < 0) {
char *dir = strrchr(local, '/');
if (errno != ENOENT && errno != EACCES) {
@@ -766,7 +784,7 @@ recvrequest(cmd, local, remote, lmode, printnames)
}
if (dir != NULL)
*dir = 0;
- d = access(dir == local ? "/" : dir ? local : ".", 2);
+ d = access(dir == local ? "/" : dir ? local : ".", W_OK);
if (dir != NULL)
*dir = '/';
if (d < 0) {
@@ -816,7 +834,7 @@ recvrequest(cmd, local, remote, lmode, printnames)
if (setjmp(recvabort))
goto abort;
if (is_retr && restart_point &&
- command("REST %ld", (long) restart_point) != CONTINUE)
+ command("REST %qd", (long long) restart_point) != CONTINUE)
return;
if (remote) {
if (command("%s %s", cmd, remote) != PRELIM) {
@@ -834,11 +852,11 @@ recvrequest(cmd, local, remote, lmode, printnames)
din = dataconn("r");
if (din == NULL)
goto abort;
- if (strcmp(local, "-") == 0) {
+ if (!ignorespecial && strcmp(local, "-") == 0) {
fout = stdout;
progress = 0;
preserve = 0;
- } else if (*local == '|') {
+ } else if (!ignorespecial && *local == '|') {
oldintp = signal(SIGPIPE, SIG_IGN);
fout = popen(local + 1, "w");
if (fout == NULL) {
@@ -869,7 +887,7 @@ recvrequest(cmd, local, remote, lmode, printnames)
}
bufsize = st.st_blksize;
}
- if ((st.st_mode & S_IFMT) != S_IFREG) {
+ if (!S_ISREG(st.st_mode)) {
progress = 0;
preserve = 0;
}
@@ -878,7 +896,7 @@ recvrequest(cmd, local, remote, lmode, printnames)
case TYPE_I:
case TYPE_L:
- if (restart_point &&
+ if (is_retr && restart_point &&
lseek(fileno(fout), restart_point, SEEK_SET) < 0) {
warn("local: %s", local);
progress = oprogress;
@@ -920,12 +938,13 @@ recvrequest(cmd, local, remote, lmode, printnames)
break;
case TYPE_A:
- if (restart_point) {
- int i, n, ch;
+ if (is_retr && restart_point) {
+ int ch;
+ long i, n;
if (fseek(fout, 0L, SEEK_SET) < 0)
goto done;
- n = restart_point;
+ n = (long)restart_point;
for (i = 0; i++ < n;) {
if ((ch = getc(fout)) == EOF)
goto done;
@@ -1063,8 +1082,8 @@ initconn()
char *p, *a;
int result, len, tmpno = 0;
int on = 1;
- int tos, ports;
int a0, a1, a2, a3, p0, p1;
+ int ports;
if (passivemode) {
data = socket(AF_INET, SOCK_STREAM, 0);
@@ -1113,8 +1132,8 @@ initconn()
goto bad;
}
#ifdef IP_TOS
- tos = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos,
+ on = IPTOS_THROUGHPUT;
+ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
sizeof(int)) < 0)
warn("setsockopt TOS (ignored)");
#endif
@@ -1349,10 +1368,18 @@ proxtrans(cmd, local, remote)
const char *cmd, *local, *remote;
{
sig_t oldintr;
- int secndflag = 0, prox_type, nfnd;
+ int prox_type, nfnd;
+ volatile int secndflag;
char *cmd2;
struct fd_set mask;
+#ifdef __GNUC__ /* XXX: to shut up gcc warnings */
+ (void)&oldintr;
+ (void)&cmd2;
+#endif
+
+ oldintr = NULL;
+ secndflag = 0;
if (strcmp(cmd, "RETR"))
cmd2 = "RETR";
else
@@ -1496,7 +1523,7 @@ gunique(local)
if (cp)
*cp = '\0';
- d = access(cp == local ? "/" : cp ? local : ".", 2);
+ d = access(cp == local ? "/" : cp ? local : ".", W_OK);
if (cp)
*cp = '/';
if (d < 0) {
@@ -1517,7 +1544,7 @@ gunique(local)
ext = '0';
else
ext++;
- if ((d = access(new, 0)) < 0)
+ if ((d = access(new, F_OK)) < 0)
break;
if (ext != '0')
cp--;
diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h
index d572bf009955..0dd071676df8 100644
--- a/usr.bin/ftp/ftp_var.h
+++ b/usr.bin/ftp/ftp_var.h
@@ -1,5 +1,5 @@
-/* $Id: ftp_var.h,v 1.4 1997/06/25 08:56:41 msmith Exp $ */
-/* $NetBSD: ftp_var.h,v 1.16 1997/04/14 09:09:23 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: ftp_var.h,v 1.20.2.1 1997/11/18 01:01:37 mellon Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@@ -55,8 +55,14 @@
#define STALLTIME 5 /* # of seconds of no xfer before "stalling" */
-#define FTP_PORT 21 /* default if getservbyname("ftp/tcp") fails */
-#define HTTP_PORT 80 /* default if getservbyname("http/tcp") fails */
+#define FTP_PORT 21 /* default if ! getservbyname("ftp/tcp") */
+#define HTTP_PORT 80 /* default if ! getservbyname("http/tcp") */
+#ifndef GATE_PORT
+#define GATE_PORT 21 /* default if ! getservbyname("ftpgate/tcp") */
+#endif
+#ifndef GATE_SERVER
+#define GATE_SERVER "" /* default server */
+#endif
#define PAGER "more" /* default pager if $PAGER isn't set */
@@ -78,6 +84,8 @@ int doglob; /* glob local file names */
int autologin; /* establish user account on connection */
int proxy; /* proxy server connection active */
int proxflag; /* proxy connection exists */
+int gatemode; /* use gate-ftp */
+char *gateserver; /* server to use for gate-ftp */
int sunique; /* store files on server with unique name */
int runique; /* store local files with unique name */
int mcase; /* map upper to lower case for mget names */
@@ -89,8 +97,8 @@ int code; /* return/reply code for ftp command */
int crflag; /* if 1, strip car. rets. on ascii gets */
char pasv[64]; /* passive port for proxy data connection */
int passivemode; /* passive mode enabled */
-int restricted_data_ports; /* restrict data port range */
-char *altarg; /* argv[1] with no shell-like preprocessing */
+int restricted_data_ports; /* enable quarantine FTP area */
+char *altarg; /* argv[1] with no shell-like preprocessing */
char ntin[17]; /* input translation table */
char ntout[17]; /* output translation table */
char mapin[MAXPATHLEN]; /* input map template */
@@ -109,25 +117,29 @@ int bytesize; /* local byte size in binary */
int anonftp; /* automatic anonymous login */
int dirchange; /* remote directory changed by cd command */
int ttywidth; /* width of tty */
+char *tmpdir; /* temporary directory */
#ifndef SMALL
int editing; /* command line editing enabled */
EditLine *el; /* editline(3) status structure */
History *hist; /* editline(3) history structure */
char *cursor_pos; /* cursor position we're looking for */
-int cursor_argc; /* location of cursor in margv */
-int cursor_argo; /* offset of cursor in margv[cursor_argc] */
+size_t cursor_argc; /* location of cursor in margv */
+size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */
#endif /* !SMALL */
off_t bytes; /* current # of bytes read */
off_t filesize; /* size of file being transferred */
char *direction; /* direction transfer is occurring */
+off_t restart_point; /* offset to restart transfer */
-char *hostname; /* name of host connected to */
+char *hostname; /* name of host connected to */
int unix_server; /* server is unix, can use binary for ascii */
int unix_proxy; /* proxy is unix, can use binary for ascii */
-int ftpport; /* port number to use for ftp connections */
-int httpport; /* port number to use for http connections */
+
+u_int16_t ftpport; /* port number to use for ftp connections */
+u_int16_t httpport; /* port number to use for http connections */
+u_int16_t gateport; /* port number to use for gateftp connections */
jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c
index f94b9519e15d..2ba5ac045a1d 100644
--- a/usr.bin/ftp/main.c
+++ b/usr.bin/ftp/main.c
@@ -1,5 +1,5 @@
-/* $Id: main.c,v 1.14 1997/06/27 09:30:13 ache Exp $ */
-/* $NetBSD: main.c,v 1.22 1997/06/10 07:04:43 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: main.c,v 1.26 1997/10/14 16:31:22 christos Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@@ -34,17 +34,18 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
-static char copyright[] =
-"@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n";
+__COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94";
#else
-static char rcsid[] = "$Id: main.c,v 1.14 1997/06/27 09:30:13 ache Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: main.c,v 1.26 1997/10/14 16:31:22 christos Exp $");
#endif
#endif /* not lint */
@@ -64,6 +65,9 @@ static char rcsid[] = "$Id: main.c,v 1.14 1997/06/27 09:30:13 ache Exp $";
#include <unistd.h>
#include "ftp_var.h"
+#include "pathnames.h"
+
+int main __P((int, char **));
int
main(argc, argv)
@@ -71,9 +75,10 @@ main(argc, argv)
char *argv[];
{
struct servent *sp;
- int ch, top, port, rval;
+ int ch, top, rval;
+ long port;
struct passwd *pw = NULL;
- char *cp, homedir[MAXPATHLEN];
+ char *cp, *ep, homedir[MAXPATHLEN];
int dumbterm;
(void) setlocale(LC_ALL, "");
@@ -88,6 +93,23 @@ main(argc, argv)
httpport = htons(HTTP_PORT); /* good fallback */
else
httpport = sp->s_port;
+ gateport = 0;
+ cp = getenv("FTPSERVERPORT");
+ if (cp != NULL) {
+ port = strtol(cp, &ep, 10);
+ if (port < 1 || port > 0xffff || *ep != '\0')
+ warnx("bad FTPSERVERPORT port number: %s (ignored)",
+ cp);
+ else
+ gateport = htons(port);
+ }
+ if (gateport == 0) {
+ sp = getservbyname("ftpgate", "tcp");
+ if (sp == 0)
+ gateport = htons(GATE_PORT);
+ else
+ gateport = sp->s_port;
+ }
doglob = 1;
interactive = 1;
autologin = 1;
@@ -96,6 +118,7 @@ main(argc, argv)
preserve = 1;
verbose = 0;
progress = 0;
+ gatemode = 0;
#ifndef SMALL
editing = 0;
el = NULL;
@@ -103,11 +126,26 @@ main(argc, argv)
#endif
mark = HASHBYTES;
marg_sl = sl_init();
+ if ((tmpdir = getenv("TMPDIR")) == NULL)
+ tmpdir = _PATH_TMP;
cp = strrchr(argv[0], '/');
cp = (cp == NULL) ? argv[0] : cp + 1;
if (getenv("FTP_PASSIVE_MODE") || strcmp(cp, "pftp") == 0)
passivemode = 1;
+ else if (strcmp(cp, "gate-ftp") == 0)
+ gatemode = 1;
+
+ gateserver = getenv("FTPSERVER");
+ if (gateserver == NULL || *gateserver == '\0')
+ gateserver = GATE_SERVER;
+ if (gatemode) {
+ if (*gateserver == '\0') {
+ warnx(
+"Neither $FTPSERVER nor GATE_SERVER is defined; disabling gate-ftp");
+ gatemode = 0;
+ }
+ }
cp = getenv("TERM");
if (cp == NULL || strcmp(cp, "dumb") == 0)
@@ -159,8 +197,8 @@ main(argc, argv)
break;
case 'P':
- port = atoi(optarg);
- if (port <= 0)
+ port = strtol(optarg, &ep, 10);
+ if (port < 1 || port > 0xffff || *ep != '\0')
warnx("bad port number: %s (ignored)", optarg);
else
ftpport = htons(port);
@@ -210,6 +248,11 @@ main(argc, argv)
setttywidth(0);
(void)signal(SIGWINCH, setttywidth);
+#ifdef __GNUC__ /* XXX: to shut up gcc warnings */
+ (void)&argc;
+ (void)&argv;
+#endif
+
if (argc > 0) {
if (strchr(argv[0], ':') != NULL) {
anonftp = 1; /* Handle "automatic" transfers. */
diff --git a/usr.bin/ftp/pathnames.h b/usr.bin/ftp/pathnames.h
index c764addb96dd..bc649d68efc4 100644
--- a/usr.bin/ftp/pathnames.h
+++ b/usr.bin/ftp/pathnames.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: pathnames.h,v 1.2 1997/06/25 08:56:43 msmith Exp $ */
/* $NetBSD: pathnames.h,v 1.7 1997/01/09 20:19:40 tls Exp $ */
/*
diff --git a/usr.bin/ftp/ruserpass.c b/usr.bin/ftp/ruserpass.c
index 35302a068dfc..bc19f621a474 100644
--- a/usr.bin/ftp/ruserpass.c
+++ b/usr.bin/ftp/ruserpass.c
@@ -1,5 +1,5 @@
-/* $Id: ruserpass.c,v 1.5 1997/06/25 08:56:45 msmith Exp $ */
-/* $NetBSD: ruserpass.c,v 1.13 1997/04/01 14:20:34 mrg Exp $ */
+/* $Id$ */
+/* $NetBSD: ruserpass.c,v 1.14.2.1 1997/11/18 01:02:05 mellon Exp $ */
/*
* Copyright (c) 1985, 1993, 1994
@@ -34,11 +34,13 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)ruserpass.c 8.4 (Berkeley) 4/27/95";
#else
-static char rcsid[] = "$Id: ruserpass.c,v 1.5 1997/06/25 08:56:45 msmith Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: ruserpass.c,v 1.14.2.1 1997/11/18 01:02:05 mellon Exp $");
#endif
#endif /* not lint */
@@ -148,10 +150,10 @@ next:
case LOGIN:
if (token())
- if (*aname == 0) {
- *aname = malloc((unsigned)
- strlen(tokval) + 1);
- (void)strcpy(*aname, tokval);
+ if (*aname == NULL) {
+ *aname = strdup(tokval);
+ if (*aname == NULL)
+ err(1, "can't strdup *aname");
} else {
if (strcmp(*aname, tokval))
goto next;
@@ -165,9 +167,10 @@ next:
warnx("Remove password or make file unreadable by others.");
goto bad;
}
- if (token() && *apass == 0) {
- *apass = malloc((unsigned) strlen(tokval) + 1);
- (void)strcpy(*apass, tokval);
+ if (token() && *apass == NULL) {
+ *apass = strdup(tokval);
+ if (*apass == NULL)
+ err(1, "can't strdup *apass");
}
break;
case ACCOUNT:
@@ -177,9 +180,10 @@ next:
warnx("Remove account or make file unreadable by others.");
goto bad;
}
- if (token() && *aacct == 0) {
- *aacct = malloc((unsigned) strlen(tokval) + 1);
- (void)strcpy(*aacct, tokval);
+ if (token() && *aacct == NULL) {
+ *aacct = strdup(tokval);
+ if (*aacct == NULL)
+ err(1, "can't strdup *aacct");
}
break;
case MACDEF:
@@ -202,7 +206,7 @@ next:
tmp = macros[macnum].mac_name;
*tmp++ = c;
for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
- (!isascii(c) || !isspace(c)); ++i) {
+ (!isascii(c) || !isspace(c)); ++i) {
*tmp++ = c;
}
if (c == EOF) {
diff --git a/usr.bin/ftp/util.c b/usr.bin/ftp/util.c
index 30b48c70119c..b69e6a77867c 100644
--- a/usr.bin/ftp/util.c
+++ b/usr.bin/ftp/util.c
@@ -1,5 +1,5 @@
-/* $Id: util.c,v 1.1 1997/06/25 08:56:46 msmith Exp $ */
-/* $NetBSD: util.c,v 1.9 1997/06/10 22:00:01 lukem Exp $ */
+/* $Id$ */
+/* $NetBSD: util.c,v 1.16.2.1 1997/11/18 01:02:33 mellon Exp $ */
/*
* Copyright (c) 1985, 1989, 1993, 1994
@@ -34,8 +34,10 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
-static char rcsid[] = "$Id: util.c,v 1.1 1997/06/25 08:56:46 msmith Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: util.c,v 1.16.2.1 1997/11/18 01:02:33 mellon Exp $");
#endif /* not lint */
/*
@@ -49,8 +51,10 @@ static char rcsid[] = "$Id: util.c,v 1.1 1997/06/25 08:56:46 msmith Exp $";
#include <err.h>
#include <fcntl.h>
#include <glob.h>
+#include <limits.h>
#include <pwd.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
@@ -58,6 +62,10 @@ static char rcsid[] = "$Id: util.c,v 1.1 1997/06/25 08:56:46 msmith Exp $";
#include "ftp_var.h"
#include "pathnames.h"
+#ifndef SECSPERHOUR
+#define SECSPERHOUR (60*60)
+#endif
+
/*
* Connect to peer server and
* auto-login, if possible.
@@ -68,7 +76,7 @@ setpeer(argc, argv)
char *argv[];
{
char *host;
- short port;
+ u_int16_t port;
if (connected) {
printf("Already connected to %s, use close first.\n",
@@ -83,21 +91,42 @@ setpeer(argc, argv)
code = -1;
return;
}
- port = ftpport;
+ if (gatemode)
+ port = gateport;
+ else
+ port = ftpport;
if (argc > 2) {
- port = atoi(argv[2]);
- if (port <= 0) {
+ char *ep;
+ long nport;
+
+ nport = strtol(argv[2], &ep, 10);
+ if (nport < 1 || nport > 0xffff || *ep != '\0') {
printf("%s: bad port number '%s'.\n", argv[1], argv[2]);
printf("usage: %s host-name [port]\n", argv[0]);
code = -1;
return;
}
- port = htons(port);
+ port = htons(nport);
}
- host = hookup(argv[1], port);
+
+ if (gatemode) {
+ if (gateserver == NULL || *gateserver == '\0')
+ errx(1, "gateserver not defined (shouldn't happen)");
+ host = hookup(gateserver, port);
+ } else
+ host = hookup(argv[1], port);
+
if (host) {
int overbose;
+ if (gatemode) {
+ if (command("PASSERVE %s", argv[1]) != COMPLETE)
+ return;
+ if (verbose)
+ printf("Connected via pass-through server %s\n",
+ gateserver);
+ }
+
connected = 1;
/*
* Set up defaults for FTP.
@@ -174,6 +203,7 @@ login(host, user, pass)
char *acct;
char anonpass[MAXLOGNAME + 1 + MAXHOSTNAMELEN]; /* "user@hostname" */
char hostname[MAXHOSTNAMELEN];
+ struct passwd *pw;
int n, aflag = 0;
acct = NULL;
@@ -194,7 +224,12 @@ login(host, user, pass)
/*
* Set up anonymous login password.
*/
- user = getlogin();
+ if ((user = getlogin()) == NULL) {
+ if ((pw = getpwuid(getuid())) == NULL)
+ user = "anonymous";
+ else
+ user = pw->pw_name;
+ }
gethostname(hostname, MAXHOSTNAMELEN);
#ifndef DONT_CHEAT_ANONPASS
/*
@@ -217,12 +252,8 @@ login(host, user, pass)
while (user == NULL) {
char *myname = getlogin();
- if (myname == NULL) {
- struct passwd *pp = getpwuid(getuid());
-
- if (pp != NULL)
- myname = pp->pw_name;
- }
+ if (myname == NULL && (pw = getpwuid(getuid())) != NULL)
+ myname = pw->pw_name;
if (myname)
printf("Name (%s:%s): ", host, myname);
else
@@ -334,7 +365,7 @@ remglob(argv, doswitch, errbuf)
return (cp);
}
if (ftemp == NULL) {
- (void)snprintf(temp, sizeof(temp), "%s%s", _PATH_TMP, TMPFILE);
+ (void)snprintf(temp, sizeof(temp), "%s/%s", tmpdir, TMPFILE);
if ((fd = mkstemp(temp)) < 0) {
warn("unable to create temporary file %s", temp);
return (NULL);
@@ -347,7 +378,7 @@ remglob(argv, doswitch, errbuf)
if (doswitch)
pswitch(!proxy);
for (mode = "w"; *++argv != NULL; mode = "a")
- recvrequest("NLST", temp, *argv, mode, 0);
+ recvrequest("NLST", temp, *argv, mode, 0, 0);
if ((code / 100) != COMPLETE) {
if (errbuf != NULL)
*errbuf = reply_string;
@@ -428,7 +459,10 @@ globulize(cpp)
globfree(&gl);
return (0);
}
- *cpp = strdup(gl.gl_pathv[0]); /* XXX - wasted memory */
+ /* XXX: caller should check if *cpp changed, and
+ * free(*cpp) if that is the case
+ */
+ *cpp = strdup(gl.gl_pathv[0]);
globfree(&gl);
return (1);
}
@@ -448,9 +482,17 @@ remotesize(file, noisy)
size = -1;
if (debug == 0)
verbose = -1;
- if (command("SIZE %s", file) == COMPLETE)
- sscanf(reply_string, "%*s %qd", &size);
- else if (noisy && debug == 0)
+ if (command("SIZE %s", file) == COMPLETE) {
+ char *cp, *ep;
+
+ cp = strchr(reply_string, ' ');
+ if (cp != NULL) {
+ cp++;
+ size = strtoq(cp, &ep, 10);
+ if (*ep != '\0' && !isspace(*ep))
+ size = -1;
+ }
+ } else if (noisy && debug == 0)
puts(reply_string);
verbose = overbose;
return (size);
@@ -466,8 +508,10 @@ remotemodtime(file, noisy)
{
int overbose;
time_t rtime;
+ int ocode;
overbose = verbose;
+ ocode = code;
rtime = -1;
if (debug == 0)
verbose = -1;
@@ -492,11 +536,16 @@ remotemodtime(file, noisy)
} else if (noisy && debug == 0)
puts(reply_string);
verbose = overbose;
+ if (rtime == -1)
+ code = ocode;
return (rtime);
}
+void updateprogressmeter __P((int));
+
void
-updateprogressmeter()
+updateprogressmeter(dummy)
+ int dummy;
{
static pid_t pgrp = -1;
int ctty_pgrp;
@@ -539,9 +588,11 @@ progressmeter(flag)
struct timeval now, td, wait;
off_t cursize, abbrevsize;
double elapsed;
- int ratio, barlength, i, remaining;
+ int ratio, barlength, i, len, remaining;
char buf[256];
+ len = 0;
+
if (flag == -1) {
(void)gettimeofday(&start, (struct timezone *)0);
lastupdate = start;
@@ -555,12 +606,12 @@ progressmeter(flag)
ratio = cursize * 100 / filesize;
ratio = MAX(ratio, 0);
ratio = MIN(ratio, 100);
- snprintf(buf, sizeof(buf), "\r%3d%% ", ratio);
+ len += snprintf(buf + len, sizeof(buf) - len, "\r%3d%% ", ratio);
barlength = ttywidth - 30;
if (barlength > 0) {
i = barlength * ratio / 100;
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ len += snprintf(buf + len, sizeof(buf) - len,
"|%.*s%*s|", i,
"*****************************************************************************"
"*****************************************************************************",
@@ -573,8 +624,8 @@ progressmeter(flag)
i++;
abbrevsize >>= 10;
}
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- " %5qd %c%c ", abbrevsize, prefixes[i],
+ len += snprintf(buf + len, sizeof(buf) - len,
+ " %5qd %c%c ", (long long)abbrevsize, prefixes[i],
prefixes[i] == ' ' ? ' ' : 'B');
timersub(&now, &lastupdate, &wait);
@@ -592,26 +643,31 @@ progressmeter(flag)
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ len += snprintf(buf + len, sizeof(buf) - len,
" --:-- ETA");
} else if (wait.tv_sec >= STALLTIME) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ len += snprintf(buf + len, sizeof(buf) - len,
" - stalled -");
} else {
- remaining = (int)((filesize - restart_point) /
- (bytes / elapsed) - elapsed);
- i = remaining / 3600;
- if (i)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "%2d:", i);
- else
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- " ");
- i = remaining % 3600;
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "%02d:%02d ETA", i / 60, i % 60);
+ remaining = (int)
+ ((filesize - restart_point) / (bytes / elapsed) - elapsed);
+ if (remaining >= 100 * SECSPERHOUR)
+ len += snprintf(buf + len, sizeof(buf) - len,
+ " --:-- ETA");
+ else {
+ i = remaining / SECSPERHOUR;
+ if (i)
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%2d:", i);
+ else
+ len += snprintf(buf + len, sizeof(buf) - len,
+ " ");
+ i = remaining % SECSPERHOUR;
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%02d:%02d ETA", i / 60, i % 60);
+ }
}
- (void)write(STDOUT_FILENO, buf, strlen(buf));
+ (void)write(STDOUT_FILENO, buf, len);
if (flag == -1) {
(void)signal(SIGALRM, updateprogressmeter);
@@ -638,7 +694,7 @@ ptransfer(siginfo)
struct timeval now, td;
double elapsed;
off_t bs;
- int meg, remaining, hh;
+ int meg, remaining, hh, len;
char buf[100];
if (!verbose && !siginfo)
@@ -651,22 +707,23 @@ ptransfer(siginfo)
meg = 0;
if (bs > (1024 * 1024))
meg = 1;
- (void)snprintf(buf, sizeof(buf),
+ len = 0;
+ len += snprintf(buf + len, sizeof(buf) - len,
"%qd byte%s %s in %.2f seconds (%.2f %sB/s)\n",
- bytes, bytes == 1 ? "" : "s", direction, elapsed,
+ (long long)bytes, bytes == 1 ? "" : "s", direction, elapsed,
bs / (1024.0 * (meg ? 1024.0 : 1.0)), meg ? "M" : "K");
if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0
&& bytes + restart_point <= filesize) {
remaining = (int)((filesize - restart_point) /
(bytes / elapsed) - elapsed);
- hh = remaining / 3600;
- remaining %= 3600;
- /* "buf+len(buf) -1" to overwrite \n */
- snprintf(buf + strlen(buf) - 1, sizeof(buf) - strlen(buf),
+ hh = remaining / SECSPERHOUR;
+ remaining %= SECSPERHOUR;
+ len--; /* decrement len to overwrite \n */
+ len += snprintf(buf + len, sizeof(buf) - len,
" ETA: %02d:%02d:%02d\n", hh, remaining / 60,
remaining % 60);
}
- (void)write(siginfo ? STDERR_FILENO : STDOUT_FILENO, buf, strlen(buf));
+ (void)write(siginfo ? STDERR_FILENO : STDOUT_FILENO, buf, len);
}
/*