#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define NAME 1
#define ADDR 2
#define CANN 4
#define ALIA 8
#define LABL 16
#define NUMB 32
#define HELP 64
#define RAWE 128
#define RESD 256
#define VERB 512
#define DEFAULT (LABL|0)
int main(int ac, char **av) {
int options = DEFAULT;
int aliasnum = -1;
struct hostent *hostent;
char *p = av[0];
char *h = 0;
int did_reset = 0;
int got_options = 0;
static char addrbuf[32];
unsigned char a[4];
int ai[4];
int i;
char x;
more:
while (ac > 1) {
av++; ac--;
if (**av == '-') {
while (*(++*av)) {
switch (**av) {
case 'a': /* addresses only */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ ADDR;
break;
case 'c': /* canonical entries only */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ CANN;
break;
case 'C': /* number of aliases only */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ NUMB;
break;
case 'D': /* debug resolver */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ RESD;
break;
case 'l': /* only show aliases */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ ALIA;
break;
case 'n': /* names only */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ NAME;
break;
case 'q': /* toggle printing field labels */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ LABL;
break;
case 'r': /* toggle printing raw hostent */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ RAWE;
break;
case 's': /* specify server(s) */
if (!**av) {
if (--ac > 1) {
if (**++av == '-')
break;
} else {
break;
}
}
if (sscanf(*av, "%d.%d.%d.%d%c", &ai[0], &ai[1], &ai[2], &ai[3], &x) != 4
|| ai[0] < 0 || ai[0] > 255 || ai[1] < 0 || ai[1] > 255
|| ai[2] < 0 || ai[2] > 255 || ai[3] < 0 || ai[3] > 255) {
hostent = gethostbyname(*av);
if (!hostent)
break;
for (i=0; i<4; i++)
ai[i] = hostent->h_addr_list[0][i];
}
for (i=0; i<4; i++)
a[i] = (unsigned char)(ai[i] & 0xFF);
snprintf(addrbuf, 32, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
if (!(did_reset++))
_res.nscount = 0;
_res.options |= RES_INIT;
_res.nsaddr_list[_res.nscount].sin_family = AF_INET;
_res.nsaddr_list[_res.nscount].sin_port = htons(53);
*(unsigned long *)&_res.nsaddr_list[_res.nscount++].sin_addr = inet_addr(addrbuf);
if (options & VERB)
printf("Server: %s -> %08x \n",addrbuf,inet_addr(addrbuf));
goto more;
case 'A': /* only show aliases */
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ ALIA;
break;
case 'v':
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ VERB;
break;
case '?':
case 'h':
if (!got_options) {
options = DEFAULT;
got_options++;
}
options = options ^ HELP;
break;
default:
if (isdigit(**av)) { /* only show specific alias */
aliasnum = strtol(*av,0,0);
options = options & ~CANN;
}
}
}
} else {
h = *av;
}
}
if (options & RESD)
_res.options |= RES_DEBUG;
if (!h || !*h || (options & HELP)) {
fprintf(stderr,"Usage: %s [-{a,n,c,q,A,C,#,sIP}] {name,addr}\n",p);
fprintf(stderr," a=addr n=name c=canonical q=nolabels A=aliases C=counts #=entry# s=server\n");
exit(2);
} else {
p = h;
}
if (p) {
if (isdigit(*p)) {
i = 0;
do {
a[i++] = strtoul(p,NULL,0L);
p = strchr(p,'.');
} while (p && isdigit(*++p) && i<4);
if (i!=4) {
fprintf(stderr,"Unable to parse host address %s\n",av[1]);
}
hostent = gethostbyaddr(a,4,AF_INET);
} else {
hostent = gethostbyname(p);
}
if (!hostent) {
perror("gethostbyname(2) failed");
exit(1);
} else {
int j;
unsigned char u;
if (options & RAWE) {
char **hptr;
printf("h_name = %s.\n",hostent->h_name ? hostent->h_name : "(null)");
hptr = hostent->h_aliases;
printf("h_aliases = \n");
j = 0;
while (*hptr)
printf(" %d: %s.\n",j++,*hptr++);
printf("addrtype = %d (0x%08x)\n",hostent->h_addrtype,hostent->h_addrtype);
printf("addrlen = %d\n",hostent->h_length);
hptr = hostent->h_addr_list;
while (*hptr) {
unsigned char *cptr;
fputc(' ',stdout);
cptr = (unsigned char *)*hptr;
for (j=0; j<hostent->h_length; j++)
printf("%d.",*cptr++);
cptr = (unsigned char *)*hptr;
printf(" = ");
for (j=0; j<hostent->h_length; j++)
printf("%02x.",*cptr++);
fputc('\n',stdout);
hptr++;
}
}
if (options & NUMB) {
int nalias, naddrs;
nalias = naddrs = 0;
for (i=0; hostent->h_aliases[i]; i++) {
nalias++;
}
for (i=0; hostent->h_addr_list[i]; i++) {
naddrs++;
}
if (!(options & NAME)) {
if (options & LABL) {
printf("addresses: %d",naddrs);
} else {
printf("%d",naddrs);
}
}
if (!(options & ADDR)) {
if (options & LABL) {
if (!(options & NAME))
putchar('\n');
printf("aliases: %d",nalias);
} else {
if (!(options & NAME))
putchar(' ');
printf("%d",nalias);
}
}
putchar('\n');
exit(0);
}
if (!(options & ADDR) && !(options & ALIA)) {
if (!(options & NAME) && !(options & CANN) && (options & LABL)) {
printf("h_name: ");
}
printf("%s",hostent->h_name);
if ((options & CANN))
putchar(' ');
else
putchar('\n');
}
if (!(options & ADDR) && !(options & CANN)) {
for (i=0; hostent->h_aliases[i]; i++) {
if (aliasnum<0 || aliasnum == i) {
if (options & LABL)
printf("h_aliases[%d]: ",i);
printf("%s\n",hostent->h_aliases[i]);
}
}
if ((options & ALIA))
exit(0);
}
if (!(options & ADDR) && !(options & CANN) && !(options & NAME)) {
if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
printf("h_addrrtype: %d\nh_length: %d\n",hostent->h_addrtype,hostent->h_length);
}
if (!(options & NAME)) {
for (i=0; hostent->h_addr_list[i]; i++) {
if (aliasnum<0 || aliasnum == i-1) {
if (!(options & ADDR) && !(options & CANN) && (options & LABL)) {
printf("h_addr_list[%u]: ",i);
}
u = hostent->h_addr_list[i][0];
printf("%u",u);
for (j=1; j<hostent->h_length; j++) {
putchar('.');
u = hostent->h_addr_list[i][j];
printf("%u",u);
}
putchar('\n');
if ((options & CANN))
break;
}
}
}
}
}
if ((options & NAME) && (options & CANN))
putchar('\n');
exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1