version 1.21, 2003/01/06 20:47:19 |
version 1.22, 2003/01/07 17:24:08 |
|
|
#include <unistd.h> |
#include <unistd.h> |
|
|
#define NICHOST "whois.crsnic.net" |
#define NICHOST "whois.crsnic.net" |
#define INICHOST "whois.internic.net" |
#define INICHOST "whois.networksolutions.com" |
#define CNICHOST "whois.corenic.net" |
#define CNICHOST "whois.corenic.net" |
#define DNICHOST "whois.nic.mil" |
#define DNICHOST "whois.nic.mil" |
#define GNICHOST "whois.nic.gov" |
#define GNICHOST "whois.nic.gov" |
|
|
#define PNICHOST "whois.apnic.net" |
#define PNICHOST "whois.apnic.net" |
#define RUNICHOST "whois.ripn.net" |
#define RUNICHOST "whois.ripn.net" |
#define MNICHOST "whois.ra.net" |
#define MNICHOST "whois.ra.net" |
#define NNICHOST "whois.networksolutions.com" |
|
#define LNICHOST "whois.lacnic.net" |
#define LNICHOST "whois.lacnic.net" |
#define SNICHOST "whois.6bone.net" |
#define SNICHOST "whois.6bone.net" |
|
#define BNICHOST "whois.registro.br" |
#define QNICHOST_TAIL ".whois-servers.net" |
#define QNICHOST_TAIL ".whois-servers.net" |
#define WHOIS_PORT 43 |
|
|
|
|
#define WHOIS_PORT "whois" |
|
#define WHOIS_SERVER_ID "Whois Server: " |
|
|
#define WHOIS_RECURSE 0x01 |
#define WHOIS_RECURSE 0x01 |
#define WHOIS_INIC_FALLBACK 0x02 |
#define WHOIS_QUICK 0x02 |
#define WHOIS_QUICK 0x04 |
|
|
|
|
const char *port = WHOIS_PORT; |
|
const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST, NULL }; |
|
|
static __dead void usage(void); |
static __dead void usage(void); |
static int whois(const char *, const char *, int); |
static int whois(const char *, const char *, const char *, int); |
static char *choose_server(const char *, const char *); |
static char *choose_server(const char *, const char *); |
|
|
int |
int |
|
|
#endif |
#endif |
country = host = server = NULL; |
country = host = server = NULL; |
flags = rval = 0; |
flags = rval = 0; |
while ((ch = getopt(argc, argv, "ac:dgh:ilmpqQrR6")) != -1) |
while ((ch = getopt(argc, argv, "aAc:dgh:ilmp:qQrR6")) != -1) |
switch((char)ch) { |
switch((char)ch) { |
case 'a': |
case 'a': |
host = ANICHOST; |
host = ANICHOST; |
break; |
break; |
|
case 'A': |
|
host = PNICHOST; |
|
break; |
case 'c': |
case 'c': |
country = optarg; |
country = optarg; |
break; |
break; |
|
|
host = MNICHOST; |
host = MNICHOST; |
break; |
break; |
case 'p': |
case 'p': |
host = PNICHOST; |
port = optarg; |
break; |
break; |
case 'q': |
case 'q': |
/* default */ |
/* deprecated, now the default */ |
break; |
break; |
case 'Q': |
case 'Q': |
flags |= WHOIS_QUICK; |
flags |= WHOIS_QUICK; |
|
|
usage(); |
usage(); |
|
|
if (host == NULL && country == NULL && !(flags & WHOIS_QUICK)) |
if (host == NULL && country == NULL && !(flags & WHOIS_QUICK)) |
flags |= WHOIS_INIC_FALLBACK | WHOIS_RECURSE; |
flags |= WHOIS_RECURSE; |
for (name = *argv; (name = *argv) != NULL; argv++) |
for (name = *argv; (name = *argv) != NULL; argv++) |
rval += whois(name, host ? host : choose_server(name, country), flags); |
rval += whois(name, host ? host : choose_server(name, country), |
|
port, flags); |
exit(rval); |
exit(rval); |
} |
} |
|
|
static int |
static int |
whois(const char *name, const char *server, int flags) |
whois(const char *query, const char *server, const char *port, int flags) |
{ |
{ |
FILE *sfi, *sfo; |
FILE *sfi, *sfo; |
char *buf, *p, *nhost, *nbuf = NULL; |
char *buf, *p, *nhost, *nbuf = NULL; |
size_t len; |
size_t len; |
int s, nomatch, error; |
int i, s, error; |
const char *reason = NULL; |
const char *reason = NULL; |
struct addrinfo hints, *res, *ai; |
struct addrinfo hints, *res, *ai; |
|
|
|
|
hints.ai_flags = 0; |
hints.ai_flags = 0; |
hints.ai_family = AF_UNSPEC; |
hints.ai_family = AF_UNSPEC; |
hints.ai_socktype = SOCK_STREAM; |
hints.ai_socktype = SOCK_STREAM; |
error = getaddrinfo(server, "whois", &hints, &res); |
error = getaddrinfo(server, port, &hints, &res); |
if (error) { |
if (error) { |
warnx("%s: %s", server, gai_strerror(error)); |
warnx("%s: %s", server, gai_strerror(error)); |
return (1); |
return (1); |
|
|
s = -1; |
s = -1; |
continue; |
continue; |
} |
} |
|
|
break; /*okay*/ |
break; /*okay*/ |
} |
} |
if (s < 0) { |
if (s < 0) { |
|
|
sfo = fdopen(s, "w"); |
sfo = fdopen(s, "w"); |
if (sfi == NULL || sfo == NULL) |
if (sfi == NULL || sfo == NULL) |
err(1, "fdopen"); |
err(1, "fdopen"); |
(void)fprintf(sfo, "%s\r\n", name); |
(void)fprintf(sfo, "%s\r\n", query); |
(void)fflush(sfo); |
(void)fflush(sfo); |
nhost = NULL; |
nhost = NULL; |
nomatch = 0; |
while ((buf = fgetln(sfi, &len)) != NULL) { |
while ((buf = fgetln(sfi, &len))) { |
p = buf + len - 1; |
if (buf[len - 2] == '\r') |
if (isspace((unsigned char)*p)) { |
buf[len - 2] = '\0'; |
do |
else if (buf[len - 1] == '\n') |
*p-- = '\0'; |
buf[len - 1] = '\0'; |
while (p != buf && isspace((unsigned char)*p)); |
else { |
} else { |
if ((nbuf = malloc(len + 1)) == NULL) |
if ((nbuf = malloc(len + 1)) == NULL) |
err(1, "malloc"); |
err(1, "malloc"); |
memcpy(nbuf, buf, len); |
memcpy(nbuf, buf, len); |
nbuf[len] = '\0'; |
nbuf[len] = '\0'; |
buf = nbuf; |
buf = nbuf; |
} |
} |
|
(void)puts(buf); |
|
|
if ((flags & WHOIS_RECURSE) && nhost == NULL && |
if (nhost != NULL || !(flags & WHOIS_RECURSE)) |
(p = strstr(buf, "Whois Server: "))) { |
continue; |
p += sizeof("Whois Server: ") - 1; |
|
|
if ((p = strstr(buf, WHOIS_SERVER_ID))) { |
|
p += sizeof(WHOIS_SERVER_ID) - 1; |
if ((len = strcspn(p, " \t\n\r"))) { |
if ((len = strcspn(p, " \t\n\r"))) { |
if ((nhost = malloc(len + 1)) == NULL) |
if ((nhost = malloc(len + 1)) == NULL) |
err(1, "malloc"); |
err(1, "malloc"); |
memcpy(nhost, p, len); |
memcpy(nhost, p, len); |
nhost[len] = '\0'; |
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]); |
|
break; |
|
} |
|
} |
} |
} |
if ((flags & WHOIS_INIC_FALLBACK) && nhost == NULL && |
|
!nomatch && (p = strstr(buf, "No match for \""))) { |
|
p += sizeof("No match for \"") - 1; |
|
if ((len = strcspn(p, "\"")) && len == strlen(name) && |
|
strncasecmp(name, p, len) == 0) |
|
nomatch = 1; |
|
} |
|
(void)puts(buf); |
|
} |
} |
if (nbuf != NULL) |
if (nbuf != NULL) |
free(nbuf); |
free(nbuf); |
|
|
/* Do second lookup as needed */ |
if (nhost != NULL) { |
if (nomatch && nhost == NULL) { |
error = whois(query, nhost, port, 0); |
(void)printf("Looking up %s at %s.\n\n", name, INICHOST); |
free(nhost); |
nhost = INICHOST; |
|
} |
} |
if (nhost) { |
|
error += whois(name, nhost, 0); |
|
if (!nomatch) |
|
free(nhost); |
|
} |
|
freeaddrinfo(res); |
freeaddrinfo(res); |
return (error); |
return (error); |
} |
} |
|
|
qhead = country; |
qhead = country; |
else if ((qhead = strrchr(name, '.')) == NULL) { |
else if ((qhead = strrchr(name, '.')) == NULL) { |
if (*name == '!') |
if (*name == '!') |
return (NNICHOST); |
return (INICHOST); |
else if ((strncasecmp(name, "COCO-", 5) == 0 || |
else if ((strncasecmp(name, "COCO-", 5) == 0 || |
strncasecmp(name, "COHO-", 5) == 0) && |
strncasecmp(name, "COHO-", 5) == 0) && |
strtol(name + 5, &ep, 10) > 0 && *ep == '\0') |
strtol(name + 5, &ep, 10) > 0 && *ep == '\0') |
|
|
extern char *__progname; |
extern char *__progname; |
|
|
(void)fprintf(stderr, |
(void)fprintf(stderr, |
"usage: %s [-adgilmpqQrR6] [-c country-code | -h hostname] " |
"usage: %s [-aAdgilmpQrR6] [-c country-code | -h hostname] " |
"name ...\n", __progname); |
"[-p port] name ...\n", __progname); |
exit(1); |
exit(1); |
} |
} |