summaryrefslogtreecommitdiffstats
path: root/usr.bin/ftp/fetch.c
diff options
context:
space:
mode:
authorpst <pst@FreeBSD.org>1997-12-13 20:38:21 +0000
committerpst <pst@FreeBSD.org>1997-12-13 20:38:21 +0000
commit5ff5a36e72d385d6aeacd844c482b8045dbc147d (patch)
treeefc37af8df64054bcc13f979ffbae7a4303972f1 /usr.bin/ftp/fetch.c
parent7f8db0dd299e62df2aa8f56158134d1af1cbbcce (diff)
downloadFreeBSD-src-5ff5a36e72d385d6aeacd844c482b8045dbc147d.zip
FreeBSD-src-5ff5a36e72d385d6aeacd844c482b8045dbc147d.tar.gz
Sync with NetBSD v1.3.
Keep I8N1 and quarantine port code. Replace our security fix with NetBSD's (their idea was better).
Diffstat (limited to 'usr.bin/ftp/fetch.c')
-rw-r--r--usr.bin/ftp/fetch.c115
1 files changed, 74 insertions, 41 deletions
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index e79c0a7..4283b35 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -1,5 +1,4 @@
-/* $Id: fetch.c,v 1.1 1997/06/25 08:56:39 msmith Exp $ */
-/* $NetBSD: fetch.c,v 1.10 1997/05/23 18:54:18 lukem Exp $ */
+/* $NetBSD: fetch.c,v 1.16.2.1 1997/11/18 01:00:22 mellon Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -27,8 +26,8 @@
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
@@ -37,8 +36,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
-static char rcsid[] = "$Id: fetch.c,v 1.1 1997/06/25 08:56:39 msmith Exp $";
+__RCSID("$Id$");
+__RCSID_SOURCE("$NetBSD: fetch.c,v 1.16.2.1 1997/11/18 01:00:22 mellon Exp $");
#endif /* not lint */
/*
@@ -66,6 +67,10 @@ static char rcsid[] = "$Id: fetch.c,v 1.1 1997/06/25 08:56:39 msmith Exp $";
#include "ftp_var.h"
+static int url_get __P((const char *, const char *));
+void aborthttp __P((int));
+
+
#define FTP_URL "ftp://" /* ftp URL prefix */
#define HTTP_URL "http://" /* http URL prefix */
#define FTP_PROXY "ftp_proxy" /* env var with ftp proxy location */
@@ -81,40 +86,54 @@ jmp_buf httpabort;
* Modifies the string argument given.
* Returns -1 on failure, 0 on success
*/
-int
+static int
url_get(origline, proxyenv)
const char *origline;
const char *proxyenv;
{
struct sockaddr_in sin;
- int i, out, port, s;
- size_t buflen, len;
- char c, *cp, *cp2, *savefile, *portnum, *path, buf[4096];
+ int i, out, isftpurl;
+ u_int16_t port;
+ volatile int s;
+ size_t len;
+ char c, *cp, *ep, *portnum, *path, buf[4096];
+ const char *savefile;
char *line, *proxy, *host;
- sig_t oldintr;
+ volatile sig_t oldintr;
off_t hashbytes;
s = -1;
proxy = NULL;
+ isftpurl = 0;
+
+#ifdef __GNUC__ /* XXX: to shut up gcc warnings */
+ (void)&savefile;
+ (void)&proxy;
+#endif
line = strdup(origline);
if (line == NULL)
errx(1, "Can't allocate memory to parse URL");
if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
host = line + sizeof(HTTP_URL) - 1;
- else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0)
+ else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
host = line + sizeof(FTP_URL) - 1;
- else
+ isftpurl = 1;
+ } else
errx(1, "url_get: Invalid URL '%s'", line);
path = strchr(host, '/'); /* find path */
if (EMPTYSTRING(path)) {
- warnx("Invalid URL: %s", origline);
+ if (isftpurl)
+ goto noftpautologin;
+ warnx("Invalid URL (no `/' after host): %s", origline);
goto cleanup_url_get;
}
*path++ = '\0';
if (EMPTYSTRING(path)) {
- warnx("Invalid URL: %s", origline);
+ if (isftpurl)
+ goto noftpautologin;
+ warnx("Invalid URL (no file after host): %s", origline);
goto cleanup_url_get;
}
@@ -124,7 +143,9 @@ url_get(origline, proxyenv)
else
savefile = path;
if (EMPTYSTRING(savefile)) {
- warnx("Invalid URL: %s", origline);
+ if (isftpurl)
+ goto noftpautologin;
+ warnx("Invalid URL (no file after directory): %s", origline);
goto cleanup_url_get;
}
@@ -162,7 +183,7 @@ url_get(origline, proxyenv)
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- if (isdigit((unsigned char)host[0])) {
+ if (isdigit(host[0])) {
if (inet_aton(host, &sin.sin_addr) == 0) {
warnx("Invalid IP address: %s", host);
goto cleanup_url_get;
@@ -183,12 +204,15 @@ url_get(origline, proxyenv)
}
if (! EMPTYSTRING(portnum)) {
- port = atoi(portnum);
- if (port < 1 || (port & 0xffff) != port) {
+ char *ep;
+ long nport;
+
+ nport = strtol(portnum, &ep, 10);
+ if (nport < 1 || nport > 0xffff || *ep != '\0') {
warnx("Invalid port: %s", portnum);
goto cleanup_url_get;
}
- port = htons(port);
+ port = htons(nport);
} else
port = httpport;
sin.sin_port = port;
@@ -212,23 +236,23 @@ url_get(origline, proxyenv)
printf("Requesting %s\n", origline);
else
printf("Requesting %s (via %s)\n", origline, proxyenv);
- snprintf(buf, sizeof(buf), "GET %s%s HTTP/1.0\n\n",
+ len = snprintf(buf, sizeof(buf), "GET %s%s HTTP/1.0\r\n\r\n",
proxy ? "" : "/", path);
- buflen = strlen(buf);
- if (write(s, buf, buflen) < buflen) {
+ if (write(s, buf, len) < len) {
warn("Writing HTTP request");
goto cleanup_url_get;
}
memset(buf, 0, sizeof(buf));
- for (i = 0, buflen = sizeof(buf), cp = buf; i < buflen; cp++, i++) {
+ for (cp = buf; cp < buf + sizeof(buf); ) {
if (read(s, cp, 1) != 1)
goto improper;
if (*cp == '\r')
continue;
if (*cp == '\n')
break;
+ cp++;
}
- buf[buflen - 1] = '\0'; /* sanity */
+ buf[sizeof(buf) - 1] = '\0'; /* sanity */
cp = strchr(buf, ' ');
if (cp == NULL)
goto improper;
@@ -244,7 +268,7 @@ url_get(origline, proxyenv)
*/
memset(buf, 0, sizeof(buf));
c = '\0';
- for (i = 0, buflen = sizeof(buf), cp = buf; i < buflen; cp++, i++) {
+ for (cp = buf; cp < buf + sizeof(buf); ) {
if (read(s, cp, 1) != 1)
goto improper;
if (*cp == '\r')
@@ -252,29 +276,31 @@ url_get(origline, proxyenv)
if (*cp == '\n' && c == '\n')
break;
c = *cp;
+ cp++;
}
- buf[buflen - 1] = '\0'; /* sanity */
+ buf[sizeof(buf) - 1] = '\0'; /* sanity */
/*
* Look for the "Content-length: " header.
*/
#define CONTENTLEN "Content-Length: "
for (cp = buf; *cp != '\0'; cp++) {
- if (tolower((unsigned char)*cp) == 'c' &&
+ if (tolower(*cp) == 'c' &&
strncasecmp(cp, CONTENTLEN, sizeof(CONTENTLEN) - 1) == 0)
break;
}
- if (*cp == '\0')
- goto improper;
- cp += sizeof(CONTENTLEN) - 1;
- cp2 = strchr(cp, '\n');
- if (cp2 == NULL)
- goto improper;
- else
- *cp2 = '\0';
- filesize = atoi(cp);
- if (filesize < 1)
- goto improper;
+ if (*cp != '\0') {
+ cp += sizeof(CONTENTLEN) - 1;
+ ep = strchr(cp, '\n');
+ if (ep == NULL)
+ goto improper;
+ else
+ *ep = '\0';
+ filesize = strtol(cp, &ep, 10);
+ if (filesize < 1 || *ep != '\0')
+ goto improper;
+ } else
+ filesize = -1;
/* Open the output file. */
out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
@@ -338,8 +364,14 @@ url_get(origline, proxyenv)
free(line);
return (0);
+noftpautologin:
+ warnx(
+ "Auto-login using ftp URLs isn't supported when using $ftp_proxy");
+ goto cleanup_url_get;
+
improper:
warnx("Improper response from %s", host);
+
cleanup_url_get:
if (s != -1)
close(s);
@@ -387,7 +419,8 @@ auto_fetch(argc, argv)
char *cp, *line, *host, *dir, *file, *portnum;
char *user, *pass;
char *ftpproxy, *httpproxy;
- int rval, xargc, argpos;
+ int rval, xargc;
+ volatile int argpos;
int dirhasglob, filehasglob;
char rempath[MAXPATHLEN];
@@ -472,17 +505,17 @@ bad_ftp_url:
portnum = strchr(host, ':');
if (portnum != NULL)
*portnum++ = '\0';
-parsed_url:
} else { /* classic style `host:file' */
dir = strchr(host, ':');
}
+parsed_url:
if (EMPTYSTRING(host)) {
rval = argpos + 1;
continue;
}
/*
- * If cp is NULL, the file wasn't specified
+ * If dir is NULL, the file wasn't specified
* (URL looked something like ftp://host)
*/
if (dir != NULL)
OpenPOWER on IntegriCloud