=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/whois/whois.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- src/usr.bin/whois/whois.c 1999/11/19 03:57:14 1.10 +++ src/usr.bin/whois/whois.c 2000/07/12 18:01:57 1.11 @@ -1,4 +1,4 @@ -/* $OpenBSD: whois.c,v 1.10 1999/11/19 03:57:14 millert Exp $ */ +/* $OpenBSD: whois.c,v 1.11 2000/07/12 18:01:57 itojun Exp $ */ /* * Copyright (c) 1980, 1993 @@ -43,7 +43,7 @@ #if 0 static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93"; #else -static char rcsid[] = "$OpenBSD: whois.c,v 1.10 1999/11/19 03:57:14 millert Exp $"; +static char rcsid[] = "$OpenBSD: whois.c,v 1.11 2000/07/12 18:01:57 itojun Exp $"; #endif #endif /* not lint */ @@ -76,20 +76,18 @@ #define WHOIS_QUICK 0x04 static void usage __P((void)); -static void whois __P((char *, struct sockaddr_in *, int)); +static void whois __P((char *, struct addrinfo *, int)); int main(argc, argv) int argc; char **argv; { - int ch, i, j; + int ch, i, j, error; int use_qnichost, flags; char *host; char *qnichost; - struct servent *sp; - struct hostent *hp; - struct sockaddr_in sin; + struct addrinfo hints, *res; #ifdef SOCKS SOCKSinit(argv[0]); @@ -144,15 +142,6 @@ if (!argc) usage(); - memset(&sin, 0, sizeof sin); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sp = getservbyname("whois", "tcp"); - if (sp == NULL) - sin.sin_port = htons(WHOIS_PORT); - else - sin.sin_port = sp->s_port; - /* * If no nic host is specified, use whois-servers.net * if there is a '.' in the name, else fall back to NICHOST. @@ -179,49 +168,68 @@ err(1, "malloc"); strcpy(qnichost, *argv + j + 1); strcat(qnichost, QNICHOST_TAIL); - - if (inet_aton(qnichost, &sin.sin_addr) == 0) { - hp = gethostbyname2(qnichost, AF_INET); - if (hp == NULL) { - free(qnichost); - qnichost = NULL; - } else { - sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; - } - } + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(qnichost, "whois", + &hints, &res); + if (error != 0) + errx(EX_NOHOST, "%s: %s", qnichost, + gai_strerror(error)); } } - if (!qnichost && inet_aton(host, &sin.sin_addr) == 0) { - hp = gethostbyname2(host, AF_INET); - if (hp == NULL) + if (!qnichost) { + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(host, "whois", &hints, &res); + if (error != 0) errx(EX_NOHOST, "%s: %s", host, - hstrerror(h_errno)); - host = hp->h_name; - sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; + gai_strerror(error)); } - whois(*argv++, &sin, flags); + whois(*argv++, res, flags); + freeaddrinfo(res); } exit(0); } static void -whois(name, sinp, flags) +whois(name, res, flags) char *name; - struct sockaddr_in *sinp; + struct addrinfo *res; int flags; { FILE *sfi, *sfo; char *buf, *p, *nhost; size_t len; int s, nomatch; + const char *reason = NULL; - s = socket(PF_INET, SOCK_STREAM, 0); - if (s < 0) - err(EX_OSERR, "socket"); + s = -1; + for (/*nothing*/; res; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s < 0) { + reason = "socket"; + continue; + } + if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { + reason = "connect"; + close(s); + s = -1; + continue; + } - if (connect(s, (struct sockaddr *)sinp, sizeof(*sinp)) < 0) - err(EX_OSERR, "connect"); + break; /*okay*/ + } + if (s < 0) { + if (reason) + err(EX_OSERR, "%s", reason); + else + errx(EX_OSERR, "unknown error in connection attempt"); + } sfi = fdopen(s, "r"); sfo = fdopen(s, "w"); @@ -263,15 +271,22 @@ nhost = INICHOST; } if (nhost) { - if (inet_aton(nhost, &sinp->sin_addr) == 0) { - struct hostent *hp = gethostbyname2(nhost, AF_INET); - if (hp == NULL) - return; - sinp->sin_addr = *(struct in_addr *)hp->h_addr_list[0]; + struct addrinfo hints, *res2; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(nhost, "whois", &hints, &res2); + if (error != 0) { + warnx("%s: %s", nhost, gai_strerror(error)); + return; } if (!nomatch) free(nhost); - whois(name, sinp, 0); + whois(name, res2, 0); + freeaddrinfo(res2); } } @@ -280,6 +295,6 @@ { (void)fprintf(stderr, - "usage: whois [-adgimpqQrR] [-h hostname] name ...\n"); + "usage: whois [-adgimpqQrR6] [-h hostname] name ...\n"); exit(EX_USAGE); }