diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-07-12 18:01:58 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-07-12 18:01:58 +0000 |
commit | 82afd208a6e448ec1730b83222e1858c50bd007e (patch) | |
tree | 8bee14cd23d6f73b565228d73c5d6a163b8e5902 /usr.bin | |
parent | 11d8c7be3b9a317ac7c2370f84f5d47476665bcd (diff) |
make whois(1) IPv6-ready. patch from deraadt + minor tweaks.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/whois/whois.c | 109 |
1 files changed, 62 insertions, 47 deletions
diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c index 99eca23ebac..3b492e2eb33 100644 --- a/usr.bin/whois/whois.c +++ b/usr.bin/whois/whois.c @@ -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 @@ static char copyright[] = #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 @@ static char rcsid[] = "$OpenBSD: whois.c,v 1.10 1999/11/19 03:57:14 millert Exp #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 @@ main(argc, argv) 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 @@ main(argc, argv) 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 @@ whois(name, sinp, flags) 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 @@ usage() { (void)fprintf(stderr, - "usage: whois [-adgimpqQrR] [-h hostname] name ...\n"); + "usage: whois [-adgimpqQrR6] [-h hostname] name ...\n"); exit(EX_USAGE); } |