version 1.7, 1999/11/15 01:46:41 |
version 1.8, 1999/11/15 19:41:00 |
|
|
#define QNICHOST_TAIL ".whois-servers.net" |
#define QNICHOST_TAIL ".whois-servers.net" |
#define WHOIS_PORT 43 |
#define WHOIS_PORT 43 |
|
|
static void usage __P((void)); |
#define WHOIS_RECURSE 0x01 |
|
#define WHOIS_INIC_FALLBACK 0x02 |
|
#define WHOIS_QUICK 0x04 |
|
|
|
static void usage __P((void)); |
|
static void whois __P((char *, struct sockaddr_in *, int)); |
|
|
int |
int |
main(argc, argv) |
main(argc, argv) |
int argc; |
int argc; |
char **argv; |
char **argv; |
{ |
{ |
register FILE *sfi, *sfo; |
int ch, i, j; |
register int ch; |
int use_qnichost, flags; |
struct sockaddr_in sin; |
|
struct hostent *hp; |
|
struct servent *sp; |
|
int s; |
|
char *host; |
char *host; |
char *qnichost; |
char *qnichost; |
int use_qnichost; |
struct servent *sp; |
int i, j; |
struct hostent *hp; |
|
struct sockaddr_in sin; |
|
|
host = NICHOST; |
host = NULL; |
|
qnichost = NULL; |
|
flags = 0; |
use_qnichost = 0; |
use_qnichost = 0; |
while ((ch = getopt(argc, argv, "adgh:impqrR")) != -1) |
while ((ch = getopt(argc, argv, "adgh:impqQrR")) != -1) |
switch((char)ch) { |
switch((char)ch) { |
case 'a': |
case 'a': |
host = ANICHOST; |
host = ANICHOST; |
|
|
host = PNICHOST; |
host = PNICHOST; |
break; |
break; |
case 'q': |
case 'q': |
use_qnichost = 1; |
/* default */ |
break; |
break; |
|
case 'Q': |
|
flags |= WHOIS_QUICK; |
|
break; |
case 'r': |
case 'r': |
host = RNICHOST; |
host = RNICHOST; |
break; |
break; |
|
|
if (!argc) |
if (!argc) |
usage(); |
usage(); |
|
|
if (use_qnichost != 0) { |
memset(&sin, 0, sizeof sin); |
if (argc == 1) { |
sin.sin_len = sizeof(sin); |
|
sin.sin_family = AF_INET; |
|
sp = getservbyname("whois", "tcp"); |
|
if (sp == NULL) |
|
sin.sin_port = htons(WHOIS_PORT); |
|
else |
|
sin.sin_port = sp->s_port; |
|
|
|
/* |
|
* If no nic host is specified, use whois-servers.net |
|
* if there is a '.' in the name, else fall back to NICHOST. |
|
*/ |
|
if (host == NULL) { |
|
use_qnichost = 1; |
|
host = NICHOST; |
|
if (!(flags & WHOIS_QUICK)) |
|
flags |= WHOIS_INIC_FALLBACK | WHOIS_RECURSE; |
|
} |
|
while (argc--) { |
|
if (use_qnichost) { |
|
if (qnichost) { |
|
free(qnichost); |
|
qnichost = NULL; |
|
} |
for (i = j = 0; (*argv)[i]; i++) |
for (i = j = 0; (*argv)[i]; i++) |
if ((*argv)[i] == '.') j = i; |
if ((*argv)[i] == '.') |
|
j = i; |
if (j != 0) { |
if (j != 0) { |
qnichost = (char *) calloc(i - j + 1 + \ |
qnichost = (char *) calloc(i - j + 1 + |
strlen(QNICHOST_TAIL), sizeof(char)); |
strlen(QNICHOST_TAIL), sizeof(char)); |
if (!qnichost) |
if (!qnichost) |
err(1, "malloc"); |
err(1, "malloc"); |
strcpy(qnichost, *argv + j + 1); |
strcpy(qnichost, *argv + j + 1); |
strcat(qnichost, QNICHOST_TAIL); |
strcat(qnichost, QNICHOST_TAIL); |
host = qnichost; |
|
|
if (inet_aton(qnichost, &sin.sin_addr) == 0) { |
|
hp = gethostbyname2(qnichost, AF_INET); |
|
if (hp == NULL) { |
|
free(qnichost); |
|
qnichost = NULL; |
|
} else { |
|
sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; |
|
} |
|
} |
} |
} |
} |
} |
|
if (!qnichost && inet_aton(host, &sin.sin_addr) == 0) { |
|
hp = gethostbyname2(host, AF_INET); |
|
if (hp == NULL) |
|
errx(EX_NOHOST, "%s: %s", host, |
|
hstrerror(h_errno)); |
|
host = hp->h_name; |
|
sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; |
|
} |
|
|
|
whois(*argv++, &sin, flags); |
} |
} |
|
exit(0); |
|
} |
|
|
|
static void |
|
whois(name, sinp, flags) |
|
char *name; |
|
struct sockaddr_in *sinp; |
|
int flags; |
|
{ |
|
FILE *sfi, *sfo; |
|
char *buf, *p, *nhost; |
|
size_t len; |
|
int s, nomatch; |
|
|
s = socket(PF_INET, SOCK_STREAM, 0); |
s = socket(PF_INET, SOCK_STREAM, 0); |
if (s < 0) |
if (s < 0) |
err(EX_OSERR, "socket"); |
err(EX_OSERR, "socket"); |
|
|
memset(&sin, 0, sizeof sin); |
if (connect(s, (struct sockaddr *)sinp, sizeof(*sinp)) < 0) |
sin.sin_len = sizeof sin; |
|
sin.sin_family = AF_INET; |
|
|
|
if (inet_aton(host, &sin.sin_addr) == 0) { |
|
hp = gethostbyname2(host, AF_INET); |
|
if (hp == NULL) |
|
errx(EX_NOHOST, "%s: %s", host, hstrerror(h_errno)); |
|
host = hp->h_name; |
|
sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; |
|
} |
|
|
|
sp = getservbyname("whois", "tcp"); |
|
if (sp == NULL) |
|
sin.sin_port = htons(WHOIS_PORT); |
|
else |
|
sin.sin_port = sp->s_port; |
|
|
|
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) |
|
err(EX_OSERR, "connect"); |
err(EX_OSERR, "connect"); |
|
|
sfi = fdopen(s, "r"); |
sfi = fdopen(s, "r"); |
sfo = fdopen(s, "w"); |
sfo = fdopen(s, "w"); |
if (sfi == NULL || sfo == NULL) |
if (sfi == NULL || sfo == NULL) |
err(EX_OSERR, "fdopen"); |
err(EX_OSERR, "fdopen"); |
while (argc-- > 1) |
(void)fprintf(sfo, "%s\r\n", name); |
(void)fprintf(sfo, "%s ", *argv++); |
|
(void)fprintf(sfo, "%s\r\n", *argv); |
|
(void)fflush(sfo); |
(void)fflush(sfo); |
while ((ch = getc(sfi)) != EOF) |
nhost = NULL; |
putchar(ch); |
nomatch = 0; |
exit(0); |
while ((buf = fgetln(sfi, &len))) { |
|
if (buf[len - 2] == '\r') |
|
buf[len - 2] = '\0'; |
|
else |
|
buf[len - 1] = '\0'; |
|
|
|
if ((flags & WHOIS_RECURSE) && !nhost && |
|
(p = strstr(buf, "Whois Server: "))) { |
|
p += sizeof("Whois Server: ") - 1; |
|
if ((len = strcspn(p, " \t\n\r"))) { |
|
if ((nhost = malloc(len + 1)) == NULL) |
|
err(1, "malloc"); |
|
memcpy(nhost, p, len); |
|
nhost[len] = '\0'; |
|
} |
|
} |
|
if ((flags & WHOIS_INIC_FALLBACK) && !nhost && !nomatch && |
|
(p = strstr(buf, "No match for \""))) { |
|
p += sizeof("No match for \"") - 1; |
|
if ((len = strcspn(p, "\"")) && |
|
strncasecmp(name, p, len) == 0) |
|
nomatch = 1; |
|
} |
|
(void)puts(buf); |
|
} |
|
|
|
/* Do second lookup as needed */ |
|
if (nomatch && !nhost) { |
|
(void)printf("Looking up %s at %s.\n\n", name, INICHOST); |
|
nhost = INICHOST; |
|
} |
|
if (nhost) { |
|
if (inet_aton(nhost, &sinp->sin_addr) == 0) { |
|
struct hostent *hp = gethostbyname2(nhost, AF_INET); |
|
if (hp == NULL) |
|
return; |
|
sinp->sin_addr = *(struct in_addr *)hp->h_addr_list[0]; |
|
} |
|
if (!nomatch) |
|
free(nhost); |
|
whois(name, sinp, 0); |
|
} |
} |
} |
|
|
static void |
static void |