Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 May 2015 10:33:01 +0000 (UTC)
From:      Tony Finch <fanf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r282887 - head/usr.bin/whois
Message-ID:  <201505141033.t4EAX1ls039152@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505141033.t4EAX1ls039152>