=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ftp/fetch.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- src/usr.bin/ftp/fetch.c 2000/05/03 19:50:41 1.30 +++ src/usr.bin/ftp/fetch.c 2000/05/15 16:07:04 1.31 @@ -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 @@ */ 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 @@ 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; + 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; - } - 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;