summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspz <spz@pkgsrc.org>2014-10-31 18:47:16 +0000
committerspz <spz@pkgsrc.org>2014-10-31 18:47:16 +0000
commit2ae8f58656b4bd25d33387403e36fff22b6cfa76 (patch)
tree121c9e28ee7f3fa5663751c95d628711fe106d26
parent9db2f083dce5056d6ab80771be33d4beae353258 (diff)
downloadpkgsrc-2ae8f58656b4bd25d33387403e36fff22b6cfa76.tar.gz
Fri Oct 31 04:07:38 UTC 2014 lukem
* Release as "tnftp 20141031". * Merge NetBSD usr.bin/ftp from 20130220 to 20141026: - Don't pay attention to special characters if they don't come from the command line (from jmcneill). Fixes CVE-2014-8517. - pr/34796: Hauke Fath: ftp does not timeout on http fetches. Sun May 5 13:51:47 UTC 2013 lukem * Release as "tnftp 20130505" * Implement --enable-ssl (and --with-openssl) to enable https:// fetch support. * Merge NetBSD ftp from 20090520 to 20130220. Changes: - https:// support. NetBSD problem report 47276 from NONAKA Kimihiro. - Allow -R to restart non-existent ftp:// URIs. - Don't assume AF_INET support is available. FreeBSD problem report 162661. - Parse HTTP 'Date' entries in the `C' locale rather than the user's. NetBSD problem report 42917 from KAMADA Ken'ichi. - Improve error handling when parsing of URI scheme. - Silence connection warnings to multi-homed hosts in non-verbose mode. - Fix compile warnings. - In ftpvis(), prevent incomplete escape sequences at end of dst, and ensure NUL-termination of dst. Fix from Uwe Stuehler and Stefan Sperling, via Marc Balmer. - When using the response to SYST to decide whether to default to 'binary' be a lot less specific. * Replace glob with newer copy from NetBSD that does not suffer from DoS exhaustion attacks. Fix in NetBSD from Maksymilian Arciemowicz. See CVE-2011-0418 Tue Jan 12 06:58:15 UTC 2010 lukem * Release as "tnftp 20100108" * Rename onoff() argument "bool" to "val". Tue Jan 5 09:12:01 UTC 2010 lukem * If ARG_MAX isn't defined, use the result from sysconf(_SC_ARG_MAX). Fixes build when using newer glibc. * Add libnetbsd.la to the LIBADD for libedit. Fix provided by Adam Sampson. Mon Jan 4 06:28:07 UTC 2010 lukem * Distribute various files not shipped by default automake rules, to use 'make dist' instead of 'cvs export'. Wed Dec 30 00:12:47 UTC 2009 lukem * Release as "tnftp 20091122" Sun Nov 15 10:14:44 UTC 2009 lukem * Merge NetBSD ftp from 20090520 to 20090915. Change: - Rename internal getline() to get_line() to avoid conflict with libc with former. - Avoid a NULL dereference in an error message. Sat Nov 14 09:21:19 UTC 2009 lukem * Convert to automake & libtool. Sat Jun 6 07:17:38 UTC 2009 lukem * Release as "tnftp 20090606" Fri May 22 01:11:15 UTC 2009 lukem * configure fixes: - Add the time.h headers to accheck_includes, for the strptime check. - Remove the check for el_init in libedit; we're always replacing the library and the presence of strvis() in some versions confuses other checks. Wed May 20 13:47:43 UTC 2009 lukem * Release as "tnftp 20090520" * Merge NetBSD ftp from 20070722 to 20090520. Changes: - Only attempt to el_parse() a command unknown by the default parser if editing is enabled. Fixes pr 38589. - Turn off the alarmtimer before resetting the SIGALRM handler back to SIG_DFL. Fixes pr 35630. - Add epsv6 and epsv to disable extended passive mode for ipv6 or both ipv4 and ipv6 respectively. This hack is due to our friends a Juniper Networks who break epsv in ipv6. Should be fixed in ScreenOS 6.2.X. - Improve parsing of chunked transfer chunks per RFC2616: - more stringent chunk-size parsing - ignore optional trailing ';chunk-ext' stuff, instead of barfing - detect EOF before final \r\n. - Use the service name to getaddrinfo() (along with the host name), so that features such as DNS Service Discovery have a better chance of working. Display the service name in various status & error messages. - Don't getservbyname() the :port component of a URL; RFC 3986 says it's just an unsigned number, not a service name. - Fix numerous WARNS=4 issues (-Wcast-qual -Wsign-compare). - Fix -Wshadow issues - Update copyrights - Remove clause 3 and 4 from TNF licenses - Rename HAVE_STRUCT_SOCKADDR_SA_LEN to HAVE_STRUCT_SOCKADDR_IN_SIN_LEN to accurately reflect the structure member being used. - Use AF_INET instead of AF_UNSPEC as the default family if !defined(INET6). * configure improvements: - Style tweaks. - Use AC_LANG_PROGRAM() instead of AC_LANG_SOURCE() - Add a check for strptime() requiring separators between conversions, and use our replacement one if it does. Sat Dec 20 15:28:24 UTC 2008 lukem * configure improvements: - Move IPv6 check from tnftp.h to configure.ac (as per tnftpd). - Rework option descriptions. - Highlight when tests are for a specific option. - Move configuration results to the end of the file. - Display $prefix in configure results. Fri Aug 15 03:03:36 UTC 2008 lukem * Add a "Configuration results" display at the end of configure. Cosmetic tweaks. Fri Feb 29 09:45:56 UTC 2008 lukem * Support @EXEEXT@ for Cygwin (etc).
-rw-r--r--net/tnftp/files/src/domacro.c10
-rw-r--r--net/tnftp/files/src/extern.h32
-rw-r--r--net/tnftp/files/src/ftp.c178
-rw-r--r--net/tnftp/files/src/progressbar.c26
-rw-r--r--net/tnftp/files/src/util.c298
5 files changed, 288 insertions, 256 deletions
diff --git a/net/tnftp/files/src/domacro.c b/net/tnftp/files/src/domacro.c
index 916abf33108..34ab872ea61 100644
--- a/net/tnftp/files/src/domacro.c
+++ b/net/tnftp/files/src/domacro.c
@@ -1,5 +1,5 @@
-/* $NetBSD: domacro.c,v 1.1.1.5 2007/08/06 04:33:23 lukem Exp $ */
-/* from NetBSD: domacro.c,v 1.21 2005/06/29 02:31:19 christos Exp */
+/* $NetBSD: domacro.c,v 1.1.1.6 2014/10/31 18:47:16 spz Exp $ */
+/* from NetBSD: domacro.c,v 1.22 2009/04/12 10:18:52 lukem Exp */
/*
* Copyright (c) 1985, 1993, 1994
@@ -39,7 +39,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 */
@@ -57,6 +57,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"))) {
@@ -133,7 +134,8 @@ domacro(int argc, char *argv[])
fputs(line, ttyout);
putc('\n', ttyout);
}
- margv[0] = c->c_name;
+ (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf));
+ margv[0] = cmdbuf;
(*c->c_handler)(margc, margv);
if (bell && c->c_bell)
(void)putc('\007', ttyout);
diff --git a/net/tnftp/files/src/extern.h b/net/tnftp/files/src/extern.h
index f498714237d..3c71da346ee 100644
--- a/net/tnftp/files/src/extern.h
+++ b/net/tnftp/files/src/extern.h
@@ -1,8 +1,8 @@
-/* $NetBSD: extern.h,v 1.1.1.5 2007/06/07 04:00:20 lukem Exp $ */
-/* from NetBSD: extern.h,v 1.72 2007/05/24 05:05:18 lukem Exp */
+/* $NetBSD: extern.h,v 1.1.1.6 2014/10/31 18:47:16 spz Exp $ */
+/* from NetBSD: extern.h,v 1.80 2012/07/04 06:09:37 is 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
@@ -16,13 +16,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -102,9 +95,6 @@ struct tm;
struct addrinfo;
void abort_remote(FILE *);
-void abort_squared(int);
-void abortpt(int);
-void abortxfer(int);
void account(int, char **);
void ai_unmapped(struct addrinfo *);
int another(int *, char ***, const char *);
@@ -142,7 +132,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);
@@ -150,10 +140,10 @@ 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);
+__dead void intr(int);
int isipv6addr(const char *);
void list_vertical(StringList *);
void lcd(int, char **);
@@ -174,10 +164,10 @@ const char *onoff(int);
void opts(int, char **);
void newer(int, char **);
void page(int, char **);
-int parseport(const char *, int);
+const char *parse_rfc2616time(struct tm *, const char *);
int parserate(int, char **, int);
char *prompt(void);
-void proxabort(int);
+__dead void proxabort(int);
void proxtrans(const char *, const char *, const char *);
void psabort(int);
void pswitch(int);
@@ -210,6 +200,8 @@ void setcr(int, char **);
void setdebug(int, char **);
void setedit(int, char **);
void setepsv4(int, char **);
+void setepsv6(int, char **);
+void setepsv(int, char **);
void setform(int, char **);
void setftmode(int, char **);
void setgate(int, char **);
@@ -235,6 +227,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 **);
@@ -246,9 +239,8 @@ int togglevar(int, char **, int *, const char *);
void unsetoption(int, char **);
void updatelocalcwd(void);
void updateremotecwd(void);
-void usage(void);
void user(int, char **);
-int ftp_connect(int, const struct sockaddr *, socklen_t);
+int ftp_connect(int, const struct sockaddr *, socklen_t, int);
int ftp_listen(int, int);
int ftp_poll(struct pollfd *, int, int);
void *ftp_malloc(size_t);
diff --git a/net/tnftp/files/src/ftp.c b/net/tnftp/files/src/ftp.c
index a94006b9ba1..15d86a890d4 100644
--- a/net/tnftp/files/src/ftp.c
+++ b/net/tnftp/files/src/ftp.c
@@ -1,8 +1,8 @@
-/* $NetBSD: ftp.c,v 1.1.1.6 2007/08/06 04:33:23 lukem Exp $ */
-/* from NetBSD: ftp.c,v 1.152 2007/07/22 05:02:50 lukem Exp */
+/* $NetBSD: ftp.c,v 1.1.1.7 2014/10/31 18:47:17 spz Exp $ */
+/* from NetBSD: ftp.c,v 1.164 2012/07/04 06:09:37 is 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
@@ -16,13 +16,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -105,7 +98,7 @@
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
-__RCSID(" NetBSD: ftp.c,v 1.152 2007/07/22 05:02:50 lukem Exp ");
+__RCSID(" NetBSD: ftp.c,v 1.164 2012/07/04 06:09:37 is Exp ");
#endif
#endif /* not lint */
@@ -121,6 +114,7 @@ __RCSID(" NetBSD: ftp.c,v 1.152 2007/07/22 05:02:50 lukem Exp ");
#include <arpa/ftp.h>
#include <arpa/telnet.h>
+#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -146,6 +140,7 @@ int ptflag = 0;
char pasv[BUFSIZ]; /* passive port for proxy data connection */
static int empty(FILE *, FILE *, int);
+__dead static void abort_squared(int);
struct sockinet {
union sockunion {
@@ -154,12 +149,12 @@ struct sockinet {
struct sockaddr_in6 su_sin6;
#endif
} si_su;
-#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
+#if !defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN)
int si_len;
#endif
};
-#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
+#if !defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN)
# define su_len si_len
#else
# define su_len si_su.su_sin.sin_len
@@ -170,11 +165,10 @@ 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, portnum;
+ int s = -1, error;
struct addrinfo hints, *res, *res0;
- char hbuf[MAXHOSTNAMELEN];
static char hostnamebuf[MAXHOSTNAMELEN];
socklen_t len;
int on = 1;
@@ -182,14 +176,13 @@ hookup(char *host, char *port)
memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
memset((char *)&myctladdr, 0, sizeof (myctladdr));
memset(&hints, 0, sizeof(hints));
- portnum = parseport(port, FTP_PORT);
hints.ai_flags = AI_CANONNAME;
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
- error = getaddrinfo(host, NULL, &hints, &res0);
+ error = getaddrinfo(host, port, &hints, &res0);
if (error) {
- warnx("Can't lookup `%s': %s", host,
+ warnx("Can't lookup `%s:%s': %s", host, port,
(error == EAI_SYSTEM) ? strerror(errno)
: gai_strerror(error));
code = -1;
@@ -204,22 +197,27 @@ hookup(char *host, char *port)
hostname = hostnamebuf;
for (res = res0; res; res = res->ai_next) {
+ char hname[NI_MAXHOST], sname[NI_MAXSERV];
+
ai_unmapped(res);
if (getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
- strlcpy(hbuf, "?", sizeof(hbuf));
+ hname, sizeof(hname), sname, sizeof(sname),
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
+ strlcpy(hname, "?", sizeof(hname));
+ strlcpy(sname, "?", sizeof(sname));
+ }
if (verbose && res0->ai_next) {
/* if we have multiple possibilities */
- fprintf(ttyout, "Trying %s...\n", hbuf);
+ fprintf(ttyout, "Trying %s:%s ...\n", hname, sname);
}
- ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(portnum);
s = socket(res->ai_family, SOCK_STREAM, res->ai_protocol);
if (s < 0) {
- warn("Can't create socket for connection to `%s'",
- hbuf);
+ warn("Can't create socket for connection to `%s:%s'",
+ hname, sname);
continue;
}
- if (ftp_connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+ if (ftp_connect(s, res->ai_addr, res->ai_addrlen,
+ verbose || !res->ai_next) < 0) {
close(s);
s = -1;
continue;
@@ -229,7 +227,7 @@ hookup(char *host, char *port)
break;
}
if (s < 0) {
- warnx("Can't connect to `%s'", host);
+ warnx("Can't connect to `%s:%s'", host, port);
code = -1;
freeaddrinfo(res0);
return 0;
@@ -241,7 +239,8 @@ hookup(char *host, char *port)
len = hisctladdr.su_len;
if (getsockname(s, (struct sockaddr *)&myctladdr.si_su, &len) == -1) {
- warn("Can't determine my address of connection to `%s'", host);
+ warn("Can't determine my address of connection to `%s:%s'",
+ host, port);
code = -1;
goto bad;
}
@@ -374,7 +373,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;
@@ -387,7 +386,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),
@@ -492,10 +491,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)
@@ -519,14 +518,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;
}
@@ -540,7 +539,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;
@@ -549,7 +548,7 @@ empty(FILE *cin, FILE *din, int sec)
sigjmp_buf xferabort;
-void
+__dead static void
abortxfer(int notused)
{
char msgbuf[100];
@@ -610,7 +609,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;
@@ -672,7 +671,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;
@@ -776,7 +775,8 @@ sendrequest(const char *cmd, const char *local, const char *remote,
if (dout == NULL)
goto abort;
- if (sndbuf_size > bufsize) {
+ assert(sndbuf_size > 0);
+ if ((size_t)sndbuf_size > bufsize) {
if (buf)
(void)free(buf);
bufsize = sndbuf_size;
@@ -817,7 +817,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++;
@@ -1037,7 +1037,8 @@ recvrequest(const char *cmd, const char *volatile local, const char *remote,
progress = 0;
preserve = 0;
}
- if (rcvbuf_size > bufsize) {
+ assert(rcvbuf_size > 0);
+ if ((size_t)rcvbuf_size > bufsize) {
if (buf)
(void)free(buf);
bufsize = rcvbuf_size;
@@ -1164,7 +1165,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 */
@@ -1211,7 +1212,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
@@ -1277,23 +1278,33 @@ initconn(void)
break;
#ifdef INET6
case AF_INET6:
- pasvcmd = "EPSV";
- overbose = verbose;
- if (ftp_debug == 0)
- verbose = -1;
- result = command("EPSV");
- verbose = overbose;
- if (verbose > 0 &&
- (result == COMPLETE || !connected))
- fprintf(ttyout, "%s\n", reply_string);
- if (!connected)
- return (1);
- /* this code is to be friendly with broken BSDI ftpd */
- if (code / 10 == 22 && code != 229) {
- fputs(
-"wrong server: return code must be 229\n",
- ttyout);
- result = COMPLETE + 1;
+ if (epsv6 && !epsv6bad) {
+ pasvcmd = "EPSV";
+ overbose = verbose;
+ if (ftp_debug == 0)
+ verbose = -1;
+ result = command("EPSV");
+ verbose = overbose;
+ if (verbose > 0 &&
+ (result == COMPLETE || !connected))
+ fprintf(ttyout, "%s\n", reply_string);
+ if (!connected)
+ return (1);
+ /*
+ * this code is to be friendly with
+ * broken BSDI ftpd
+ */
+ if (code / 10 == 22 && code != 229) {
+ fputs(
+ "wrong server: return code must be 229\n",
+ ttyout);
+ result = COMPLETE + 1;
+ }
+ if (result != COMPLETE) {
+ epsv6bad = 1;
+ DPRINTF("disabling epsv6 for this "
+ "connection\n");
+ }
}
if (result != COMPLETE) {
pasvcmd = "LPSV";
@@ -1425,7 +1436,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]);
@@ -1466,7 +1477,7 @@ initconn(void)
goto bad;
if (ftp_connect(data, (struct sockaddr *)&data_addr.si_su,
- data_addr.su_len) < 0) {
+ data_addr.su_len, 1) < 0) {
if (activefallback) {
(void)close(data);
data = -1;
@@ -1532,7 +1543,6 @@ initconn(void)
if (sendport) {
char hname[NI_MAXHOST], sname[NI_MAXSERV];
- int af;
struct sockinet tmp;
switch (data_addr.su_family) {
@@ -1544,6 +1554,10 @@ initconn(void)
/* FALLTHROUGH */
#ifdef INET6
case AF_INET6:
+ if (!epsv6 || epsv6bad) {
+ result = COMPLETE + 1;
+ break;
+ }
#endif
af = (data_addr.su_family == AF_INET) ? 1 : 2;
tmp = data_addr;
@@ -1559,7 +1573,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 &&
@@ -1590,18 +1604,25 @@ initconn(void)
UC(p[0]), UC(p[1]));
break;
#ifdef INET6
- case AF_INET6:
- a = (char *)&data_addr.si_su.su_sin6.sin6_addr;
- p = (char *)&data_addr.su_port;
+ case AF_INET6: {
+ uint8_t ua[sizeof(data_addr.si_su.su_sin6.sin6_addr)];
+ uint8_t up[sizeof(data_addr.su_port)];
+
+ memcpy(ua, &data_addr.si_su.su_sin6.sin6_addr,
+ sizeof(ua));
+ memcpy(up, &data_addr.su_port, sizeof(up));
+
result = command(
"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
6, 16,
- UC(a[0]),UC(a[1]),UC(a[2]),UC(a[3]),
- UC(a[4]),UC(a[5]),UC(a[6]),UC(a[7]),
- UC(a[8]),UC(a[9]),UC(a[10]),UC(a[11]),
- UC(a[12]),UC(a[13]),UC(a[14]),UC(a[15]),
- 2, UC(p[0]), UC(p[1]));
+ ua[0], ua[1], ua[2], ua[3],
+ ua[4], ua[5], ua[6], ua[7],
+ ua[8], ua[9], ua[10], ua[11],
+ ua[12], ua[13], ua[14], ua[15],
+ 2,
+ up[0], up[1]);
break;
+ }
#endif
default:
result = COMPLETE + 1; /* xxx */
@@ -1623,8 +1644,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);
@@ -1810,7 +1832,7 @@ pswitch(int flag)
}
}
-void
+__dead static void
abortpt(int notused)
{
@@ -1830,7 +1852,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;
@@ -2022,7 +2044,7 @@ gunique(const char *local)
* too impatient to wait or there's another problem then ftp really
* needs to get back to a known state.
*/
-void
+static void
abort_squared(int dummy)
{
char msgbuf[100];
@@ -2122,7 +2144,7 @@ ai_unmapped(struct addrinfo *ai)
sin.sin_port = sin6->sin6_port;
ai->ai_family = AF_INET;
-#if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
+#if defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN)
sin.sin_len = len;
#endif
memcpy(ai->ai_addr, &sin, len);
diff --git a/net/tnftp/files/src/progressbar.c b/net/tnftp/files/src/progressbar.c
index 317262b98fd..418d9cc261c 100644
--- a/net/tnftp/files/src/progressbar.c
+++ b/net/tnftp/files/src/progressbar.c
@@ -1,8 +1,8 @@
-/* $NetBSD: progressbar.c,v 1.1.1.5 2007/08/06 04:33:24 lukem Exp $ */
-/* from NetBSD: progressbar.c,v 1.17 2007/05/05 18:09:24 martin Exp */
+/* $NetBSD: progressbar.c,v 1.1.1.6 2014/10/31 18:47:16 spz Exp $ */
+/* from NetBSD: progressbar.c,v 1.22 2012/06/27 22:07:36 riastradh 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
@@ -16,13 +16,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -43,14 +36,15 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID(" NetBSD: progressbar.c,v 1.17 2007/05/05 18:09:24 martin Exp ");
+__RCSID(" NetBSD: progressbar.c,v 1.22 2012/06/27 22:07:36 riastradh Exp ");
#endif /* not lint */
/*
* FTP User Program -- Misc support routines
*/
-#include <sys/types.h>
#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
#include <err.h>
#include <errno.h>
@@ -118,7 +112,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.
@@ -191,8 +185,8 @@ progressmeter(int flag)
"transfer aborted because stalled for %lu sec.\r\n",
getprogname(), (unsigned long)wait.tv_sec);
(void)write(fileno(ttyout), buf, len);
- (void)xsignal(SIGALRM, SIG_DFL);
alarmtimer(0);
+ (void)xsignal(SIGALRM, SIG_DFL);
siglongjmp(toplevel, 1);
}
#endif /* !STANDALONE_PROGRESS */
@@ -209,8 +203,8 @@ progressmeter(int flag)
(void)xsignal_restart(SIGALRM, updateprogressmeter, 1);
alarmtimer(1); /* set alarm timer for 1 Hz */
} else if (flag == 1) {
- (void)xsignal(SIGALRM, SIG_DFL);
alarmtimer(0);
+ (void)xsignal(SIGALRM, SIG_DFL);
}
}
#ifndef NO_PROGRESS
@@ -237,7 +231,7 @@ progressmeter(int flag)
* calculate the length of the `*' bar, ensuring that
* the number of stars won't exceed the buffer size
*/
- barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD;
+ barlength = MIN((int)(sizeof(buf) - 1), ttywidth) - BAROVERHEAD;
if (prefix)
barlength -= (int)strlen(prefix);
if (barlength > 0) {
diff --git a/net/tnftp/files/src/util.c b/net/tnftp/files/src/util.c
index add29b6c453..6bd5be396eb 100644
--- a/net/tnftp/files/src/util.c
+++ b/net/tnftp/files/src/util.c
@@ -1,8 +1,8 @@
-/* $NetBSD: util.c,v 1.1.1.6 2007/08/06 04:33:24 lukem Exp $ */
-/* from NetBSD: util.c,v 1.143 2007/05/24 05:05:19 lukem Exp */
+/* $NetBSD: util.c,v 1.1.1.7 2014/10/31 18:47:16 spz Exp $ */
+/* from NetBSD: util.c,v 1.158 2013/02/19 23:29:15 dsl 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
@@ -20,13 +20,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -76,7 +69,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID(" NetBSD: util.c,v 1.143 2007/05/24 05:05:19 lukem Exp ");
+__RCSID(" NetBSD: util.c,v 1.158 2013/02/19 23:29:15 dsl Exp ");
#endif /* not lint */
/*
@@ -97,6 +90,7 @@ __RCSID(" NetBSD: util.c,v 1.143 2007/05/24 05:05:19 lukem Exp ");
#include <signal.h>
#include <libgen.h>
#include <limits.h>
+#include <locale.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
@@ -117,7 +111,7 @@ void
setpeer(int argc, char *argv[])
{
char *host;
- char *port;
+ const char *port;
if (argc == 0)
goto usage;
@@ -177,25 +171,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;
}
@@ -215,25 +209,20 @@ getremoteinfo(void)
/* determine remote system type */
if (command("SYST") == COMPLETE) {
if (overbose) {
- char *cp, c;
-
- c = 0;
- cp = strchr(reply_string + 4, ' ');
- if (cp == NULL)
- cp = strchr(reply_string + 4, '\r');
- if (cp) {
- if (cp[-1] == '.')
- cp--;
- c = *cp;
- *cp = '\0';
- }
-
- fprintf(ttyout, "Remote system type is %s.\n",
- reply_string + 4);
- if (cp)
- *cp = c;
+ int os_len = strcspn(reply_string + 4, " \r\n\t");
+ if (os_len > 1 && reply_string[4 + os_len - 1] == '.')
+ os_len--;
+ fprintf(ttyout, "Remote system type is %.*s.\n",
+ os_len, reply_string + 4);
}
- if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
+ /*
+ * Decide whether we should default to bninary.
+ * Traditionally checked for "215 UNIX Type: L8", but
+ * some printers report "Linux" ! so be more forgiving.
+ * In reality we probably almost never want text any more.
+ */
+ if (!strncasecmp(reply_string + 4, "unix", 4) ||
+ !strncasecmp(reply_string + 4, "linux", 5)) {
if (proxy)
unix_proxy = 1;
else
@@ -317,6 +306,7 @@ cleanuppeer(void)
anonftp = 0;
data = -1;
epsv4bad = 0;
+ epsv6bad = 0;
if (username)
free(username);
username = NULL;
@@ -385,52 +375,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",
- user ? user : "<null>", pass ? pass : "<null>",
- host ? host : "<null>");
+ 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);
}
}
@@ -438,16 +427,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: ");
@@ -461,27 +450,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;
@@ -499,13 +488,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);
}
@@ -516,7 +505,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;
@@ -527,10 +516,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);
@@ -557,7 +546,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) {
@@ -596,8 +585,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;
@@ -769,10 +758,12 @@ remotemodtime(const char *file, int noisy)
goto bad_parse_time;
else
goto cleanup_parse_time;
- } else
- DPRINTF("parsed date `%s' as " LLF ", %s",
+ } 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;
@@ -789,7 +780,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 *
@@ -799,11 +790,41 @@ 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;
+#if defined(HAVE_SETLOCALE)
+ const char *curlocale;
+
+ /* The representation of %a depends on the current locale. */
+ curlocale = setlocale(LC_TIME, NULL);
+ (void)setlocale(LC_TIME, "C");
+#endif
+ /* 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 */
+ }
+#if defined(HAVE_SETLOCALE)
+ (void)setlocale(LC_TIME, curlocale);
+#endif
+ return t;
+}
+
+/*
* Update global `localcwd', which contains the state of the local cwd
*/
void
@@ -812,7 +833,7 @@ updatelocalcwd(void)
if (getcwd(localcwd, sizeof(localcwd)) == NULL)
localcwd[0] = '\0';
- DPRINTF("got localcwd as `%s'\n", localcwd);
+ DPRINTF("updatelocalcwd: got `%s'\n", localcwd);
}
/*
@@ -821,7 +842,8 @@ updatelocalcwd(void)
void
updateremotecwd(void)
{
- int overbose, ocode, i;
+ int overbose, ocode;
+ size_t i;
char *cp;
overbose = verbose;
@@ -844,7 +866,7 @@ updateremotecwd(void)
remotecwd[i] = *cp;
}
remotecwd[i] = '\0';
- DPRINTF("got remotecwd as `%s'\n", remotecwd);
+ DPRINTF("updateremotecwd: got `%s'\n", remotecwd);
goto cleanupremotecwd;
badremotecwd:
remotecwd[0]='\0';
@@ -878,10 +900,6 @@ fileindir(const char *file, const char *dir)
if (realdir[0] != '/') /* relative result is ok */
return 1;
dirlen = strlen(dir);
-#if 0
-printf("file %s parent %s realdir %s dir %s [%d]\n",
- file, parentdir, realdir, dir, dirlen);
-#endif
if (strncmp(realdir, dir, dirlen) == 0 &&
(realdir[dirlen] == '/' || realdir[dirlen] == '\0'))
return 1;
@@ -894,8 +912,8 @@ printf("file %s parent %s realdir %s dir %s [%d]\n",
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;
@@ -1068,6 +1086,32 @@ strsuftoi(const char *arg)
void
setupsockbufsize(int sock)
{
+ socklen_t slen;
+
+ if (0 == rcvbuf_size) {
+ slen = sizeof(rcvbuf_size);
+ if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+ (void *)&rcvbuf_size, &slen) == -1)
+ err(1, "Unable to determine rcvbuf size");
+ if (rcvbuf_size <= 0)
+ rcvbuf_size = 8 * 1024;
+ if (rcvbuf_size > 8 * 1024 * 1024)
+ rcvbuf_size = 8 * 1024 * 1024;
+ DPRINTF("setupsockbufsize: rcvbuf_size determined as %d\n",
+ rcvbuf_size);
+ }
+ if (0 == sndbuf_size) {
+ slen = sizeof(sndbuf_size);
+ if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF,
+ (void *)&sndbuf_size, &slen) == -1)
+ err(1, "Unable to determine sndbuf size");
+ if (sndbuf_size <= 0)
+ sndbuf_size = 8 * 1024;
+ if (sndbuf_size > 8 * 1024 * 1024)
+ sndbuf_size = 8 * 1024 * 1024;
+ DPRINTF("setupsockbufsize: sndbuf_size determined as %d\n",
+ sndbuf_size);
+ }
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
(void *)&sndbuf_size, sizeof(sndbuf_size)) == -1)
@@ -1084,11 +1128,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 ' ':
@@ -1096,12 +1139,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';
@@ -1114,7 +1163,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) \
@@ -1221,39 +1271,6 @@ formatbuf(char *buf, size_t len, const char *src)
}
/*
- * Parse `port' into a TCP port number, defaulting to `defport' if `port' is
- * an unknown service name. If defport != -1, print a warning upon bad parse.
- */
-int
-parseport(const char *port, int defport)
-{
- int rv;
- long nport;
- char *p, *ep;
-
- p = ftp_strdup(port);
- nport = strtol(p, &ep, 10);
- if (*ep != '\0' && ep == p) {
- struct servent *svp;
-
- svp = getservbyname(port, "tcp");
- if (svp == NULL) {
- badparseport:
- if (defport != -1)
- warnx("Unknown port `%s', using port %d",
- port, defport);
- rv = defport;
- } else
- rv = ntohs(svp->s_port);
- } else if (nport < 1 || nport > MAX_IN_PORT_T || *ep != '\0')
- goto badparseport;
- else
- rv = nport;
- free(p);
- return (rv);
-}
-
-/*
* Determine if given string is an IPv6 address or not.
* Return 1 for yes, 0 for no
*/
@@ -1265,7 +1282,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)
@@ -1295,7 +1312,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;
@@ -1340,18 +1357,22 @@ getline(FILE *stream, char *buf, size_t buflen, const char **errormsg)
* error message displayed.)
*/
int
-ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen)
+ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen, int pe)
{
int flags, rv, timeout, error;
socklen_t slen;
struct timeval endtime, now, td;
struct pollfd pfd[1];
char hname[NI_MAXHOST];
+ char sname[NI_MAXSERV];
setupsockbufsize(sock);
if (getnameinfo(name, namelen,
- hname, sizeof(hname), NULL, 0, NI_NUMERICHOST) != 0)
+ hname, sizeof(hname), sname, sizeof(sname),
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
strlcpy(hname, "?", sizeof(hname));
+ strlcpy(sname, "?", sizeof(sname));
+ }
if (bindai != NULL) { /* bind to specific addr */
struct addrinfo *ai;
@@ -1378,14 +1399,14 @@ ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen)
/* save current socket flags */
if ((flags = fcntl(sock, F_GETFL, 0)) == -1) {
- warn("Can't %s socket flags for connect to `%s'",
- "save", hname);
+ warn("Can't %s socket flags for connect to `%s:%s'",
+ "save", hname, sname);
return -1;
}
/* set non-blocking connect */
if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
- warn("Can't set socket non-blocking for connect to `%s'",
- hname);
+ warn("Can't set socket non-blocking for connect to `%s:%s'",
+ hname, sname);
return -1;
}
@@ -1402,8 +1423,9 @@ ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen)
rv = connect(sock, name, namelen); /* inititate the connection */
if (rv == -1) { /* connection error */
if (errno != EINPROGRESS) { /* error isn't "please wait" */
+ if (pe || (errno != EHOSTUNREACH))
connecterror:
- warn("Can't connect to `%s'", hname);
+ warn("Can't connect to `%s:%s'", hname, sname);
return -1;
}
@@ -1448,8 +1470,8 @@ ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen)
if (fcntl(sock, F_SETFL, flags) == -1) {
/* restore socket flags */
- warn("Can't %s socket flags for connect to `%s'",
- "restore", hname);
+ warn("Can't %s socket flags for connect to `%s:%s'",
+ "restore", hname, sname);
return -1;
}
return 0;