@ -857,124 +857,6 @@ ares_status_t ares__hosts_search_host(ares_channel_t *channel,
return ARES_SUCCESS ;
}
ares_status_t ares__hosts_entry_to_hostent ( const ares_hosts_entry_t * entry ,
int family , struct hostent * * hostent )
{
ares_status_t status ;
size_t naliases ;
ares__llist_node_t * node ;
size_t idx ;
* hostent = ares_malloc_zero ( sizeof ( * * hostent ) ) ;
if ( * hostent = = NULL ) {
status = ARES_ENOMEM ;
goto fail ;
}
( * hostent ) - > h_addrtype = family ;
/* Copy IP addresses that match the address family */
idx = 0 ;
for ( node = ares__llist_node_first ( entry - > ips ) ; node ! = NULL ;
node = ares__llist_node_next ( node ) ) {
struct ares_addr addr ;
const void * ptr = NULL ;
size_t ptr_len = 0 ;
const char * ipaddr = ares__llist_node_val ( node ) ;
char * * temp = NULL ;
memset ( & addr , 0 , sizeof ( addr ) ) ;
addr . family = family ;
ptr = ares_dns_pton ( ipaddr , & addr , & ptr_len ) ;
if ( ptr = = NULL ) {
continue ;
}
/* If family == AF_UNSPEC, then we want to inherit this for future
* conversions as we can only support a single address class */
if ( family = = AF_UNSPEC ) {
family = addr . family ;
( * hostent ) - > h_addrtype = addr . family ;
}
temp = ares_realloc_zero ( ( * hostent ) - > h_addr_list ,
( idx + 1 ) * sizeof ( * ( * hostent ) - > h_addr_list ) ,
( idx + 2 ) * sizeof ( * ( * hostent ) - > h_addr_list ) ) ;
if ( temp = = NULL ) {
status = ARES_ENOMEM ;
goto fail ;
}
( * hostent ) - > h_addr_list = temp ;
( * hostent ) - > h_addr_list [ idx ] = ares_malloc ( ptr_len ) ;
if ( ( * hostent ) - > h_addr_list [ idx ] = = NULL ) {
status = ARES_ENOMEM ;
goto fail ;
}
memcpy ( ( * hostent ) - > h_addr_list [ idx ] , ptr , ptr_len ) ;
idx + + ;
( * hostent ) - > h_length = ( int ) ptr_len ;
}
/* entry didn't match address class */
if ( idx = = 0 ) {
status = ARES_ENOTFOUND ;
goto fail ;
}
/* Copy main hostname */
( * hostent ) - > h_name = ares_strdup ( ares__llist_first_val ( entry - > hosts ) ) ;
if ( ( * hostent ) - > h_name = = NULL ) {
status = ARES_ENOMEM ;
goto fail ;
}
/* Copy aliases */
naliases = ares__llist_len ( entry - > hosts ) - 1 ;
/* Cap at 100, some people use https://github.com/StevenBlack/hosts and we
* don ' t need 200 k + aliases */
if ( naliases > 100 ) {
naliases = 100 ;
}
( * hostent ) - > h_aliases =
ares_malloc_zero ( ( naliases + 1 ) * sizeof ( * ( * hostent ) - > h_aliases ) ) ;
if ( ( * hostent ) - > h_aliases = = NULL ) {
status = ARES_ENOMEM ;
goto fail ;
}
/* Copy all entries to the alias except the first */
idx = 0 ;
node = ares__llist_node_first ( entry - > hosts ) ;
node = ares__llist_node_next ( node ) ;
while ( node ! = NULL ) {
( * hostent ) - > h_aliases [ idx ] = ares_strdup ( ares__llist_node_val ( node ) ) ;
if ( ( * hostent ) - > h_aliases [ idx ] = = NULL ) {
status = ARES_ENOMEM ;
goto fail ;
}
idx + + ;
/* Break out if artificially capped */
if ( idx = = naliases ) {
break ;
}
node = ares__llist_node_next ( node ) ;
}
return ARES_SUCCESS ;
fail :
ares_free_hostent ( * hostent ) ;
* hostent = NULL ;
return status ;
}
static ares_status_t
ares__hosts_ai_append_cnames ( const ares_hosts_entry_t * entry ,
struct ares_addrinfo_cname * * cnames_out )
@ -1068,10 +950,12 @@ ares_status_t ares__hosts_entry_to_addrinfo(const ares_hosts_entry_t *entry,
return ARES_EBADFAMILY ;
}
ai - > name = ares_strdup ( name ) ;
if ( ai - > name = = NULL ) {
status = ARES_ENOMEM ;
goto done ;
if ( name ! = NULL ) {
ai - > name = ares_strdup ( name ) ;
if ( ai - > name = = NULL ) {
status = ARES_ENOMEM ;
goto done ;
}
}
for ( node = ares__llist_node_first ( entry - > ips ) ; node ! = NULL ;
@ -1117,3 +1001,35 @@ done:
return status ;
}
ares_status_t ares__hosts_entry_to_hostent ( const ares_hosts_entry_t * entry ,
int family , struct hostent * * hostent )
{
ares_status_t status ;
struct ares_addrinfo * ai = ares_malloc_zero ( sizeof ( * ai ) ) ;
* hostent = NULL ;
if ( ai = = NULL ) {
return ARES_ENOMEM ;
}
status = ares__hosts_entry_to_addrinfo ( entry , NULL , family , 0 , ARES_TRUE , ai ) ;
if ( status ! = ARES_SUCCESS ) {
goto done ;
}
status = ares__addrinfo2hostent ( ai , family , hostent ) ;
if ( status ! = ARES_SUCCESS ) {
goto done ;
}
done :
ares_freeaddrinfo ( ai ) ;
if ( status ! = ARES_SUCCESS ) {
ares_free_hostent ( * hostent ) ;
* hostent = NULL ;
}
return status ;
}