diff options
author | Tony Finch <fanf@FreeBSD.org> | 2015-05-14 10:33:01 +0000 |
---|---|---|
committer | Tony Finch <fanf@FreeBSD.org> | 2015-05-14 10:33:01 +0000 |
commit | 1326bf51e64bcd95dde12fe5ccfa6330f567bb73 (patch) | |
tree | 342b340314de571eac5ad23940240ae9f9eaeb7b /usr.bin/whois | |
parent | 0279f129c6be907095fc22cdf5c91bfc7e476285 (diff) | |
download | src-1326bf51e64bcd95dde12fe5ccfa6330f567bb73.tar.gz src-1326bf51e64bcd95dde12fe5ccfa6330f567bb73.zip |
whois: try whois.nic.TLD if TLD.whois-servers.net does not exist
Based on an idea from OpenBSD.
Notes
Notes:
svn path=/head/; revision=282887
Diffstat (limited to 'usr.bin/whois')
-rw-r--r-- | usr.bin/whois/whois.1 | 26 | ||||
-rw-r--r-- | usr.bin/whois/whois.c | 47 |
2 files changed, 47 insertions, 26 deletions
diff --git a/usr.bin/whois/whois.1 b/usr.bin/whois/whois.1 index 54c71fce5f0d..ca1ceb5b5dc6 100644 --- a/usr.bin/whois/whois.1 +++ b/usr.bin/whois/whois.1 @@ -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 . +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 -In the event that an IP -address is specified, the whois server will default to the American -Registry for Internet Numbers +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, provided that the .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 government database, which contains points of 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 diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c index 9fe979cca210..9fdd0070612d 100644 --- a/usr.bin/whois/whois.c +++ b/usr.bin/whois/whois.c @@ -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[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST, 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_on_error) 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); } |