Snyc tnftp with NetBSD:
authorPeter Avalos <pavalos@dragonflybsd.org>
Wed, 15 Dec 2010 05:40:35 +0000 (19:40 -1000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Wed, 15 Dec 2010 05:40:35 +0000 (19:40 -1000)
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.

14 files changed:
contrib/tnftp/cmds.c
contrib/tnftp/cmdtab.c
contrib/tnftp/complete.c
contrib/tnftp/domacro.c
contrib/tnftp/extern.h
contrib/tnftp/fetch.c
contrib/tnftp/ftp.1
contrib/tnftp/ftp.c
contrib/tnftp/ftp_var.h
contrib/tnftp/main.c
contrib/tnftp/progressbar.c
contrib/tnftp/progressbar.h
contrib/tnftp/util.c
contrib/tnftp/version.h

index 7a32850..caa0960 100644 (file)
@@ -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 <limits.h>
 #include <netdb.h>
 #include <paths.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -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
  */
index 3320216..17d7477 100644 (file)
@@ -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 },
 };
index 6cf3597..617af07 100644 (file)
@@ -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 <sys/cdefs.h>
 #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';
 
index 4b76a68..04799bc 100644 (file)
@@ -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);
index 98518ec..30341fa 100644 (file)
@@ -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 **);
index 351b179..67b2442 100644 (file)
@@ -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 <sys/cdefs.h>
 #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):
  *     <type>://[<user>[:<password>]@]<host>[:<port>][/<path>]
  * 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; <path> will have the
+ * XXX: this is not totally RFC 3986 compliant; <path> 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, ':');
index 1cfd946..8c82903 100644 (file)
@@ -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
 .\"
 .\"    @(#)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
index e26ea10..3eeb678 100644 (file)
@@ -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;
index 2c5d053..db501cf 100644 (file)
@@ -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
  * 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 */
index 43674f1..3724790 100644 (file)
@@ -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
 
 #include <sys/cdefs.h>
 #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
index 7bcc769..d7edd27 100644 (file)
@@ -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 <sys/cdefs.h>
 #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) {
index 8b683bb..f627e88 100644 (file)
@@ -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 */
index bc7f690..4072db0 100644 (file)
@@ -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 <sys/cdefs.h>
 #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 <signal.h>
 #include <libgen.h>
 #include <limits.h>
+#include <locale.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -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,11 +788,37 @@ 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
  */
 void
@@ -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;
index 78b5d53..9033ce4 100644 (file)
@@ -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