=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ftp/fetch.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- src/usr.bin/ftp/fetch.c 1999/02/09 03:43:48 1.24 +++ src/usr.bin/ftp/fetch.c 1999/12/08 12:57:06 1.25 @@ -1,4 +1,4 @@ -/* $OpenBSD: fetch.c,v 1.24 1999/02/09 03:43:48 deraadt Exp $ */ +/* $OpenBSD: fetch.c,v 1.25 1999/12/08 12:57:06 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.24 1999/02/09 03:43:48 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: fetch.c,v 1.25 1999/12/08 12:57:06 itojun Exp $"; #endif /* not lint */ /* @@ -96,17 +96,17 @@ const char *proxyenv; const char *outfile; { - struct sockaddr_in sin; + struct addrinfo hints, *res0, *res; + int error; int i, out, isftpurl, isfileurl; - in_port_t port; volatile int s; size_t len; char c, *cp, *ep, *portnum, *path, buf[4096]; const char *savefile; - char *line, *proxy, *host; + char *line, *proxy, *host, *port; volatile sig_t oldintr; off_t hashbytes; - struct hostent *hp = NULL; + char *cause = "unknown"; s = -1; proxy = NULL; @@ -276,71 +276,43 @@ fprintf(ttyout, "host %s, port %s, path %s, save as %s.\n", host, portnum, path, savefile); - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - - if (isdigit(host[0])) { - if (inet_aton(host, &sin.sin_addr) == 0) { - warnx("Invalid IP address: %s", host); - goto cleanup_url_get; - } - } else { - hp = gethostbyname(host); - if (hp == NULL) { - warnx("%s: %s", host, hstrerror(h_errno)); - goto cleanup_url_get; - } - if (hp->h_addrtype != AF_INET) { - warnx("%s: not an Internet address?", host); - goto cleanup_url_get; - } - memcpy(&sin.sin_addr, hp->h_addr, (size_t)hp->h_length); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + port = portnum ? portnum : httpport; + error = getaddrinfo(host, port, &hints, &res0); + if (error) { + warnx("%s: %s", gai_strerror(error), host); + goto cleanup_url_get; } - if (! EMPTYSTRING(portnum)) { - char *ep; - long nport; + s = -1; + for (res = res0; res; res = res->ai_next) { + getnameinfo(res->ai_addr, res->ai_addrlen, buf, sizeof(buf), + NULL, 0, NI_NUMERICHOST); + fprintf(ttyout, "Trying %s...\n", buf); - nport = strtol(portnum, &ep, 10); - if (nport < 1 || nport > USHRT_MAX || *ep != '\0') { - warnx("Invalid port: %s", portnum); - goto cleanup_url_get; + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == -1) { + cause = "socket"; + continue; } - port = htons((in_port_t)nport); - } else - port = httpport; - sin.sin_port = port; - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { - warn("Can't create socket"); - goto cleanup_url_get; - } - - while (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - if (errno == EINTR) +again: + if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { + if (errno == EINTR) + goto again; + close(s); + s = -1; + cause = "connect"; continue; - if (hp && hp->h_addr_list[1]) { - int oerrno = errno; - char *ia; - - ia = inet_ntoa(sin.sin_addr); - errno = oerrno; - warn("connect to address %s", ia); - hp->h_addr_list++; - memcpy(&sin.sin_addr, hp->h_addr_list[0], - (size_t)hp->h_length); - fprintf(ttyout, "Trying %s...\n", - inet_ntoa(sin.sin_addr)); - (void)close(s); - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { - warn("socket"); - goto cleanup_url_get; - } - continue; } - warn("connect"); + + break; + } + freeaddrinfo(res0); + if (s < 0) { + warn(cause); goto cleanup_url_get; } @@ -648,7 +620,17 @@ if (EMPTYSTRING(user)) goto bad_ftp_url; host = cp; - portnum = strchr(host, ':'); + +#if 0 + /* look for IPv6 address URL */ + if (host == '[' && (cp = strrchr(host, ']'))) { + host++; + *cp++ = '\0'; + } else + cp = host; +#endif + + portnum = strrchr(cp, ':'); if (portnum != NULL) *portnum++ = '\0'; } else { /* classic style `host:file' */ @@ -791,4 +773,15 @@ if (connected && rval != -1) disconnect(0, NULL); return (rval); +} + +int +isurl(p) + const char *p; +{ + if (strncasecmp(p, FTP_URL, sizeof(FTP_URL) - 1) == 0 + || strncasecmp(p, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) { + return 1; + } + return 0; }