Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/ftp * change fetch_ftp() to be fully rfc 1738 compli...
details: https://anonhg.NetBSD.org/src/rev/aca3ead7a099
branches: trunk
changeset: 474588:aca3ead7a099
user: lukem <lukem%NetBSD.org@localhost>
date: Mon Jul 12 13:20:34 1999 +0000
description:
* change fetch_ftp() to be fully rfc 1738 compliant; if the URL contains
the an empty directory (e.g, between `some' and `path' in
`ftp://host/some//path'), then execute `CWD ' (without a path).
This command will probably fail on rfc 959 compliant servers, so
issue a warning in this case and bail. [noted by cgd].
(i wonder if the people who wrote rfc 1738 actually realised that this
requirement appears to contravene the spec for `cwd' in rfc 959 ?)
* replace isurl() with isipv6addr(), and use appropriately. fixes
auto-login with `classic ftp URLs' (e.g, `ftp somehost:')
* cleanup and rework some of the ipv6 stuff in parse_url()
* prevent potential coredump in fetch_ftp() when parsing `;type=X'
* KNF a few lines
* fix a couple of comments
* cleanup the man page a bit
diffstat:
usr.bin/ftp/extern.h | 4 +-
usr.bin/ftp/fetch.c | 176 +++++++++++++++++++++++++++++---------------------
usr.bin/ftp/ftp.1 | 35 ++++++----
usr.bin/ftp/main.c | 6 +-
usr.bin/ftp/util.c | 24 ++++++-
5 files changed, 149 insertions(+), 96 deletions(-)
diffs (truncated from 548 to 300 lines):
diff -r 931db40ffa40 -r aca3ead7a099 usr.bin/ftp/extern.h
--- a/usr.bin/ftp/extern.h Mon Jul 12 12:34:57 1999 +0000
+++ b/usr.bin/ftp/extern.h Mon Jul 12 13:20:34 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.33 1999/07/11 20:37:39 itojun Exp $ */
+/* $NetBSD: extern.h,v 1.34 1999/07/12 13:20:34 lukem Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@@ -111,7 +111,7 @@
void idle __P((int, char **));
int initconn __P((void));
void intr __P((void));
-int isurl __P((const char *));
+int isipv6addr __P((const char *));
void list_vertical __P((StringList *));
void lcd __P((int, char **));
void lostpeer __P((void));
diff -r 931db40ffa40 -r aca3ead7a099 usr.bin/ftp/fetch.c
--- a/usr.bin/ftp/fetch.c Mon Jul 12 12:34:57 1999 +0000
+++ b/usr.bin/ftp/fetch.c Mon Jul 12 13:20:34 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fetch.c,v 1.62 1999/07/06 22:11:37 tron Exp $ */
+/* $NetBSD: fetch.c,v 1.63 1999/07/12 13:20:34 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.62 1999/07/06 22:11:37 tron Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.63 1999/07/12 13:20:34 lukem Exp $");
#endif /* not lint */
/*
@@ -252,16 +252,19 @@
/*
* Parse URL of form:
- * <type>://[<user>[:<password>@]]<host>[:<port>]/<url-path>
+ * <type>://[<user>[:<password>@]]<host>[:<port>][/<path>]
* Returns -1 if a parse error occurred, otherwise 0.
- * Only permit [<user>[:<password>@]] for ftp:// URLs
* It's the caller's responsibility to url_decode() the returned
* user, pass and path.
+ *
* Sets type to url_t, each of the given char ** pointers to a
* malloc(3)ed strings of the relevant section, and port to
* the number given, or ftpport if ftp://, or httpport if http://.
*
- * XXX: this is not totally RFC 1738 compliant; path will have the
+ * If <host> is surrounded by `[' and ']', it's parsed as an
+ * IPv6 address (as per draft-ietf-ipngwg-url-literal-01.txt).
+ *
+ * XXX: this is not totally RFC 1738 compliant; <path> will have the
* leading `/' unless it's an ftp:// URL, as this makes things easier
* for file:// and http:// URLs. ftp:// URLs have the `/' between the
* host and the url-path removed, but any additional leading slashes
@@ -271,10 +274,11 @@
* Examples:
* input url output path
* --------- -----------
- * "http://host" NULL
- * "http://host/" "/"
- * "http://host/dir/file" "/dir/file"
- * "ftp://host/dir/file" "dir/file"
+ * "ftp://host" NULL
+ * "http://host/" NULL
+ * "file://host/dir/file" "dir/file"
+ * "ftp://host/" ""
+ * "ftp://host//" NULL
* "ftp://host//dir/file" "/dir/file"
*/
static int
@@ -288,7 +292,7 @@
char **port;
char **path;
{
- char *cp, *ep, *thost;
+ char *cp, *ep, *thost, *tport;
size_t len;
if (url == NULL || desc == NULL || type == NULL || user == NULL
@@ -296,17 +300,17 @@
errx(1, "parse_url: invoked with NULL argument!");
*type = UNKNOWN_URL_T;
- *user = *pass = *host = *path = NULL;
- *port = NULL;
+ *user = *pass = *host = *port = *path = NULL;
+ tport = NULL;
if (strncasecmp(url, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) {
url += sizeof(HTTP_URL) - 1;
*type = HTTP_URL_T;
- *port = strdup(httpport);
+ tport = httpport;
} else if (strncasecmp(url, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
url += sizeof(FTP_URL) - 1;
*type = FTP_URL_T;
- *port = strdup(ftpport);
+ tport = ftpport;
} else if (strncasecmp(url, FILE_URL, sizeof(FILE_URL) - 1) == 0) {
url += sizeof(FILE_URL) - 1;
*type = FILE_URL_T;
@@ -338,52 +342,66 @@
*path = xstrdup(ep);
}
- cp = strchr(thost, '@');
- /* look for user[:pass]@ in URLs */
+ cp = strchr(thost, '@'); /* look for user[:pass]@ in URLs */
if (cp != NULL) {
if (*type == FTP_URL_T)
anonftp = 0; /* disable anonftp */
*user = thost;
*cp = '\0';
- *host = xstrdup(cp + 1);
+ thost = xstrdup(cp + 1);
cp = strchr(*user, ':');
if (cp != NULL) {
*cp = '\0';
*pass = xstrdup(cp + 1);
}
- } else
- *host = thost;
+ }
- /* look for IPv6 address URL */
- if (*thost == '[' && (cp = strrchr(thost, ']'))) {
- size_t len = cp - thost - 1 ;
- *host = (char *)xmalloc(len + 1);
- strncpy(*host, thost + 1, len);
- (*host)[len] = '\0';
- cp = strrchr(++cp, ':');
- } else if ((cp = strrchr(thost, ':')) != NULL) {
- size_t len = cp - thost;
- *host = (char *)xmalloc(len + 1);
- strncpy(*host, thost, len);
- (*host)[len] = '\0';
- } else {
- *host = xstrdup(thost);
- cp = NULL;
- }
+#ifdef INET6
+ /*
+ * Check if thost is an encoded IPv6 address, as per
+ * draft-ietf-ipngwg-url-literal-01.txt:
+ * `[' ipv6-address ']'
+ */
+ if (*thost == '[') {
+ cp = thost + 1;
+ if ((ep = strchr(cp, ']')) == NULL ||
+ (ep[1] != '\0' && ep[1] != '\0')) {
+ warnx("Invalid address `%s' in %s `%s'",
+ thost, desc, url);
+ goto cleanup_parse_url;
+ }
+ len = ep - cp; /* change `[xxx]' -> `xxx' */
+ memmove(thost, thost + 1, len);
+ thost[len] = '\0';
+ if (! isipv6addr(thost)) {
+ warnx("Invalid IPv6 address `%s' in %s `%s'",
+ thost, desc, url);
+ goto cleanup_parse_url;
+ }
+ cp = ep + 1;
+ if (*cp == ':')
+ cp++;
+ else
+ cp = NULL;
+ } else
+#endif /* INET6 */
+ if ((cp = strchr(thost, ':')) != NULL)
+ *cp++ = '\0';
+ *host = thost;
/* look for [:port] */
if (cp != NULL) {
long nport;
- *cp = '\0';
- nport = strtol(cp + 1, &ep, 10);
+ nport = strtol(cp, &ep, 10);
if (nport < 1 || nport > MAX_IN_PORT_T || *ep != '\0') {
warnx("Invalid port `%s' in %s `%s'", cp, desc, url);
goto cleanup_parse_url;
}
- *port = (char *)xmalloc(6); /* large enough for "65535\0" */
- snprintf(*port, 6, "%ld", nport);
+ tport = cp;
}
+ if (tport != NULL);
+ *port = xstrdup(tport);
if (debug)
fprintf(ttyout,
@@ -420,7 +438,7 @@
size_t len;
char *cp, *ep, *buf, *savefile;
char *auth, *location, *message;
- char *user, *pass, *host, *path, *decodedpath;
+ char *user, *pass, *host, *port, *path, *decodedpath;
char *puser, *ppass;
off_t hashbytes;
int (*closefunc) __P((FILE *));
@@ -428,7 +446,6 @@
time_t mtime;
url_t urltype;
in_port_t portnum;
- char *port;
int error;
closefunc = NULL;
@@ -620,7 +637,7 @@
warnx("Unknown port for URL `%s'", url);
goto cleanup_fetch_url;
}
- sin.sin_port = port;
+ sin.sin_port = portnum;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) {
@@ -687,11 +704,12 @@
close(s);
res = res->ai_next;
if (res) {
- getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), NULL, 0,
- NI_NUMERICHOST);
+ getnameinfo(res->ai_addr,
+ res->ai_addrlen, hbuf, sizeof(hbuf),
+ NULL, 0, NI_NUMERICHOST);
if (verbose)
- fprintf(ttyout, "Trying %s...\n", hbuf);
+ fprintf(ttyout,
+ "Trying %s...\n", hbuf);
continue;
}
warn("Can't connect to %s", host);
@@ -1159,7 +1177,7 @@
/*
* Retrieve ftp URL or classic ftp argument using FTP.
- * Returns -1 on failure, 0 on completed xfer, 1 if ftp connection
+ * Returns 1 on failure, 0 on completed xfer, -1 if ftp connection
* is still open (e.g, ftp xfer with trailing /)
*/
static int
@@ -1194,7 +1212,7 @@
*/
/* check for trailing ';type=[aid]' */
- if (path != NULL && (cp = strrchr(path, ';')) != NULL) {
+ if (! EMPTYSTRING(path) && (cp = strrchr(path, ';')) != NULL) {
if (strcasecmp(cp, ";type=a") == 0)
type = TYPE_A;
else if (strcasecmp(cp, ";type=i") == 0)
@@ -1229,7 +1247,7 @@
* If we are dealing with classic `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 retreiving the file. So we set
+ * do "CWD /" before retrieving the file. So we set
* dir="/" and file="file".
*
* But if we are dealing with URLs like
@@ -1262,7 +1280,8 @@
file = dir;
dir = NULL;
}
- }
+ } else
+ dir = NULL;
if (urltype == FTP_URL_T && file != NULL) {
url_decode(file);
/* but still don't url_decode(dir) */
@@ -1317,12 +1336,12 @@
errx(1, "fetch_ftp: unknown transfer type %d\n", type);
}
- /*
- * Change directories, if necessary.
- *
- * Note: don't use EMPTYSTRING(dir) below, because
- * dir="" means something different from dir=NULL.
- */
+ /*
+ * Change directories, if necessary.
+ *
+ * Note: don't use EMPTYSTRING(dir) below, because
+ * dir=="" means something different from dir==NULL.
+ */
if (dir != NULL && !dirhasglob) {
char *nextpart;
@@ -1341,21 +1360,30 @@
* slashes in the path) and RFC 1738 says that we should
* still do `CWD ' (with a null argument) in such cases.
Home |
Main Index |
Thread Index |
Old Index