summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-07-12 18:01:58 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-07-12 18:01:58 +0000
commit82afd208a6e448ec1730b83222e1858c50bd007e (patch)
tree8bee14cd23d6f73b565228d73c5d6a163b8e5902 /usr.bin
parent11d8c7be3b9a317ac7c2370f84f5d47476665bcd (diff)
make whois(1) IPv6-ready. patch from deraadt + minor tweaks.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/whois/whois.c109
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);
}