summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-05-15 16:07:05 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-05-15 16:07:05 +0000
commitdede4ab447a054fafe32bcedba55c65628e6a98b (patch)
tree3bc45c6c9af547e8a47639f9eb88b38f9f130c7f
parent6fa7621b02967b78a790f2c0432d7732bc4d9fbc (diff)
parse RFC2732 ftp URL (ftp://[::1]:21/readme)
-rw-r--r--usr.bin/ftp/fetch.c95
1 files changed, 57 insertions, 38 deletions
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index 164678e867c..5ba2a89529c 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fetch.c,v 1.30 2000/05/03 19:50:41 deraadt Exp $ */
+/* $OpenBSD: fetch.c,v 1.31 2000/05/15 16:07:04 itojun Exp $ */
/* $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */
/*-
@@ -38,7 +38,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: fetch.c,v 1.30 2000/05/03 19:50:41 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: fetch.c,v 1.31 2000/05/15 16:07:04 itojun Exp $";
#endif /* not lint */
/*
@@ -619,6 +619,8 @@ auto_fetch(argc, argv, outfile)
*/
host = line;
if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
+ char *passend, *userend;
+
if (ftpproxy) {
if (url_get(line, ftpproxy, outfile) == -1)
rval = argpos + 1;
@@ -628,50 +630,67 @@ auto_fetch(argc, argv, outfile)
dir = strchr(host, '/');
/* Look for [user:pass@]host[:port] */
- pass = strpbrk(host, ":@/");
- if (pass == NULL || *pass == '/') {
- pass = NULL;
- goto parsed_url;
- }
- if (pass == host || *pass == '@') {
+
+ /* check if we have "user:pass@" */
+ passend = strchr(host, '@');
+ userend = strchr(host, ':');
+ if (passend && userend && userend < passend &&
+ (!dir || passend < dir)) {
+ user = host;
+ pass = userend + 1;
+ host = passend + 1;
+ *userend = *passend = '\0';
+
+ if (EMPTYSTRING(user) || EMPTYSTRING(pass)) {
bad_ftp_url:
- warnx("Invalid URL: %s", argv[argpos]);
- rval = argpos + 1;
- continue;
- }
- *pass++ = '\0';
- /* XXX - assumes no '@' in pathname */
- if ((cp = strrchr(pass, '@')) == NULL)
- cp = strpbrk(pass, ":@/");
- if (cp == NULL || *cp == '/') {
- portnum = pass;
- pass = NULL;
- goto parsed_url;
+ warnx("Invalid URL: %s", argv[argpos]);
+ rval = argpos + 1;
+ continue;
+ }
}
- if (EMPTYSTRING(cp) || *cp == ':')
- goto bad_ftp_url;
- *cp++ = '\0';
- user = host;
- if (EMPTYSTRING(user))
- goto bad_ftp_url;
- host = cp;
-
-#if 0
- /* look for IPv6 address URL */
- if (host == '[' && (cp = strrchr(host, ']'))) {
- host++;
- *cp++ = '\0';
+
+#ifdef INET6
+ /* check [host]:port, or [host] */
+ if (host[0] == '[') {
+ cp = strchr(host, ']');
+ if (cp && (!dir || cp < dir)) {
+ if (cp + 1 == dir || cp[1] == ':') {
+ host++;
+ *cp++ = '\0';
+ } else
+ cp = NULL;
+ } else
+ cp = host;
} else
cp = host;
+#else
+ cp = host;
#endif
-
- portnum = strrchr(cp, ':');
- if (portnum != NULL)
- *portnum++ = '\0';
+
+ /* split off host[:port] if there is */
+ if (cp) {
+ portnum = strchr(cp, ':');
+ if (!portnum)
+ ;
+ else {
+ if (!dir)
+ ;
+ else if (portnum + 1 < dir) {
+ *portnum++ = '\0';
+ /*
+ * XXX should check if portnum
+ * is decimal number
+ */
+ } else {
+ /* empty portnum */
+ goto bad_ftp_url;
+ }
+ }
+ } else
+ portnum = NULL;
} else { /* classic style `host:file' */
dir = strchr(host, ':');
}
-parsed_url:
if (EMPTYSTRING(host)) {
rval = argpos + 1;
continue;