Module Name: src Committed By: martin Date: Mon Sep 12 15:05:21 UTC 2022
Modified Files: src/usr.bin/ftp [netbsd-8]: Makefile cmds.c complete.c domacro.c extern.h fetch.c ftp.1 ftp.c ftp_var.h main.c progressbar.c progressbar.h ssl.c ssl.h util.c version.h Log Message: Backout ticket #1763 for now - trust anchors are not solved. To generate a diff of this commit: cvs rdiff -u -r1.37.2.1 -r1.37.2.2 src/usr.bin/ftp/Makefile cvs rdiff -u -r1.137.8.1 -r1.137.8.2 src/usr.bin/ftp/cmds.c cvs rdiff -u -r1.46.38.1 -r1.46.38.2 src/usr.bin/ftp/complete.c cvs rdiff -u -r1.22.38.1 -r1.22.38.2 src/usr.bin/ftp/domacro.c cvs rdiff -u -r1.80.24.1 -r1.80.24.2 src/usr.bin/ftp/extern.h cvs rdiff -u -r1.228.4.1 -r1.228.4.2 src/usr.bin/ftp/fetch.c cvs rdiff -u -r1.135.8.1 -r1.135.8.2 src/usr.bin/ftp/ftp.1 cvs rdiff -u -r1.167.6.1 -r1.167.6.2 src/usr.bin/ftp/ftp.c cvs rdiff -u -r1.84.8.1 -r1.84.8.2 src/usr.bin/ftp/ftp_var.h cvs rdiff -u -r1.123.8.1 -r1.123.8.2 src/usr.bin/ftp/main.c cvs rdiff -u -r1.22.24.1 -r1.22.24.2 src/usr.bin/ftp/progressbar.c cvs rdiff -u -r1.8.38.1 -r1.8.38.2 src/usr.bin/ftp/progressbar.h cvs rdiff -u -r1.5.8.1 -r1.5.8.2 src/usr.bin/ftp/ssl.c cvs rdiff -u -r1.3.8.1 -r1.3.8.2 src/usr.bin/ftp/ssl.h cvs rdiff -u -r1.158.22.1 -r1.158.22.2 src/usr.bin/ftp/util.c cvs rdiff -u -r1.87.8.1 -r1.87.8.2 src/usr.bin/ftp/version.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/ftp/Makefile diff -u src/usr.bin/ftp/Makefile:1.37.2.1 src/usr.bin/ftp/Makefile:1.37.2.2 --- src/usr.bin/ftp/Makefile:1.37.2.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/Makefile Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.37.2.1 2022/09/12 14:46:51 martin Exp $ +# $NetBSD: Makefile,v 1.37.2.2 2022/09/12 15:05:21 martin Exp $ # from: @(#)Makefile 8.2 (Berkeley) 4/3/94 .include <bsd.own.mk> @@ -8,7 +8,6 @@ USE_FORT?= yes # network client PROG= ftp SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c \ progressbar.c ruserpass.c util.c -SRCS+= ssl.c # Uncomment the following to provide defaults for gate-ftp operation # @@ -20,6 +19,7 @@ CPPFLAGS+=-DNO_EDITCOMPLETE -DNO_ABOUT - LDADD+= -ledit -lterminfo DPADD+= ${LIBEDIT} ${LIBTERMINFO} CPPFLAGS+= -DWITH_SSL +SRCS+=ssl.c LDADD+= -lssl -lcrypto DPADD+= ${LIBSSL} ${LIBCRYPTO} .endif @@ -31,6 +31,4 @@ CPPFLAGS+= -DINET6 cmds.o fetch.o: version.h main.o: ftp_var.h -CWARNFLAGS.gcc+= ${GCC_NO_FORMAT_OVERFLOW} - .include <bsd.prog.mk> Index: src/usr.bin/ftp/cmds.c diff -u src/usr.bin/ftp/cmds.c:1.137.8.1 src/usr.bin/ftp/cmds.c:1.137.8.2 --- src/usr.bin/ftp/cmds.c:1.137.8.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/cmds.c Mon Sep 12 15:05:21 2022 @@ -1,7 +1,7 @@ -/* $NetBSD: cmds.c,v 1.137.8.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: cmds.c,v 1.137.8.2 2022/09/12 15:05:21 martin Exp $ */ /*- - * Copyright (c) 1996-2021 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.137.8.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: cmds.c,v 1.137.8.2 2022/09/12 15:05:21 martin Exp $"); #endif #endif /* not lint */ @@ -1131,7 +1131,7 @@ setdebug(int argc, char *argv[]) options |= SO_DEBUG; else options &= ~SO_DEBUG; - fprintf(ttyout, "Debugging %s (debug=%d).\n", onoff(ftp_debug), ftp_debug); + fprintf(ttyout, "Debugging %s (ftp_debug=%d).\n", onoff(ftp_debug), ftp_debug); code = ftp_debug > 0; } @@ -1158,8 +1158,7 @@ cd(int argc, char *argv[]) } if (r == COMPLETE) { dirchange = 1; - remotecwd[0] = '\0'; - remcwdvalid = 0; + updateremotecwd(); } } @@ -1545,9 +1544,9 @@ pwd(int argc, char *argv[]) UPRINTF("usage: %s\n", argv[0]); return; } - if (!remcwdvalid || remotecwd[0] == '\0') + if (! remotecwd[0]) updateremotecwd(); - if (remotecwd[0] == '\0') + if (! remotecwd[0]) fprintf(ttyout, "Unable to determine remote directory\n"); else { fprintf(ttyout, "Remote directory: %s\n", remotecwd); @@ -1776,18 +1775,6 @@ quit(int argc, char *argv[]) exit(0); } -void __dead -justquit(void) -{ - - quit(0, NULL); - /* - * quit is not __dead, but for our invocation it never will return, - * but some compilers are not smart enough to find this out. - */ - exit(0); -} - /* * Terminate session, but don't exit. * May be called with 0, NULL. @@ -2197,7 +2184,7 @@ LOOP: } break; } - /* FALLTHROUGH */ + /* intentional drop through */ default: *cp2++ = *cp1; break; @@ -2372,8 +2359,7 @@ cdup(int argc, char *argv[]) } if (r == COMPLETE) { dirchange = 1; - remotecwd[0] = '\0'; - remcwdvalid = 0; + updateremotecwd(); } } Index: src/usr.bin/ftp/complete.c diff -u src/usr.bin/ftp/complete.c:1.46.38.1 src/usr.bin/ftp/complete.c:1.46.38.2 --- src/usr.bin/ftp/complete.c:1.46.38.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/complete.c Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: complete.c,v 1.46.38.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: complete.c,v 1.46.38.2 2022/09/12 15:05:21 martin Exp $ */ /*- * Copyright (c) 1997-2009 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: complete.c,v 1.46.38.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: complete.c,v 1.46.38.2 2022/09/12 15:05:21 martin Exp $"); #endif /* not lint */ /* @@ -99,10 +99,11 @@ complete_ambiguous(char *word, int list, } if (!list) { + matchlen = 0; lastmatch = words->sl_str[0]; matchlen = strlen(lastmatch); for (i = 1 ; i < words->sl_cur ; i++) { - for (j = wordlen; j < strlen(words->sl_str[i]); j++) + for (j = wordlen ; j < strlen(words->sl_str[i]); j++) if (lastmatch[j] != words->sl_str[i][j]) break; if (j < matchlen) Index: src/usr.bin/ftp/domacro.c diff -u src/usr.bin/ftp/domacro.c:1.22.38.1 src/usr.bin/ftp/domacro.c:1.22.38.2 --- src/usr.bin/ftp/domacro.c:1.22.38.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/domacro.c Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: domacro.c,v 1.22.38.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: domacro.c,v 1.22.38.2 2022/09/12 15:05:21 martin 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.22.38.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: domacro.c,v 1.22.38.2 2022/09/12 15:05:21 martin Exp $"); #endif #endif /* not lint */ @@ -102,7 +102,7 @@ domacro(int argc, char *argv[]) } break; } - /* FALLTHROUGH */ + /* intentional drop through */ default: *cp2++ = *cp1; break; Index: src/usr.bin/ftp/extern.h diff -u src/usr.bin/ftp/extern.h:1.80.24.1 src/usr.bin/ftp/extern.h:1.80.24.2 --- src/usr.bin/ftp/extern.h:1.80.24.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/extern.h Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.80.24.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: extern.h,v 1.80.24.2 2022/09/12 15:05:21 martin Exp $ */ /*- * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. @@ -173,7 +173,6 @@ void pswitch(int); void put(int, char **); void pwd(int, char **); void quit(int, char **); -void justquit(void) __dead; void quote(int, char **); void quote1(const char *, int, char **); void recvrequest(const char *, const char *, const char *, @@ -243,14 +242,7 @@ void user(int, char **); int ftp_connect(int, const struct sockaddr *, socklen_t, int); int ftp_listen(int, int); int ftp_poll(struct pollfd *, int, int); -#ifndef SMALL void *ftp_malloc(size_t); StringList *ftp_sl_init(void); void ftp_sl_add(StringList *, char *); char *ftp_strdup(const char *); -#else -#define ftp_malloc(a) malloc(a); -#define ftp_sl_init() sl_init() -#define ftp_sl_add(a, b) sl_add((a), (b)) -#define ftp_strdup(a) strdup(a) -#endif Index: src/usr.bin/ftp/fetch.c diff -u src/usr.bin/ftp/fetch.c:1.228.4.1 src/usr.bin/ftp/fetch.c:1.228.4.2 --- src/usr.bin/ftp/fetch.c:1.228.4.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/fetch.c Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: fetch.c,v 1.228.4.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: fetch.c,v 1.228.4.2 2022/09/12 15:05:21 martin Exp $ */ /*- * Copyright (c) 1997-2015 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: fetch.c,v 1.228.4.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: fetch.c,v 1.228.4.2 2022/09/12 15:05:21 martin Exp $"); #endif /* not lint */ /* @@ -106,13 +106,12 @@ __dead static void timeouthttp(int); static int auth_url(const char *, char **, const struct authinfo *); static void base64_encode(const unsigned char *, size_t, unsigned char *); #endif -static int go_fetch(const char *, struct urlinfo *); +static int go_fetch(const char *); static int fetch_ftp(const char *); -static int fetch_url(const char *, const char *, char *, char *, - struct urlinfo *); +static int fetch_url(const char *, const char *, char *, char *); static const char *match_token(const char **, const char *); static int parse_url(const char *, const char *, struct urlinfo *, - struct authinfo *, struct urlinfo *); + struct authinfo *); static void url_decode(char *); static void freeauthinfo(struct authinfo *); static void freeurlinfo(struct urlinfo *); @@ -139,43 +138,6 @@ static int redirect_loop; ((urltype) == HTTP_URL_T) #endif -/** - * fwrite(3) replacement that just uses write(2). Many stdio implementations - * don't handle interrupts properly and corrupt the output. We are taking - * alarm interrupts because of the progress bar. - * - * Assumes `fp' is pristine with no prior I/O calls on it. - */ -static size_t -maxwrite(const void *buf, size_t size, size_t nmemb, FILE *fp) -{ - const char *p = buf; - ssize_t nwr = 0; - ssize_t n; - int fd = fileno(fp); - - size *= nmemb; /* assume no overflow */ - - while (size > 0) { - if ((n = write(fd, p, size)) == -1) { - switch (errno) { - case EINTR: - case EAGAIN: -#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - continue; - default: - return nwr; - } - } - p += n; - nwr += n; - size -= n; - } - return nwr; -} - /* * Determine if token is the next word in buf (case insensitive). * If so, advance buf past the token and any trailing LWS, and @@ -275,7 +237,7 @@ auth_url(const char *challenge, char **r scheme = "Basic"; /* only support Basic authentication */ gotpass = NULL; - DPRINTF("%s: challenge `%s'\n", __func__, challenge); + DPRINTF("auth_url: challenge `%s'\n", challenge); if (! match_token(&cp, scheme)) { warnx("Unsupported authentication challenge `%s'", @@ -337,7 +299,7 @@ auth_url(const char *challenge, char **r *response = ftp_malloc(rlen); (void)strlcpy(*response, scheme, rlen); len = strlcat(*response, " ", rlen); - /* use `clen - 1' to not encode the trailing NUL */ + /* use `clen - 1' to not encode the trailing NUL */ base64_encode((unsigned char *)clear, clen - 1, (unsigned char *)*response + len); memset(clear, 0, clen); @@ -368,7 +330,7 @@ base64_encode(const unsigned char *clear | ((clear[i + 1] >> 4) & 0x0f)]; *(cp++) = enc[((clear[i + 1] << 2) & 0x3c) | ((clear[i + 2] >> 6) & 0x03)]; - *(cp++) = enc[((clear[i + 2] ) & 0x3f)]; + *(cp++) = enc[((clear[i + 2] ) & 0x3f)]; } *cp = '\0'; while (i-- > len) @@ -401,42 +363,6 @@ url_decode(char *url) *q = '\0'; } -static const char * -get_port(const struct urlinfo *ui) -{ - - switch(ui->utype) { - case HTTP_URL_T: - return httpport; - case FTP_URL_T: - return ftpport; - case FILE_URL_T: - return ""; -#ifdef WITH_SSL - case HTTPS_URL_T: - return httpsport; -#endif - default: - return NULL; - } -} - -static int -use_relative(const struct urlinfo *ui) -{ - if (ui == NULL) - return 0; - switch (ui->utype) { - case HTTP_URL_T: - case FILE_URL_T: -#ifdef WITH_SSL - case HTTPS_URL_T: -#endif - return 1; - default: - return 0; - } -} /* * Parse URL of form (per RFC 3986): @@ -472,7 +398,7 @@ use_relative(const struct urlinfo *ui) static int parse_url(const char *url, const char *desc, struct urlinfo *ui, - struct authinfo *auth, struct urlinfo *rui) + struct authinfo *auth) { const char *origurl, *tport; char *cp, *ep, *thost; @@ -483,26 +409,29 @@ parse_url(const char *url, const char *d DPRINTF("parse_url: %s `%s'\n", desc, url); origurl = url; + tport = NULL; if (STRNEQUAL(url, HTTP_URL)) { url += sizeof(HTTP_URL) - 1; ui->utype = HTTP_URL_T; ui->portnum = HTTP_PORT; + tport = httpport; } else if (STRNEQUAL(url, FTP_URL)) { url += sizeof(FTP_URL) - 1; ui->utype = FTP_URL_T; ui->portnum = FTP_PORT; + tport = ftpport; } else if (STRNEQUAL(url, FILE_URL)) { url += sizeof(FILE_URL) - 1; ui->utype = FILE_URL_T; + tport = ""; #ifdef WITH_SSL } else if (STRNEQUAL(url, HTTPS_URL)) { url += sizeof(HTTPS_URL) - 1; ui->utype = HTTPS_URL_T; ui->portnum = HTTPS_PORT; + tport = httpsport; #endif - } else if (rui != NULL) { - copyurlinfo(ui, rui); } else { warnx("Invalid %s `%s'", desc, url); cleanup_parse_url: @@ -511,7 +440,6 @@ parse_url(const char *url, const char *d return (-1); } - if (*url == '\0') return (0); @@ -576,8 +504,7 @@ parse_url(const char *url, const char *d #endif /* INET6 */ if ((cp = strchr(thost, ':')) != NULL) *cp++ = '\0'; - if (*thost != '\0') - ui->host = thost; + ui->host = thost; /* look for [:port] */ if (cp != NULL) { @@ -592,9 +519,7 @@ parse_url(const char *url, const char *d } ui->portnum = nport; tport = cp; - } else - tport = get_port(ui); - + } if (tport != NULL) ui->port = ftp_strdup(tport); @@ -605,8 +530,8 @@ parse_url(const char *url, const char *d ui->path = ftp_strdup(emptypath); } - DPRINTF("%s: user `%s' pass `%s' host %s port %s(%d) " - "path `%s'\n", __func__, + DPRINTF("parse_url: user `%s' pass `%s' host %s port %s(%d) " + "path `%s'\n", STRorNULL(auth->user), STRorNULL(auth->pass), STRorNULL(ui->host), STRorNULL(ui->port), ui->portnum ? ui->portnum : -1, STRorNULL(ui->path)); @@ -619,7 +544,7 @@ sigjmp_buf httpabort; static int ftp_socket(const struct urlinfo *ui, void **ssl) { - struct addrinfo hints, *res, *res0 = NULL; + struct addrinfo hints, *res, *res0 = NULL; int error; int s; const char *host = ui->host; @@ -724,7 +649,7 @@ handle_noproxy(const char *host, in_port if (*cp == '\0') continue; if ((np = strrchr(cp, ':')) != NULL) { - *np++ = '\0'; + *np++ = '\0'; np_port = strtoul(np, &ep, 10); if (*np == '\0' || *ep != '\0') continue; @@ -756,7 +681,7 @@ handle_proxy(const char *url, const char } initurlinfo(&pui); - if (parse_url(penv, "proxy URL", &pui, pauth, NULL) == -1) + if (parse_url(penv, "proxy URL", &pui, pauth) == -1) return -1; if ((!IS_HTTP_TYPE(pui.utype) && pui.utype != FTP_URL_T) || @@ -927,9 +852,9 @@ print_connect(FETCH *fin, const struct u } #endif -#define C_OK 0 -#define C_CLEANUP 1 -#define C_IMPROPER 2 +#define C_OK 0 +#define C_CLEANUP 1 +#define C_IMPROPER 2 static int getresponseline(FETCH *fin, char *buf, size_t buflen, int *len) @@ -1028,7 +953,7 @@ parse_posinfo(const char **cp, struct po static void do_auth(int hcode, const char *url, const char *penv, struct authinfo *wauth, struct authinfo *pauth, char **auth, const char *message, - volatile int *rval, struct urlinfo *ui) + volatile int *rval) { struct authinfo aauth; char *response; @@ -1063,8 +988,7 @@ do_auth(int hcode, const char *url, cons if (auth_url(*auth, &response, &aauth) == 0) { *rval = fetch_url(url, penv, hcode == 401 ? pauth->auth : response, - hcode == 401 ? response : wauth->auth, - ui); + hcode == 401 ? response: wauth->auth); memset(response, 0, strlen(response)); FREEPTR(response); } @@ -1075,12 +999,12 @@ static int negotiate_connection(FETCH *fin, const char *url, const char *penv, struct posinfo *pi, time_t *mtime, struct authinfo *wauth, struct authinfo *pauth, volatile int *rval, volatile int *ischunked, - char **auth, struct urlinfo *ui) + char **auth) { int len, hcode, rv; char buf[FTPBUFLEN], *ep; const char *cp, *token; - char *location, *message; + char *location, *message; *auth = message = location = NULL; @@ -1195,19 +1119,18 @@ negotiate_connection(FETCH *fin, const c fprintf(ttyout, "Redirected via %s\n", location); *rval = fetch_url(url, location, - pauth->auth, wauth->auth, ui); + pauth->auth, wauth->auth); } else { if (verbose) fprintf(ttyout, "Redirected to %s\n", location); - *rval = go_fetch(location, ui); + *rval = go_fetch(location); } goto cleanup_fetch_url; #ifndef NO_AUTH case 401: case 407: - do_auth(hcode, url, penv, wauth, pauth, auth, message, rval, - ui); + do_auth(hcode, url, penv, wauth, pauth, auth, message, rval); goto cleanup_fetch_url; #endif default: @@ -1272,7 +1195,7 @@ connectmethod(FETCH *fin, const char *ur message = ftp_strdup(ep); break; } - + for (;;) { int len; if (getresponseline(fin, buf, sizeof(buf), &len) != C_OK) @@ -1301,8 +1224,7 @@ connectmethod(FETCH *fin, const char *ur break; #ifndef NO_AUTH case 407: - do_auth(hcode, url, penv, wauth, pauth, auth, message, rval, - ui); + do_auth(hcode, url, penv, wauth, pauth, auth, message, rval); goto cleanup_fetch_url; #endif default: @@ -1340,8 +1262,7 @@ out: * is still open (e.g, ftp xfer with trailing /) */ static int -fetch_url(const char *url, const char *proxyenv, char *proxyauth, - char *wwwauth, struct urlinfo *rui) +fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) { sigfunc volatile oldint; sigfunc volatile oldpipe; @@ -1350,18 +1271,18 @@ fetch_url(const char *url, const char *p int volatile s; struct stat sb; int volatile isproxy; - int volatile rval, ischunked; + int volatile rval, ischunked; size_t flen; static size_t bufsize; static char *xferbuf; const char *cp; char *ep; - char *volatile auth; + char *auth; char *volatile savefile; char *volatile location; char *volatile message; char *volatile decodedpath; - struct authinfo wauth, pauth; + struct authinfo wauth, pauth; struct posinfo pi; off_t hashbytes; int (*volatile closefunc)(FILE *); @@ -1374,7 +1295,7 @@ fetch_url(const char *url, const char *p DPRINTF("%s: `%s' proxyenv `%s'\n", __func__, url, STRorNULL(penv)); - oldquit = oldalrm = oldint = oldpipe = SIG_ERR; + oldquit = oldalrm = oldint = oldpipe = NULL; closefunc = NULL; fin = NULL; fout = NULL; @@ -1394,7 +1315,7 @@ fetch_url(const char *url, const char *p if (sigsetjmp(httpabort, 1)) goto cleanup_fetch_url; - if (parse_url(url, "URL", &ui, &wauth, rui) == -1) + if (parse_url(url, "URL", &ui, &wauth) == -1) goto cleanup_fetch_url; copyurlinfo(&oui, &ui); @@ -1410,7 +1331,7 @@ fetch_url(const char *url, const char *p rval = fetch_ftp(url); goto cleanup_fetch_url; } - if (!IS_HTTP_TYPE(ui.utype) || outfile == NULL) { + if (!IS_HTTP_TYPE(ui.utype) || outfile == NULL) { warnx("Invalid URL (no file after host) `%s'", url); goto cleanup_fetch_url; } @@ -1465,8 +1386,7 @@ fetch_url(const char *url, const char *p filesize = sb.st_size; } if (restart_point) { - if (lseek(fetch_fileno(fin), restart_point, SEEK_SET) - < 0) { + if (lseek(fetch_fileno(fin), restart_point, SEEK_SET) < 0) { warn("Can't seek to restart `%s'", decodedpath); goto cleanup_fetch_url; @@ -1540,8 +1460,7 @@ fetch_url(const char *url, const char *p #ifdef WITH_SSL if (isproxy && oui.utype == HTTPS_URL_T) { switch (connectmethod(fin, url, penv, &oui, &ui, - &wauth, &pauth, __UNVOLATILE(&auth), &hasleading, - &rval)) { + &wauth, &pauth, &auth, &hasleading, &rval)) { case C_CLEANUP: goto cleanup_fetch_url; case C_IMPROPER: @@ -1577,8 +1496,7 @@ fetch_url(const char *url, const char *p alarmtimer(0); switch (negotiate_connection(fin, url, penv, &pi, - &mtime, &wauth, &pauth, &rval, &ischunked, - __UNVOLATILE(&auth), &ui)) { + &mtime, &wauth, &pauth, &rval, &ischunked, &auth)) { case C_OK: break; case C_CLEANUP: @@ -1652,9 +1570,9 @@ fetch_url(const char *url, const char *p bytes = 0; hashbytes = mark; - if (oldalrm != SIG_ERR) { + if (oldalrm) { (void)xsignal(SIGALRM, oldalrm); - oldalrm = SIG_ERR; + oldalrm = NULL; } progressmeter(-1); @@ -1685,7 +1603,7 @@ fetch_url(const char *url, const char *p } /* - * XXX: Work around bug in Apache 1.3.9 and + * XXX: Work around bug in Apache 1.3.9 and * 1.3.11, which incorrectly put trailing * space after the chunk-size. */ @@ -1720,17 +1638,13 @@ fetch_url(const char *url, const char *p if (ischunked) bufrem = MIN(chunksize, bufrem); while (bufrem > 0) { - size_t nr = MIN((off_t)bufsize, bufrem); flen = fetch_read(xferbuf, sizeof(char), - nr, fin); - if (flen == 0) { - if (fetch_error(fin)) - goto chunkerror; + MIN((off_t)bufsize, bufrem), fin); + if (flen <= 0) goto chunkdone; - } bytes += flen; bufrem -= flen; - if (maxwrite(xferbuf, sizeof(char), flen, fout) + if (fwrite(xferbuf, sizeof(char), flen, fout) != flen) { warn("Writing `%s'", savefile); goto cleanup_fetch_url; @@ -1778,7 +1692,7 @@ fetch_url(const char *url, const char *p } while (ischunked); /* XXX: deal with optional trailer & CRLF here? */ -chunkerror: + if (hash && !progress && bytes > 0) { if (bytes < mark) (void)putc('#', ttyout); @@ -1816,14 +1730,14 @@ chunkerror: warnx("Improper response from `%s:%s'", ui.host, ui.port); cleanup_fetch_url: - if (oldint != SIG_ERR) + if (oldint) (void)xsignal(SIGINT, oldint); - if (oldpipe != SIG_ERR) + if (oldpipe) (void)xsignal(SIGPIPE, oldpipe); - if (oldalrm != SIG_ERR) + if (oldalrm) (void)xsignal(SIGALRM, oldalrm); - if (oldquit != SIG_ERR) - (void)xsignal(SIGQUIT, oldquit); + if (oldquit) + (void)xsignal(SIGQUIT, oldpipe); if (fin != NULL) fetch_close(fin); else if (s != -1) @@ -1893,10 +1807,10 @@ fetch_ftp(const char *url) char dirbuf[4]; int dirhasglob, filehasglob, rval, transtype, xargc; int oanonftp, oautologin; - struct authinfo auth; + struct authinfo auth; struct urlinfo ui; - DPRINTF("%s: `%s'\n", __func__, url); + DPRINTF("fetch_ftp: `%s'\n", url); dir = file = NULL; rval = 1; transtype = TYPE_I; @@ -1905,7 +1819,7 @@ fetch_ftp(const char *url) initauthinfo(&auth, NULL); if (STRNEQUAL(url, FTP_URL)) { - if ((parse_url(url, "URL", &ui, &auth, NULL) == -1) || + if ((parse_url(url, "URL", &ui, &auth) == -1) || (auth.user != NULL && *auth.user == '\0') || EMPTYSTRING(ui.host)) { warnx("Invalid URL `%s'", url); @@ -1917,8 +1831,7 @@ fetch_ftp(const char *url) */ /* check for trailing ';type=[aid]' */ - if (! EMPTYSTRING(ui.path) - && (cp = strrchr(ui.path, ';')) != NULL) { + if (! EMPTYSTRING(ui.path) && (cp = strrchr(ui.path, ';')) != NULL) { if (strcasecmp(cp, ";type=a") == 0) transtype = TYPE_A; else if (strcasecmp(cp, ";type=i") == 0) @@ -1960,12 +1873,12 @@ fetch_ftp(const char *url) * If we are dealing with classic `[user@]host:[path]' syntax, * then a path of the form `/file' (resulting from input of the * form `host:/file') means that we should do "CWD /" before - * retrieving the file. So we set dir="/" and file="file". + * retrieving the file. So we set dir="/" and file="file". * * But if we are dealing with URLs like `ftp://host/path' then * a path of the form `/file' (resulting from a URL of the form * `ftp://host//file') means that we should do `CWD ' (with an - * empty argument) before retrieving the file. So we set + * empty argument) before retrieving the file. So we set * dir="" and file="file". * * If the path does not contain / at all, we set dir=NULL. @@ -1996,8 +1909,8 @@ fetch_ftp(const char *url) url_decode(file); /* but still don't url_decode(dir) */ } - DPRINTF("%s: user `%s' pass `%s' host %s port %s " - "path `%s' dir `%s' file `%s'\n", __func__, + DPRINTF("fetch_ftp: user `%s' pass `%s' host %s port %s " + "path `%s' dir `%s' file `%s'\n", STRorNULL(auth.user), STRorNULL(auth.pass), STRorNULL(ui.host), STRorNULL(ui.port), STRorNULL(ui.path), STRorNULL(dir), STRorNULL(file)); @@ -2046,7 +1959,7 @@ fetch_ftp(const char *url) setbinary(1, xargv); break; default: - errx(1, "%s: unknown transfer type %d", __func__, transtype); + errx(1, "fetch_ftp: unknown transfer type %d", transtype); } /* @@ -2068,7 +1981,7 @@ fetch_ftp(const char *url) * (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 + * *after* we find the slashes. It's possible to get * empty components here, (from multiple adjacent * slashes in the path) and RFC 3986 says that we should * still do `CWD ' (with a null argument) in such cases. @@ -2111,7 +2024,7 @@ fetch_ftp(const char *url) * "CWD /", "CWD foo", "CWD bar", "RETR file" * ftp://host/%2Ffoo/bar/file dir="%2Ffoo/bar" * "CWD /foo", "CWD bar", "RETR file" - * ftp://host/%2Ffoo%2Fbar/file dir="%2Ffoo%2Fbar" + * ftp://host/%2Ffoo%2Fbar/file dir="%2Ffoo%2Fbar" * "CWD /foo/bar", "RETR file" * ftp://host/%2Ffoo%2Fbar%2Ffile dir=NULL * "RETR /foo/bar/file" @@ -2128,7 +2041,7 @@ fetch_ftp(const char *url) url_decode(dir); } else nextpart = NULL; - DPRINTF("%s: dir `%s', nextpart `%s'\n", __func__, + DPRINTF("fetch_ftp: dir `%s', nextpart `%s'\n", STRorNULL(dir), STRorNULL(nextpart)); if (ui.utype == FTP_URL_T || *dir != '\0') { (void)strlcpy(cmdbuf, "cd", sizeof(cmdbuf)); @@ -2184,15 +2097,14 @@ fetch_ftp(const char *url) mget(xargc, xargv); interactive = ointeractive; } else { - char *destfile = outfile; - if (destfile == NULL) { + if (outfile == NULL) { cp = strrchr(file, '/'); /* find savefile */ if (cp != NULL) - destfile = cp + 1; + outfile = cp + 1; else - destfile = file; + outfile = file; } - xargv[2] = (char *)destfile; + xargv[2] = (char *)outfile; xargv[3] = NULL; xargc++; if (restartautofetch) @@ -2223,7 +2135,7 @@ fetch_ftp(const char *url) * is still open (e.g, ftp xfer with trailing /) */ static int -go_fetch(const char *url, struct urlinfo *rui) +go_fetch(const char *url) { char *proxyenv; char *p; @@ -2272,7 +2184,7 @@ go_fetch(const char *url, struct urlinfo || STRNEQUAL(url, HTTPS_URL) #endif || STRNEQUAL(url, FILE_URL)) - return (fetch_url(url, NULL, NULL, NULL, rui)); + return (fetch_url(url, NULL, NULL, NULL)); /* * If it contains "://" but does not begin with ftp:// @@ -2287,20 +2199,13 @@ go_fetch(const char *url, struct urlinfo errx(1, "Unsupported URL scheme `%.*s'", (int)(p - url), url); /* - * Refer to previous urlinfo if provided. This makes relative - * redirects work. - */ - if (use_relative(rui)) - return fetch_url(url, NULL, NULL, NULL, rui); - - /* * Try FTP URL-style and host:file arguments next. * If ftpproxy is set with an FTP URL, use fetch_url() - * Otherwise, use fetch_ftp(). + * Othewise, use fetch_ftp(). */ proxyenv = getoptionvalue("ftp_proxy"); if (!EMPTYSTRING(proxyenv) && STRNEQUAL(url, FTP_URL)) - return (fetch_url(url, NULL, NULL, NULL, rui)); + return (fetch_url(url, NULL, NULL, NULL)); return (fetch_ftp(url)); } @@ -2343,11 +2248,10 @@ auto_fetch(int argc, char *argv[]) redirect_loop = 0; if (!anonftp) anonftp = 2; /* Handle "automatic" transfers. */ - rval = go_fetch(argv[argpos], NULL); + rval = go_fetch(argv[argpos]); if (outfile != NULL && strcmp(outfile, "-") != 0 - && outfile[0] != '|') { - FREEPTR(outfile); - } + && outfile[0] != '|') + outfile = NULL; if (rval > 0) rval = argpos + 1; } @@ -2382,7 +2286,7 @@ auto_put(int argc, char **argv, const ch pathsep = NULL; rval = 1; - DPRINTF("%s: target `%s'\n", __func__, uploadserver); + DPRINTF("auto_put: target `%s'\n", uploadserver); path = ftp_strdup(uploadserver); len = strlen(path); @@ -2391,7 +2295,7 @@ auto_put(int argc, char **argv, const ch * make sure we always pass a directory to auto_fetch */ if (argc > 1) { /* more than one file to upload */ - len = strlen(uploadserver) + 2; /* path + "/" + "\0" */ + len = strlen(uploadserver) + 2; /* path + "/" + "\0" */ free(path); path = (char *)ftp_malloc(len); (void)strlcpy(path, uploadserver, len); @@ -2415,7 +2319,7 @@ auto_put(int argc, char **argv, const ch uargc++; } } - DPRINTF("%s: URL `%s' argv[2] `%s'\n", __func__, + DPRINTF("auto_put: URL `%s' argv[2] `%s'\n", path, STRorNULL(uargv[2])); /* connect and cwd */ Index: src/usr.bin/ftp/ftp.1 diff -u src/usr.bin/ftp/ftp.1:1.135.8.1 src/usr.bin/ftp/ftp.1:1.135.8.2 --- src/usr.bin/ftp/ftp.1:1.135.8.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/ftp.1 Mon Sep 12 15:05:21 2022 @@ -1,6 +1,6 @@ -.\" $NetBSD: ftp.1,v 1.135.8.1 2022/09/12 14:46:51 martin Exp $ +.\" $NetBSD: ftp.1,v 1.135.8.2 2022/09/12 15:05:21 martin Exp $ .\" -.\" Copyright (c) 1996-2021 The NetBSD Foundation, Inc. +.\" Copyright (c) 1996-2015 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -57,7 +57,7 @@ .\" .\" @(#)ftp.1 8.3 (Berkeley) 10/9/94 .\" -.Dd August 29, 2022 +.Dd April 24, 2015 .Dt FTP 1 .Os .Sh NAME @@ -65,7 +65,7 @@ .Nd Internet file transfer program .Sh SYNOPSIS .Nm -.Op Fl 46AadefginpRtVv? +.Op Fl 46AadefginpRtVv .Op Fl N Ar netrc .Op Fl o Ar output .Op Fl P Ar port @@ -84,11 +84,12 @@ .Xc .Oc .Ek -.Op Fl x Ar xfersize +.Op Fl x Ar xferbufsize .Bk -words .\" [[user@]host [port]] .Oo -.Oo Ar user Ns Li \&@ Oc Ns Ar host Oo Ar port Oc +.Oo Ar user Ns Li \&@ Oc Ns Ar host +.Op Ar port .Oc .Ek .Bk -words @@ -121,7 +122,7 @@ .Ar host Oo Li \&: Ar port Oc .Li / Ar path .Op Li / -.Op Li ;type= Ar type +.Op Li ;type= Ar X .Oc .Sm on .Ek @@ -138,24 +139,12 @@ .Oc .Sm on .Ek -.Bk -words -.\" [https://[user[:password]@]host[:port]/path] -.Sm off -.Oo -.Li https:// -.Oo Ar user -.Op Li \&: Ar password -.Li \&@ Oc -.Ar host Oo Li \&: Ar port Oc -.Li / Ar path -.Oc -.Sm on -.Ek -.Ar \&... +.Op Ar \&.\&.\&. .Nm .Bk -words -.Fl u Ar url Ar +.Fl u Ar URL Ar file .Ek +.Op Ar \&.\&.\&. .Sh DESCRIPTION .Nm is the user interface to the Internet standard File Transfer Protocol. @@ -184,13 +173,10 @@ Forces .Nm to only use IPv6 addresses. .It Fl A -Force active mode -.Tn FTP . +Force active mode ftp. By default, .Nm -will try to use passive mode -.Tn FTP -and fall back to active mode +will try to use passive mode ftp and fall back to active mode if passive is not supported by the server. This option causes .Nm @@ -298,14 +284,12 @@ bytes/second. Refer to .Ic rate for more information. -.It Fl u Ar url Ar +.It Fl u Ar URL file Op \&.\&.\&. Upload files on the command line to -.Ar url +.Ar URL where -.Ar url -is one of the -.Sq Li ftp:// -URL types as supported by auto-fetch +.Ar URL +is one of the ftp URL types as supported by auto-fetch (with an optional target filename for single file uploads), and .Ar file is one or more local files to be uploaded. @@ -328,14 +312,12 @@ Forces .Nm to show all responses from the remote server, as well as report on data transfer statistics. -.It Fl x Ar xfersize +.It Fl x Ar xferbufsize Set the size of the socket send and receive buffers to -.Ar xfersize . +.Ar xferbufsize . Refer to .Ic xferbuf for more information. -.It Fl ? -Display help to stdout, and exit. .El .Pp The client host with which @@ -352,7 +334,7 @@ from the user. When .Nm is awaiting commands from the user the prompt -.Ql ftp> +.Ql ftp\*[Gt] is provided to the user. The following commands are recognized by @@ -460,16 +442,6 @@ when an ascii type transfer is made, the distinguished from a record delimiter only when .Ic \&cr is off. -.It Ic debug Op Ar debug-value -Toggle debugging mode. -If an optional -.Ar debug-value -is specified it is used to set the debugging level. -When debugging is on, -.Nm -prints each command sent to the remote machine, preceded -by the string -.Ql \-\-> . .It Ic delete Ar remote-file Delete the file .Ar remote-file @@ -505,16 +477,18 @@ Toggle command line editing, and context completion. This is automatically enabled if input is from a terminal, and disabled otherwise. -.It Ic epsv , epsv4 , epsv6 +.It Ic epsv epsv4 epsv6 Toggle the use of the extended .Dv EPSV and .Dv EPRT commands on all IP, IPv4, and IPv6 connections respectively. First try -.Dv EPSV Ns \^/\^ Ns Dv EPRT , +.Dv EPSV / +.Dv EPRT , and then -.Dv PASV Ns \^/\^ Ns Dv PORT . +.Dv PASV / +.Dv PORT . This is enabled by default. If an extended command fails then this option will be temporarily disabled for the duration of the current connection, or until @@ -545,11 +519,19 @@ format is .It Ic ftp Ar host Op Ar port A synonym for .Ic open . +.It Ic ftp_debug Op Ar ftp_debug-value +Toggle debugging mode. +If an optional +.Ar ftp_debug-value +is specified it is used to set the debugging level. +When debugging is on, +.Nm +prints each command sent to the remote machine, preceded +by the string +.Ql \-\-\*[Gt] . .It Ic gate Op Ar host Op Ar port Toggle gate-ftp mode, which used to connect through the -TIS FWTK and Gauntlet -.Tn FTP -proxies. +TIS FWTK and Gauntlet ftp proxies. This will not be permitted if the gate-ftp server hasn't been set (either explicitly by the user, or from the .Ev FTPSERVER @@ -607,11 +589,9 @@ each remote file name is expanded separately on the remote machine and the lists are not merged. Expansion of a directory name is likely to be different from expansion of the name of an ordinary file: -the exact result depends on the foreign operating system and -.Tn FTP -server, +the exact result depends on the foreign operating system and ftp server, and can be previewed by doing -.Sq Li mls remote-files \- . +.Ql mls remote-files \- Note: .Ic mget , .Ic mput @@ -692,32 +672,32 @@ To invoke a macro, use the command (see above). .Pp The macro processor interprets -.Ql $ +.Sq $ and -.Ql \e +.Sq \e as special characters. A -.Ql $ +.Sq $ followed by a number (or numbers) is replaced by the corresponding argument on the macro invocation command line. A -.Ql $ +.Sq $ followed by an -.Ql i +.Sq i signals the macro processor that the executing macro is to be looped. On the first pass -.Ql $i +.Dq $i is replaced by the first argument on the macro invocation command line, on the second pass it is replaced by the second argument, and so on. A -.Ql \e +.Sq \e followed by any character is replaced by that character. Use the -.Ql \e +.Sq \e to prevent special treatment of the -.Ql $ . +.Sq $ . .It Ic mdelete Op Ar remote-files Delete the .Ar remote-files @@ -752,7 +732,7 @@ Files are transferred into the local wor which can be changed with .Ql lcd directory ; new local directories can be created with -.Sq Li "\&! mkdir directory" . +.Ql "\&! mkdir directory" . .It Ic mkdir Ar directory-name Make a directory on the remote machine. .It Ic mls Ar remote-files local-file @@ -775,7 +755,7 @@ Display the contents of in a machine-parsable form, using .Dv MLSD . The format of display can be changed with -.Sq Li "remopts mlst ..." . +.Sq "remopts mlst ..." . .It Ic mlst Op Ar remote-path Display the details about .Ar remote-path @@ -783,7 +763,7 @@ Display the details about in a machine-parsable form, using .Dv MLST . The format of display can be changed with -.Sq Li "remopts mlst ..." . +.Sq "remopts mlst ..." . .It Ic mode Ar mode-name Set the file transfer .Ic mode @@ -829,7 +809,7 @@ If the file does not exist on the current system, the remote file is considered .Ic newer . Otherwise, this command is identical to -.Ic get . +.Ar get . .It Ic nlist Op Ar remote-path Op Ar local-file A synonym for .Ic ls . @@ -854,8 +834,7 @@ The mapping follows the pattern set by .Ar inpattern and .Ar outpattern . -.Pp -.Ar inpattern +.Op Ar Inpattern is a template for incoming filenames (which may have already been processed according to the .Ic ntrans @@ -864,16 +843,16 @@ and settings). Variable templating is accomplished by including the sequences -.Ql $1 , -.Ql $2 , -\&...\|, -.Ql $9 +.Dq $1 , +.Dq $2 , +\&... +.Dq $9 in .Ar inpattern . Use -.Ql \e +.Sq \e to prevent this special treatment of the -.Ql $ +.Sq $ character. All other characters are treated literally, and are used to determine the .Ic nmap @@ -881,72 +860,53 @@ All other characters are treated literal variable values. For example, given .Ar inpattern -.Sq Li $1.$2 -and the remote file name -.Sq Li mydata.data , -.Ql $1 -would have the value -.Sq Li mydata , -and -.Ql $2 -would have the value -.Sq Li data . -.Pp +$1.$2 and the remote file name "mydata.data", $1 would have the value +"mydata", and $2 would have the value "data". The .Ar outpattern determines the resulting mapped filename. The sequences -.Ql $1 , -.Ql $2 , -\&...\|, -.Ql $9 +.Dq $1 , +.Dq $2 , +\&... +.Dq $9 are replaced by any value resulting from the .Ar inpattern template. The sequence -.Ql $0 +.Dq $0 is replaced by the original filename. Additionally, the sequence .Dq Op Ar seq1 , Ar seq2 is replaced by -.Ar seq1 +.Op Ar seq1 if .Ar seq1 is not a null string; otherwise it is replaced by .Ar seq2 . For example, the command .Pp -.Dl nmap $1.$2.$3 [$1,$2].[$2,file] +.Bd -literal -offset indent -compact +nmap $1.$2.$3 [$1,$2].[$2,file] +.Ed .Pp would yield -the output filename -.Sq Li myfile.data -for input filenames -.Sq Li myfile.data -and -.Sq Li myfile.data.old , -.Sq Li myfile.file -for the input filename -.Sq Li myfile , -and -.Sq Li myfile.myfile -for the input filename -.Sq Li "\&.myfile" . +the output filename "myfile.data" for input filenames "myfile.data" and +"myfile.data.old", "myfile.file" for the input filename "myfile", and +"myfile.myfile" for the input filename ".myfile". Spaces may be included in .Ar outpattern , as in the example: -.Pp -.Dl nmap $1 sed "s/ *$//" > $1 -.Pp +.Dl nmap $1 sed "s/ *$//" \*[Gt] $1 Use the -.Ql \e +.Sq \e character to prevent special treatment of the -.Ql $ , -.Ql \&[ , -.Ql \&] , +.Sq $ , +.Sq \&[ , +.Sq \&] , and -.Ql \&, +.Sq \&, characters. .It Ic ntrans Op Ar inchars Op Ar outchars Set or unset the filename character translation mechanism. @@ -1067,7 +1027,7 @@ The progress bar will be disabled for a as .Sq Fl or a command that starts with -.Ql \&| . +.Sq \&| . Refer to .Sx FILE NAMING CONVENTIONS for more information. @@ -1121,9 +1081,7 @@ Any other response will answer .Sq yes to the current file. .It Ic proxy Ar ftp-command -Execute an -.Tn FTP -command on a secondary control connection. +Execute an ftp command on a secondary control connection. This command allows simultaneous connection to two remote .Tn FTP servers for transferring files between the two servers. @@ -1132,13 +1090,11 @@ The first command should be an .Ic open , to establish the secondary control connection. -Enter the command -.Sq Li "proxy ?" -to see other +Enter the command "proxy ?" to see other .Tn FTP commands executable on the secondary connection. The following commands behave differently when prefaced by -.Ic proxy\^ : +.Ic proxy : .Ic open will not define new macros during the auto-login process, .Ic close @@ -1183,7 +1139,7 @@ machine. .It Ic quit A synonym for .Ic bye . -.It Ic quote Op Ar arg ... +.It Ic quote Ar arg1 arg2 ... The arguments specified are sent, verbatim, to the remote .Tn FTP server. @@ -1197,7 +1153,7 @@ is 0, disable the throttle. .Pp .Ar direction may be one of: -.Bl -tag -width ".Cm all" -offset indent -compact +.Bl -tag -width "all" -offset indent -compact .It Cm all Both directions. .It Cm get @@ -1210,7 +1166,7 @@ Outgoing transfers. can be modified on the fly by .Ar increment bytes (default: 1024) each time a given signal is received: -.Bl -tag -width ".Dv SIGUSR1" -offset indent +.Bl -tag -width "SIGUSR1" -offset indent .It Dv SIGUSR1 Increment .Ar maximum @@ -1268,7 +1224,7 @@ to Remote .Tn FTP commands known to support options include: -.Dv MLST +.Sq MLST (used for .Dv MLSD and @@ -1321,16 +1277,10 @@ local filename for a .Ic get or .Ic mget -command, a -.Ql \&.1 -is appended to the name. +command, a ".1" is appended to the name. If the resulting name matches another existing file, -a -.Ql \&.2 -is appended to the original name. -If this process continues up to -.Ql .99 , -an error +a ".2" is appended to the original name. +If this process continues up to ".99", an error message is printed, and the transfer does not take place. The generated unique filename will be reported. Note that @@ -1408,7 +1358,7 @@ Defaults to Defaults to .Ev $FTPRPROMPT . .El -.It Ic site Op Ar arg ... +.It Ic site Ar arg1 arg2 ... The arguments specified are sent, verbatim, to the remote .Tn FTP server as a @@ -1529,7 +1479,7 @@ A synonym for .Pp Command arguments which have embedded spaces may be quoted with quote -.Ql \&\(dq +.Sq \&" marks. .Pp Commands which toggle settings can take an explicit @@ -1564,7 +1514,7 @@ If receives a .Dv SIGINFO (see the -.Cm status +.Dq status argument of .Xr stty 1 ) or @@ -1594,7 +1544,7 @@ contains a glob character and globbing i (see .Ic glob ) , then the equivalent of -.Sq Li mget path +.Ql mget path is performed. .Pp If the directory component of @@ -1607,10 +1557,10 @@ of 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=type] +.\" ftp://[user[:password]@]host[:port]/path[/][;type=X] .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 type Oc +Ns Oo Li ;type= Ns Ar X Oc An .Tn FTP URL, retrieved using the @@ -1633,9 +1583,9 @@ In this case, use if supplied, otherwise prompt the user for one. .Pp If a suffix of -.Sq Li \&;type=A +.Sq ;type=A or -.Sq Li \&;type=I +.Sq ;type=I is supplied, then the transfer type will take place as ascii or binary (respectively). The default transfer type is binary. @@ -1646,7 +1596,7 @@ In order to be compliant with interprets the .Ar path part of an -.Sq Li ftp:// +.Dq ftp:// auto-fetch URL as follows: .Bl -bullet .It @@ -1726,20 +1676,20 @@ user. If the .Pa / directory is required, use a leading path of -.Sq Li \&%2F . +.Dq %2F . If a user's home directory is required (and the remote server supports the syntax), use a leading path of -.Sq Li \&%7E Ns Ar user Ns Li / . +.Dq %7Euser/ . For example, to retrieve .Pa /etc/motd from -.Sq Li localhost +.Sq localhost as the user -.Sq Li myname +.Sq myname with the password -.Sq Li mypass , +.Sq mypass , use -.Sq Li ftp://myname:mypass@localhost/%2fetc/motd +.Dq ftp://myname:mypass@localhost/%2fetc/motd .It The exact .Ic cd @@ -1747,11 +1697,11 @@ and .Ic get commands can be controlled by careful choice of where to use -.Sq Li / +.Sq / and where to use -.Sq Li \&%2F +.Sq %2F (or -.Sq Li %2f ) . +.Sq %2f ) . For example, the following URLs correspond to the equivalents of the indicated commands: .Bl -tag -width "ftp://host/%2Fdir1%2Fdir2%2Ffile" @@ -1798,9 +1748,9 @@ If authorization is required to retrieve .Ar path , and -.Ar user +.Sq user (and optionally -.Ar password\^ ) +.Sq password ) is in the URL, use them for the first attempt to authenticate. .\" https://[user[:password]@]host[:port]/path .It Li https:// Ns Oo Ar user Ns Oo Li \&: Ns Ar password Oc Ns Li \&@ Oc \ @@ -1820,9 +1770,9 @@ If authorization is required to retrieve .Ar path , and -.Ar user +.Sq user (and optionally -.Ar password\^ ) +.Sq password ) is in the URL, use them for the first attempt to authenticate. There is currently no certificate validation and verification. .\" file:///path @@ -1865,7 +1815,7 @@ is recommended, to avoid writing to unex If a classic format or an .Tn FTP URL format has a trailing -.Ql / +.Sq / or an empty .Ar path component, then @@ -1897,9 +1847,9 @@ proxies will be restarted. For .Tn FTP , this is implemented by using -.Ic reget +.Nm reget instead of -.Ic get . +.Nm get . For .Tn HTTP , this is implemented by using the @@ -1913,7 +1863,7 @@ to enter a username and password to auth When specifying IPv6 numeric addresses in a URL, you need to surround the address in square brackets. E.g.: -.Sq Li ftp://[::1]:21/ . +.Dq ftp://[::1]:21/ . This is because colons are used in IPv6 numeric address as well as being the separator for the port number. .Sh ABORTING A FILE TRANSFER @@ -1936,9 +1886,7 @@ sending the requested file. .Pp If the terminal interrupt key sequence is used whilst .Nm -is awaiting a reply from the remote server for the -.Dv ABOR -processing, +is awaiting a reply from the remote server for the ABOR processing, then the connection will be closed. This is different from the traditional behaviour (which ignores the terminal interrupt during this phase), but is considered more useful. @@ -1951,13 +1899,13 @@ commands are processed according to the If the file name .Sq Fl is specified, the -.Va stdin +.Ar stdin (for reading) or -.Va stdout +.Ar stdout (for writing) is used. .It If the first character of the file name is -.Ql \&| , +.Sq \&| , the remainder of the argument is interpreted as a shell command. .Nm @@ -1967,12 +1915,13 @@ with the argument supplied, and reads (w (stdin). If the shell command includes spaces, the argument must be quoted; e.g. -.Sq Li \(dq|\~ls\~\-lt\(dq . +.Dq Qq Li \&| ls\ \-lt . A particularly useful example of this mechanism is: -.Sq Li dir\~\(dq\(dq\~|more . +.Dq Li dir \&"\&" \&|more . .It -Failing the above checks, if globbing +Failing the above checks, if +.Dq globbing is enabled, local file names are expanded according to the rules used in the .Xr csh 1 ; @@ -1983,7 +1932,7 @@ If the .Nm command expects a single local file (e.g. .Ic put ) , -only the first filename generated by the globbing operation is used. +only the first filename generated by the "globbing" operation is used. .It For .Ic mget @@ -2184,7 +2133,7 @@ The .Xr editline 3 library is configured with a .Pa .editrc -file \(em refer to +file - refer to .Xr editrc 5 for more information. .Pp @@ -2201,7 +2150,7 @@ By default, this is bound to the TAB key By default, .Nm displays a command line prompt of -.Sq Li ftp>\~ +.Dq "ftp\*[Gt] " to the user. This can be changed with the .Ic "set prompt" @@ -2218,42 +2167,42 @@ information: .It Li \&%/ The current remote working directory. .\" %c[[0]n], %.[[0]n] -.It Li \&%c Ns Oo Oo Li 0 Oc Ns Ar n Oc , Li \&%. Ns Oo Oo Li 0 Oc Ns Ar n Oc +.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 -.Ar n +.Em n trailing components if a digit -.Ar n +.Em n is given. If -.Ar n +.Em n begins with -.Ql 0 , +.Sq 0 , the number of skipped components precede the trailing component(s) in the format .\" ``/<number>trailing'' .Do .Sm off -.Li / Li < Ar number Li > -.Ar trailing +.Li / Li \*[Lt] Va number Li \*[Gt] +.Va trailing .Sm on .Dc (for -.Ql \&%c ) +.Sq \&%c ) or .\" ``...trailing'' -.Dq Li \&... Ns Ar trailing +.Dq Li \&... Ns Va trailing (for -.Ql \&%. ) . +.Sq \&%. ) . .It Li \&%M The remote host name. .It Li \&%m -The remote host name, up to the first dot -.Ql \&. . +The remote host name, up to the first +.Sq \&. . .It Li \&%n The remote user name. .It Li \&%% -A single percent character -.Ql % . +A single +.Sq % . .El .Sh ENVIRONMENT .Nm @@ -2264,7 +2213,7 @@ Password to send in an anonymous .Tn FTP transfer. Defaults to -.Dq Li \&\`whoami\`@ . +.Dq Li `whoami`@ . .It Ev FTPMODE Overrides the default operation mode. Support values are: @@ -2285,13 +2234,14 @@ only .It Ev FTPPROMPT Command-line prompt to use. Defaults to -.Sq Li ftp>\~ . +.Dq "ftp\*[Gt] " . Refer to .Sx COMMAND LINE PROMPT for more information. .It Ev FTPRPROMPT Command-line right side prompt to use. -Defaults to empty string. +Defaults to +.Dq "" . Refer to .Sx COMMAND LINE PROMPT for more information. @@ -2304,9 +2254,9 @@ Port to use when connecting to gate-ftp .Ic gate is enabled. Default is port returned by a -.Xr getservbyname 3 +.Fn getservbyname lookup of -.Dq Li ftpgate/tcp . +.Dq ftpgate/tcp . .It Ev FTPUSERAGENT The value to send for the .Tn HTTP @@ -2320,8 +2270,6 @@ file, if one exists. An alternate location of the .Pa .netrc file. -.It Ev NO_CERT_VERIFY -Don't verify SSL certificates. .It Ev PAGER Used by various commands to display files. Defaults to @@ -2356,9 +2304,9 @@ If .Dq unsafe URL characters are required in the username or password (for example -.Ql @ +.Sq @ or -.Ql / ) , +.Sq / ) , encode them with .Li RFC 3986 .Sq Li \&% Ns Ar XX @@ -2375,22 +2323,10 @@ may be incompatible with other programs .Em NOTE : this is not used for interactive sessions, only for command-line fetches. -.It Ev https_proxy -URL of -.Tn HTTPS -proxy to use when making -.Tn HTTPS -URL requests. -.Pp -See -.Ev http_proxy -for further notes about proxy use. .It Ev no_proxy A space or comma separated list of hosts (or domains) for which proxying is not to be used. -Each entry may have an optional trailing -.Sq Li \&: Ns Ar port , -which restricts +Each entry may have an optional trailing ":port", which restricts the matching to connections to that port. .El .Sh EXTENDED PASSIVE MODE AND FIREWALLS Index: src/usr.bin/ftp/ftp.c diff -u src/usr.bin/ftp/ftp.c:1.167.6.1 src/usr.bin/ftp/ftp.c:1.167.6.2 --- src/usr.bin/ftp/ftp.c:1.167.6.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/ftp.c Mon Sep 12 15:05:21 2022 @@ -1,7 +1,7 @@ -/* $NetBSD: ftp.c,v 1.167.6.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: ftp.c,v 1.167.6.2 2022/09/12 15:05:21 martin Exp $ */ /*- - * Copyright (c) 1996-2021 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.167.6.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: ftp.c,v 1.167.6.2 2022/09/12 15:05:21 martin Exp $"); #endif #endif /* not lint */ @@ -280,11 +280,6 @@ hookup(const char *host, const char *por goto bad; } - if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, - (void *)&on, sizeof(on)) == -1) { - DWARN("setsockopt %s (ignored)", "SO_KEEPALIVE"); - } - if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *)&on, sizeof(on)) == -1) { DWARN("setsockopt %s (ignored)", "SO_OOBINLINE"); @@ -325,17 +320,6 @@ cmdtimeout(int notused) errno = oerrno; } -static int -issighandler(sigfunc func) -{ - return (func != SIG_IGN && - func != SIG_DFL && -#ifdef SIG_HOLD - func != SIG_HOLD && -#endif - func != SIG_ERR); -} - /*VARARGS*/ int command(const char *fmt, ...) @@ -375,9 +359,8 @@ command(const char *fmt, ...) (void)fflush(cout); cpend = 1; r = getreply(!strcmp(fmt, "QUIT")); - if (abrtflag && issighandler(oldsigint)) { + if (abrtflag && oldsigint != SIG_IGN) (*oldsigint)(SIGINT); - } (void)xsignal(SIGINT, oldsigint); return (r); } @@ -527,14 +510,11 @@ getreply(int expecteof) (void)xsignal(SIGALRM, oldsigalrm); if (code == 421 || originalcode == 421) lostpeer(0); - if (abrtflag && oldsigint != cmdabort && - issighandler(oldsigint)) { + if (abrtflag && oldsigint != cmdabort && oldsigint != SIG_IGN) (*oldsigint)(SIGINT); - } if (timeoutflag && oldsigalrm != cmdtimeout && - issighandler(oldsigalrm)) { + oldsigalrm != SIG_IGN) (*oldsigalrm)(SIGINT); - } return (n - '0'); } } @@ -598,7 +578,7 @@ abortxfer(int notused) /* * Read data from infd & write to outfd, using buf/bufsize as the temporary - * buffer, dealing with short reads or writes. + * buffer, dealing with short writes. * If rate_limit != 0, rate-limit the transfer. * If hash_interval != 0, fputc('c', ttyout) every hash_interval bytes. * Updates global variables: bytes. @@ -632,25 +612,15 @@ copy_bytes(int infd, int outfd, char *bu bufrem = bufchunk; while (bufrem > 0) { inc = read(infd, buf, MIN((off_t)bufsize, bufrem)); - if (inc < 0) { - if (errno == EINTR || errno == EAGAIN) { - continue; - } - goto copy_done; - } else if (inc == 0) { + if (inc <= 0) goto copy_done; - } bytes += inc; bufrem -= inc; bufp = buf; while (inc > 0) { outc = write(outfd, bufp, inc); - if (outc < 0) { - if (errno == EINTR || errno == EAGAIN) { - continue; - } + if (outc < 0) goto copy_done; - } inc -= outc; bufp += outc; } @@ -700,7 +670,7 @@ sendrequest(const char *cmd, const char FILE *volatile dout; int (*volatile closefunc)(FILE *); sigfunc volatile oldintr; - sigfunc volatile oldpipe; + sigfunc volatile oldintp; off_t volatile hashbytes; int hash_interval; const char *lmode; @@ -727,8 +697,8 @@ sendrequest(const char *cmd, const char if (curtype != type) changetype(type, 0); closefunc = NULL; - oldintr = SIG_ERR; - oldpipe = SIG_ERR; + oldintr = NULL; + oldintp = NULL; lmode = "w"; if (sigsetjmp(xferabort, 1)) { while (cpend) @@ -742,7 +712,7 @@ sendrequest(const char *cmd, const char fin = stdin; progress = 0; } else if (*local == '|') { - oldpipe = xsignal(SIGPIPE, SIG_IGN); + oldintp = xsignal(SIGPIPE, SIG_IGN); fin = popen(local + 1, "r"); if (fin == NULL) { warn("Can't execute `%s'", local + 1); @@ -816,9 +786,7 @@ sendrequest(const char *cmd, const char } progressmeter(-1); - if (oldpipe == SIG_ERR) { - oldpipe = xsignal(SIGPIPE, SIG_IGN); - } + oldintp = xsignal(SIGPIPE, SIG_IGN); hash_interval = (hash && (!progress || filesize < 0)) ? mark : 0; switch (curtype) { @@ -887,7 +855,7 @@ sendrequest(const char *cmd, const char abort: (void)xsignal(SIGINT, oldintr); - oldintr = SIG_ERR; + oldintr = NULL; if (!cpend) { code = -1; goto cleanupsend; @@ -906,10 +874,10 @@ sendrequest(const char *cmd, const char ptransfer(0); cleanupsend: - if (oldintr != SIG_ERR) + if (oldintr) (void)xsignal(SIGINT, oldintr); - if (oldpipe != SIG_ERR) - (void)xsignal(SIGPIPE, oldpipe); + if (oldintp) + (void)xsignal(SIGPIPE, oldintp); if (data >= 0) { (void)close(data); data = -1; @@ -931,7 +899,7 @@ recvrequest(const char *cmd, const char FILE *volatile din; int (*volatile closefunc)(FILE *); sigfunc volatile oldintr; - sigfunc volatile oldpipe; + sigfunc volatile oldintp; int c, d; int volatile is_retr; int volatile tcrflag; @@ -967,8 +935,8 @@ recvrequest(const char *cmd, const char return; } closefunc = NULL; - oldintr = SIG_ERR; - oldpipe = SIG_ERR; + oldintr = NULL; + oldintp = NULL; tcrflag = !crflag && is_retr; if (sigsetjmp(xferabort, 1)) { while (cpend) @@ -1049,7 +1017,7 @@ recvrequest(const char *cmd, const char progress = 0; preserve = 0; } else if (!ignorespecial && *local == '|') { - oldpipe = xsignal(SIGPIPE, SIG_IGN); + oldintp = xsignal(SIGPIPE, SIG_IGN); fout = popen(local + 1, "w"); if (fout == NULL) { warn("Can't execute `%s'", local+1); @@ -1215,10 +1183,10 @@ recvrequest(const char *cmd, const char ptransfer(0); cleanuprecv: - if (oldintr != SIG_ERR) + if (oldintr) (void)xsignal(SIGINT, oldintr); - if (oldpipe != SIG_ERR) - (void)xsignal(SIGPIPE, oldpipe); + if (oldintp) + (void)xsignal(SIGPIPE, oldintp); if (data >= 0) { (void)close(data); data = -1; @@ -1381,11 +1349,13 @@ initconn(void) if (data_addr.su_family != AF_INET) { fputs( "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); + error = 1; goto bad; } if (code / 10 == 22 && code != 227) { fputs("wrong server: return code must be 227\n", ttyout); + error = 1; goto bad; } error = sscanf(pasv, "%u,%u,%u,%u,%u,%u", @@ -1394,24 +1364,21 @@ initconn(void) if (error != 6) { fputs( "Passive mode address scan failure. Shouldn't happen!\n", ttyout); + error = 1; goto bad; } + error = 0; memset(&data_addr, 0, sizeof(data_addr)); data_addr.su_family = AF_INET; data_addr.su_len = sizeof(struct sockaddr_in); data_addr.si_su.su_sin.sin_addr.s_addr = htonl(pack4(addr, 0)); data_addr.su_port = htons(pack2(port, 0)); - if (data_addr.si_su.su_sin.sin_addr.s_addr != - hisctladdr.si_su.su_sin.sin_addr.s_addr) { - fputs("Passive mode address mismatch.\n", - ttyout); - goto bad; - } } else if (strcmp(pasvcmd, "LPSV") == 0) { if (code / 10 == 22 && code != 228) { fputs("wrong server: return code must be 228\n", ttyout); + error = 1; goto bad; } switch (data_addr.su_family) { @@ -1424,26 +1391,23 @@ initconn(void) if (error != 9) { fputs( "Passive mode address scan failure. Shouldn't happen!\n", ttyout); + error = 1; goto bad; } if (af != 4 || hal != 4 || pal != 2) { fputs( "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); + error = 1; goto bad; } + error = 0; memset(&data_addr, 0, sizeof(data_addr)); data_addr.su_family = AF_INET; data_addr.su_len = sizeof(struct sockaddr_in); data_addr.si_su.su_sin.sin_addr.s_addr = htonl(pack4(addr, 0)); data_addr.su_port = htons(pack2(port, 0)); - if (data_addr.si_su.su_sin.sin_addr.s_addr != - hisctladdr.si_su.su_sin.sin_addr.s_addr) { - fputs("Passive mode address mismatch.\n", - ttyout); - goto bad; - } break; #ifdef INET6 case AF_INET6: @@ -1459,14 +1423,17 @@ initconn(void) if (error != 21) { fputs( "Passive mode address scan failure. Shouldn't happen!\n", ttyout); + error = 1; goto bad; } if (af != 6 || hal != 16 || pal != 2) { fputs( "Passive mode AF mismatch. Shouldn't happen!\n", ttyout); + error = 1; goto bad; } + error = 0; memset(&data_addr, 0, sizeof(data_addr)); data_addr.su_family = AF_INET6; data_addr.su_len = sizeof(struct sockaddr_in6); @@ -1478,19 +1445,10 @@ initconn(void) } } data_addr.su_port = htons(pack2(port, 0)); - if (memcmp( - &data_addr.si_su.su_sin6.sin6_addr, - &hisctladdr.si_su.su_sin6.sin6_addr, - sizeof(data_addr.si_su.su_sin6.sin6_addr))) { - fputs("Passive mode address mismatch.\n", - ttyout); - goto bad; - } break; #endif default: - fputs("Unknown passive mode AF.\n", ttyout); - goto bad; + error = 1; } } else if (strcmp(pasvcmd, "EPSV") == 0) { char delim[4]; @@ -1499,17 +1457,20 @@ initconn(void) if (code / 10 == 22 && code != 229) { fputs("wrong server: return code must be 229\n", ttyout); + error = 1; goto bad; } if (sscanf(pasv, "%c%c%c%d%c", &delim[0], &delim[1], &delim[2], &port[1], &delim[3]) != 5) { fputs("parse error!\n", ttyout); + error = 1; goto bad; } if (delim[0] != delim[1] || delim[0] != delim[2] || delim[0] != delim[3]) { fputs("parse error!\n", ttyout); + error = 1; goto bad; } data_addr = hisctladdr; @@ -1592,8 +1553,8 @@ initconn(void) result = COMPLETE + 1; break; } -#ifdef INET6 /* FALLTHROUGH */ +#ifdef INET6 case AF_INET6: if (!epsv6 || epsv6bad) { result = COMPLETE + 1; @@ -1895,7 +1856,7 @@ proxtrans(const char *cmd, const char *l int volatile secndflag; const char *volatile cmd2; - oldintr = SIG_ERR; + oldintr = NULL; secndflag = 0; if (strcmp(cmd, "RETR")) cmd2 = "RETR"; @@ -2086,7 +2047,7 @@ gunique(const char *local) * needs to get back to a known state. */ static void -abort_squared(int signo) +abort_squared(int dummy) { char msgbuf[100]; size_t len; @@ -2096,7 +2057,7 @@ abort_squared(int signo) len = strlcpy(msgbuf, "\nremote abort aborted; closing connection.\n", sizeof(msgbuf)); write(fileno(ttyout), msgbuf, len); - lostpeer(signo); + lostpeer(0); siglongjmp(xferabort, 1); } Index: src/usr.bin/ftp/ftp_var.h diff -u src/usr.bin/ftp/ftp_var.h:1.84.8.1 src/usr.bin/ftp/ftp_var.h:1.84.8.2 --- src/usr.bin/ftp/ftp_var.h:1.84.8.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/ftp_var.h Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ftp_var.h,v 1.84.8.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: ftp_var.h,v 1.84.8.2 2022/09/12 15:05:21 martin Exp $ */ /*- * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. @@ -269,7 +269,6 @@ GLOBAL int unix_server; /* server is uni GLOBAL int unix_proxy; /* proxy is unix, can use binary for ascii */ GLOBAL char localcwd[MAXPATHLEN]; /* local dir */ GLOBAL char remotecwd[MAXPATHLEN]; /* remote dir */ -GLOBAL int remcwdvalid; /* remotecwd has been updated */ GLOBAL char *username; /* name of user logged in as. (dynamic) */ GLOBAL sa_family_t family; /* address family to use for connections */ @@ -341,7 +340,7 @@ extern struct option optiontab[]; #define DPRINTF(...) (void)0 #define DWARN(...) (void)0 #else -#define DWFTP(a) do a; while (0) +#define DWFTP(a) do a; while (/*CONSTCOND*/0) #define DPRINTF(...) DWFTP(if (ftp_debug) (void)fprintf(ttyout, __VA_ARGS__)) #define DWARN(...) DWFTP(if (ftp_debug) warn(__VA_ARGS__)) #endif Index: src/usr.bin/ftp/main.c diff -u src/usr.bin/ftp/main.c:1.123.8.1 src/usr.bin/ftp/main.c:1.123.8.2 --- src/usr.bin/ftp/main.c:1.123.8.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/main.c Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.123.8.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: main.c,v 1.123.8.2 2022/09/12 15:05:21 martin Exp $ */ /*- * Copyright (c) 1996-2015 The NetBSD Foundation, Inc. @@ -98,7 +98,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 19 #if 0 static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94"; #else -__RCSID("$NetBSD: main.c,v 1.123.8.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: main.c,v 1.123.8.2 2022/09/12 15:05:21 martin Exp $"); #endif #endif /* not lint */ @@ -130,8 +130,7 @@ __RCSID("$NetBSD: main.c,v 1.123.8.1 202 #define NO_PROXY "no_proxy" /* env var with list of non-proxied * hosts, comma or space separated */ -static int usage(void); -static int usage_help(void); +__dead static void usage(void); static void setupoption(const char *, const char *, const char *); int @@ -267,7 +266,7 @@ main(int volatile argc, char **volatile } } - while ((ch = getopt(argc, argv, ":46AadefginN:o:pP:q:r:Rs:tT:u:vVx:")) != -1) { + while ((ch = getopt(argc, argv, "46AadefginN:o:pP:q:r:Rs:tT:u:vVx:")) != -1) { switch (ch) { case '4': family = AF_INET; @@ -325,7 +324,7 @@ main(int volatile argc, char **volatile break; case 'o': - outfile = ftp_strdup(optarg); + outfile = optarg; if (strcmp(outfile, "-") == 0) ttyout = stderr; break; @@ -379,15 +378,15 @@ main(int volatile argc, char **volatile if (*cp == '\0') { warnx("Bad throttle value `%s'", optarg); - return usage(); + usage(); + /* NOTREACHED */ } targv[targc++] = cp; if (targc >= 5) break; } - if (parserate(targc, targv, 1) == -1) { - return usage(); - } + if (parserate(targc, targv, 1) == -1) + usage(); free(oac); break; } @@ -416,19 +415,8 @@ main(int volatile argc, char **volatile rcvbuf_size = sndbuf_size; break; - case '?': - if (optopt == '?') { - return usage_help(); - } - warnx("-%c: unknown option", optopt); - return usage(); - - case ':': - warnx("-%c: missing argument", optopt); - return usage(); - default: - errx(1, "unimplemented option -%c", ch); + usage(); } } /* set line buffering on ttyout */ @@ -476,6 +464,7 @@ main(int volatile argc, char **volatile if (localhome == NULL && !EMPTYSTRING(pw->pw_dir)) localhome = ftp_strdup(pw->pw_dir); localname = ftp_strdup(pw->pw_name); + anonuser = localname; } if (netrc[0] == '\0' && localhome != NULL) { if (strlcpy(netrc, localhome, sizeof(netrc)) >= sizeof(netrc) || @@ -584,9 +573,8 @@ main(int volatile argc, char **volatile retry_connect = 0; /* connected, stop hiding msgs */ } } - if (isupload) { - return usage(); - } + if (isupload) + usage(); #ifndef NO_EDITCOMPLETE controlediting(); @@ -673,7 +661,7 @@ cmdscanner(void) case -2: /* error */ if (fromatty) putc('\n', ttyout); - justquit(); + quit(0, NULL); /* NOTREACHED */ case -3: /* too long; try again */ fputs("Sorry, input line is too long.\n", @@ -695,7 +683,7 @@ cmdscanner(void) if (buf == NULL || num == 0) { if (fromatty) putc('\n', ttyout); - justquit(); + quit(0, NULL); } if (num >= sizeof(line)) { fputs("Sorry, input line is too long.\n", @@ -849,6 +837,7 @@ slurpstring(void) slrflag++; INC_CHKCURSOR(stringbase); return ((*sb == '!') ? bangstr : dollarstr); + /* NOTREACHED */ case 1: slrflag++; altarg = stringbase; @@ -977,7 +966,7 @@ help(int argc, char *argv[]) cmd = argv[0]; isusage = (strcmp(cmd, "usage") == 0); if (argc == 0 || (isusage && argc == 1)) { - UPRINTF("usage: %s [command ...]\n", cmd); + UPRINTF("usage: %s [command [...]]\n", cmd); return; } if (argc == 1) { @@ -1056,69 +1045,20 @@ setupoption(const char *name, const char set_option(name, value ? value : defaultvalue, 0); } -static void -synopsis(FILE * stream) +void +usage(void) { - const char * progname = getprogname(); + const char *progname = getprogname(); - fprintf(stream, -"usage: %s [-46AadefginpRtVv] [-N NETRC] [-o OUTPUT] [-P PORT] [-q QUITTIME]\n" -" [-r RETRY] [-s SRCADDR] [-T DIR,MAX[,INC]] [-x XFERSIZE]\n" -" [[USER@]HOST [PORT]]\n" -" [[USER@]HOST:[PATH][/]]\n" -" [file:///PATH]\n" -" [ftp://[USER[:PASSWORD]@]HOST[:PORT]/PATH[/][;type=TYPE]]\n" -" [http://[USER[:PASSWORD]@]HOST[:PORT]/PATH]\n" + (void)fprintf(stderr, +"usage: %s [-46AadefginpRtVv] [-N netrc] [-o outfile] [-P port] [-q quittime]\n" +" [-r retry] [-s srcaddr] [-T dir,max[,inc]] [-x xferbufsize]\n" +" [[user@]host [port]] [host:path[/]] [file:///file]\n" +" [ftp://[user[:pass]@]host[:port]/path[/]]\n" +" [http://[user[:pass]@]host[:port]/path] [...]\n" #ifdef WITH_SSL -" [https://[USER[:PASSWORD]@]HOST[:PORT]/PATH]\n" +" [https://[user[:pass]@]host[:port]/path] [...]\n" #endif -" ...\n" -" %s -u URL FILE ...\n" -" %s -?\n", - progname, progname, progname); -} - -static int -usage_help(void) -{ - synopsis(stdout); -#ifndef NO_USAGE - printf( -" -4 Only use IPv4 addresses\n" -" -6 Only use IPv6 addresses\n" -" -A Force active mode\n" -" -a Use anonymous login\n" -" -d Enable debugging\n" -" -e Disable command-line editing\n" -" -f Force cache reload for FTP or HTTP proxy transfers\n" -" -g Disable file name globbing\n" -" -i Disable interactive prompt during multiple file transfers\n" -" -N NETRC Use NETRC instead of ~/.netrc\n" -" -n Disable auto-login\n" -" -o OUTPUT Save auto-fetched files to OUTPUT\n" -" -P PORT Use port PORT\n" -" -p Force passive mode\n" -" -q QUITTIME Quit if connection stalls for QUITTIME seconds\n" -" -R Restart non-proxy auto-fetch\n" -" -r RETRY Retry failed connection attempts after RETRY seconds\n" -" -s SRCADDR Use source address SRCADDR\n" -" -t Enable packet tracing\n" -" -T DIR,MAX[,INC]\n" -" Set maximum transfer rate for direction DIR to MAX bytes/s,\n" -" with optional increment INC bytes/s\n" -" -u URL URL to upload file arguments to\n" -" -V Disable verbose and progress\n" -" -v Enable verbose and progress\n" -" -x XFERSIZE Set socket send and receive size to XFERSIZE\n" -" -? Display this help and exit\n" - ); -#endif - return EXIT_SUCCESS; -} - -static int -usage(void) -{ - synopsis(stderr); - return EXIT_FAILURE; +" %s -u URL file [...]\n", progname, progname); + exit(1); } Index: src/usr.bin/ftp/progressbar.c diff -u src/usr.bin/ftp/progressbar.c:1.22.24.1 src/usr.bin/ftp/progressbar.c:1.22.24.2 --- src/usr.bin/ftp/progressbar.c:1.22.24.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/progressbar.c Mon Sep 12 15:05:21 2022 @@ -1,7 +1,7 @@ -/* $NetBSD: progressbar.c,v 1.22.24.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: progressbar.c,v 1.22.24.2 2022/09/12 15:05:21 martin Exp $ */ /*- - * Copyright (c) 1997-2021 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.22.24.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: progressbar.c,v 1.22.24.2 2022/09/12 15:05:21 martin Exp $"); #endif /* not lint */ /* @@ -87,7 +87,6 @@ updateprogressmeter(int dummy) /* * List of order of magnitude suffixes, per IEC 60027-2. */ -#if !defined(NO_PROGRESS) || !defined(STANDALONE_PROGRESS) static const char * const suffixes[] = { "", /* 2^0 (byte) */ "KiB", /* 2^10 Kibibyte */ @@ -103,7 +102,6 @@ static const char * const suffixes[] = { #endif }; #define NSUFFIXES (int)(sizeof(suffixes) / sizeof(suffixes[0])) -#endif /* * Display a transfer progress bar if progress is non-zero. @@ -141,10 +139,8 @@ progressmeter(int flag) * these appropriately. */ #endif -#if !defined(NO_PROGRESS) || !defined(STANDALONE_PROGRESS) size_t len; char buf[256]; /* workspace for progress bar */ -#endif #ifndef NO_PROGRESS #define BAROVERHEAD 45 /* non `*' portion of progress bar */ /* @@ -193,7 +189,7 @@ progressmeter(int flag) if (quit_time > 0 || progress) { #endif /* !STANDALONE_PROGRESS */ if (flag == -1) { - (void)xsignal(SIGALRM, updateprogressmeter); + (void)xsignal_restart(SIGALRM, updateprogressmeter, 1); alarmtimer(1); /* set alarm timer for 1 Hz */ } else if (flag == 1) { alarmtimer(0); @@ -404,21 +400,73 @@ alarmtimer(int wait) setitimer(ITIMER_REAL, &itv, NULL); } + /* - * Install a non-restartable POSIX signal handler. + * Install a POSIX signal handler, allowing the invoker to set whether + * the signal should be restartable or not */ sigfunc -xsignal(int sig, sigfunc func) +xsignal_restart(int sig, sigfunc func, int restartable) { struct sigaction act, oact; act.sa_handler = func; sigemptyset(&act.sa_mask); - act.sa_flags = 0; -#if defined(SA_INTERRUPT) /* SunOS 4.x */ - act.sa_flags = SA_INTERRUPT; +#if defined(SA_RESTART) /* 4.4BSD, Posix(?), SVR4 */ + act.sa_flags = restartable ? SA_RESTART : 0; +#elif defined(SA_INTERRUPT) /* SunOS 4.x */ + act.sa_flags = restartable ? 0 : SA_INTERRUPT; +#else +#error "system must have SA_RESTART or SA_INTERRUPT" #endif if (sigaction(sig, &act, &oact) < 0) return (SIG_ERR); return (oact.sa_handler); } + +/* + * Install a signal handler with the `restartable' flag set dependent upon + * which signal is being set. (This is a wrapper to xsignal_restart()) + */ +sigfunc +xsignal(int sig, sigfunc func) +{ + int restartable; + + /* + * Some signals print output or change the state of the process. + * There should be restartable, so that reads and writes are + * not affected. Some signals should cause program flow to change; + * these signals should not be restartable, so that the system call + * will return with EINTR, and the program will go do something + * different. If the signal handler calls longjmp() or siglongjmp(), + * it doesn't matter if it's restartable. + */ + + switch(sig) { +#ifdef SIGINFO + case SIGINFO: +#endif + case SIGQUIT: + case SIGUSR1: + case SIGUSR2: + case SIGWINCH: + restartable = 1; + break; + + case SIGALRM: + case SIGINT: + case SIGPIPE: + restartable = 0; + break; + + default: + /* + * This is unpleasant, but I don't know what would be better. + * Right now, this "can't happen" + */ + errx(1, "xsignal_restart: called with signal %d", sig); + } + + return(xsignal_restart(sig, func, restartable)); +} Index: src/usr.bin/ftp/progressbar.h diff -u src/usr.bin/ftp/progressbar.h:1.8.38.1 src/usr.bin/ftp/progressbar.h:1.8.38.2 --- src/usr.bin/ftp/progressbar.h:1.8.38.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/progressbar.h Mon Sep 12 15:05:21 2022 @@ -1,7 +1,7 @@ -/* $NetBSD: progressbar.h,v 1.8.38.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: progressbar.h,v 1.8.38.2 2022/09/12 15:05:21 martin Exp $ */ /*- - * Copyright (c) 1996-2021 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 @@ -68,6 +68,7 @@ int foregroundproc(void); void alarmtimer(int); void progressmeter(int); sigfunc xsignal(int, sigfunc); +sigfunc xsignal_restart(int, sigfunc, int); #ifndef STANDALONE_PROGRESS void psummary(int); Index: src/usr.bin/ftp/ssl.c diff -u src/usr.bin/ftp/ssl.c:1.5.8.1 src/usr.bin/ftp/ssl.c:1.5.8.2 --- src/usr.bin/ftp/ssl.c:1.5.8.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/ssl.c Mon Sep 12 15:05:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ssl.c,v 1.5.8.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: ssl.c,v 1.5.8.2 2022/09/12 15:05:21 martin Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav @@ -34,17 +34,12 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ssl.c,v 1.5.8.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: ssl.c,v 1.5.8.2 2022/09/12 15:05:21 martin Exp $"); #endif -#include <errno.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <time.h> #include <unistd.h> +#include <fcntl.h> #include <sys/param.h> #include <sys/select.h> @@ -52,14 +47,11 @@ __RCSID("$NetBSD: ssl.c,v 1.5.8.1 2022/0 #include <netinet/tcp.h> #include <netinet/in.h> - -#ifdef WITH_SSL #include <openssl/crypto.h> #include <openssl/x509.h> #include <openssl/pem.h> #include <openssl/ssl.h> #include <openssl/err.h> -#endif #include "ssl.h" @@ -82,9 +74,7 @@ struct fetch_connect { int issock; int iserr; int iseof; -#ifdef WITH_SSL SSL *ssl; /* SSL handle */ -#endif }; /* @@ -97,7 +87,6 @@ fetch_writev(struct fetch_connect *conn, struct timeval now, timeout, delta; fd_set writefds; ssize_t len, total; - int fd = conn->sd; int r; if (quit_time > 0) { @@ -108,8 +97,8 @@ fetch_writev(struct fetch_connect *conn, total = 0; while (iovcnt > 0) { - while (quit_time > 0 && !FD_ISSET(fd, &writefds)) { - FD_SET(fd, &writefds); + while (quit_time > 0 && !FD_ISSET(conn->sd, &writefds)) { + FD_SET(conn->sd, &writefds); gettimeofday(&now, NULL); delta.tv_sec = timeout.tv_sec - now.tv_sec; delta.tv_usec = timeout.tv_usec - now.tv_usec; @@ -122,7 +111,7 @@ fetch_writev(struct fetch_connect *conn, return -1; } errno = 0; - r = select(fd + 1, NULL, &writefds, NULL, &delta); + r = select(conn->sd + 1, NULL, &writefds, NULL, &delta); if (r == -1) { if (errno == EINTR) continue; @@ -130,12 +119,10 @@ fetch_writev(struct fetch_connect *conn, } } errno = 0; -#ifdef WITH_SSL if (conn->ssl != NULL) len = SSL_write(conn->ssl, iov->iov_base, iov->iov_len); else -#endif - len = writev(fd, iov, iovcnt); + len = writev(conn->sd, iov, iovcnt); if (len == 0) { /* we consider a short write a failure */ /* XXX perhaps we shouldn't in the SSL case */ @@ -143,7 +130,7 @@ fetch_writev(struct fetch_connect *conn, return -1; } if (len < 0) { - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR) continue; return -1; } @@ -161,8 +148,11 @@ fetch_writev(struct fetch_connect *conn, return total; } -static ssize_t -fetch_write(const void *str, size_t len, struct fetch_connect *conn) +/* + * Write to a connection w/ timeout + */ +static int +fetch_write(struct fetch_connect *conn, const char *str, size_t len) { struct iovec iov[1]; @@ -191,7 +181,7 @@ fetch_printf(struct fetch_connect *conn, return -1; } - r = fetch_write(msg, len, conn); + r = fetch_write(conn, msg, len); free(msg); return r; } @@ -220,16 +210,15 @@ fetch_clearerr(struct fetch_connect *con int fetch_flush(struct fetch_connect *conn) { + int v; if (conn->issock) { - int fd = conn->sd; - int v; #ifdef TCP_NOPUSH v = 0; - setsockopt(fd, IPPROTO_TCP, TCP_NOPUSH, &v, sizeof(v)); + setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &v, sizeof(v)); #endif v = 1; - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)); + setsockopt(conn->sd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)); } return 0; } @@ -282,44 +271,44 @@ fetch_fdopen(int sd, const char *fmode) int fetch_close(struct fetch_connect *conn) { - if (conn == NULL) - return 0; + int rv = 0; - fetch_flush(conn); -#ifdef WITH_SSL - SSL_free(conn->ssl); -#endif - close(conn->sd); - free(conn->cache.buf); - free(conn->buf); - free(conn); - return 0; + if (conn != NULL) { + fetch_flush(conn); + SSL_free(conn->ssl); + rv = close(conn->sd); + if (rv < 0) { + errno = rv; + rv = EOF; + } + free(conn->cache.buf); + free(conn->buf); + free(conn); + } + return rv; } -#define FETCH_WRITE_WAIT -3 #define FETCH_READ_WAIT -2 #define FETCH_READ_ERROR -1 -#ifdef WITH_SSL static ssize_t fetch_ssl_read(SSL *ssl, void *buf, size_t len) { ssize_t rlen; - rlen = SSL_read(ssl, buf, len); - if (rlen >= 0) - return rlen; + int ssl_err; - switch (SSL_get_error(ssl, rlen)) { - case SSL_ERROR_WANT_READ: - return FETCH_READ_WAIT; - case SSL_ERROR_WANT_WRITE: - return FETCH_WRITE_WAIT; - default: + rlen = SSL_read(ssl, buf, len); + if (rlen < 0) { + ssl_err = SSL_get_error(ssl, rlen); + if (ssl_err == SSL_ERROR_WANT_READ || + ssl_err == SSL_ERROR_WANT_WRITE) { + return FETCH_READ_WAIT; + } ERR_print_errors_fp(ttyout); return FETCH_READ_ERROR; } + return rlen; } -#endif /* WITH_SSL */ static ssize_t fetch_nonssl_read(int sd, void *buf, size_t len) @@ -327,7 +316,7 @@ fetch_nonssl_read(int sd, void *buf, siz ssize_t rlen; rlen = read(sd, buf, len); - if (rlen == -1) { + if (rlen < 0) { if (errno == EAGAIN || errno == EINTR) return FETCH_READ_WAIT; return FETCH_READ_ERROR; @@ -358,49 +347,14 @@ fetch_cache_data(struct fetch_connect *c return 0; } -static int -fetch_wait(struct fetch_connect *conn, ssize_t rlen, struct timeval *timeout) -{ - struct timeval now, delta; - int fd = conn->sd; - fd_set fds; - - FD_ZERO(&fds); - while (!FD_ISSET(fd, &fds)) { - FD_SET(fd, &fds); - if (quit_time > 0) { - gettimeofday(&now, NULL); - if (!timercmp(timeout, &now, >)) { - fprintf(ttyout, "\r\n%s: transfer aborted" - " because stalled for %lu sec.\r\n", - getprogname(), (unsigned long)quit_time); - errno = ETIMEDOUT; - conn->iserr = ETIMEDOUT; - return -1; - } - timersub(timeout, &now, &delta); - } - errno = 0; - if (select(fd + 1, - rlen == FETCH_READ_WAIT ? &fds : NULL, - rlen == FETCH_WRITE_WAIT ? &fds : NULL, - NULL, quit_time > 0 ? &delta : NULL) < 0) { - if (errno == EINTR) - continue; - conn->iserr = errno; - return -1; - } - } - return 0; -} - -size_t +ssize_t fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn) { + struct timeval now, timeout, delta; + fd_set readfds; ssize_t rlen, total; size_t len; char *start, *buf; - struct timeval timeout; if (quit_time > 0) { gettimeofday(&timeout, NULL); @@ -448,31 +402,40 @@ fetch_read(void *ptr, size_t size, size_ * In the non-SSL case, it may improve performance (very * slightly) when reading small amounts of data. */ -#ifdef WITH_SSL if (conn->ssl != NULL) rlen = fetch_ssl_read(conn->ssl, buf, len); else -#endif rlen = fetch_nonssl_read(conn->sd, buf, len); - switch (rlen) { - case 0: - conn->iseof = 1; - return total; - case FETCH_READ_ERROR: - conn->iserr = errno; - if (errno == EINTR) - fetch_cache_data(conn, start, total); - return 0; - case FETCH_READ_WAIT: - case FETCH_WRITE_WAIT: - if (fetch_wait(conn, rlen, &timeout) == -1) - return 0; + if (rlen == 0) { break; - default: + } else if (rlen > 0) { len -= rlen; buf += rlen; total += rlen; - break; + continue; + } else if (rlen == FETCH_READ_ERROR) { + if (errno == EINTR) + fetch_cache_data(conn, start, total); + return -1; + } + FD_ZERO(&readfds); + while (!FD_ISSET(conn->sd, &readfds)) { + FD_SET(conn->sd, &readfds); + if (quit_time > 0) { + gettimeofday(&now, NULL); + if (!timercmp(&timeout, &now, >)) { + errno = ETIMEDOUT; + return -1; + } + timersub(&timeout, &now, &delta); + } + errno = 0; + if (select(conn->sd + 1, &readfds, NULL, NULL, + quit_time > 0 ? &delta : NULL) < 0) { + if (errno == EINTR) + continue; + return -1; + } } } return total; @@ -487,7 +450,7 @@ char * fetch_getln(char *str, int size, struct fetch_connect *conn) { size_t tmpsize; - size_t len; + ssize_t len; char c; if (conn->buf == NULL) { @@ -510,12 +473,13 @@ fetch_getln(char *str, int size, struct conn->buflen = 0; do { len = fetch_read(&c, sizeof(c), 1, conn); + if (len == -1) { + conn->iserr = 1; + return NULL; + } if (len == 0) { - if (conn->iserr) - return NULL; - if (conn->iseof) - break; - abort(); + conn->iseof = 1; + break; } conn->buf[conn->buflen++] = c; if (conn->buflen == conn->bufsize) { @@ -567,8 +531,8 @@ fetch_getline(struct fetch_connect *conn } else if (len == buflen - 1) { /* line too long */ while (1) { char c; - size_t rlen = fetch_read(&c, sizeof(c), 1, conn); - if (rlen == 0 || c == '\n') + ssize_t rlen = fetch_read(&c, sizeof(c), 1, conn); + if (rlen <= 0 || c == '\n') break; } if (errormsg) @@ -581,15 +545,12 @@ fetch_getline(struct fetch_connect *conn return len; } -#ifdef WITH_SSL void * fetch_start_ssl(int sock, const char *servername) { SSL *ssl; SSL_CTX *ctx; - X509_VERIFY_PARAM *param; int ret, ssl_err; - int verify = getenv("NO_CERT_VERIFY") == NULL; /* Init the SSL library and context */ if (!SSL_library_init()){ @@ -601,10 +562,6 @@ fetch_start_ssl(int sock, const char *se ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); - if (verify) { - SSL_CTX_set_default_verify_paths(ctx); - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); - } ssl = SSL_new(ctx); if (ssl == NULL){ @@ -612,19 +569,6 @@ fetch_start_ssl(int sock, const char *se SSL_CTX_free(ctx); return NULL; } - - if (verify) { - param = SSL_get0_param(ssl); - if (!X509_VERIFY_PARAM_set1_host(param, servername, - strlen(servername))) { - fprintf(ttyout, "SSL verification setup failed\n"); - return NULL; - } - - /* Enable peer verification, (using the default callback) */ - SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); - } - SSL_set_fd(ssl, sock); if (!SSL_set_tlsext_host_name(ssl, __UNCONST(servername))) { fprintf(ttyout, "SSL hostname setting failed\n"); @@ -661,13 +605,10 @@ fetch_start_ssl(int sock, const char *se return ssl; } -#endif /* WITH_SSL */ void fetch_set_ssl(struct fetch_connect *conn, void *ssl) { -#ifdef WITH_SSL conn->ssl = ssl; -#endif } Index: src/usr.bin/ftp/ssl.h diff -u src/usr.bin/ftp/ssl.h:1.3.8.1 src/usr.bin/ftp/ssl.h:1.3.8.2 --- src/usr.bin/ftp/ssl.h:1.3.8.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/ssl.h Mon Sep 12 15:05:21 2022 @@ -1,7 +1,7 @@ -/* $NetBSD: ssl.h,v 1.3.8.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: ssl.h,v 1.3.8.2 2022/09/12 15:05:21 martin Exp $ */ /*- - * Copyright (c) 2012-2021 The NetBSD Foundation, Inc. + * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,6 +25,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#ifdef WITH_SSL #define FETCH struct fetch_connect struct fetch_connect; @@ -37,8 +38,26 @@ int fetch_flush(struct fetch_connect *); struct fetch_connect *fetch_open(const char *, const char *); struct fetch_connect *fetch_fdopen(int, const char *); int fetch_close(struct fetch_connect *); -size_t fetch_read(void *, size_t, size_t, struct fetch_connect *); +ssize_t fetch_read(void *, size_t, size_t, struct fetch_connect *); char *fetch_getln(char *, int, struct fetch_connect *); int fetch_getline(struct fetch_connect *, char *, size_t, const char **); void fetch_set_ssl(struct fetch_connect *, void *); void *fetch_start_ssl(int, const char *); + +#else /* !WITH_SSL */ + +#define FETCH FILE + +#define fetch_printf fprintf +#define fetch_fileno fileno +#define fetch_error ferror +#define fetch_flush fflush +#define fetch_open fopen +#define fetch_fdopen fdopen +#define fetch_close fclose +#define fetch_read fread +#define fetch_getln fgets +#define fetch_getline get_line +#define fetch_set_ssl(a, b) + +#endif /* !WITH_SSL */ Index: src/usr.bin/ftp/util.c diff -u src/usr.bin/ftp/util.c:1.158.22.1 src/usr.bin/ftp/util.c:1.158.22.2 --- src/usr.bin/ftp/util.c:1.158.22.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/util.c Mon Sep 12 15:05:21 2022 @@ -1,7 +1,7 @@ -/* $NetBSD: util.c,v 1.158.22.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: util.c,v 1.158.22.2 2022/09/12 15:05:21 martin Exp $ */ /*- - * Copyright (c) 1997-2020 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.158.22.1 2022/09/12 14:46:51 martin Exp $"); +__RCSID("$NetBSD: util.c,v 1.158.22.2 2022/09/12 15:05:21 martin Exp $"); #endif /* not lint */ /* @@ -171,7 +171,7 @@ parse_feat(const char *fline) * work-around broken ProFTPd servers that can't * even obey RFC 2389. */ - while (*fline && isspace((unsigned char)*fline)) + while (*fline && isspace((int)*fline)) fline++; if (strcasecmp(fline, "MDTM") == 0) @@ -324,10 +324,9 @@ intr(int signo) /* * Signal handler for lost connections; cleanup various elements of * the connection state, and call cleanuppeer() to finish it off. - * This function is not signal safe, so exit if called by a signal. */ void -lostpeer(int signo) +lostpeer(int dummy) { int oerrno = errno; @@ -357,9 +356,6 @@ lostpeer(int signo) proxflag = 0; pswitch(0); cleanuppeer(); - if (signo) { - errx(1, "lostpeer due to signal %d", signo); - } errno = oerrno; } @@ -482,8 +478,7 @@ ftp_login(const char *host, const char * } } updatelocalcwd(); - remotecwd[0] = '\0'; - remcwdvalid = 0; + updateremotecwd(); cleanup_ftp_login: FREEPTR(fuser); @@ -620,7 +615,7 @@ remglob(char *argv[], int doswitch, cons * return value. Can't control multiple values being expanded from the * expression, we return only the first. * Returns NULL on error, or a pointer to a buffer containing the filename - * that's the caller's responsibility to free(3) when finished with. + * that's the caller's responsiblity to free(3) when finished with. */ char * globulize(const char *pattern) @@ -731,7 +726,7 @@ remotemodtime(const char *file, int nois *frac++ = '\0'; if (strlen(timestr) == 15 && strncmp(timestr, "191", 3) == 0) { /* - * XXX: Workaround for buggy ftp servers that return + * XXX: Workaround for lame ftpd's that return * `19100' instead of `2000' */ fprintf(ttyout, @@ -840,7 +835,6 @@ updateremotecwd(void) size_t i; char *cp; - remcwdvalid = 1; /* whether it works or not, we are done */ overbose = verbose; ocode = code; if (ftp_debug == 0) @@ -1180,8 +1174,6 @@ formatbuf(char *buf, size_t len, const c case '/': case '.': case 'c': - if (connected && !remcwdvalid) - updateremotecwd(); p2 = connected ? remotecwd : ""; updirs = pdirs = 0; @@ -1495,7 +1487,6 @@ ftp_poll(struct pollfd *fds, int nfds, i return poll(fds, nfds, timeout); } -#ifndef SMALL /* * malloc() with inbuilt error checking */ @@ -1550,4 +1541,3 @@ ftp_strdup(const char *str) err(1, "Unable to allocate memory for string copy"); return (s); } -#endif Index: src/usr.bin/ftp/version.h diff -u src/usr.bin/ftp/version.h:1.87.8.1 src/usr.bin/ftp/version.h:1.87.8.2 --- src/usr.bin/ftp/version.h:1.87.8.1 Mon Sep 12 14:46:51 2022 +++ src/usr.bin/ftp/version.h Mon Sep 12 15:05:21 2022 @@ -1,7 +1,7 @@ -/* $NetBSD: version.h,v 1.87.8.1 2022/09/12 14:46:51 martin Exp $ */ +/* $NetBSD: version.h,v 1.87.8.2 2022/09/12 15:05:21 martin Exp $ */ /*- - * Copyright (c) 1999-2021 The NetBSD Foundation, Inc. + * Copyright (c) 1999-2015 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 "20210826" +#define FTP_VERSION "20150912" #endif