changeset 13429:b2fbfacb9f9c

1350 whois(1) should use correct whois server for lookups Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com> Reviewed by: Garrett D'Amore <garrett@nexenta.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Albert Lee <trisk@nexenta.com>
author Yuri Pankov <yuri.pankov@nexenta.com>
date Fri, 12 Aug 2011 18:09:43 -0400
parents a9dfa4813bcd
children 8e6add739e38
files usr/src/cmd/cmd-inet/usr.bin/Makefile usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.whois usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.whois.descrip usr/src/cmd/cmd-inet/usr.bin/whois.c usr/src/man/man1/whois.1 usr/src/pkg/manifests/service-network-network-clients.mf
diffstat 6 files changed, 570 insertions(+), 167 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/cmd-inet/usr.bin/Makefile	Fri Aug 12 16:07:25 2011 -0400
+++ b/usr/src/cmd/cmd-inet/usr.bin/Makefile	Fri Aug 12 18:09:43 2011 -0400
@@ -22,6 +22,8 @@
 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+#
 
 PROG=		dns-sd finger rdate ruptime rwho whois
 SUIDPROG=	rcp rlogin rsh
@@ -36,7 +38,7 @@
 
 # As programs get lint-clean, add them here.  Eventually.
 # This hack should go away, and all in PROG should be lint-clean.
-LINTCLEAN=	rlogin.c rsh.c rcp.c rdate.c rwho.c
+LINTCLEAN=	rlogin.c rsh.c rcp.c rdate.c rwho.c whois.c
 
 # Likewise, as subdirs get lint-clean, add them here.  Once
 # they're all clean, replace the dependency of the lint target
@@ -81,7 +83,7 @@
 rdate lint-rdate:=	LDLIBS += -lsocket
 rlogin lint-rlogin :=	LDLIBS += -lnsl -lsocket
 rsh lint-rsh :=		LDLIBS += -lsocket
-whois :=		LDLIBS += -lsocket
+whois lint-whois :=	LDLIBS += -lsocket
 
 include  $(SRC)/lib/gss_mechs/mech_krb5/Makefile.mech_krb5
 $(KCMDPROGS)	:=	LDLIBS += -lnsl -lmech_krb5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.whois	Fri Aug 12 18:09:43 2011 -0400
@@ -0,0 +1,28 @@
+Copyright (c) 1980, 1993
+     The Regents of the University of California.  All rights reserved.
+
+Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+4. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.whois.descrip	Fri Aug 12 18:09:43 2011 -0400
@@ -0,0 +1,1 @@
+WHOIS - INTERNET DOMAIN NAME AND NETWORK NUMBER DIRECTORY SERVICE
--- a/usr/src/cmd/cmd-inet/usr.bin/whois.c	Fri Aug 12 16:07:25 2011 -0400
+++ b/usr/src/cmd/cmd-inet/usr.bin/whois.c	Fri Aug 12 18:09:43 2011 -0400
@@ -1,117 +1,385 @@
 /*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
+ * Copyright (c) 1980, 1993
+ *	The Regents of the University of California.  All rights reserved.
  *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
-/*	  All Rights Reserved  	*/
-
-/*
- * University Copyright- Copyright (c) 1982, 1986, 1988
- * The Regents of the University of California
- * All Rights Reserved
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
- * University Acknowledgment- Portions of this document are derived from
- * software developed by the University of California, Berkeley, and its
- * contributors.
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #include <sys/types.h>
 #include <sys/socket.h>
 
 #include <netinet/in.h>
-
-#include <stdio.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <err.h>
+#include <limits.h>
 #include <netdb.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <stdlib.h>
+#include <sysexits.h>
 #include <unistd.h>
 
-#define	NICHOST	"whois.internic.net"
+#define	ABUSEHOST	"whois.abuse.net"
+#define	NICHOST		"whois.crsnic.net"
+#define	INICHOST	"whois.networksolutions.com"
+#define	GNICHOST	"whois.nic.gov"
+#define	ANICHOST	"whois.arin.net"
+#define	LNICHOST	"whois.lacnic.net"
+#define	KNICHOST	"whois.krnic.net"
+#define	RNICHOST	"whois.ripe.net"
+#define	PNICHOST	"whois.apnic.net"
+#define	MNICHOST	"whois.ra.net"
+#define	QNICHOST_TAIL	".whois-servers.net"
+#define	BNICHOST	"whois.registro.br"
+#define	NORIDHOST	"whois.norid.no"
+#define	IANAHOST	"whois.iana.org"
+#define	GERMNICHOST	"de.whois-servers.net"
+#define	FNICHOST	"whois.afrinic.net"
+#define	DEFAULT_PORT	"whois"
+#define	WHOIS_SERVER_ID	"Whois Server: "
+#define	WHOIS_ORG_SERVER_ID	"Registrant Street1:Whois Server:"
+
+#define	WHOIS_RECURSE		0x01
+#define	WHOIS_QUICK		0x02
+
+#define	ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-')
+
+const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST,
+    FNICHOST, NULL };
+const char *port = DEFAULT_PORT;
+
+static char *choose_server(char *);
+static struct addrinfo *gethostinfo(char const *host, int exit_on_error);
+static void s_asprintf(char **ret, const char *format, ...);
+static void usage(void);
+static void whois(const char *, const char *, int);
+static char *getln(FILE *in, size_t *lenp);
 
 int
 main(int argc, char *argv[])
 {
-	int s, rv;
-	register FILE *sfi, *sfo;
-	register int c;
-	char *host = NICHOST;
-	struct addrinfo *ai_head, *ai;
-	struct addrinfo hints;
+	const char *country, *host;
+	char *qnichost;
+	int ch, flags, use_qnichost;
 
-	argc--, argv++;
-	if (argc > 2 && strcmp(*argv, "-h") == 0) {
-		argv++, argc--;
-		host = *argv++;
-		argc--;
+	country = host = qnichost = NULL;
+	flags = use_qnichost = 0;
+	while ((ch = getopt(argc, argv, "aAbc:fgh:iIklmp:Qr")) != -1) {
+		switch (ch) {
+		case 'a':
+			host = ANICHOST;
+			break;
+		case 'A':
+			host = PNICHOST;
+			break;
+		case 'b':
+			host = ABUSEHOST;
+			break;
+		case 'c':
+			country = optarg;
+			break;
+		case 'f':
+			host = FNICHOST;
+			break;
+		case 'g':
+			host = GNICHOST;
+			break;
+		case 'h':
+			host = optarg;
+			break;
+		case 'i':
+			host = INICHOST;
+			break;
+		case 'I':
+			host = IANAHOST;
+			break;
+		case 'k':
+			host = KNICHOST;
+			break;
+		case 'l':
+			host = LNICHOST;
+			break;
+		case 'm':
+			host = MNICHOST;
+			break;
+		case 'p':
+			port = optarg;
+			break;
+		case 'Q':
+			flags |= WHOIS_QUICK;
+			break;
+		case 'r':
+			host = RNICHOST;
+			break;
+		case '?':
+		default:
+			usage();
+			/* NOTREACHED */
+		}
 	}
-	if (argc != 1) {
-		(void) fprintf(stderr, "usage: whois [ -h host ] name\n");
-		exit(1);
+	argc -= optind;
+	argv += optind;
+
+	if (!argc || (country != NULL && host != NULL))
+		usage();
+
+	/*
+	 * If no host or country is specified determine the top level domain
+	 * from the query.  If the TLD is a number, query ARIN.  Otherwise, use
+	 * TLD.whois-server.net.  If the domain does not contain '.', fall
+	 * back to NICHOST.
+	 */
+	if (host == NULL && country == NULL) {
+		use_qnichost = 1;
+		host = NICHOST;
+		if (!(flags & WHOIS_QUICK))
+			flags |= WHOIS_RECURSE;
+	}
+	while (argc-- > 0) {
+		if (country != NULL) {
+			s_asprintf(&qnichost, "%s%s", country, QNICHOST_TAIL);
+			whois(*argv, qnichost, flags);
+		} else if (use_qnichost)
+			if ((qnichost = choose_server(*argv)) != NULL)
+				whois(*argv, qnichost, flags);
+		if (qnichost == NULL)
+			whois(*argv, host, flags);
+		free(qnichost);
+		qnichost = NULL;
+		argv++;
 	}
 
-	memset(&hints, 0, sizeof (hints));
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_protocol = IPPROTO_TCP;
-	hints.ai_flags = AI_ADDRCONFIG;
-	rv = getaddrinfo(host, "whois", &hints, &ai_head);
-	if (rv != 0) {
-		(void) fprintf(stderr, "whois: %s: %s\n", host,
-		    gai_strerror(rv));
-		exit(1);
+	return (0);
+}
+
+/*
+ * This function will remove any trailing periods from domain, after which it
+ * returns a pointer to newly allocated memory containing the whois server to
+ * be queried, or a NULL if the correct server couldn't be determined.  The
+ * caller must remember to free(3) the allocated memory.
+ */
+static char *
+choose_server(char *domain)
+{
+	char *pos, *retval;
+
+	if (strchr(domain, ':')) {
+		s_asprintf(&retval, "%s", ANICHOST);
+		return (retval);
 	}
+	for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.'; )
+		*pos = '\0';
+	if (*domain == '\0')
+		errx(EX_USAGE, "can't search for a null string");
+	if (strlen(domain) > sizeof ("-NORID")-1 &&
+	    strcasecmp(domain + strlen(domain) - sizeof ("-NORID") + 1,
+	    "-NORID") == 0) {
+		s_asprintf(&retval, "%s", NORIDHOST);
+		return (retval);
+	}
+	while (pos > domain && *pos != '.')
+		--pos;
+	if (pos <= domain)
+		return (NULL);
+	if (isdigit((unsigned char)*++pos))
+		s_asprintf(&retval, "%s", ANICHOST);
+	else
+		s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL);
+	return (retval);
+}
+
+static struct addrinfo *
+gethostinfo(char const *host, int exit_on_error)
+{
+	struct addrinfo hints, *res;
+	int error;
 
-	for (ai = ai_head; ai != NULL; ai = ai->ai_next) {
-		s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-		if (s >= 0) {
-			rv = connect(s, ai->ai_addr, ai->ai_addrlen);
-			if (rv < 0)
-				(void) close(s);
-			else
-				break;
-		}
+	(void) memset(&hints, 0, sizeof (hints));
+	hints.ai_flags = 0;
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	error = getaddrinfo(host, port, &hints, &res);
+	if (error) {
+		warnx("%s: %s", host, gai_strerror(error));
+		if (exit_on_error)
+			exit(EX_NOHOST);
+		return (NULL);
 	}
-	if (ai_head != NULL)
-		freeaddrinfo(ai_head);
+	return (res);
+}
+
+/*
+ * Wrapper for asprintf(3) that exits on error.
+ */
+/* PRINTFLIKE2 */
+static void
+s_asprintf(char **ret, const char *format, ...)
+{
+	va_list ap;
+
+	va_start(ap, format);
+	if (vasprintf(ret, format, ap) == -1) {
+		va_end(ap);
+		err(EX_OSERR, "vasprintf()");
+	}
+	va_end(ap);
+}
 
-	if (s < 0) {
-		perror("whois: socket");
-		exit(2);
-	} else if (rv < 0) {
-		perror("whois: connect");
-		exit(5);
+static void
+whois(const char *query, const char *hostname, int flags)
+{
+	FILE *sfi, *sfo;
+	struct addrinfo *hostres, *res;
+	char *buf, *host, *nhost, *p;
+	int i, s;
+	size_t c, len;
+
+	s = -1;
+	hostres = gethostinfo(hostname, 1);
+	for (res = hostres; res; res = res->ai_next) {
+		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+		if (s < 0)
+			continue;
+		if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
+			break;
+		(void) close(s);
 	}
+	freeaddrinfo(hostres);
+	if (res == NULL)
+		err(EX_OSERR, "connect()");
 
 	sfi = fdopen(s, "r");
 	sfo = fdopen(s, "w");
-	if (sfi == NULL || sfo == NULL) {
-		perror("fdopen");
-		(void) close(s);
-		exit(1);
+	if (sfi == NULL || sfo == NULL)
+		err(EX_OSERR, "fdopen()");
+	if (strcmp(hostname, GERMNICHOST) == 0) {
+		(void) fprintf(sfo, "-T dn,ace -C US-ASCII %s\r\n", query);
+	} else if (strcmp(hostname, "dk" QNICHOST_TAIL) == 0) {
+		(void) fprintf(sfo, "--show-handles %s\r\n", query);
+	} else {
+		(void) fprintf(sfo, "%s\r\n", query);
+	}
+	(void) fflush(sfo);
+	nhost = NULL;
+	while ((buf = getln(sfi, &len)) != NULL) {
+		while (len > 0 && isspace((unsigned char)buf[len - 1]))
+			buf[--len] = '\0';
+		(void) printf("%.*s\n", (int)len, buf);
+
+		if ((flags & WHOIS_RECURSE) && nhost == NULL) {
+			host = strnstr(buf, WHOIS_SERVER_ID, len);
+			if (host != NULL) {
+				host += sizeof (WHOIS_SERVER_ID) - 1;
+				for (p = host; p < buf + len; p++) {
+					if (!ishost(*p)) {
+						*p = '\0';
+						break;
+					}
+				}
+				s_asprintf(&nhost, "%.*s",
+				    (int)(buf + len - host), host);
+			} else if ((host =
+			    strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
+				host += sizeof (WHOIS_ORG_SERVER_ID) - 1;
+				for (p = host; p < buf + len; p++) {
+					if (!ishost(*p)) {
+						*p = '\0';
+						break;
+					}
+				}
+				s_asprintf(&nhost, "%.*s",
+				    (int)(buf + len - host), host);
+			} else if (strcmp(hostname, ANICHOST) == 0) {
+				for (c = 0; c <= len; c++)
+					buf[c] = tolower((unsigned char)buf[c]);
+				for (i = 0; ip_whois[i] != NULL; i++) {
+					if (strnstr(buf, ip_whois[i], len) !=
+					    NULL) {
+						s_asprintf(&nhost, "%s",
+						    ip_whois[i]);
+						break;
+					}
+				}
+			}
+		}
 	}
-	(void) fprintf(sfo, "%s\r\n", *argv);
-	(void) fflush(sfo);
-	while ((c = getc(sfi)) != EOF)
-		(void) putchar(c);
-	return (0);
+	if (nhost != NULL) {
+		whois(query, nhost, 0);
+		free(nhost);
+	}
+}
+
+static void
+usage(void)
+{
+	(void) fprintf(stderr,
+	    "usage: whois [-aAbfgiIklmQr] [-c country-code | -h hostname] "
+	    "[-p port] name ...\n");
+	exit(EX_USAGE);
 }
+
+static char *
+getln(FILE *in, size_t *lenp)
+{
+	static char	*buffer = NULL;
+	static size_t	sz = 0;
+
+	size_t		len = 0;
+
+	for (;;) {
+		if (sz <= (len + 1)) {
+			char *nb;
+			if ((nb = realloc(buffer, sz + LINE_MAX)) == NULL) {
+				err(1, "realloc");
+			}
+			buffer = nb;
+			sz += LINE_MAX;
+		}
+
+		buffer[len] = 0;
+
+		if (fgets(buffer + len, sz - len, in) == NULL) {
+			/* END OF FILE */
+			*lenp = len;
+			if (len == 0)
+				return (NULL);
+			break;
+		}
+
+		len += strlen(buffer + len);
+
+		if (buffer[len - 1] == '\n') {
+			/* got the new line */
+			*lenp = len;
+			break;
+		}
+	}
+
+	return (buffer);
+}
--- a/usr/src/man/man1/whois.1	Fri Aug 12 16:07:25 2011 -0400
+++ b/usr/src/man/man1/whois.1	Fri Aug 12 18:09:43 2011 -0400
@@ -1,90 +1,191 @@
-'\" te
-.\"  Copyright 1989 AT&T  Copyright (c) 1992, Sun Microsystems, Inc.  All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH whois 1 "6 Nov 2000" "SunOS 5.11" "User Commands"
+.TH WHOIS 1 "October 2, 2009" ""
 .SH NAME
-whois \- Internet user name directory service
+\fBwhois\fP
+\- Internet domain name and network number directory service
 .SH SYNOPSIS
-.LP
-.nf
-\fBwhois\fR [\fB-h\fR \fIhost\fR] \fIidentifier\fR
-.fi
-
+.br
+\fBwhois\fP
+[\fB\-aAbfgiIklmQr\fP]
+[\fB\-c\fP \fIcountry-code\fP | \fIFl\fP h \fIhost\fP]
+[\fB\-p\fP \fIport\fP]
+\fIname\fP...
 .SH DESCRIPTION
-.sp
-.LP
-\fBwhois\fR searches for an \fBInternet\fR directory entry for an
-\fIidentifier\fR which is either a name (such as ``Smith'') or a handle (such
-as ``SRI-NIC''). To force a name-only search, precede the name with a period;
-to force a handle-only search, precede the handle with an exclamation point.
-.sp
-.LP
-To search for a group or organization entry, precede the argument with \fB*\fR
-(an asterisk). The entire membership list of the group will be displayed with
-the record.
-.sp
-.LP
-You may of course use an exclamation point and asterisk, or a period and
-asterisk together.
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRUsing The \fBwhois\fR Command
-.sp
-.LP
-The command:
+The
+\fBwhois\fP
+utility looks up records in the databases maintained by several
+Network Information Centers (NICs).
+
+The options are as follows:
+.TP
+\fB\-a\fP
+Use the American Registry for Internet Numbers (ARIN) database.
+It contains network numbers used in those parts of the world covered neither by
+APNIC, AfriNIC, LACNIC, nor by RIPE.
+
+(Hint: All point of contact handles in the ARIN whois database end with -ARIN.)
 
-.sp
-.in +2
-.nf
-example% whois Smith
-.fi
-.in -2
-.sp
+.TP
+\fB\-A\fP
+Use the Asia/Pacific Network Information Center (APNIC) database.
+It contains network numbers used in East Asia, Australia,
+New Zealand, and the Pacific islands.
+.TP
+\fB\-b\fP
+Use the Network Abuse Clearinghouse database.
+It contains addresses to which network abuse should be reported,
+indexed by domain name.
+.TP
+\fB\-c\fP \fIcountry-code\fP
+This is the equivalent of using the
+\fB\-h\fP
+option with an argument of \fIcountry-code\fP.whois-servers.net.
+.TP
+\fB\-f\fP
+Use the African Network Information Centre (AfriNIC) database.
+It contains network numbers used in Africa and the islands of the
+western Indian Ocean.
+.TP
+\fB\-g\fP
+Use the US non-military federal government database, which contains points of
+contact for subdomains of
+\fI\&.GOV\fP.
+.TP
+\fB\-h\fP \fIhost\fP
+Use the specified host instead of the default variant.
+Either a host name or an IP address may be specified.
+
+By default
+\fBwhois\fP
+constructs the name of a whois server to use from the top-level domain (TLD)
+of the supplied (single) argument, and appending .whois-servers.net .
+This effectively allows a suitable whois server to be selected
+automatically for a large number of TLDs.
+
+In the event that an IP
+address is specified, the whois server will default to the American
+Registry for Internet Numbers (ARIN).
+If a query to ARIN references APNIC, AfriNIC, LACNIC, or RIPE,
+that server will be queried also, provided that the
+\fB\-Q\fP
+option is not specified.
+
+If the query is not a domain name or IP address,
+\fBwhois\fP
+will fall back to
+\fIwhois.crsnic.net\fP.
+.TP
+\fB\-i\fP
+Use the Network Solutions Registry for Internet Numbers
+(\fIwhois.networksolutions.com\fP)
+database.
+It contains network numbers and domain contact information for most of
+\fI\&.COM\fP,.NET,.ORG
+and
+\fI\&.EDU\fP
+domains.
+
+.B NOTE !
+The registration of these domains is now done by a number of
+independent and competing registrars and this database holds no information
+on the domains registered by organizations other than Network Solutions, Inc.
+Also, note that the InterNIC database
+(\fIwhois.internic.net\fP)
+is no longer handled by Network Solutions, Inc.
+For details, see
+\fIhttp://www.internic.net/\fP.
 
-.sp
-.LP
-looks for the name or handle SMITH.
-
-.sp
-.LP
-The command:
-
-.sp
-.in +2
-.nf
-example% whois !SRI-NIC
-.fi
-.in -2
-.sp
-
-.sp
-.LP
-looks for the handle SRI-NIC only.
+(Hint: Contact information, identified by the term
+.IR handle ,
+can be looked up by prefixing "handle" to the NIC
+handle in the query.)
+.TP
+\fB\-I\fP
+Use the Internet Assigned Numbers Authority (IANA) database.
+It contains network information for top-level domains.
+.TP
+\fB\-k\fP
+Use the National Internet Development Agency of Korea's (KRNIC)
+database.
+It contains network numbers and domain contact information
+for Korea.
+.TP
+\fB\-l\fP
+Use the Latin American and Caribbean IP address Regional Registry
+(Tn LACNIC)
+database.
+It contains network numbers used in much of Latin America and the
+Caribbean.
+.TP
+\fB\-m\fP
+Use the Route Arbiter Database (RADB) database.
+It contains route policy specifications for a large
+number of operators' networks.
+.TP
+\fB\-p\fP \fIport\fP
+Connect to the whois server on
+\fIport\fP.
+If this option is not specified,
+\fBwhois\fP
+defaults to port 43.
+.TP
+\fB\-Q\fP
+Do a quick lookup.
+This means that
+\fBwhois\fP
+will not attempt to lookup the name in the authoritative whois
+server (if one is listed).
+This option has no effect when combined with any other options.
+.TP
+\fB\-r\fP
+Use the R\(aaeseaux IP Europ\(aaeens (RIPE) database.
+It contains network numbers and domain contact information
+for Europe.
 
-.sp
-.LP
-The command:
-
-.sp
-.in +2
-.nf
-example% whois .Smith, John
-.fi
-.in -2
-.sp
+The operands specified to
+\fBwhois\fP
+are treated independently and may be used
+as queries on different whois servers.
+.SH EXIT STATUS
+The \fBwhois\fP utility exits 0 on success, and >0 if an error occurs.
+.SH EXAMPLES
+Most types of data, such as domain names and IP addresses, can be used as
+arguments to
+\fBwhois\fP
+without any options, and
+\fBwhois\fP
+will choose the correct whois server to query.
+Some exceptions, where
+\fBwhois\fP
+will not be able to handle data correctly, are detailed below.
 
-.sp
-.LP
-looks for the name \fBJOHN SMITH\fR only.
+To obtain contact information about an
+administrator located in the Russian TLD domain RU,
+use the
+\fB\-c\fP
+option as shown in the following example, where
+\fICONTACT-ID\fP
+is substituted with the actual contact identifier.
+
+whois -c RU CONTACT-ID
+
+(Note: This example is specific to the TLD RU,
+but other TLDs can be queried by using a similar syntax.)
 
-.sp
-.LP
-Adding \fB\&.\|.\|.\fR to the name or handle argument will match anything from
-that point; that is, \fBZU .\|.\|.\fR will match ZUL, ZUM, and so on.
+The following example demonstrates how to query
+a whois server using a non-standard port, where
+``query-data''
+is the query to be sent to
+``whois.example.com''
+on port
+``rwhois''
+(written numerically as 4321).
 
+whois -h whois.example.com -p rwhois query-data
 .SH SEE ALSO
-.sp
-.LP
-\fBattributes\fR(5)
+
+Vic White and Ken Harrenstien, \fINICNAME/WHOIS\fP, 1 March 1982, RFC 812.
+.SH HISTORY
+The
+\fBwhois\fP
+command appeared in
+4.3BSD.
--- a/usr/src/pkg/manifests/service-network-network-clients.mf	Fri Aug 12 16:07:25 2011 -0400
+++ b/usr/src/pkg/manifests/service-network-network-clients.mf	Fri Aug 12 18:09:43 2011 -0400
@@ -21,6 +21,7 @@
 
 #
 # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
 #
 
 set name=pkg.fmri value=pkg:/service/network/network-clients@$(PKGVERS)
@@ -78,6 +79,8 @@
     license=usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.rcp
 license usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.rsh \
     license=usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.rsh
+license usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.whois \
+    license=usr/src/cmd/cmd-inet/usr.bin/THIRDPARTYLICENSE.whois
 license usr/src/cmd/cmd-inet/usr.bin/rdist/THIRDPARTYLICENSE \
     license=usr/src/cmd/cmd-inet/usr.bin/rdist/THIRDPARTYLICENSE
 link path=usr/bin/remsh target=./rsh