aboutsummaryrefslogtreecommitdiffstats
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c126
1 files changed, 92 insertions, 34 deletions
diff --git a/src/util.c b/src/util.c
index 366b19450b84..531712c3ded1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,5 +1,5 @@
-/* $NetBSD: util.c,v 1.21 2009/11/15 10:12:37 lukem Exp $ */
-/* from NetBSD: util.c,v 1.152 2009/07/13 19:05:41 roy Exp */
+/* $NetBSD: util.c,v 1.23 2013/05/05 11:51:43 lukem Exp $ */
+/* from NetBSD: util.c,v 1.158 2013/02/19 23:29:15 dsl Exp */
/*-
* Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID(" NetBSD: util.c,v 1.152 2009/07/13 19:05:41 roy Exp ");
+__RCSID(" NetBSD: util.c,v 1.158 2013/02/19 23:29:15 dsl Exp ");
#endif /* not lint */
/*
@@ -90,6 +90,7 @@ __RCSID(" NetBSD: util.c,v 1.152 2009/07/13 19:05:41 roy Exp ");
#include <signal.h>
#include <libgen.h>
#include <limits.h>
+#include <locale.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
@@ -175,7 +176,7 @@ parse_feat(const char *fline)
/*
* work-around broken ProFTPd servers that can't
- * even obey RFC2389.
+ * even obey RFC 2389.
*/
while (*fline && isspace((int)*fline))
fline++;
@@ -208,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
@@ -399,7 +395,7 @@ ftp_login(const char *host, const char *luser, const char *lpass)
*/
if (anonftp) {
FREEPTR(fuser);
- fuser = ftp_strdup("anonymous"); /* as per RFC1635 */
+ fuser = ftp_strdup("anonymous"); /* as per RFC 1635 */
FREEPTR(pass);
pass = ftp_strdup(getoptionvalue("anonpass"));
}
@@ -763,7 +759,7 @@ remotemodtime(const char *file, int noisy)
else
goto cleanup_parse_time;
} else {
- DPRINTF("remotemodtime: parsed date `%s' as " LLF
+ DPRINTF("remotemodtime: parsed time `%s' as " LLF
", %s",
timestr, (LLT)rtime,
rfc2822time(localtime(&rtime)));
@@ -784,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 *
@@ -794,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
@@ -1060,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)
@@ -1078,9 +1130,8 @@ ftpvis(char *dst, size_t dstlen, const char *src, size_t srclen)
{
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 ' ':
@@ -1088,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';
@@ -1300,7 +1357,7 @@ get_line(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;
@@ -1366,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:%s'", hname, sname);
+ warn("Can't connect to `%s:%s'", hname, sname);
return -1;
}