diff options
author | Paul Traina <pst@FreeBSD.org> | 1997-12-13 20:38:21 +0000 |
---|---|---|
committer | Paul Traina <pst@FreeBSD.org> | 1997-12-13 20:38:21 +0000 |
commit | b62081305ab334cee7b23e179ea854c66e31ca38 (patch) | |
tree | 2970c392cbb587321233b9ac30aac8fb173245dd | |
parent | f2c90b95385de064f438eccbfa3e49935975201d (diff) | |
download | src-test2-b62081305ab334cee7b23e179ea854c66e31ca38.tar.gz src-test2-b62081305ab334cee7b23e179ea854c66e31ca38.zip |
Notes
-rw-r--r-- | usr.bin/ftp/Makefile | 14 | ||||
-rw-r--r-- | usr.bin/ftp/cmds.c | 258 | ||||
-rw-r--r-- | usr.bin/ftp/cmdtab.c | 10 | ||||
-rw-r--r-- | usr.bin/ftp/complete.c | 24 | ||||
-rw-r--r-- | usr.bin/ftp/domacro.c | 8 | ||||
-rw-r--r-- | usr.bin/ftp/extern.h | 13 | ||||
-rw-r--r-- | usr.bin/ftp/fetch.c | 115 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.1 | 43 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.c | 141 | ||||
-rw-r--r-- | usr.bin/ftp/ftp_var.h | 34 | ||||
-rw-r--r-- | usr.bin/ftp/main.c | 63 | ||||
-rw-r--r-- | usr.bin/ftp/pathnames.h | 2 | ||||
-rw-r--r-- | usr.bin/ftp/ruserpass.c | 32 | ||||
-rw-r--r-- | usr.bin/ftp/util.c | 159 |
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); } /* |