From owner-svn-src-head@FreeBSD.ORG Thu May 14 10:33:02 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 68C0035F; Thu, 14 May 2015 10:33:02 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4AD351FCD; Thu, 14 May 2015 10:33:02 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4EAX2IX039154; Thu, 14 May 2015 10:33:02 GMT (envelope-from fanf@FreeBSD.org) Received: (from fanf@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4EAX1ls039152; Thu, 14 May 2015 10:33:01 GMT (envelope-from fanf@FreeBSD.org) Message-Id: <201505141033.t4EAX1ls039152@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: fanf set sender to fanf@FreeBSD.org using -f From: Tony Finch Date: Thu, 14 May 2015 10:33:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282887 - head/usr.bin/whois X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 May 2015 10:33:02 -0000 Author: fanf Date: Thu May 14 10:33:01 2015 New Revision: 282887 URL: https://svnweb.freebsd.org/changeset/base/282887 Log: whois: try whois.nic.TLD if TLD.whois-servers.net does not exist Based on an idea from OpenBSD. Modified: head/usr.bin/whois/whois.1 head/usr.bin/whois/whois.c Modified: head/usr.bin/whois/whois.1 ============================================================================== --- head/usr.bin/whois/whois.1 Thu May 14 10:32:35 2015 (r282886) +++ head/usr.bin/whois/whois.1 Thu May 14 10:33:01 2015 (r282887) @@ -49,17 +49,18 @@ Network Information Centers .Pp By default .Nm -constructs the name of a whois server to use from the top-level domain +automatically discovers 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 +of the supplied (single) argument. +It tries +.Qq Va TLD Ns Li .whois-servers.net +and +.Qq Li whois.nic. Ns Va TLD +and if neither host exists it falls back to its default server. +.Pp +If 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 @@ -71,9 +72,10 @@ that server will be queried also, provid .Fl Q option is not specified. .Pp -If the query is not a domain name or IP address, +If .Nm -will fall back to +cannot automatically discover a server, +it will fall back to the host specified in the .Ev WHOIS_SERVER or @@ -122,7 +124,7 @@ Use the US non-military federal governme contact for subdomains of .Pa .GOV . .It Fl h Ar host -Use the specified host instead of the default variant. +Use the specified host instead of the default. Either a host name or an IP address may be specified. .It Fl i Use the obsolete Network Solutions Registry for Internet Numbers Modified: head/usr.bin/whois/whois.c ============================================================================== --- head/usr.bin/whois/whois.c Thu May 14 10:32:35 2015 (r282886) +++ head/usr.bin/whois/whois.c Thu May 14 10:33:01 2015 (r282887) @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #define RNICHOST "whois.ripe.net" #define PNICHOST "whois.apnic.net" #define MNICHOST "whois.ra.net" +#define QNICHOST_HEAD "whois.nic." #define QNICHOST_TAIL ".whois-servers.net" #define BNICHOST "whois.registro.br" #define IANAHOST "whois.iana.org" @@ -101,7 +102,7 @@ static const char *ip_whois[] = { LNICHO static const char *port = DEFAULT_PORT; static char *choose_server(char *); -static struct addrinfo *gethostinfo(char const *host, int exit_on_error); +static struct addrinfo *gethostinfo(char const *host, int exitnoname); static void s_asprintf(char **ret, const char *format, ...) __printflike(2, 3); static void usage(void); static void whois(const char *, const char *, int); @@ -214,14 +215,15 @@ main(int argc, char *argv[]) * caller must remember to free(3) the allocated memory. * * If the domain is an IPv6 address or has a known suffix, that determines - * the server, else if the TLD is a number, query ARIN, else use - * TLD.whois-server.net. Fail if the domain does not contain '.'. + * the server, else if the TLD is a number, query ARIN, else try a couple of + * formulaic server names. Fail if the domain does not contain '.'. */ static char * choose_server(char *domain) { char *pos, *retval; int i; + struct addrinfo *res; if (strchr(domain, ':')) { s_asprintf(&retval, "%s", ANICHOST); @@ -243,15 +245,35 @@ choose_server(char *domain) --pos; if (pos <= domain) return (NULL); - if (isdigit((unsigned char)*++pos)) + if (isdigit((unsigned char)*++pos)) { s_asprintf(&retval, "%s", ANICHOST); - else - s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL); - return (retval); + return (retval); + } + /* Try possible alternative whois server name formulae. */ + for (i = 0; ; ++i) { + switch (i) { + case 0: + s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL); + break; + case 1: + s_asprintf(&retval, "%s%s", QNICHOST_HEAD, pos); + break; + default: + return (NULL); + } + res = gethostinfo(retval, 0); + if (res) { + freeaddrinfo(res); + return (retval); + } else { + free(retval); + continue; + } + } } static struct addrinfo * -gethostinfo(char const *host, int exit_on_error) +gethostinfo(char const *host, int exit_on_noname) { struct addrinfo hints, *res; int error; @@ -260,13 +282,10 @@ gethostinfo(char const *host, int exit_o hints.ai_flags = 0; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; + res = NULL; 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 (error && (exit_on_noname || error != EAI_NONAME)) + err(EX_NOHOST, "%s: %s", host, gai_strerror(error)); return (res); }