diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index 1884bb95f..bbc19b4c4 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -543,6 +543,7 @@ ./usr/bin/which minix-sys ./usr/bin/who minix-sys ./usr/bin/whoami minix-sys +./usr/bin/whois minix-sys ./usr/bin/worldstone minix-sys ./usr/bin/write minix-sys ./usr/bin/writeisofs minix-sys @@ -2102,6 +2103,7 @@ ./usr/man/man1/which.1 minix-sys ./usr/man/man1/who.1 minix-sys ./usr/man/man1/whoami.1 minix-sys +./usr/man/man1/whois.1 minix-sys ./usr/man/man1/worldstone.1 minix-sys ./usr/man/man1/write.1 minix-sys ./usr/man/man1/xargs.1 minix-sys diff --git a/releasetools/nbsd_ports b/releasetools/nbsd_ports index 7fe3b0f83..db13255a1 100644 --- a/releasetools/nbsd_ports +++ b/releasetools/nbsd_ports @@ -217,6 +217,7 @@ 2012/10/17 12:00:00,usr.bin/wc 2013/03/22 12:00:00,usr.bin/whatis 2013/03/15 12:00:00,usr.bin/who +2012/10/17 12:00:00,usr.bin/whois 2012/10/17 12:00:00,usr.bin/write 2012/10/17 12:00:00,usr.bin/xinstall 2013/03/15 12:00:00,usr.bin/yes diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 5058afbaf..eb3679934 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -31,7 +31,7 @@ SUBDIR= asa \ uniq units unzip users \ uuidgen \ \ - wc whatis who \ + wc whatis who whois \ write xargs xinstall yes .if !defined(__MINIX) diff --git a/usr.bin/whois/Makefile b/usr.bin/whois/Makefile new file mode 100644 index 000000000..e9121e195 --- /dev/null +++ b/usr.bin/whois/Makefile @@ -0,0 +1,9 @@ +# $NetBSD: Makefile,v 1.7 2009/04/14 22:15:29 lukem Exp $ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +USE_FORT?= yes # network client + +PROG= whois +CPPFLAGS+= -DRIPE + +.include diff --git a/usr.bin/whois/whois.1 b/usr.bin/whois/whois.1 new file mode 100644 index 000000000..593bfdbd2 --- /dev/null +++ b/usr.bin/whois/whois.1 @@ -0,0 +1,311 @@ +.\" $NetBSD: whois.1,v 1.26 2012/03/15 22:35:03 njoly Exp $ +.\" $OpenBSD: whois.1,v 1.22 2003/09/02 18:50:07 jmc Exp $ +.\" +.\" Copyright (c) 1985, 1990, 1993 +.\" 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. +.\" 3. 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. +.\" +.\" @(#)whois.1 8.2 (Berkeley) 6/20/94 +.\" +.Dd September 9, 2007 +.Dt WHOIS 1 +.Os +.Sh NAME +.Nm whois +.Nd Internet domain name and network number directory service +.Sh SYNOPSIS +.Nm whois +.Op Fl 6AadfgilmQRr +.Oo +.Fl c Ar country-code | Fl h Ar host +.Oc +.Op Fl p Ar port +.Ar name Op Ar ... +.Sh DESCRIPTION +The +.Nm +utility looks up records in the databases maintained by several +Network Information Centers +.Pq Tn NICs . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl 6 +Use the IPv6 Resource Center +.Pq Tn 6bone +database. +It contains network names and addresses for the IPv6 network. +.It Fl A +Use the Asia/Pacific Network Information Center +.Pq Tn APNIC +database. +It contains network numbers used in East Asia, Australia, +New Zealand, and the Pacific islands. +.It Fl a +Use the American Registry for Internet Numbers +.Pq Tn ARIN +database. +It contains network numbers used in those parts of the world +not covered by +.Tn AfriNIC , +.Tn APNIC , +.Tn LACNIC +or by +.Tn RIPE . +.Pp +(Hint: All point of contact handles in the +.Tn ARIN +whois database end with +.Qq Li -ARIN . ) +.It Fl c Ar country-code +This is the equivalent of using the +.Fl h +option with an argument of +.Qq Ar country-code Ns Li .whois-servers.net . +.It Fl d +Use the US Department of Defense database. +It contains points of contact for subdomains of +.Tn \&.MIL . +.It Fl f +Use the African Network Information Center +.Pq Tn AfriNIC +database. +It contains network numbers used in Africa. +.It Fl g +Use the US non-military federal government database, which contains points of +contact for subdomains of +.Tn \&.GOV . +.It Fl h Ar host +Use the specified host instead of the default NIC +(whois.crsnic.net). +Either a host name or an IP address may be specified. +.Pp +By default +.Nm +constructs the name of a whois server to use from the top-level domain +.Pq Tn TLD +of the supplied (single) argument, and appending +.Qq Li .whois-servers.net . +This effectively allows a suitable whois server to be selected +automatically for a large number of +.Tn TLDs . +.Pp +In the event that an IP +address is specified, the whois server will default to the American +Registry for Internet Numbers +.Pq Tn ARIN . +If a query to +.Tn ARIN +references +.Tn AfriNIC, APNIC , LACNIC , +or +.Tn RIPE , +that server will be queried also, provided that the +.Fl Q +option is not specified. +.Pp +If the query is not a domain name or IP address, +.Nm +will fall back to +.Pa whois.crsnic.net . +.It Fl i +Use the Network Solutions Registry for Internet Numbers +.Pq Tn whois.networksolutions.com +database. +Historically, it contained network numbers and domain contact information +for most of +.Tn \&.COM , +.Tn \&.NET , +.Tn \&.ORG +and +.Tn \&.EDU +domains. +However, 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 +.Tn InterNIC +database +.Pq Pa whois.internic.net +is no longer handled by Network Solutions, Inc. +For details, see +.Lk http://www.internic.net/ . +.Pp +(Hint: Contact information, identified by the term +.Em handle , +can be looked up by prefixing +.Qq Li \&! +or +.Qq Li handle\ \& +to the +.Tn NIC +handle in the query.) +.It Fl l +Use the Latin American and Caribbean IP address Regional Registry +.Pq Tn LACNIC +database. +It contains network numbers used in much of Latin America and the +Caribbean. +.It Fl m +Use the Route Arbiter Database +.Pq Tn RADB +database. +It contains route policy specifications for a large +number of operators' networks. +.It Fl p Ar port +Connect to the whois server on +.Ar port . +If this option is not specified, +.Nm +defaults to the +.Dq whois +port listed in +.Pa /etc/services +(port 43). +.It Fl Q +Do a quick lookup. +This means that +.Nm +will not attempt to lookup the name in the authoritative whois +server (if one is listed) nor will it contact InterNic if a lookup +fails. +This flag has no effect when combined with any other flag. +.It Fl R +Use the Russia Network Information Center +.Pq Tn RIPN +database. +It contains network numbers and domain contact information +for subdomains of +.Tn \&.RU . +This option is deprecated; use the +.Fl c +option with an argument of +.Qq Li RU +instead. +.It Fl r +Use the R\(aaeseaux IP Europ\(aaeens +.Pq Tn RIPE +database. +It contains network numbers and domain contact information for Europe. +.El +.Pp +The default action, unless directed otherwise with a special +.Ar name , +is to do a very broad search, looking for matches to +.Ar name +in all types of records and most fields (name, nicknames, hostname, net +address, etc.) in the database. +For more information as to what +.Ar name +operands have special meaning, and how to guide the search, use +the special name +.Dq help . +.Ss Special cases +Queries beginning with an exclamation point +.Ql \&! +are assumed to be +.Tn NSI +contact handles. +Unless a host or domain is specified on the command line, +.Pq Tn whois.networksolutions.com +will be used as the +.Nm +database. +.Pp +Similarly, queries beginning with +.Dq COCO- +are assumed to be +.Tn CORE +contact handles. +Unless a host or domain is specified on the command line, +.Pq Tn whois.corenic.net +will be used as the +.Nm +database. +.Sh EXAMPLES +Most types of data, such as domain names and +.Tn IP +addresses, can be used as arguments to +.Nm +without any options, and +.Nm +will choose the correct whois server to query. +Some exceptions, where +.Nm +will not be able to handle data correctly, are detailed below. +.Pp +To obtain contact information about an +administrator located in the Russian +.Tn TLD +domain +.Qq Li RU , +use the +.Fl c +option as shown in the following example, where +.Ar CONTACT-ID +is substituted with the actual contact identifier. +.Pp +.Dl "whois -c RU CONTACT-ID" +.Pp +(Note: This example is specific to the +.Tn TLD +.Qq Li RU , +but other +.Tn TLDs +can be queried by using a similar syntax.) +.Pp +The following example demonstrates how to obtain information about an +.Tn IPv6 +address or hostname using the +.Fl 6 +option, which directs the query to +.Tn 6bone . +.Pp +.Dl "whois -6 IPv6-IP-Address" +.Pp +The following example demonstrates how to query +a whois server using a non-standard port, where +.Dq Li query-data +is the query to be sent to +.Dq Li whois.example.com +on port +.Dq Li rwhois +(written numerically as 4321). +.Pp +.Dl "whois -h whois.example.com -p rwhois query-data" +.Sh SEE ALSO +.Rs +.%A Ken Harrenstien +.%A Vic White +.%T NICNAME/WHOIS +.%D 1 March 1982 +.%O RFC 812 +.Re +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 . diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c new file mode 100644 index 000000000..6f2e7ec37 --- /dev/null +++ b/usr.bin/whois/whois.c @@ -0,0 +1,329 @@ +/* $NetBSD: whois.c,v 1.35 2011/08/17 13:57:12 christos Exp $ */ +/* $OpenBSD: whois.c,v 1.28 2003/09/18 22:16:15 fgsch Exp $ */ + +/* + * Copyright (c) 1980, 1993 + * 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. + * 3. 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. + */ + +#include + +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1980, 1993\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static const char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93"; +#else +__RCSID("$NetBSD: whois.c,v 1.35 2011/08/17 13:57:12 christos Exp $"); +#endif +#endif /* not lint */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ANICHOST "whois.arin.net" +#define BNICHOST "whois.registro.br" +#define CNICHOST "whois.corenic.net" +#define DNICHOST "whois.nic.mil" +#define FNICHOST "whois.afrinic.net" +#define GNICHOST "whois.nic.gov" +#define INICHOST "whois.networksolutions.com" +#define LNICHOST "whois.lacnic.net" +#define MNICHOST "whois.ra.net" +#define NICHOST "whois.crsnic.net" +#define PNICHOST "whois.apnic.net" +#define QNICHOST_TAIL ".whois-servers.net" +#define RNICHOST "whois.ripe.net" +#define RUNICHOST "whois.ripn.net" +#define SNICHOST "whois.6bone.net" + +#define WHOIS_PORT "whois" +#define WHOIS_SERVER_ID "Whois Server:" + +#define WHOIS_RECURSE 0x01 +#define WHOIS_QUICK 0x02 + +static const char *port_whois = WHOIS_PORT; +static const char *ip_whois[] = + { LNICHOST, RNICHOST, PNICHOST, FNICHOST, BNICHOST, NULL }; + +static void usage(void) __dead; +static int whois(const char *, const char *, const char *, int); +static const char *choose_server(const char *, const char *); + +int +main(int argc, char *argv[]) +{ + int ch, flags, rval; + const char *host, *name, *country; + +#ifdef SOCKS + SOCKSinit(argv[0]); +#endif + country = host = NULL; + flags = rval = 0; + while ((ch = getopt(argc, argv, "6Aac:dfgh:ilmp:qQRr")) != -1) + switch(ch) { + case 'a': + host = ANICHOST; + break; + case 'A': + host = PNICHOST; + break; + case 'c': + country = optarg; + break; + case 'd': + host = DNICHOST; + break; + case 'f': + host = FNICHOST; + break; + case 'g': + host = GNICHOST; + break; + case 'h': + host = optarg; + break; + case 'i': + host = INICHOST; + break; + case 'l': + host = LNICHOST; + break; + case 'm': + host = MNICHOST; + break; + case 'p': + port_whois = optarg; + break; + case 'q': + /* deprecated, now the default */ + break; + case 'Q': + flags |= WHOIS_QUICK; + break; + case 'r': + host = RNICHOST; + break; + case 'R': + host = RUNICHOST; + break; + case '6': + host = SNICHOST; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + if (!argc || (country != NULL && host != NULL)) + usage(); + + if (host == NULL && country == NULL && !(flags & WHOIS_QUICK)) + flags |= WHOIS_RECURSE; + for (name = *argv; (name = *argv) != NULL; argv++) + rval += whois(name, host ? host : choose_server(name, country), + port_whois, flags); + return rval; +} + +static int +whois(const char *query, const char *server, const char *port, int flags) +{ + FILE *sfi, *sfo; + char *buf, *p, *nhost, *nbuf = NULL; + size_t len; + int i, s, error; + const char *reason = NULL, *fmt; + struct addrinfo hints, *res, *ai; + + (void)memset(&hints, 0, sizeof(hints)); + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(server, port, &hints, &res); + if (error) { + warnx("%s: %s", server, gai_strerror(error)); + return (1); + } + + for (s = -1, ai = res; ai != NULL; ai = ai->ai_next) { + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (s < 0) { + error = errno; + reason = "socket"; + continue; + } + if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) { + error = errno; + reason = "connect"; + close(s); + s = -1; + continue; + } + break; /*okay*/ + } + if (s < 0) { + if (reason) { + errno = error; + warn("%s: %s", server, reason); + } else + warnx("Unknown error in connection attempt"); + freeaddrinfo(res); + return (1); + } + + if (strcmp(server, "whois.denic.de") == 0 || + strcmp(server, "de.whois-servers.net") == 0) + fmt = "-T dn,ace -C ISO-8859-1"; + else + fmt = ""; + + sfi = fdopen(s, "r"); + sfo = fdopen(s, "w"); + if (sfi == NULL || sfo == NULL) + err(1, "fdopen"); + (void)fprintf(sfo, "%s%s\r\n", fmt, query); + (void)fflush(sfo); + nhost = NULL; + while ((buf = fgetln(sfi, &len)) != NULL) { + p = buf + len - 1; + if (isspace((unsigned char)*p)) { + do + *p = '\0'; + while (p > buf && isspace((unsigned char)*--p)); + } else { + if ((nbuf = malloc(len + 1)) == NULL) + err(1, "malloc"); + (void)memcpy(nbuf, buf, len); + nbuf[len] = '\0'; + buf = nbuf; + } + (void)puts(buf); + + if (nhost != NULL || !(flags & WHOIS_RECURSE)) + continue; + + if ((p = strstr(buf, WHOIS_SERVER_ID))) { + p += sizeof(WHOIS_SERVER_ID) - 1; + while (isblank((unsigned char)*p)) + p++; + if ((len = strcspn(p, " \t\n\r"))) { + if ((nhost = malloc(len + 1)) == NULL) + err(1, "malloc"); + (void)memcpy(nhost, p, len); + nhost[len] = '\0'; + } + } else if (strcmp(server, ANICHOST) == 0) { + for (p = buf; *p != '\0'; p++) + *p = tolower((unsigned char)*p); + for (i = 0; ip_whois[i] != NULL; i++) { + if (strstr(buf, ip_whois[i]) != NULL) { + nhost = strdup(ip_whois[i]); + if (nhost == NULL) + err(1, "strdup"); + break; + } + } + } + } + if (nbuf != NULL) + free(nbuf); + + if (nhost != NULL) { + error = whois(query, nhost, port, 0); + free(nhost); + } + freeaddrinfo(res); + (void)fclose(sfi); + (void)fclose(sfo); + return (error); +} + +/* + * If no 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 '.', check to see if it is an NSI handle + * (starts with '!') or a CORE handle (COCO-[0-9]+ or COHO-[0-9]+). + * Fall back to NICHOST for the non-handle case. + */ +static const char * +choose_server(const char *name, const char *country) +{ + static char *server; + char *nserver; + const char *qhead; + char *ep; + size_t len; + + if (country != NULL) + qhead = country; + else if ((qhead = strrchr(name, '.')) == NULL) { + if (*name == '!') + return (INICHOST); + else if ((strncasecmp(name, "COCO-", 5) == 0 || + strncasecmp(name, "COHO-", 5) == 0) && + strtol(name + 5, &ep, 10) > 0 && *ep == '\0') + return (CNICHOST); + else + return (NICHOST); + } else if (isdigit((unsigned char)*(++qhead))) + return (ANICHOST); + len = strlen(qhead) + sizeof(QNICHOST_TAIL); + if ((nserver = realloc(server, len)) == NULL) + err(1, "realloc"); + server = nserver; + (void)strlcpy(server, qhead, len); + (void)strlcat(server, QNICHOST_TAIL, len); + return (server); +} + +static void +usage(void) +{ + (void)fprintf(stderr, + "usage: %s [-6AadgilmQRr] [-c country-code | -h hostname] " + "[-p port] name ...\n", getprogname()); + exit(1); +}