@ -58,6 +58,8 @@
# endif
static void callback ( void * arg , int status , int timeouts , struct hostent * host ) ;
static void ai_callback ( void * arg , int status , int timeouts ,
struct ares_addrinfo * result ) ;
static void usage ( void ) ;
static void print_help_info_ahost ( void ) ;
@ -69,7 +71,7 @@ int main(int argc, char **argv)
int status ;
int nfds ;
int c ;
int addr_family = AF_INET ;
int addr_family = AF_UNSPEC ;
fd_set read_fds ;
fd_set write_fds ;
struct timeval * tvp ;
@ -77,6 +79,7 @@ int main(int argc, char **argv)
struct in_addr addr4 ;
struct ares_in6_addr addr6 ;
ares_getopt_state_t state ;
char * servers = NULL ;
# ifdef USE_WINSOCK
WORD wVersionRequested = MAKEWORD ( USE_WINSOCK , USE_WINSOCK ) ;
@ -93,14 +96,14 @@ int main(int argc, char **argv)
}
ares_getopt_init ( & state , argc , ( const char * * ) argv ) ;
while ( ( c = ares_getopt ( & state , " dt:h?s: " ) ) ! = - 1 ) {
while ( ( c = ares_getopt ( & state , " dt:h?D: s: " ) ) ! = - 1 ) {
switch ( c ) {
case ' d ' :
# ifdef WATT32
dbug_init ( ) ;
# endif
break ;
case ' s ' :
case ' D ' :
optmask | = ARES_OPT_DOMAINS ;
options . ndomains + + ;
options . domains = ( char * * ) realloc (
@ -118,9 +121,18 @@ int main(int argc, char **argv)
usage ( ) ;
}
break ;
case ' h ' :
print_help_info_ahost ( ) ;
case ' s ' :
if ( state . optarg = = NULL ) {
fprintf ( stderr , " %s " , " missing servers " ) ;
usage ( ) ;
break ;
}
if ( servers ) {
free ( servers ) ;
}
servers = strdup ( state . optarg ) ;
break ;
case ' h ' :
case ' ? ' :
print_help_info_ahost ( ) ;
break ;
@ -138,10 +150,22 @@ int main(int argc, char **argv)
status = ares_init_options ( & channel , & options , optmask ) ;
if ( status ! = ARES_SUCCESS ) {
free ( servers ) ;
fprintf ( stderr , " ares_init: %s \n " , ares_strerror ( status ) ) ;
return 1 ;
}
if ( servers ) {
status = ares_set_servers_csv ( channel , servers ) ;
if ( status ! = ARES_SUCCESS ) {
fprintf ( stderr , " ares_set_serveres_csv: %s \n " , ares_strerror ( status ) ) ;
free ( servers ) ;
usage ( ) ;
return 1 ;
}
free ( servers ) ;
}
/* Initiate the queries, one per command-line argument. */
for ( ; * argv ; argv + + ) {
if ( ares_inet_pton ( AF_INET , * argv , & addr4 ) = = 1 ) {
@ -151,7 +175,10 @@ int main(int argc, char **argv)
ares_gethostbyaddr ( channel , & addr6 , sizeof ( addr6 ) , AF_INET6 , callback ,
* argv ) ;
} else {
ares_gethostbyname ( channel , * argv , addr_family , callback , * argv ) ;
struct ares_addrinfo_hints hints ;
memset ( & hints , 0 , sizeof ( hints ) ) ;
hints . ai_family = addr_family ;
ares_getaddrinfo ( channel , * argv , NULL , & hints , ai_callback , * argv ) ;
}
}
@ -202,25 +229,47 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host)
ares_inet_ntop ( host - > h_addrtype , * p , addr_buf , sizeof ( addr_buf ) ) ;
printf ( " %-32s \t %s " , host - > h_name , addr_buf ) ;
#if 0
if ( host - > h_aliases [ 0 ] )
{
int i ;
printf ( " , Aliases: " ) ;
for ( i = 0 ; host - > h_aliases [ i ] ; i + + )
printf ( " %s " , host - > h_aliases [ i ] ) ;
}
# endif
puts ( " " ) ;
}
}
static void ai_callback ( void * arg , int status , int timeouts ,
struct ares_addrinfo * result )
{
struct ares_addrinfo_node * node = NULL ;
( void ) timeouts ;
if ( status ! = ARES_SUCCESS ) {
fprintf ( stderr , " %s: %s \n " , ( char * ) arg , ares_strerror ( status ) ) ;
return ;
}
for ( node = result - > nodes ; node ! = NULL ; node = node - > ai_next ) {
char addr_buf [ 64 ] = " " ;
const void * ptr = NULL ;
if ( node - > ai_family = = AF_INET ) {
struct sockaddr_in * in_addr =
( struct sockaddr_in * ) ( ( void * ) node - > ai_addr ) ;
ptr = & in_addr - > sin_addr ;
} else if ( node - > ai_family = = AF_INET6 ) {
struct sockaddr_in6 * in_addr =
( struct sockaddr_in6 * ) ( ( void * ) node - > ai_addr ) ;
ptr = & in_addr - > sin6_addr ;
} else {
continue ;
}
ares_inet_ntop ( node - > ai_family , ptr , addr_buf , sizeof ( addr_buf ) ) ;
printf ( " %-32s \t %s \n " , result - > name , addr_buf ) ;
}
ares_freeaddrinfo ( result ) ;
}
static void usage ( void )
{
fprintf (
stderr ,
" usage: ahost [-h] [-d] [-s {domain}] [-t {a|aaaa|u}] {host|addr} ... \n " ) ;
fprintf ( stderr , " usage: ahost [-h] [-d] [[-D {domain}] ...] [-s {server}] "
" [-t {a|aaaa|u}] {host|addr} ... \n " ) ;
exit ( 1 ) ;
}
@ -229,19 +278,18 @@ static void print_help_info_ahost(void)
{
printf ( " ahost, version %s \n \n " , ARES_VERSION_STR ) ;
printf (
" usage: ahost [-h] [-d] [[-s domain] ...] [-t a|aaaa|u] host|addr ... \n \n "
" h : Display this help and exit. \n "
" d : Print some extra debugging output. \n \n "
" s domain : Specify the domain to search instead of using the default "
" usage: ahost [-h] [-d] [-D domain] [-s server] [-t a|aaaa|u] host|addr "
" ... \n \n "
" -h : Display this help and exit. \n "
" -d : Print some extra debugging output. \n \n "
" -D domain : Specify the domain to search instead of using the default "
" values \n "
" from /etc/resolv.conf. This option only has an effect on \n "
" platforms that use /etc/resolv.conf for DNS "
" configuration; \n "
" it has no effect on other platforms (such as Win32 or "
" Android). \n \n "
" t type : If type is \" a \" , print the A record (default). \n "
" If type is \" aaaa \" , print the AAAA record. \n "
" If type is \" u \" , look for either AAAA or A record (in "
" that order). \n \n " ) ;
" -s server : Connect to the specified DNS server, instead of the \n "
" system's default one(s). Servers are tried in round-robin, \n "
" if the previous one failed. \n "
" -t type : If type is \" a \" , print the A record. \n "
" If type is \" aaaa \" , print the AAAA record. \n "
" If type is \" u \" (default), print both A and AAAA records. \n "
" \n " ) ;
exit ( 0 ) ;
}