From 20e59a13da22ed730008e138d6c6e71e0c138cce Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Tue, 14 Dec 2010 19:40:35 -1000 Subject: [PATCH] Snyc tnftp with NetBSD: Fix numerous WARNS issues. Rename internal getline() function to get_line() to prevent conflicts. Rename argument from "bool" to "val". Parse HTTP 'Date' entries in the `C' locale rather than the user's. Avoid NULL dereference in log output if the command line parser failed to extract a port number from the URL. Use AF_INET instead of AF_UNSPEC as the default family if !defined(INET6). In ftpvis(), prevent incomplete escape sequences at end of dst, and ensure NUL-termination of dst. Also tweak for readibility. --- contrib/tnftp/cmds.c | 180 ++++++++++++++++-------------- contrib/tnftp/cmdtab.c | 10 +- contrib/tnftp/complete.c | 35 +++--- contrib/tnftp/domacro.c | 8 +- contrib/tnftp/extern.h | 10 +- contrib/tnftp/fetch.c | 214 ++++++++++++++++++------------------ contrib/tnftp/ftp.1 | 119 ++++++-------------- contrib/tnftp/ftp.c | 48 ++++---- contrib/tnftp/ftp_var.h | 24 ++-- contrib/tnftp/main.c | 96 ++++++++-------- contrib/tnftp/progressbar.c | 10 +- contrib/tnftp/progressbar.h | 6 +- contrib/tnftp/util.c | 161 ++++++++++++++++----------- contrib/tnftp/version.h | 6 +- 14 files changed, 473 insertions(+), 454 deletions(-) diff --git a/contrib/tnftp/cmds.c b/contrib/tnftp/cmds.c index 7a328503c5..caa0960b34 100644 --- a/contrib/tnftp/cmds.c +++ b/contrib/tnftp/cmds.c @@ -1,7 +1,7 @@ -/* $NetBSD: cmds.c,v 1.125 2008/05/10 00:05:31 skd Exp $ */ +/* $NetBSD: cmds.c,v 1.131 2010/01/12 06:50:04 lukem Exp $ */ /*- - * Copyright (c) 1996-2007 The NetBSD Foundation, Inc. + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -96,7 +96,7 @@ #if 0 static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94"; #else -__RCSID("$NetBSD: cmds.c,v 1.125 2008/05/10 00:05:31 skd Exp $"); +__RCSID("$NetBSD: cmds.c,v 1.131 2010/01/12 06:50:04 lukem Exp $"); #endif #endif /* not lint */ @@ -115,6 +115,7 @@ __RCSID("$NetBSD: cmds.c,v 1.125 2008/05/10 00:05:31 skd Exp $"); #include #include #include +#include #include #include #include @@ -125,17 +126,17 @@ __RCSID("$NetBSD: cmds.c,v 1.125 2008/05/10 00:05:31 skd Exp $"); #include "version.h" static struct types { - char *t_name; - char *t_mode; - int t_type; - char *t_arg; + const char *t_name; + const char *t_mode; + int t_type; + const char *t_arg; } types[] = { { "ascii", "A", TYPE_A, 0 }, { "binary", "I", TYPE_I, 0 }, { "image", "I", TYPE_I, 0 }, { "ebcdic", "E", TYPE_E, 0 }, { "tenex", "L", TYPE_L, bytename }, - { NULL } + { NULL, NULL, 0, NULL } }; static sigjmp_buf jabort; @@ -143,6 +144,7 @@ static sigjmp_buf jabort; static int confirm(const char *, const char *); static void mintr(int); static void mabort(const char *); +static void set_type(const char *); static const char *doprocess(char *, size_t, const char *, int, int, int); static const char *domap(char *, size_t, const char *); @@ -157,7 +159,7 @@ static int confirm(const char *cmd, const char *file) { const char *errormsg; - char line[BUFSIZ]; + char cline[BUFSIZ]; const char *promptleft, *promptright; if (!interactive || confirmrest) @@ -172,12 +174,12 @@ confirm(const char *cmd, const char *file) while (1) { fprintf(ttyout, "%s %s [anpqy?]? ", promptleft, promptright); (void)fflush(ttyout); - if (getline(stdin, line, sizeof(line), &errormsg) < 0) { + if (get_line(stdin, cline, sizeof(cline), &errormsg) < 0) { mflag = 0; fprintf(ttyout, "%s; %s aborted\n", errormsg, cmd); return (0); } - switch (tolower((unsigned char)*line)) { + switch (tolower((unsigned char)*cline)) { case 'a': confirmrest = 1; fprintf(ttyout, @@ -217,10 +219,9 @@ void settype(int argc, char *argv[]) { struct types *p; - int comret; if (argc == 0 || argc > 2) { - char *sep; + const char *sep; UPRINTF("usage: %s [", argv[0]); sep = " "; @@ -237,11 +238,20 @@ settype(int argc, char *argv[]) code = 0; return; } + set_type(argv[1]); +} + +void +set_type(const char *ttype) +{ + struct types *p; + int comret; + for (p = types; p->t_name; p++) - if (strcmp(argv[1], p->t_name) == 0) + if (strcmp(ttype, p->t_name) == 0) break; if (p->t_name == 0) { - fprintf(ttyout, "%s: unknown mode.\n", argv[1]); + fprintf(ttyout, "%s: unknown mode.\n", ttype); code = -1; return; } @@ -287,12 +297,6 @@ changetype(int newtype, int show) verbose = oldverbose; } -char *stype[] = { - "type", - "", - 0 -}; - /* * Set binary transfer type. */ @@ -306,8 +310,7 @@ setbinary(int argc, char *argv[]) code = -1; return; } - stype[1] = "binary"; - settype(2, stype); + set_type("binary"); } /* @@ -323,8 +326,7 @@ setascii(int argc, char *argv[]) code = -1; return; } - stype[1] = "ascii"; - settype(2, stype); + set_type("ascii"); } /* @@ -340,8 +342,7 @@ settenex(int argc, char *argv[]) code = -1; return; } - stype[1] = "tenex"; - settype(2, stype); + set_type("tenex"); } /* @@ -402,7 +403,7 @@ void put(int argc, char *argv[]) { char buf[MAXPATHLEN]; - char *cmd; + const char *cmd; int loc = 0; char *locfile; const char *remfile; @@ -571,7 +572,7 @@ get(int argc, char *argv[]) * If restartit is -1, restart the xfer only if the remote file is newer. */ int -getit(int argc, char *argv[], int restartit, const char *mode) +getit(int argc, char *argv[], int restartit, const char *gmode) { int loc, rval; char *remfile, *olocfile; @@ -630,7 +631,7 @@ getit(int argc, char *argv[], int restartit, const char *mode) } } - recvrequest("RETR", locfile, remfile, mode, + recvrequest("RETR", locfile, remfile, gmode, remfile != argv[1] || locfile != argv[2], loc); restart_point = 0; freegetit: @@ -680,7 +681,7 @@ mget(int argc, char *argv[]) int ointer; char *cp; const char *tp; - int restartit; + int volatile restartit; if (argc == 0 || (argc == 1 && !another(&argc, &argv, "remote-files"))) { @@ -747,9 +748,9 @@ mget(int argc, char *argv[]) void fget(int argc, char *argv[]) { - char *mode; + const char *gmode; FILE *fp; - char buf[MAXPATHLEN]; + char buf[MAXPATHLEN], cmdbuf[MAX_C_NAME]; if (argc != 2) { UPRINTF("usage: %s localfile\n", argv[0]); @@ -764,23 +765,24 @@ fget(int argc, char *argv[]) return; } - argv[0] = "get"; - mode = restart_point ? "r+" : "w"; + (void)strlcpy(cmdbuf, "get", sizeof(cmdbuf)); + argv[0] = cmdbuf; + gmode = restart_point ? "r+" : "w"; - while (getline(fp, buf, sizeof(buf), NULL) >= 0) { + while (get_line(fp, buf, sizeof(buf), NULL) >= 0) { if (buf[0] == '\0') continue; argv[1] = buf; - (void)getit(argc, argv, 0, mode); + (void)getit(argc, argv, 0, gmode); } fclose(fp); } const char * -onoff(int bool) +onoff(int val) { - return (bool ? "on" : "off"); + return (val ? "on" : "off"); } /* @@ -1276,18 +1278,20 @@ renamefile(int argc, char *argv[]) * mlsd MLSD * nlist NLST * pdir, pls LIST |$PAGER - * mmlsd MLSD |$PAGER + * pmlsd MLSD |$PAGER */ void ls(int argc, char *argv[]) { const char *cmd; - char *remdir, *locfile; - int freelocfile, pagecmd, mlsdcmd; + char *remdir, *locbuf; + const char *locfile; + int pagecmd, mlsdcmd; remdir = NULL; + locbuf = NULL; locfile = "-"; - freelocfile = pagecmd = mlsdcmd = 0; + pagecmd = mlsdcmd = 0; /* * the only commands that start with `p' are * the `pager' versions. @@ -1328,29 +1332,29 @@ ls(int argc, char *argv[]) } if (pagecmd) { - char *p; + const char *p; size_t len; p = getoptionvalue("pager"); if (EMPTYSTRING(p)) p = DEFAULTPAGER; len = strlen(p) + 2; - locfile = ftp_malloc(len); - locfile[0] = '|'; - (void)strlcpy(locfile + 1, p, len - 1); - freelocfile = 1; + locbuf = ftp_malloc(len); + locbuf[0] = '|'; + (void)strlcpy(locbuf + 1, p, len - 1); + locfile = locbuf; } else if ((strcmp(locfile, "-") != 0) && *locfile != '|') { - if ((locfile = globulize(locfile)) == NULL || - !confirm("output to local-file:", locfile)) { + if ((locbuf = globulize(locfile)) == NULL || + !confirm("output to local-file:", locbuf)) { code = -1; goto freels; } - freelocfile = 1; + locfile = locbuf; } recvrequest(cmd, locfile, remdir, "w", 0, 0); freels: - if (freelocfile && locfile) - (void)free(locfile); + if (locbuf) + (void)free(locbuf); } /* @@ -1361,8 +1365,9 @@ mls(int argc, char *argv[]) { sigfunc oldintr; int ointer, i; - int dolist; - char *mode, *dest, *odest; + int volatile dolist; + char * volatile dest, *odest; + const char *lmode; if (argc == 0) goto usage; @@ -1388,8 +1393,8 @@ mls(int argc, char *argv[]) if (sigsetjmp(jabort, 1)) mabort(argv[0]); for (i = 1; mflag && i < argc-1 && connected; i++) { - mode = (i == 1) ? "w" : "a"; - recvrequest(dolist ? "LIST" : "NLST", dest, argv[i], mode, + lmode = (i == 1) ? "w" : "a"; + recvrequest(dolist ? "LIST" : "NLST", dest, argv[i], lmode, 0, 0); if (!mflag && fromatty) { ointer = interactive; @@ -1415,7 +1420,8 @@ shell(int argc, char *argv[]) { pid_t pid; sigfunc oldintr; - char shellnam[MAXPATHLEN], *shell, *namep; + char shellnam[MAXPATHLEN]; + const char *shellp, *namep; int wait_status; if (argc == 0) { @@ -1428,26 +1434,26 @@ shell(int argc, char *argv[]) for (pid = 3; pid < 20; pid++) (void)close(pid); (void)xsignal(SIGINT, SIG_DFL); - shell = getenv("SHELL"); - if (shell == NULL) - shell = _PATH_BSHELL; - namep = strrchr(shell, '/'); + shellp = getenv("SHELL"); + if (shellp == NULL) + shellp = _PATH_BSHELL; + namep = strrchr(shellp, '/'); if (namep == NULL) - namep = shell; + namep = shellp; else namep++; (void)strlcpy(shellnam, namep, sizeof(shellnam)); if (ftp_debug) { - fputs(shell, ttyout); + fputs(shellp, ttyout); putc('\n', ttyout); } if (argc > 1) { - execl(shell, shellnam, "-c", altarg, (char *)0); + execl(shellp, shellnam, "-c", altarg, (char *)0); } else { - execl(shell, shellnam, (char *)0); + execl(shellp, shellnam, (char *)0); } - warn("Can't execute `%s'", shell); + warn("Can't execute `%s'", shellp); code = -1; exit(1); } @@ -1833,6 +1839,7 @@ doproxy(int argc, char *argv[]) struct cmd *c; int cmdpos; sigfunc oldintr; + char cmdbuf[MAX_C_NAME]; if (argc == 0 || (argc == 1 && !another(&argc, &argv, "command"))) { UPRINTF("usage: %s command\n", argv[0]); @@ -1871,7 +1878,8 @@ doproxy(int argc, char *argv[]) cmdpos = strcspn(line, " \t"); if (cmdpos > 0) /* remove leading "proxy " from input buffer */ memmove(line, line + cmdpos + 1, strlen(line) - cmdpos + 1); - argv[1] = c->c_name; + (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf)); + argv[1] = cmdbuf; (*c->c_handler)(argc-1, argv+1); if (connected) { proxflag = 1; @@ -1963,7 +1971,7 @@ dotrans(char *dst, size_t dlen, const char *src) found++; if (i < ostop) { *cp2++ = *(ntout + i); - if (cp2 - dst >= dlen - 1) + if (cp2 - dst >= (ptrdiff_t)(dlen - 1)) goto out; } break; @@ -2545,7 +2553,8 @@ void lpage(int argc, char *argv[]) { size_t len; - char *p, *pager, *locfile; + const char *p; + char *pager, *locfile; if (argc == 0 || argc > 2 || (argc == 1 && !another(&argc, &argv, "local-file"))) { @@ -2579,7 +2588,8 @@ page(int argc, char *argv[]) { int ohash, orestart_point, overbose; size_t len; - char *p, *pager; + const char *p; + char *pager; if (argc == 0 || argc > 2 || (argc == 1 && !another(&argc, &argv, "remote-file"))) { @@ -2667,20 +2677,28 @@ setoption(int argc, char *argv[]) o->name, o->value ? o->value : ""); } } else { - o = getoption(argv[1]); - if (o == NULL) { - fprintf(ttyout, "No such option `%s'.\n", argv[1]); - return; - } - FREEPTR(o->value); - o->value = ftp_strdup(argv[2]); - if (verbose) - fprintf(ttyout, "Setting `%s' to `%s'.\n", - o->name, o->value); + set_option(argv[1], argv[2], 1); } code = 0; } +void +set_option(const char * option, const char * value, int doverbose) +{ + struct option *o; + + o = getoption(option); + if (o == NULL) { + fprintf(ttyout, "No such option `%s'.\n", option); + return; + } + FREEPTR(o->value); + o->value = ftp_strdup(value); + if (verbose && doverbose) + fprintf(ttyout, "Setting `%s' to `%s'.\n", + o->name, o->value); +} + /* * Unset an option */ diff --git a/contrib/tnftp/cmdtab.c b/contrib/tnftp/cmdtab.c index 3320216fd9..17d7477958 100644 --- a/contrib/tnftp/cmdtab.c +++ b/contrib/tnftp/cmdtab.c @@ -1,7 +1,7 @@ -/* $NetBSD: cmdtab.c,v 1.49 2008/05/10 00:05:31 skd Exp $ */ +/* $NetBSD: cmdtab.c,v 1.51 2009/04/12 10:18:52 lukem Exp $ */ /*- - * Copyright (c) 1996-2005 The NetBSD Foundation, Inc. + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -63,7 +63,7 @@ #if 0 static char sccsid[] = "@(#)cmdtab.c 8.4 (Berkeley) 10/9/94"; #else -__RCSID("$NetBSD: cmdtab.c,v 1.49 2008/05/10 00:05:31 skd Exp $"); +__RCSID("$NetBSD: cmdtab.c,v 1.51 2009/04/12 10:18:52 lukem Exp $"); #endif #endif /* not lint */ @@ -291,7 +291,7 @@ struct cmd cmdtab[] = { { "verbose", H(verbosehelp), 0, 0, 0, CMPL0 setverbose }, { "xferbuf", H(xferbufhelp), 0, 0, 0, CMPL0 setxferbuf }, { "?", H(helphelp), 0, 0, 1, CMPL(C) help }, - { 0 }, + { NULL, NULL, 0, 0, 0, CMPL0 NULL }, }; struct option optiontab[] = { @@ -302,5 +302,5 @@ struct option optiontab[] = { { "pager", NULL }, { "prompt", NULL }, { "rprompt", NULL }, - { 0 }, + { NULL, NULL }, }; diff --git a/contrib/tnftp/complete.c b/contrib/tnftp/complete.c index 6cf359750e..617af07ca8 100644 --- a/contrib/tnftp/complete.c +++ b/contrib/tnftp/complete.c @@ -1,7 +1,7 @@ -/* $NetBSD: complete.c,v 1.43 2008/04/28 20:24:13 martin Exp $ */ +/* $NetBSD: complete.c,v 1.46 2009/04/12 10:18:52 lukem Exp $ */ /*- - * Copyright (c) 1997-2000,2005 The NetBSD Foundation, Inc. + * Copyright (c) 1997-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -31,7 +31,7 @@ #include #ifndef lint -__RCSID("$NetBSD: complete.c,v 1.43 2008/04/28 20:24:13 martin Exp $"); +__RCSID("$NetBSD: complete.c,v 1.46 2009/04/12 10:18:52 lukem Exp $"); #endif /* not lint */ /* @@ -80,7 +80,7 @@ complete_ambiguous(char *word, int list, StringList *words) { char insertstr[MAXPATHLEN]; char *lastmatch, *p; - int i, j; + size_t i, j; size_t matchlen, wordlen; wordlen = strlen(word); @@ -143,7 +143,7 @@ complete_command(char *word, int list) if (wordlen > strlen(c->c_name)) continue; if (strncmp(word, c->c_name, wordlen) == 0) - ftp_sl_add(words, c->c_name); + ftp_sl_add(words, ftp_strdup(c->c_name)); } rv = complete_ambiguous(word, list, words); @@ -151,7 +151,7 @@ complete_command(char *word, int list) if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } - sl_free(words, 0); + sl_free(words, 1); return (rv); } @@ -255,7 +255,7 @@ complete_option(char *word, int list) if (wordlen > strlen(o->name)) continue; if (strncmp(word, o->name, wordlen) == 0) - ftp_sl_add(words, o->name); + ftp_sl_add(words, ftp_strdup(o->name)); } rv = complete_ambiguous(word, list, words); @@ -263,7 +263,7 @@ complete_option(char *word, int list) if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } - sl_free(words, 0); + sl_free(words, 1); return (rv); } @@ -278,10 +278,13 @@ complete_remote(char *word, int list) StringList *words; char dir[MAXPATHLEN]; char *file, *cp; - int i; + size_t i; unsigned char rv; + char cmdbuf[MAX_C_NAME]; + char *dummyargv[3] = { NULL, NULL, NULL }; - char *dummyargv[] = { "complete", NULL, NULL }; + (void)strlcpy(cmdbuf, "complete", sizeof(cmdbuf)); + dummyargv[0] = cmdbuf; dummyargv[1] = dir; if ((file = strrchr(word, '/')) == NULL) { @@ -347,17 +350,17 @@ complete_remote(char *word, int list) * Generic complete routine */ unsigned char -complete(EditLine *el, int ch) +complete(EditLine *cel, int ch) { static char word[FTPBUFLEN]; - static int lastc_argc, lastc_argo; + static size_t lastc_argc, lastc_argo; struct cmd *c; const LineInfo *lf; - int celems, dolist, cmpltype; - size_t len; + int dolist, cmpltype; + size_t celems, len; - lf = el_line(el); + lf = el_line(cel); len = lf->lastchar - lf->buffer; if (len >= sizeof(line)) return (CC_ERROR); @@ -376,7 +379,7 @@ complete(EditLine *el, int ch) && strncmp(word, margv[cursor_argc] ? margv[cursor_argc] : "", cursor_argo) == 0) dolist = 1; - else if (cursor_argc < margc) + else if (cursor_argc < (size_t)margc) (void)strlcpy(word, margv[cursor_argc], cursor_argo + 1); word[cursor_argo] = '\0'; diff --git a/contrib/tnftp/domacro.c b/contrib/tnftp/domacro.c index 4b76a68b44..04799bc7b9 100644 --- a/contrib/tnftp/domacro.c +++ b/contrib/tnftp/domacro.c @@ -1,4 +1,4 @@ -/* $NetBSD: domacro.c,v 1.21 2005/06/29 02:31:19 christos Exp $ */ +/* $NetBSD: domacro.c,v 1.22 2009/04/12 10:18:52 lukem Exp $ */ /* * Copyright (c) 1985, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)domacro.c 8.3 (Berkeley) 4/2/94"; #else -__RCSID("$NetBSD: domacro.c,v 1.21 2005/06/29 02:31:19 christos Exp $"); +__RCSID("$NetBSD: domacro.c,v 1.22 2009/04/12 10:18:52 lukem Exp $"); #endif #endif /* not lint */ @@ -50,6 +50,7 @@ domacro(int argc, char *argv[]) int i, j, count = 2, loopflg = 0; char *cp1, *cp2, line2[FTPBUFLEN]; struct cmd *c; + char cmdbuf[MAX_C_NAME]; if ((argc == 0 && argv != NULL) || (argc < 2 && !another(&argc, &argv, "macro name"))) { @@ -126,7 +127,8 @@ domacro(int argc, char *argv[]) fputs(line, ttyout); putc('\n', ttyout); } - margv[0] = c->c_name; + (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf)); + margv[0] = cmdbuf; (*c->c_handler)(margc, margv); if (bell && c->c_bell) (void)putc('\007', ttyout); diff --git a/contrib/tnftp/extern.h b/contrib/tnftp/extern.h index 98518ec368..30341fa66e 100644 --- a/contrib/tnftp/extern.h +++ b/contrib/tnftp/extern.h @@ -1,7 +1,7 @@ -/* $NetBSD: extern.h,v 1.75 2008/05/10 00:05:31 skd Exp $ */ +/* $NetBSD: extern.h,v 1.78 2010/03/04 21:40:53 lukem Exp $ */ /*- - * Copyright (c) 1996-2008 The NetBSD Foundation, Inc. + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -134,7 +134,7 @@ int ftp_login(const char *, const char *, const char *); void get(int, char **); struct cmd *getcmd(const char *); int getit(int, char **, int, const char *); -int getline(FILE *, char *, size_t, const char **); +int get_line(FILE *, char *, size_t, const char **); struct option *getoption(const char *); char *getoptionvalue(const char *); void getremoteinfo(void); @@ -142,7 +142,7 @@ int getreply(int); char *globulize(const char *); char *gunique(const char *); void help(int, char **); -char *hookup(char *, char *); +char *hookup(const char *, const char *); void idlecmd(int, char **); int initconn(void); void intr(int); @@ -166,6 +166,7 @@ const char *onoff(int); void opts(int, char **); void newer(int, char **); void page(int, char **); +const char *parse_rfc2616time(struct tm *, const char *); int parserate(int, char **, int); char *prompt(void); void proxabort(int); @@ -228,6 +229,7 @@ void settype(int, char **); void setupsockbufsize(int); void setverbose(int, char **); void setxferbuf(int, char **); +void set_option(const char *, const char *, int); void shell(int, char **); void site(int, char **); void sizecmd(int, char **); diff --git a/contrib/tnftp/fetch.c b/contrib/tnftp/fetch.c index 351b1797cc..67b2442452 100644 --- a/contrib/tnftp/fetch.c +++ b/contrib/tnftp/fetch.c @@ -1,7 +1,7 @@ -/* $NetBSD: fetch.c,v 1.185 2008/04/28 20:24:13 martin Exp $ */ +/* $NetBSD: fetch.c,v 1.193 2010/03/05 07:41:10 lukem Exp $ */ /*- - * Copyright (c) 1997-2008 The NetBSD Foundation, Inc. + * Copyright (c) 1997-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -34,7 +34,7 @@ #include #ifndef lint -__RCSID("$NetBSD: fetch.c,v 1.185 2008/04/28 20:24:13 martin Exp $"); +__RCSID("$NetBSD: fetch.c,v 1.193 2010/03/05 07:41:10 lukem Exp $"); #endif /* not lint */ /* @@ -141,7 +141,8 @@ auth_url(const char *challenge, char **response, const char *guser, { const char *cp, *scheme, *errormsg; char *ep, *clear, *realm; - char user[BUFSIZ], *pass; + char uuser[BUFSIZ], *gotpass; + const char *upass; int rval; size_t len, clen, rlen; @@ -150,6 +151,7 @@ auth_url(const char *challenge, char **response, const char *guser, rval = -1; cp = challenge; scheme = "Basic"; /* only support Basic authentication */ + gotpass = NULL; DPRINTF("auth_url: challenge `%s'\n", challenge); @@ -169,8 +171,7 @@ auth_url(const char *challenge, char **response, const char *guser, } /* XXX: need to improve quoted-string parsing to support \ quoting, etc. */ if ((ep = strchr(cp, '\"')) != NULL) { - size_t len = ep - cp; - + len = ep - cp; realm = (char *)ftp_malloc(len + 1); (void)strlcpy(realm, cp, len + 1); } else { @@ -181,32 +182,33 @@ auth_url(const char *challenge, char **response, const char *guser, fprintf(ttyout, "Username for `%s': ", realm); if (guser != NULL) { - (void)strlcpy(user, guser, sizeof(user)); - fprintf(ttyout, "%s\n", user); + (void)strlcpy(uuser, guser, sizeof(uuser)); + fprintf(ttyout, "%s\n", uuser); } else { (void)fflush(ttyout); - if (getline(stdin, user, sizeof(user), &errormsg) < 0) { + if (get_line(stdin, uuser, sizeof(uuser), &errormsg) < 0) { warnx("%s; can't authenticate", errormsg); goto cleanup_auth_url; } } if (gpass != NULL) - pass = (char *)gpass; + upass = gpass; else { - pass = getpass("Password: "); - if (pass == NULL) { + gotpass = getpass("Password: "); + if (gotpass == NULL) { warnx("Can't read password"); goto cleanup_auth_url; } + upass = gotpass; } - clen = strlen(user) + strlen(pass) + 2; /* user + ":" + pass + "\0" */ + clen = strlen(uuser) + strlen(upass) + 2; /* user + ":" + pass + "\0" */ clear = (char *)ftp_malloc(clen); - (void)strlcpy(clear, user, clen); + (void)strlcpy(clear, uuser, clen); (void)strlcat(clear, ":", clen); - (void)strlcat(clear, pass, clen); - if (gpass == NULL) - memset(pass, 0, strlen(pass)); + (void)strlcat(clear, upass, clen); + if (gotpass) + memset(gotpass, 0, strlen(gotpass)); /* scheme + " " + enc + "\0" */ rlen = strlen(scheme) + 1 + (clen + 2) * 4 / 3 + 1; @@ -235,7 +237,7 @@ base64_encode(const unsigned char *clear, size_t len, unsigned char *encoded) static const unsigned char enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; unsigned char *cp; - int i; + size_t i; cp = encoded; for (i = 0; i < len; i += 3) { @@ -279,7 +281,7 @@ url_decode(char *url) /* - * Parse URL of form (per RFC3986): + * Parse URL of form (per RFC 3986): * ://[[:]@][:][/] * Returns -1 if a parse error occurred, otherwise 0. * It's the caller's responsibility to url_decode() the returned @@ -289,7 +291,7 @@ url_decode(char *url) * malloc(3)ed strings of the relevant section, and port to * the number given, or ftpport if ftp://, or httpport if http://. * - * XXX: this is not totally RFC3986 compliant; will have the + * XXX: this is not totally RFC 3986 compliant; will have the * leading `/' unless it's an ftp:// URL, as this makes things easier * for file:// and http:// URLs. ftp:// URLs have the `/' between the * host and the URL-path removed, but any additional leading slashes @@ -310,43 +312,43 @@ url_decode(char *url) * "ftp://host//dir/file" "/dir/file" */ static int -parse_url(const char *url, const char *desc, url_t *type, - char **user, char **pass, char **host, char **port, +parse_url(const char *url, const char *desc, url_t *utype, + char **uuser, char **pass, char **host, char **port, in_port_t *portnum, char **path) { - const char *origurl; - char *cp, *ep, *thost, *tport; + const char *origurl, *tport; + char *cp, *ep, *thost; size_t len; - if (url == NULL || desc == NULL || type == NULL || user == NULL + if (url == NULL || desc == NULL || utype == NULL || uuser == NULL || pass == NULL || host == NULL || port == NULL || portnum == NULL || path == NULL) errx(1, "parse_url: invoked with NULL argument!"); DPRINTF("parse_url: %s `%s'\n", desc, url); origurl = url; - *type = UNKNOWN_URL_T; - *user = *pass = *host = *port = *path = NULL; + *utype = UNKNOWN_URL_T; + *uuser = *pass = *host = *port = *path = NULL; *portnum = 0; tport = NULL; if (STRNEQUAL(url, HTTP_URL)) { url += sizeof(HTTP_URL) - 1; - *type = HTTP_URL_T; + *utype = HTTP_URL_T; *portnum = HTTP_PORT; tport = httpport; } else if (STRNEQUAL(url, FTP_URL)) { url += sizeof(FTP_URL) - 1; - *type = FTP_URL_T; + *utype = FTP_URL_T; *portnum = FTP_PORT; tport = ftpport; } else if (STRNEQUAL(url, FILE_URL)) { url += sizeof(FILE_URL) - 1; - *type = FILE_URL_T; + *utype = FILE_URL_T; } else { warnx("Invalid %s `%s'", desc, url); cleanup_parse_url: - FREEPTR(*user); + FREEPTR(*uuser); if (*pass != NULL) memset(*pass, 0, strlen(*pass)); FREEPTR(*pass); @@ -367,24 +369,24 @@ parse_url(const char *url, const char *desc, url_t *type, len = ep - url; thost = (char *)ftp_malloc(len + 1); (void)strlcpy(thost, url, len + 1); - if (*type == FTP_URL_T) /* skip first / for ftp URLs */ + if (*utype == FTP_URL_T) /* skip first / for ftp URLs */ ep++; *path = ftp_strdup(ep); } cp = strchr(thost, '@'); /* look for user[:pass]@ in URLs */ if (cp != NULL) { - if (*type == FTP_URL_T) + if (*utype == FTP_URL_T) anonftp = 0; /* disable anonftp */ - *user = thost; + *uuser = thost; *cp = '\0'; thost = ftp_strdup(cp + 1); - cp = strchr(*user, ':'); + cp = strchr(*uuser, ':'); if (cp != NULL) { *cp = '\0'; *pass = ftp_strdup(cp + 1); } - url_decode(*user); + url_decode(*uuser); if (*pass) url_decode(*pass); } @@ -392,7 +394,7 @@ parse_url(const char *url, const char *desc, url_t *type, #ifdef INET6 /* * Check if thost is an encoded IPv6 address, as per - * RFC3986: + * RFC 3986: * `[' ipv6-address ']' */ if (*thost == '[') { @@ -441,14 +443,14 @@ parse_url(const char *url, const char *desc, url_t *type, *port = ftp_strdup(tport); if (*path == NULL) { const char *emptypath = "/"; - if (*type == FTP_URL_T) /* skip first / for ftp URLs */ + if (*utype == FTP_URL_T) /* skip first / for ftp URLs */ emptypath++; *path = ftp_strdup(emptypath); } DPRINTF("parse_url: user `%s' pass `%s' host %s port %s(%d) " "path `%s'\n", - STRorNULL(*user), STRorNULL(*pass), + STRorNULL(*uuser), STRorNULL(*pass), STRorNULL(*host), STRorNULL(*port), *portnum ? *portnum : -1, STRorNULL(*path)); @@ -478,7 +480,8 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) int volatile isproxy; int volatile rval; int volatile hcode; - size_t len; + int len; + size_t flen; static size_t bufsize; static char *xferbuf; const char *cp, *token; @@ -489,7 +492,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) char *volatile auth; char *volatile location; char *volatile message; - char *user, *pass, *host, *port, *path; + char *uuser, *pass, *host, *port, *path; char *volatile decodedpath; char *puser, *ppass, *useragent; off_t hashbytes, rangestart, rangeend, entitylen; @@ -510,9 +513,9 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) auth = location = message = NULL; ischunked = isproxy = hcode = 0; rval = 1; - user = pass = host = path = decodedpath = puser = ppass = NULL; + uuser = pass = host = path = decodedpath = puser = ppass = NULL; - if (parse_url(url, "URL", &urltype, &user, &pass, &host, &port, + if (parse_url(url, "URL", &urltype, &uuser, &pass, &host, &port, &portnum, &path) == -1) goto cleanup_fetch_url; @@ -591,7 +594,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) fputs("\n", ttyout); } } else { /* ftp:// or http:// URLs */ - char *leading; + const char *leading; int hasleading; if (proxyenv == NULL) { @@ -831,7 +834,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) } /* Read the response */ - len = getline(fin, buf, sizeof(buf), &errormsg); + len = get_line(fin, buf, sizeof(buf), &errormsg); if (len < 0) { if (*errormsg == '\n') errormsg++; @@ -855,7 +858,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) /* Read the rest of the header. */ while (1) { - len = getline(fin, buf, sizeof(buf), &errormsg); + len = get_line(fin, buf, sizeof(buf), &errormsg); if (len < 0) { if (*errormsg == '\n') errormsg++; @@ -931,28 +934,18 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) } else if (match_token(&cp, "Last-Modified:")) { struct tm parsed; - char *t; + const char *t; memset(&parsed, 0, sizeof(parsed)); - /* RFC1123 */ - if ((t = strptime(cp, - "%a, %d %b %Y %H:%M:%S GMT", - &parsed)) - /* RFC0850 */ - || (t = strptime(cp, - "%a, %d-%b-%y %H:%M:%S GMT", - &parsed)) - /* asctime */ - || (t = strptime(cp, - "%a, %b %d %H:%M:%S %Y", - &parsed))) { + t = parse_rfc2616time(&parsed, cp); + if (t != NULL) { parsed.tm_isdst = -1; if (*t == '\0') mtime = timegm(&parsed); #ifndef NO_DEBUG if (ftp_debug && mtime != -1) { fprintf(ttyout, - "parsed date as: %s", + "parsed time as: %s", rfc2822time(localtime(&mtime))); } #endif @@ -1040,7 +1033,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) if (hcode == 401) { authp = &wwwauth; - auser = user; + auser = uuser; apass = pass; } else { authp = &proxyauth; @@ -1060,7 +1053,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) fprintf(ttyout, "Authorization failed. Retry (y/n)? "); - if (getline(stdin, reply, sizeof(reply), NULL) + if (get_line(stdin, reply, sizeof(reply), NULL) < 0) { goto cleanup_fetch_url; } @@ -1132,7 +1125,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) (void)xsignal(SIGQUIT, psummary); oldintr = xsignal(SIGINT, aborthttp); - if (rcvbuf_size > bufsize) { + if ((size_t)rcvbuf_size > bufsize) { if (xferbuf) (void)free(xferbuf); bufsize = rcvbuf_size; @@ -1201,18 +1194,18 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) if (rate_get) (void)gettimeofday(&then, NULL); - bufrem = rate_get ? rate_get : bufsize; + bufrem = rate_get ? rate_get : (off_t)bufsize; if (ischunked) bufrem = MIN(chunksize, bufrem); while (bufrem > 0) { - len = fread(xferbuf, sizeof(char), - MIN(bufsize, bufrem), fin); - if (len <= 0) + flen = fread(xferbuf, sizeof(char), + MIN((off_t)bufsize, bufrem), fin); + if (flen <= 0) goto chunkdone; - bytes += len; - bufrem -= len; - if (fwrite(xferbuf, sizeof(char), len, fout) - != len) { + bytes += flen; + bufrem -= flen; + if (fwrite(xferbuf, sizeof(char), flen, fout) + != flen) { warn("Writing `%s'", savefile); goto cleanup_fetch_url; } @@ -1224,7 +1217,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) (void)fflush(ttyout); } if (ischunked) { - chunksize -= len; + chunksize -= flen; if (chunksize <= 0) break; } @@ -1309,7 +1302,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) if (res0) freeaddrinfo(res0); FREEPTR(savefile); - FREEPTR(user); + FREEPTR(uuser); if (pass != NULL) memset(pass, 0, strlen(pass)); FREEPTR(pass); @@ -1352,23 +1345,25 @@ static int fetch_ftp(const char *url) { char *cp, *xargv[5], rempath[MAXPATHLEN]; - char *host, *path, *dir, *file, *user, *pass; + char *host, *path, *dir, *file, *uuser, *pass; char *port; - int dirhasglob, filehasglob, rval, type, xargc; + char cmdbuf[MAXPATHLEN]; + char dirbuf[4]; + int dirhasglob, filehasglob, rval, transtype, xargc; int oanonftp, oautologin; in_port_t portnum; url_t urltype; DPRINTF("fetch_ftp: `%s'\n", url); - host = path = dir = file = user = pass = NULL; + host = path = dir = file = uuser = pass = NULL; port = NULL; rval = 1; - type = TYPE_I; + transtype = TYPE_I; if (STRNEQUAL(url, FTP_URL)) { - if ((parse_url(url, "URL", &urltype, &user, &pass, + if ((parse_url(url, "URL", &urltype, &uuser, &pass, &host, &port, &portnum, &path) == -1) || - (user != NULL && *user == '\0') || + (uuser != NULL && *uuser == '\0') || EMPTYSTRING(host)) { warnx("Invalid URL `%s'", url); goto cleanup_fetch_ftp; @@ -1381,9 +1376,9 @@ fetch_ftp(const char *url) /* check for trailing ';type=[aid]' */ if (! EMPTYSTRING(path) && (cp = strrchr(path, ';')) != NULL) { if (strcasecmp(cp, ";type=a") == 0) - type = TYPE_A; + transtype = TYPE_A; else if (strcasecmp(cp, ";type=i") == 0) - type = TYPE_I; + transtype = TYPE_I; else if (strcasecmp(cp, ";type=d") == 0) { warnx( "Directory listing via a URL is not supported"); @@ -1401,7 +1396,7 @@ fetch_ftp(const char *url) cp = strchr(host, '@'); if (cp != NULL) { *cp = '\0'; - user = host; + uuser = host; anonftp = 0; /* disable anonftp */ host = ftp_strdup(cp + 1); } @@ -1442,7 +1437,8 @@ fetch_ftp(const char *url) cp = strrchr(dir, '/'); if (cp == dir && urltype == CLASSIC_URL_T) { file = cp + 1; - dir = "/"; + (void)strlcpy(dirbuf, "/", sizeof(dirbuf)); + dir = dirbuf; } else if (cp != NULL) { *cp++ = '\0'; file = cp; @@ -1458,7 +1454,7 @@ fetch_ftp(const char *url) } DPRINTF("fetch_ftp: user `%s' pass `%s' host %s port %s " "path `%s' dir `%s' file `%s'\n", - STRorNULL(user), STRorNULL(pass), + STRorNULL(uuser), STRorNULL(pass), STRorNULL(host), STRorNULL(port), STRorNULL(path), STRorNULL(dir), STRorNULL(file)); @@ -1475,7 +1471,8 @@ fetch_ftp(const char *url) if (connected) disconnect(0, NULL); anonftp = oanonftp; - xargv[0] = (char *)getprogname(); /* XXX discards const */ + (void)strlcpy(cmdbuf, getprogname(), sizeof(cmdbuf)); + xargv[0] = cmdbuf; xargv[1] = host; xargv[2] = NULL; xargc = 2; @@ -1490,12 +1487,13 @@ fetch_ftp(const char *url) setpeer(xargc, xargv); autologin = oautologin; if ((connected == 0) || - (connected == 1 && !ftp_login(host, user, pass))) { - warnx("Can't connect or login to host `%s:%s'", host, port); + (connected == 1 && !ftp_login(host, uuser, pass))) { + warnx("Can't connect or login to host `%s:%s'", + host, port ? port : "?"); goto cleanup_fetch_ftp; } - switch (type) { + switch (transtype) { case TYPE_A: setascii(1, xargv); break; @@ -1503,7 +1501,7 @@ fetch_ftp(const char *url) setbinary(1, xargv); break; default: - errx(1, "fetch_ftp: unknown transfer type %d", type); + errx(1, "fetch_ftp: unknown transfer type %d", transtype); } /* @@ -1522,12 +1520,12 @@ fetch_ftp(const char *url) * directories in one step. * * If we are dealing with an `ftp://host/path' URL - * (urltype is FTP_URL_T), then RFC3986 says we need to + * (urltype is FTP_URL_T), then RFC 3986 says we need to * send a separate CWD command for each unescaped "/" * in the path, and we have to interpret %hex escaping * *after* we find the slashes. It's possible to get * empty components here, (from multiple adjacent - * slashes in the path) and RFC3986 says that we should + * slashes in the path) and RFC 3986 says that we should * still do `CWD ' (with a null argument) in such cases. * * Many ftp servers don't support `CWD ', so if there's an @@ -1588,7 +1586,8 @@ fetch_ftp(const char *url) DPRINTF("fetch_ftp: dir `%s', nextpart `%s'\n", STRorNULL(dir), STRorNULL(nextpart)); if (urltype == FTP_URL_T || *dir != '\0') { - xargv[0] = "cd"; + (void)strlcpy(cmdbuf, "cd", sizeof(cmdbuf)); + xargv[0] = cmdbuf; xargv[1] = dir; xargv[2] = NULL; dirchange = 0; @@ -1598,8 +1597,8 @@ fetch_ftp(const char *url) fprintf(stderr, "\n" "ftp: The `CWD ' command (without a directory), which is required by\n" -" RFC3986 to support the empty directory in the URL pathname (`//'),\n" -" conflicts with the server's conformance to RFC0959.\n" +" RFC 3986 to support the empty directory in the URL pathname (`//'),\n" +" conflicts with the server's conformance to RFC 959.\n" " Try the same URL without the `//' in the URL pathname.\n" "\n"); goto cleanup_fetch_ftp; @@ -1623,7 +1622,8 @@ fetch_ftp(const char *url) /* Fetch the file(s). */ xargc = 2; - xargv[0] = "get"; + (void)strlcpy(cmdbuf, "get", sizeof(cmdbuf)); + xargv[0] = cmdbuf; xargv[1] = file; xargv[2] = NULL; if (dirhasglob || filehasglob) { @@ -1632,9 +1632,10 @@ fetch_ftp(const char *url) ointeractive = interactive; interactive = 0; if (restartautofetch) - xargv[0] = "mreget"; + (void)strlcpy(cmdbuf, "mreget", sizeof(cmdbuf)); else - xargv[0] = "mget"; + (void)strlcpy(cmdbuf, "mget", sizeof(cmdbuf)); + xargv[0] = cmdbuf; mget(xargc, xargv); interactive = ointeractive; } else { @@ -1661,7 +1662,7 @@ fetch_ftp(const char *url) FREEPTR(port); FREEPTR(host); FREEPTR(path); - FREEPTR(user); + FREEPTR(uuser); if (pass) memset(pass, 0, strlen(pass)); FREEPTR(pass); @@ -1683,7 +1684,7 @@ fetch_ftp(const char *url) static int go_fetch(const char *url) { - char *proxy; + char *proxyenv; #ifndef NO_ABOUT /* @@ -1732,8 +1733,8 @@ go_fetch(const char *url) * If ftpproxy is set with an FTP URL, use fetch_url() * Othewise, use fetch_ftp(). */ - proxy = getoptionvalue("ftp_proxy"); - if (!EMPTYSTRING(proxy) && STRNEQUAL(url, FTP_URL)) + proxyenv = getoptionvalue("ftp_proxy"); + if (!EMPTYSTRING(proxyenv) && STRNEQUAL(url, FTP_URL)) return (fetch_url(url, NULL, NULL, NULL)); return (fetch_ftp(url)); @@ -1805,10 +1806,12 @@ auto_put(int argc, char **argv, const char *uploadserver) char *uargv[4], *path, *pathsep; int uargc, rval, argpos; size_t len; + char cmdbuf[MAX_C_NAME]; - uargc = 0; - uargv[uargc++] = "mput"; - uargv[uargc++] = argv[0]; + (void)strlcpy(cmdbuf, "mput", sizeof(cmdbuf)); + uargv[0] = cmdbuf; + uargv[1] = argv[0]; + uargc = 2; uargv[2] = uargv[3] = NULL; pathsep = NULL; rval = 1; @@ -1828,7 +1831,8 @@ auto_put(int argc, char **argv, const char *uploadserver) (void)strlcpy(path, uploadserver, len); (void)strlcat(path, "/", len); } else { /* single file to upload */ - uargv[0] = "put"; + (void)strlcpy(cmdbuf, "put", sizeof(cmdbuf)); + uargv[0] = cmdbuf; pathsep = strrchr(path, '/'); if (pathsep == NULL) { pathsep = strrchr(path, ':'); diff --git a/contrib/tnftp/ftp.1 b/contrib/tnftp/ftp.1 index 1cfd9463fd..8c8290365a 100644 --- a/contrib/tnftp/ftp.1 +++ b/contrib/tnftp/ftp.1 @@ -1,6 +1,6 @@ -.\" $NetBSD: ftp.1,v 1.126 2008/05/13 09:33:36 wiz Exp $ +.\" $NetBSD: ftp.1,v 1.131 2010/03/05 07:41:10 lukem Exp $ .\" -.\" Copyright (c) 1996-2007 The NetBSD Foundation, Inc. +.\" Copyright (c) 1996-2010 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -57,13 +57,12 @@ .\" .\" @(#)ftp.1 8.3 (Berkeley) 10/9/94 .\" -.Dd May 10, 2008 +.Dd March 5, 2010 .Dt FTP 1 .Os .Sh NAME .Nm ftp -.Nd -Internet file transfer program +.Nd Internet file transfer program .Sh SYNOPSIS .Nm .Op Fl 46AadefginpRtVv @@ -282,14 +281,7 @@ Uses as the local IP address for all connections. .It Fl t Enables packet tracing. -.It Xo -.Fl T -.Sm off -.Ar direction , -.Ar maximum -.Op , Ar increment -.Sm on -.Xc +.It Fl T Ar direction Ns , Ns Ar maximum Ns Oo , Ns Ar increment Oc Set the maximum transfer rate for .Ar direction to @@ -493,7 +485,8 @@ Toggle the use of the extended .Dv EPSV and .Dv EPRT -commands on all IP, IPv4, and IPv6 connections respectively. First try +commands on all IP, IPv4, and IPv6 connections respectively. +First try .Dv EPSV / .Dv EPRT , and then @@ -784,7 +777,7 @@ mode is .Dq stream . .It Ic modtime Ar remote-file Show the last modification time of the file on the remote machine, in -.Li RFC2822 +.Li RFC 2822 format. .It Ic more Ar file A synonym for @@ -1005,7 +998,7 @@ traffic. servers are required to support the .Dv PASV command by -.Li RFC1123 , +.Li RFC 1123 , some do not.) .It Ic pdir Op Ar remote-path Perform @@ -1153,10 +1146,7 @@ A synonym for The arguments specified are sent, verbatim, to the remote .Tn FTP server. -.It Xo -.Ic rate Ar direction -.Op Ar maximum Op Ar increment -.Xc +.It Ic rate Ar direction Oo Ar maximum Oo Ar increment Oc Oc Throttle the maximum transfer rate to .Ar maximum bytes/second. @@ -1179,7 +1169,6 @@ Outgoing transfers. can be modified on the fly by .Ar increment bytes (default: 1024) each time a given signal is received: -.B .Bl -tag -width "SIGUSR1" -offset indent .It Dv SIGUSR1 Increment @@ -1441,10 +1430,7 @@ for more information. .It Ic usage Ar command Print the usage message for .Ar command . -.It Xo -.Ic user Ar user-name -.Op Ar password Op Ar account -.Xc +.It Ic user Ar user-name Oo Ar password Oo Ar account Oc Oc Identify yourself to the remote .Tn FTP server. @@ -1546,14 +1532,8 @@ on the command line. The following formats are valid syntax for an auto-fetch element: .Bl -tag -width "FOO " .\" [user@]host:[path][/] -.It Xo -.Sm off -.Op Ar user Li \&@ -.Ar host Li \&: -.Op Ar path -.Op Li / -.Sm on -.Xc +.It Oo Ar user Ns Li \&@ Oc Ns Ar host Ns Li \&: Ns Oo Ar path Oc \ +Ns Oo Li / Oc .Dq Classic .Tn FTP format. @@ -1578,18 +1558,9 @@ in the current directory. Otherwise, the full remote name is used as the local name, relative to the local root directory. .\" ftp://[user[:password]@]host[:port]/path[/][;type=X] -.It Xo -.Sm off -.Li ftp:// -.Oo Ar user -.Op Li \&: Ar password -.Li \&@ Oc -.Ar host Oo Li \&: Ar port Oc -.Li / Ar path -.Op Li / -.Op Li ;type= Ar X -.Sm on -.Xc +.It Li ftp:// Ns Oo Ar user Ns Oo Ns Li \&: Ns Ar password Oc Ns Li \&@ Oc \ +Ns Ar host Ns Oo Li \&: Ns Ar port Oc Ns Li / Ns Ar path Ns Oo Li / Oc \ +Ns Oo Li ;type= Ns Ar X Oc An .Tn FTP URL, retrieved using the @@ -1620,7 +1591,7 @@ ascii or binary (respectively). The default transfer type is binary. .Pp In order to be compliant with -.Li RFC3986 , +.Li RFC 3986 , .Nm interprets the .Ar path @@ -1673,7 +1644,7 @@ Any .Sq Li \&% Ns Ar XX codes (per -.Li RFC3986 ) +.Li RFC 3986 ) within the path components are decoded, with .Ar XX representing a character code in hexadecimal. @@ -1760,16 +1731,8 @@ intermediate directories that is used in the equivalent of a command. .El .\" http://[user[:password]@]host[:port]/path -.It Xo -.Sm off -.Li http:// -.Oo Ar user -.Op Li \&: Ar password -.Li \&@ Oc -.Ar host Oo Li \&: Ar port Oc -.Li / Ar path -.Sm on -.Xc +.It Li http:// Ns Oo Ar user Ns Oo Li \&: Ns Ar password Oc Ns Li \&@ Oc \ +Ns Ar host Ns Oo Li \&: Ns Ar port Oc Ns Li / Ns Ar path An .Tn HTTP URL, retrieved using the @@ -1790,21 +1753,12 @@ and .Sq password ) is in the URL, use them for the first attempt to authenticate. .\" file:///path -.It Xo -.Sm off -.Li file:/// Ar path -.Sm on -.Xc +.It Li file:/// Ns Ar path A local URL, copied from .Pa / Ns Ar path on the local host. .\" about: -.It Xo -.Sm off -.Li about: -.Ar topic -.Sm on -.Xc +.It Li about: Ns Ar topic Display information regarding .Ar topic ; no file is retrieved for this auto-fetched element. @@ -2190,14 +2144,7 @@ information: .It Li \&%/ The current remote working directory. .\" %c[[0]n], %.[[0]n] -.It Xo -.Sm off -.Li \&%c -.Op Oo Li 0 Oc Ar n Ns , -.Li \&%. -.Op Oo Li 0 Oc Ar n -.Sm on -.Xc +.It \&%c Ns Oo Oo Li 0 Oc Ns Ar n Oc , Ns Li \&%. Ns Oo Oo Li 0 Oc Ns Ar n Oc The trailing component of the current remote working directory, or .Em n trailing components if a digit @@ -2338,7 +2285,7 @@ URL characters are required in the username or password or .Sq / ) , encode them with -.Li RFC3986 +.Li RFC 3986 .Sq Li \&% Ns Ar XX encoding. .Pp @@ -2383,23 +2330,23 @@ for an example of how to make this automatic. .Nm attempts to be compliant with: .Bl -tag -offset indent -width 8n -.It Li RFC0959 +.It Li RFC 959 .Em File Transfer Protocol -.It Li RFC1123 +.It Li RFC 1123 .Em Requirements for Internet Hosts - Application and Support -.It Li RFC1635 +.It Li RFC 1635 .Em How to Use Anonymous FTP -.It Li RFC2389 +.It Li RFC 2389 .Em Feature negotiation mechanism for the File Transfer Protocol -.It Li RFC2428 +.It Li RFC 2428 .Em FTP Extensions for IPv6 and NATs -.It Li RFC2616 +.It Li RFC 2616 .Em Hypertext Transfer Protocol -- HTTP/1.1 -.It Li RFC2822 +.It Li RFC 2822 .Em Internet Message Format -.It Li RFC3659 +.It Li RFC 3659 .Em Extensions to FTP -.It Li RFC3986 +.It Li RFC 3986 .Em Uniform Resource Identifier (URI) .El .Sh HISTORY diff --git a/contrib/tnftp/ftp.c b/contrib/tnftp/ftp.c index e26ea10d73..3eeb678a67 100644 --- a/contrib/tnftp/ftp.c +++ b/contrib/tnftp/ftp.c @@ -1,7 +1,7 @@ -/* $NetBSD: ftp.c,v 1.156 2008/05/10 00:05:31 skd Exp $ */ +/* $NetBSD: ftp.c,v 1.160 2010/03/05 07:41:10 lukem Exp $ */ /*- - * Copyright (c) 1996-2008 The NetBSD Foundation, Inc. + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -92,7 +92,7 @@ #if 0 static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94"; #else -__RCSID("$NetBSD: ftp.c,v 1.156 2008/05/10 00:05:31 skd Exp $"); +__RCSID("$NetBSD: ftp.c,v 1.160 2010/03/05 07:41:10 lukem Exp $"); #endif #endif /* not lint */ @@ -155,7 +155,7 @@ struct sockinet { struct sockinet myctladdr, hisctladdr, data_addr; char * -hookup(char *host, char *port) +hookup(const char *host, const char *port) { int s = -1, error; struct addrinfo hints, *res, *res0; @@ -362,7 +362,7 @@ int getreply(int expecteof) { char current_line[BUFSIZ]; /* last line of previous reply */ - int c, n, line; + int c, n, lineno; int dig; int originalcode = 0, continuation = 0; sigfunc oldsigint, oldsigalrm; @@ -375,7 +375,7 @@ getreply(int expecteof) oldsigint = xsignal(SIGINT, cmdabort); oldsigalrm = xsignal(SIGALRM, cmdtimeout); - for (line = 0 ;; line++) { + for (lineno = 0 ;; lineno++) { dig = n = code = 0; cp = current_line; while (alarmtimer(quit_time ? quit_time : 60), @@ -480,10 +480,10 @@ getreply(int expecteof) if (cp[-1] == '\r') cp[-1] = '\0'; *cp = '\0'; - if (line == 0) + if (lineno == 0) (void)strlcpy(reply_string, current_line, sizeof(reply_string)); - if (line > 0 && code == 0 && reply_callback != NULL) + if (lineno > 0 && code == 0 && reply_callback != NULL) (*reply_callback)(current_line); if (continuation && code != originalcode) { if (originalcode == 0) @@ -507,14 +507,14 @@ getreply(int expecteof) } static int -empty(FILE *cin, FILE *din, int sec) +empty(FILE *ecin, FILE *din, int sec) { int nr, nfd; struct pollfd pfd[2]; nfd = 0; - if (cin) { - pfd[nfd].fd = fileno(cin); + if (ecin) { + pfd[nfd].fd = fileno(ecin); pfd[nfd++].events = POLLIN; } @@ -528,7 +528,7 @@ empty(FILE *cin, FILE *din, int sec) nr = 0; nfd = 0; - if (cin) + if (ecin) nr |= (pfd[nfd++].revents & POLLIN) ? 1 : 0; if (din) nr |= (pfd[nfd++].revents & POLLIN) ? 2 : 0; @@ -598,7 +598,7 @@ copy_bytes(int infd, int outfd, char *buf, size_t bufsize, /* copy bufchunk at a time */ bufrem = bufchunk; while (bufrem > 0) { - inc = read(infd, buf, MIN(bufsize, bufrem)); + inc = read(infd, buf, MIN((off_t)bufsize, bufrem)); if (inc <= 0) goto copy_done; bytes += inc; @@ -660,7 +660,7 @@ sendrequest(const char *cmd, const char *local, const char *remote, sigfunc volatile oldintp; off_t volatile hashbytes; int hash_interval; - char *volatile lmode; + const char *lmode; static size_t bufsize; static char *buf; int oprogress; @@ -764,7 +764,7 @@ sendrequest(const char *cmd, const char *local, const char *remote, if (dout == NULL) goto abort; - if (sndbuf_size > bufsize) { + if ((size_t)sndbuf_size > bufsize) { if (buf) (void)free(buf); bufsize = sndbuf_size; @@ -805,7 +805,7 @@ sendrequest(const char *cmd, const char *local, const char *remote, } (void)putc(c, dout); bytes++; -#if 0 /* this violates RFC0959 */ +#if 0 /* this violates RFC 959 */ if (c == '\r') { (void)putc('\0', dout); bytes++; @@ -1025,7 +1025,7 @@ recvrequest(const char *cmd, const char *volatile local, const char *remote, progress = 0; preserve = 0; } - if (rcvbuf_size > bufsize) { + if ((size_t)rcvbuf_size > bufsize) { if (buf) (void)free(buf); bufsize = rcvbuf_size; @@ -1152,7 +1152,7 @@ recvrequest(const char *cmd, const char *volatile local, const char *remote, abort: /* - * abort using RFC0959 recommended IP,SYNC sequence + * abort using RFC 959 recommended IP,SYNC sequence */ if (! sigsetjmp(xferabort, 1)) { /* this is the first call */ @@ -1199,7 +1199,7 @@ initconn(void) unsigned int addr[16], port[2]; unsigned int af, hal, pal; socklen_t len; - char *pasvcmd = NULL; + const char *pasvcmd = NULL; int overbose; #ifdef INET6 @@ -1423,7 +1423,7 @@ initconn(void) data_addr.su_family = AF_INET6; data_addr.su_len = sizeof(struct sockaddr_in6); { - int i; + size_t i; for (i = 0; i < sizeof(struct in6_addr); i++) { data_addr.si_su.su_sin6.sin6_addr.s6_addr[i] = UC(addr[i]); @@ -1530,7 +1530,6 @@ initconn(void) if (sendport) { char hname[NI_MAXHOST], sname[NI_MAXSERV]; - int af; struct sockinet tmp; switch (data_addr.su_family) { @@ -1561,7 +1560,7 @@ initconn(void) overbose = verbose; if (ftp_debug == 0) verbose = -1; - result = command("EPRT |%d|%s|%s|", af, hname, + result = command("EPRT |%u|%s|%s|", af, hname, sname); verbose = overbose; if (verbose > 0 && @@ -1625,8 +1624,9 @@ initconn(void) if (data_addr.su_family == AF_INET) { on = IPTOS_THROUGHPUT; if (setsockopt(data, IPPROTO_IP, IP_TOS, - (void *)&on, sizeof(on)) == -1) + (void *)&on, sizeof(on)) == -1) { DWARN("setsockopt %s (ignored)", "IPTOS_THROUGHPUT"); + } } #endif return (0); @@ -1832,7 +1832,7 @@ proxtrans(const char *cmd, const char *local, const char *remote) sigfunc volatile oldintr; int prox_type, nfnd; int volatile secndflag; - char *volatile cmd2; + const char *volatile cmd2; oldintr = NULL; secndflag = 0; diff --git a/contrib/tnftp/ftp_var.h b/contrib/tnftp/ftp_var.h index 2c5d0531fc..db501cf2b1 100644 --- a/contrib/tnftp/ftp_var.h +++ b/contrib/tnftp/ftp_var.h @@ -1,7 +1,7 @@ -/* $NetBSD: ftp_var.h,v 1.79 2008/05/10 00:05:31 skd Exp $ */ +/* $NetBSD: ftp_var.h,v 1.81 2009/04/12 10:18:52 lukem Exp $ */ /*- - * Copyright (c) 1996-2007 The NetBSD Foundation, Inc. + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -121,7 +121,7 @@ * Format of command table. */ struct cmd { - char *c_name; /* name of command */ + const char *c_name; /* name of command */ const char *c_help; /* help string */ char c_bell; /* give bell when command completes */ char c_conn; /* must be connected to use command */ @@ -132,6 +132,8 @@ struct cmd { void (*c_handler)(int, char **); /* function to call */ }; +#define MAX_C_NAME 12 /* maximum length of cmd.c_name */ + /* * Format of macro table */ @@ -145,8 +147,8 @@ struct macel { * Format of option table */ struct option { - char *name; - char *value; + const char *name; + char *value; }; /* @@ -210,7 +212,7 @@ GLOBAL int autologin; /* establish user account on connection */ GLOBAL int proxy; /* proxy server connection active */ GLOBAL int proxflag; /* proxy connection exists */ GLOBAL int gatemode; /* use gate-ftp */ -GLOBAL char *gateserver; /* server to use for gate-ftp */ +GLOBAL const char *gateserver; /* server to use for gate-ftp */ GLOBAL int sunique; /* store files on server with unique name */ GLOBAL int runique; /* store local files with unique name */ GLOBAL int mcase; /* map upper to lower case for mget names */ @@ -245,7 +247,7 @@ GLOBAL int rate_get_incr; /* increment for get xfer rate */ GLOBAL int rate_put; /* maximum put xfer rate */ GLOBAL int rate_put_incr; /* increment for put xfer rate */ GLOBAL int retry_connect; /* seconds between retrying connection */ -GLOBAL char *tmpdir; /* temporary directory */ +GLOBAL const char *tmpdir; /* temporary directory */ GLOBAL int epsv4; /* use EPSV/EPRT on IPv4 connections */ GLOBAL int epsv4bad; /* EPSV doesn't work on the current server */ GLOBAL int epsv6; /* use EPSV/EPRT on IPv6 connections */ @@ -261,8 +263,6 @@ GLOBAL size_t cursor_argc; /* location of cursor in margv */ GLOBAL size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */ #endif /* !NO_EDITCOMPLETE */ -GLOBAL char *direction; /* direction transfer is occurring */ - GLOBAL char *hostname; /* name of host connected to */ GLOBAL int unix_server; /* server is unix, can use binary for ascii */ GLOBAL int unix_proxy; /* proxy is unix, can use binary for ascii */ @@ -271,9 +271,9 @@ GLOBAL char remotecwd[MAXPATHLEN]; /* remote dir */ GLOBAL char *username; /* name of user logged in as. (dynamic) */ GLOBAL sa_family_t family; /* address family to use for connections */ -GLOBAL char *ftpport; /* port number to use for FTP connections */ -GLOBAL char *httpport; /* port number to use for HTTP connections */ -GLOBAL char *gateport; /* port number to use for gateftp connections */ +GLOBAL const char *ftpport; /* port number to use for FTP connections */ +GLOBAL const char *httpport; /* port number to use for HTTP connections */ +GLOBAL const char *gateport; /* port number to use for gateftp connections */ GLOBAL struct addrinfo *bindai; /* local address to bind as */ GLOBAL char *outfile; /* filename to output URLs to */ diff --git a/contrib/tnftp/main.c b/contrib/tnftp/main.c index 43674f1842..3724790cda 100644 --- a/contrib/tnftp/main.c +++ b/contrib/tnftp/main.c @@ -1,7 +1,7 @@ -/* $NetBSD: main.c,v 1.109 2008/05/10 00:05:31 skd Exp $ */ +/* $NetBSD: main.c,v 1.117 2009/07/13 19:05:41 roy Exp $ */ /*- - * Copyright (c) 1996-2008 The NetBSD Foundation, Inc. + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -89,15 +89,16 @@ #include #ifndef lint -__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\ + The Regents of the University of California. All rights reserved.\ + Copyright 1996-2008 The NetBSD Foundation, Inc. All rights reserved"); #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94"; #else -__RCSID("$NetBSD: main.c,v 1.109 2008/05/10 00:05:31 skd Exp $"); +__RCSID("$NetBSD: main.c,v 1.117 2009/07/13 19:05:41 roy Exp $"); #endif #endif /* not lint */ @@ -128,7 +129,7 @@ __RCSID("$NetBSD: main.c,v 1.109 2008/05/10 00:05:31 skd Exp $"); #define NO_PROXY "no_proxy" /* env var with list of non-proxied * hosts, comma or space separated */ -static void setupoption(char *, char *, char *); +static void setupoption(const char *, const char *, const char *); int main(int, char *[]); int @@ -136,7 +137,8 @@ main(int volatile argc, char **volatile argv) { int ch, rval; struct passwd *pw; - char *cp, *ep, *anonuser, *anonpass, *upload_path, *src_addr; + char *cp, *ep, *anonpass, *upload_path, *src_addr; + const char *anonuser; int dumbterm, s, isupload; size_t len; socklen_t slen; @@ -191,7 +193,11 @@ main(int volatile argc, char **volatile argv) upload_path = NULL; isupload = 0; reply_callback = NULL; +#ifdef INET6 family = AF_UNSPEC; +#else + family = AF_INET; /* force AF_INET if no INET6 support */ +#endif netrc[0] = '\0'; cp = getenv("NETRC"); @@ -386,10 +392,12 @@ main(int volatile argc, char **volatile argv) { int targc; char *targv[6], *oac; + char cmdbuf[MAX_C_NAME]; /* look for `dir,max[,incr]' */ targc = 0; - targv[targc++] = "-T"; + (void)strlcpy(cmdbuf, "-T", sizeof(cmdbuf)); + targv[targc++] = cmdbuf; oac = ftp_strdup(optarg); while ((cp = strsep(&oac, ",")) != NULL) { @@ -538,22 +546,23 @@ main(int volatile argc, char **volatile argv) if (rval >= 0) /* -1 == connected and cd-ed */ goto sigint_or_rval_exit; } else { - char *xargv[4], *user, *host; + char *xargv[4], *uuser, *host; + char cmdbuf[MAXPATHLEN]; if ((rval = sigsetjmp(toplevel, 1))) goto sigint_or_rval_exit; (void)xsignal(SIGINT, intr); (void)xsignal(SIGPIPE, lostpeer); - user = NULL; + uuser = NULL; host = argv[0]; cp = strchr(host, '@'); if (cp) { *cp = '\0'; - user = host; + uuser = host; host = cp + 1; } - /* XXX discards const */ - xargv[0] = (char *)getprogname(); + (void)strlcpy(cmdbuf, getprogname(), sizeof(cmdbuf)); + xargv[0] = cmdbuf; xargv[1] = host; xargv[2] = argv[1]; xargv[3] = NULL; @@ -561,14 +570,14 @@ main(int volatile argc, char **volatile argv) int oautologin; oautologin = autologin; - if (user != NULL) { + if (uuser != NULL) { anonftp = 0; autologin = 0; } setpeer(argc+1, xargv); autologin = oautologin; - if (connected == 1 && user != NULL) - (void)ftp_login(host, user, NULL); + if (connected == 1 && uuser != NULL) + (void)ftp_login(host, uuser, NULL); if (!retry_connect) break; if (!connected) { @@ -602,18 +611,18 @@ main(int volatile argc, char **volatile argv) char * prompt(void) { - static char **prompt; + static char **promptopt; static char buf[MAXPATHLEN]; - if (prompt == NULL) { + if (promptopt == NULL) { struct option *o; o = getoption("prompt"); if (o == NULL) errx(1, "prompt: no such option `prompt'"); - prompt = &(o->value); + promptopt = &(o->value); } - formatbuf(buf, sizeof(buf), *prompt ? *prompt : DEFAULTPROMPT); + formatbuf(buf, sizeof(buf), *promptopt ? *promptopt : DEFAULTPROMPT); return (buf); } @@ -623,18 +632,18 @@ prompt(void) char * rprompt(void) { - static char **rprompt; + static char **rpromptopt; static char buf[MAXPATHLEN]; - if (rprompt == NULL) { + if (rpromptopt == NULL) { struct option *o; o = getoption("rprompt"); if (o == NULL) errx(1, "rprompt: no such option `rprompt'"); - rprompt = &(o->value); + rpromptopt = &(o->value); } - formatbuf(buf, sizeof(buf), *rprompt ? *rprompt : DEFAULTRPROMPT); + formatbuf(buf, sizeof(buf), *rpromptopt ? *rpromptopt : DEFAULTRPROMPT); return (buf); } @@ -648,8 +657,10 @@ cmdscanner(void) char *p; #ifndef NO_EDITCOMPLETE int ch; -#endif size_t num; +#endif + int len; + char cmdbuf[MAX_C_NAME]; for (;;) { #ifndef NO_EDITCOMPLETE @@ -662,8 +673,8 @@ cmdscanner(void) fprintf(ttyout, "%s ", p); } (void)fflush(ttyout); - num = getline(stdin, line, sizeof(line), NULL); - switch (num) { + len = get_line(stdin, line, sizeof(line), NULL); + switch (len) { case -1: /* EOF */ case -2: /* error */ if (fromatty) @@ -736,7 +747,8 @@ cmdscanner(void) continue; } confirmrest = 0; - margv[0] = c->c_name; + (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf)); + margv[0] = cmdbuf; (*c->c_handler)(margc, margv); if (bell && c->c_bell) (void)putc('\007', ttyout); @@ -830,6 +842,8 @@ makeargv(void) char * slurpstring(void) { + static char bangstr[2] = { '!', '\0' }; + static char dollarstr[2] = { '$', '\0' }; int got_one = 0; char *sb = stringbase; char *ap = argbase; @@ -840,7 +854,7 @@ slurpstring(void) case 0: slrflag++; INC_CHKCURSOR(stringbase); - return ((*sb == '!') ? "!" : "$"); + return ((*sb == '!') ? bangstr : dollarstr); /* NOTREACHED */ case 1: slrflag++; @@ -963,7 +977,8 @@ void help(int argc, char *argv[]) { struct cmd *c; - char *nargv[1], *p, *cmd; + char *nargv[1], *cmd; + const char *p; int isusage; cmd = argv[0]; @@ -981,9 +996,9 @@ help(int argc, char *argv[]) proxy ? "Proxy c" : "C"); for (c = cmdtab; (p = c->c_name) != NULL; c++) if (!proxy || c->c_proxy) - ftp_sl_add(buf, p); + ftp_sl_add(buf, ftp_strdup(p)); list_vertical(buf); - sl_free(buf, 0); + sl_free(buf, 1); return; } @@ -991,6 +1006,7 @@ help(int argc, char *argv[]) while (--argc > 0) { char *arg; + char cmdbuf[MAX_C_NAME]; arg = *++argv; c = getcmd(arg); @@ -1002,7 +1018,8 @@ help(int argc, char *argv[]) cmd, arg); else { if (isusage) { - nargv[0] = c->c_name; + (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf)); + nargv[0] = cmdbuf; (*c->c_handler)(0, nargv); } else fprintf(ttyout, "%-*s\t%s\n", HELPINDENT, @@ -1041,18 +1058,9 @@ getoptionvalue(const char *name) } static void -setupoption(char *name, char *value, char *defaultvalue) +setupoption(const char *name, const char *value, const char *defaultvalue) { - char *nargv[3]; - int overbose; - - nargv[0] = "setupoption()"; - nargv[1] = name; - nargv[2] = (value ? value : defaultvalue); - overbose = verbose; - verbose = 0; - setoption(3, nargv); - verbose = overbose; + set_option(name, value ? value : defaultvalue, 0); } void diff --git a/contrib/tnftp/progressbar.c b/contrib/tnftp/progressbar.c index 7bcc769041..d7edd2715d 100644 --- a/contrib/tnftp/progressbar.c +++ b/contrib/tnftp/progressbar.c @@ -1,7 +1,7 @@ -/* $NetBSD: progressbar.c,v 1.19 2008/04/28 20:24:13 martin Exp $ */ +/* $NetBSD: progressbar.c,v 1.21 2009/04/12 10:18:52 lukem Exp $ */ /*- - * Copyright (c) 1997-2007 The NetBSD Foundation, Inc. + * Copyright (c) 1997-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -31,7 +31,7 @@ #include #ifndef lint -__RCSID("$NetBSD: progressbar.c,v 1.19 2008/04/28 20:24:13 martin Exp $"); +__RCSID("$NetBSD: progressbar.c,v 1.21 2009/04/12 10:18:52 lukem Exp $"); #endif /* not lint */ /* @@ -100,7 +100,7 @@ static const char * const suffixes[] = { "YiB", /* 2^80 Yobibyte */ #endif }; -#define NSUFFIXES (sizeof(suffixes) / sizeof(suffixes[0])) +#define NSUFFIXES (int)(sizeof(suffixes) / sizeof(suffixes[0])) /* * Display a transfer progress bar if progress is non-zero. @@ -219,7 +219,7 @@ progressmeter(int flag) * calculate the length of the `*' bar, ensuring that * the number of stars won't exceed the buffer size */ - barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD; + barlength = MIN((int)(sizeof(buf) - 1), ttywidth) - BAROVERHEAD; if (prefix) barlength -= (int)strlen(prefix); if (barlength > 0) { diff --git a/contrib/tnftp/progressbar.h b/contrib/tnftp/progressbar.h index 8b683bb243..f627e88d5f 100644 --- a/contrib/tnftp/progressbar.h +++ b/contrib/tnftp/progressbar.h @@ -1,7 +1,7 @@ -/* $NetBSD: progressbar.h,v 1.6 2008/04/28 20:24:13 martin Exp $ */ +/* $NetBSD: progressbar.h,v 1.8 2009/04/12 10:18:52 lukem Exp $ */ /*- - * Copyright (c) 1996-2003 The NetBSD Foundation, Inc. + * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -59,7 +59,7 @@ GLOBAL int fromatty; /* input is from a terminal */ GLOBAL int verbose; /* print messages coming back from server */ GLOBAL int quit_time; /* maximum time to wait if stalled */ -GLOBAL char *direction; /* direction transfer is occurring */ +GLOBAL const char *direction; /* direction transfer is occurring */ GLOBAL sigjmp_buf toplevel; /* non-local goto stuff for cmd scanner */ #endif /* !STANDALONE_PROGRESS */ diff --git a/contrib/tnftp/util.c b/contrib/tnftp/util.c index bc7f690926..4072db0ad1 100644 --- a/contrib/tnftp/util.c +++ b/contrib/tnftp/util.c @@ -1,7 +1,7 @@ -/* $NetBSD: util.c,v 1.147 2008/05/10 00:05:31 skd Exp $ */ +/* $NetBSD: util.c,v 1.155 2010/06/05 13:59:39 lukem Exp $ */ /*- - * Copyright (c) 1997-2008 The NetBSD Foundation, Inc. + * Copyright (c) 1997-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -64,7 +64,7 @@ #include #ifndef lint -__RCSID("$NetBSD: util.c,v 1.147 2008/05/10 00:05:31 skd Exp $"); +__RCSID("$NetBSD: util.c,v 1.155 2010/06/05 13:59:39 lukem Exp $"); #endif /* not lint */ /* @@ -85,6 +85,7 @@ __RCSID("$NetBSD: util.c,v 1.147 2008/05/10 00:05:31 skd Exp $"); #include #include #include +#include #include #include #include @@ -103,7 +104,7 @@ void setpeer(int argc, char *argv[]) { char *host; - char *port; + const char *port; if (argc == 0) goto usage; @@ -163,25 +164,25 @@ setpeer(int argc, char *argv[]) } static void -parse_feat(const char *line) +parse_feat(const char *fline) { /* * work-around broken ProFTPd servers that can't - * even obey RFC2389. + * even obey RFC 2389. */ - while (*line && isspace((int)*line)) - line++; + while (*fline && isspace((int)*fline)) + fline++; - if (strcasecmp(line, "MDTM") == 0) + if (strcasecmp(fline, "MDTM") == 0) features[FEAT_MDTM] = 1; - else if (strncasecmp(line, "MLST", sizeof("MLST") - 1) == 0) { + else if (strncasecmp(fline, "MLST", sizeof("MLST") - 1) == 0) { features[FEAT_MLST] = 1; - } else if (strcasecmp(line, "REST STREAM") == 0) + } else if (strcasecmp(fline, "REST STREAM") == 0) features[FEAT_REST_STREAM] = 1; - else if (strcasecmp(line, "SIZE") == 0) + else if (strcasecmp(fline, "SIZE") == 0) features[FEAT_SIZE] = 1; - else if (strcasecmp(line, "TVFS") == 0) + else if (strcasecmp(fline, "TVFS") == 0) features[FEAT_TVFS] = 1; } @@ -372,51 +373,51 @@ int ftp_login(const char *host, const char *luser, const char *lpass) { char tmp[80]; - char *user, *pass, *acct, *p; + char *fuser, *pass, *facct, *p; char emptypass[] = ""; const char *errormsg; int n, aflag, rval, nlen; aflag = rval = 0; - user = pass = acct = NULL; + fuser = pass = facct = NULL; if (luser) - user = ftp_strdup(luser); + fuser = ftp_strdup(luser); if (lpass) pass = ftp_strdup(lpass); DPRINTF("ftp_login: user `%s' pass `%s' host `%s'\n", - STRorNULL(user), STRorNULL(pass), STRorNULL(host)); + STRorNULL(fuser), STRorNULL(pass), STRorNULL(host)); /* * Set up arguments for an anonymous FTP session, if necessary. */ if (anonftp) { - FREEPTR(user); - user = ftp_strdup("anonymous"); /* as per RFC1635 */ + FREEPTR(fuser); + fuser = ftp_strdup("anonymous"); /* as per RFC 1635 */ FREEPTR(pass); pass = ftp_strdup(getoptionvalue("anonpass")); } - if (ruserpass(host, &user, &pass, &acct) < 0) { + if (ruserpass(host, &fuser, &pass, &facct) < 0) { code = -1; goto cleanup_ftp_login; } - while (user == NULL) { + while (fuser == NULL) { if (localname) fprintf(ttyout, "Name (%s:%s): ", host, localname); else fprintf(ttyout, "Name (%s): ", host); errormsg = NULL; - nlen = getline(stdin, tmp, sizeof(tmp), &errormsg); + nlen = get_line(stdin, tmp, sizeof(tmp), &errormsg); if (nlen < 0) { fprintf(ttyout, "%s; %s aborted.\n", errormsg, "login"); code = -1; goto cleanup_ftp_login; } else if (nlen == 0) { - user = ftp_strdup(localname); + fuser = ftp_strdup(localname); } else { - user = ftp_strdup(tmp); + fuser = ftp_strdup(tmp); } } @@ -424,16 +425,16 @@ ftp_login(const char *host, const char *luser, const char *lpass) char *nuser; size_t len; - len = strlen(user) + 1 + strlen(host) + 1; + len = strlen(fuser) + 1 + strlen(host) + 1; nuser = ftp_malloc(len); - (void)strlcpy(nuser, user, len); + (void)strlcpy(nuser, fuser, len); (void)strlcat(nuser, "@", len); (void)strlcat(nuser, host, len); - FREEPTR(user); - user = nuser; + FREEPTR(fuser); + fuser = nuser; } - n = command("USER %s", user); + n = command("USER %s", fuser); if (n == CONTINUE) { if (pass == NULL) { p = getpass("Password: "); @@ -447,27 +448,27 @@ ftp_login(const char *host, const char *luser, const char *lpass) } if (n == CONTINUE) { aflag++; - if (acct == NULL) { + if (facct == NULL) { p = getpass("Account: "); if (p == NULL) p = emptypass; - acct = ftp_strdup(p); + facct = ftp_strdup(p); memset(p, 0, strlen(p)); } - if (acct[0] == '\0') { + if (facct[0] == '\0') { warnx("Login failed"); goto cleanup_ftp_login; } - n = command("ACCT %s", acct); - memset(acct, 0, strlen(acct)); + n = command("ACCT %s", facct); + memset(facct, 0, strlen(facct)); } if ((n != COMPLETE) || - (!aflag && acct != NULL && command("ACCT %s", acct) != COMPLETE)) { + (!aflag && facct != NULL && command("ACCT %s", facct) != COMPLETE)) { warnx("Login failed"); goto cleanup_ftp_login; } rval = 1; - username = ftp_strdup(user); + username = ftp_strdup(fuser); if (proxy) goto cleanup_ftp_login; @@ -485,13 +486,13 @@ ftp_login(const char *host, const char *luser, const char *lpass) updateremotecwd(); cleanup_ftp_login: - FREEPTR(user); + FREEPTR(fuser); if (pass != NULL) memset(pass, 0, strlen(pass)); FREEPTR(pass); - if (acct != NULL) - memset(acct, 0, strlen(acct)); - FREEPTR(acct); + if (facct != NULL) + memset(facct, 0, strlen(facct)); + FREEPTR(facct); return (rval); } @@ -502,7 +503,7 @@ ftp_login(const char *host, const char *luser, const char *lpass) * Returns false if no new arguments have been added. */ int -another(int *pargc, char ***pargv, const char *prompt) +another(int *pargc, char ***pargv, const char *aprompt) { const char *errormsg; int ret, nlen; @@ -513,10 +514,10 @@ another(int *pargc, char ***pargv, const char *prompt) fputs("Sorry, arguments too long.\n", ttyout); intr(0); } - fprintf(ttyout, "(%s) ", prompt); + fprintf(ttyout, "(%s) ", aprompt); line[len++] = ' '; errormsg = NULL; - nlen = getline(stdin, line + len, sizeof(line)-len, &errormsg); + nlen = get_line(stdin, line + len, sizeof(line)-len, &errormsg); if (nlen < 0) { fprintf(ttyout, "%s; %s aborted.\n", errormsg, "operation"); intr(0); @@ -543,7 +544,7 @@ remglob(char *argv[], int doswitch, const char **errbuf) char temp[MAXPATHLEN]; int oldverbose, oldhash, oldprogress, fd; char *cp; - const char *mode; + const char *rmode; size_t len; if (!mflag || !connected) { @@ -582,8 +583,8 @@ remglob(char *argv[], int doswitch, const char **errbuf) progress = 0; if (doswitch) pswitch(!proxy); - for (mode = "w"; *++argv != NULL; mode = "a") - recvrequest("NLST", temp, *argv, mode, 0, 0); + for (rmode = "w"; *++argv != NULL; rmode = "a") + recvrequest("NLST", temp, *argv, rmode, 0, 0); if ((code / 100) != COMPLETE) { if (errbuf != NULL) *errbuf = reply_string; @@ -755,11 +756,12 @@ remotemodtime(const char *file, int noisy) goto bad_parse_time; else goto cleanup_parse_time; - } else - DPRINTF("remotemodtime: parsed date `%s' as " LLF + } else { + DPRINTF("remotemodtime: parsed time `%s' as " LLF ", %s", timestr, (LLT)rtime, rfc2822time(localtime(&rtime))); + } } else { if (r == ERROR && code == 500 && features[FEAT_MDTM] == -1) features[FEAT_MDTM] = 0; @@ -776,7 +778,7 @@ remotemodtime(const char *file, int noisy) } /* - * Format tm in an RFC2822 compatible manner, with a trailing \n. + * Format tm in an RFC 2822 compatible manner, with a trailing \n. * Returns a pointer to a static string containing the result. */ const char * @@ -786,10 +788,36 @@ rfc2822time(const struct tm *tm) if (strftime(result, sizeof(result), "%a, %d %b %Y %H:%M:%S %z\n", tm) == 0) - errx(1, "Can't convert RFC2822 time: buffer too small"); + errx(1, "Can't convert RFC 2822 time: buffer too small"); return result; } +/* + * Parse HTTP-date as per RFC 2616. + * Return a pointer to the next character of the consumed date string, + * or NULL if failed. + */ +const char * +parse_rfc2616time(struct tm *parsed, const char *httpdate) +{ + const char *t; + const char *curlocale; + + /* The representation of %a depends on the current locale. */ + curlocale = setlocale(LC_TIME, NULL); + (void)setlocale(LC_TIME, "C"); + /* RFC 1123 */ + if ((t = strptime(httpdate, "%a, %d %b %Y %H:%M:%S GMT", parsed)) || + /* RFC 850 */ + (t = strptime(httpdate, "%a, %d-%b-%y %H:%M:%S GMT", parsed)) || + /* asctime */ + (t = strptime(httpdate, "%a, %b %d %H:%M:%S %Y", parsed))) { + ; /* do nothing */ + } + (void)setlocale(LC_TIME, curlocale); + return t; +} + /* * Update global `localcwd', which contains the state of the local cwd */ @@ -808,7 +836,8 @@ updatelocalcwd(void) void updateremotecwd(void) { - int overbose, ocode, i; + int overbose, ocode; + size_t i; char *cp; overbose = verbose; @@ -877,8 +906,8 @@ fileindir(const char *file, const char *dir) void list_vertical(StringList *sl) { - int i, j; - int columns, lines; + size_t i, j; + size_t columns, lines; char *p; size_t w, width; @@ -1067,11 +1096,10 @@ setupsockbufsize(int sock) void ftpvis(char *dst, size_t dstlen, const char *src, size_t srclen) { - int di, si; + size_t di, si; - for (di = si = 0; - src[si] != '\0' && di < dstlen && si < srclen; - di++, si++) { + di = si = 0; + while (src[si] != '\0' && di < dstlen && si < srclen) { switch (src[si]) { case '\\': case ' ': @@ -1079,12 +1107,18 @@ ftpvis(char *dst, size_t dstlen, const char *src, size_t srclen) case '\r': case '\n': case '"': - dst[di++] = '\\'; - if (di >= dstlen) + /* + * Need room for two characters and NUL, avoiding + * incomplete escape sequences at end of dst. + */ + if (di >= dstlen - 3) break; + dst[di++] = '\\'; /* FALLTHROUGH */ default: - dst[di] = src[si]; + dst[di] = src[si++]; + if (di < dstlen) + di++; } } dst[di] = '\0'; @@ -1097,7 +1131,8 @@ void formatbuf(char *buf, size_t len, const char *src) { const char *p, *p2, *q; - int i, op, updirs, pdirs; + size_t i; + int op, updirs, pdirs; #define ADDBUF(x) do { \ if (i >= len - 1) \ @@ -1215,7 +1250,7 @@ isipv6addr(const char *addr) struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_INET6; + hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_DGRAM; /*dummy*/ hints.ai_flags = AI_NUMERICHOST; if (getaddrinfo(addr, "0", &hints, &res) != 0) @@ -1245,7 +1280,7 @@ isipv6addr(const char *addr) * -3 line was too long */ int -getline(FILE *stream, char *buf, size_t buflen, const char **errormsg) +get_line(FILE *stream, char *buf, size_t buflen, const char **errormsg) { int rv, ch; size_t len; diff --git a/contrib/tnftp/version.h b/contrib/tnftp/version.h index 78b5d53318..9033ce4779 100644 --- a/contrib/tnftp/version.h +++ b/contrib/tnftp/version.h @@ -1,7 +1,7 @@ -/* $NetBSD: version.h,v 1.76 2008/05/10 01:14:57 skd Exp $ */ +/* $NetBSD: version.h,v 1.82 2010/06/05 13:59:39 lukem Exp $ */ /*- - * Copyright (c) 1999-2008 The NetBSD Foundation, Inc. + * Copyright (c) 1999-2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -34,5 +34,5 @@ #endif #ifndef FTP_VERSION -#define FTP_VERSION "20080509" +#define FTP_VERSION "20100605" #endif -- 2.41.0