1
0
mirror of https://frontier.innolan.net/rainlance/c-ares.git synced 2025-10-05 23:59:35 +00:00

Ashish Sharma provided a patch for supporting multiple entries in the

/etc/hosts file. Patch edited for coding style and functionality by me
(Daniel).
This commit is contained in:
Daniel Stenberg
2007-06-02 19:42:25 +00:00
parent 1ea96cf8dd
commit 4e27354b82
5 changed files with 138 additions and 21 deletions

View File

@ -20,3 +20,8 @@ Brad Spencer
Ravi Pratap Ravi Pratap
William Ahern William Ahern
Bram Matthys Bram Matthys
Michael Wallner
Vlad Dinulescu
Brad House
Shmulik Regev
Ashish Sharma

View File

@ -1,5 +1,14 @@
Changelog for the c-ares project Changelog for the c-ares project
* June 2 2007
- Brad House's man pages for ares_save_options() and ares_destroy_options()
were added.
- Ashish Sharma provided a patch for supporting multiple entries in the
/etc/hosts file. Patch edited for coding style and functionality by me
(Daniel).
* May 30 2007 * May 30 2007
- Shmulik Regev brought cryptographically secure transaction IDs: - Shmulik Regev brought cryptographically secure transaction IDs:

View File

@ -183,6 +183,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
free(hostent->h_addr_list); free(hostent->h_addr_list);
free(hostent); free(hostent);
} }
*host = NULL;
return ARES_ENOMEM; return ARES_ENOMEM;
} }

View File

@ -33,7 +33,10 @@ void ares_free_hostent(struct hostent *host)
for (p = host->h_aliases; *p; p++) for (p = host->h_aliases; *p; p++)
free(*p); free(*p);
free(host->h_aliases); free(host->h_aliases);
free(host->h_addr_list[0]); for(p = host->h_addr_list; *p; p++)
{
free(*p);
}
free(host->h_addr_list); free(host->h_addr_list);
free(host); free(host);
} }

View File

@ -116,7 +116,7 @@ static void next_lookup(struct host_query *hquery)
{ {
int status; int status;
const char *p; const char *p;
struct hostent *host; struct hostent *host = NULL;
for (p = hquery->remaining_lookups; *p; p++) for (p = hquery->remaining_lookups; *p; p++)
{ {
@ -151,7 +151,7 @@ static void host_callback(void *arg, int status, unsigned char *abuf, int alen)
{ {
struct host_query *hquery = (struct host_query *) arg; struct host_query *hquery = (struct host_query *) arg;
ares_channel channel = hquery->channel; ares_channel channel = hquery->channel;
struct hostent *host; struct hostent *host = NULL;
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
{ {
@ -242,12 +242,86 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
return 1; return 1;
} }
static int add_host(struct hostent *hostent, struct hostent **host)
{
char **p;
char **h_addr_list = NULL;
struct hostent *hostptr = *host;
int count = 0;
int index = 0;
if (hostptr == NULL)
{
*host = hostent;
return 0;
}
for (p = hostptr->h_addr_list; *p; p++)
{
count++;
}
for (p = hostent->h_addr_list; *p; p++)
{
count++;
}
h_addr_list = malloc((count+1) * sizeof(char *));
if (!h_addr_list)
{
*host = NULL;
return -1;
}
for (p = hostptr->h_addr_list; *p; p++)
{
h_addr_list[index] = malloc(sizeof(struct in_addr));
if (h_addr_list[index])
{
memcpy(h_addr_list[index], *p, sizeof(struct in_addr));
}
else
{
free(h_addr_list);
return -1;
}
index++;
}
for(p = hostent->h_addr_list; *p; p++)
{
h_addr_list[index] = malloc(sizeof(struct in_addr));
if (h_addr_list[index])
{
memcpy(h_addr_list[index], *p, sizeof(struct in_addr));
}
else
{
free(h_addr_list);
return -1;
}
index++;
}
h_addr_list[index] = NULL;
for (p = hostptr->h_addr_list; *p; p++)
{
free(*p);
}
free(hostptr->h_addr_list);
hostptr->h_addr_list = h_addr_list;
return 0;
}
static int file_lookup(const char *name, int family, struct hostent **host) static int file_lookup(const char *name, int family, struct hostent **host)
{ {
FILE *fp; FILE *fp;
char **alias; char **alias;
int status; int status;
int error; int error;
int match;
struct hostent *hostent = NULL;
#ifdef WIN32 #ifdef WIN32
char PATH_HOSTS[MAX_PATH]; char PATH_HOSTS[MAX_PATH];
@ -283,35 +357,60 @@ static int file_lookup(const char *name, int family, struct hostent **host)
{ {
error = ERRNO; error = ERRNO;
switch(error) switch(error)
{ {
case ENOENT: case ENOENT:
case ESRCH: case ESRCH:
return ARES_ENOTFOUND; return ARES_ENOTFOUND;
default: default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error))); error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n", DEBUGF(fprintf(stderr, "Error opening file: %s\n",
PATH_HOSTS)); PATH_HOSTS));
*host = NULL; *host = NULL;
return ARES_EFILE; return ARES_EFILE;
} }
} }
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS) while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
{ {
match = 0;
hostent = *host;
if (strcasecmp((*host)->h_name, name) == 0) if (strcasecmp((*host)->h_name, name) == 0)
break; {
for (alias = (*host)->h_aliases; *alias; alias++) match = 1;
}
else
{
for (alias = (*host)->h_aliases; *alias; alias++)
{ {
if (strcasecmp(*alias, name) == 0) if (strcasecmp(*alias, name) == 0)
{
match = 1;
break; break;
}
} }
if (*alias) }
break; if (match)
ares_free_hostent(*host); {
if(!add_host(hostent, host))
ares_free_hostent(hostent);
else {
*host = NULL;
}
}
else
{
ares_free_hostent(*host);
*host = NULL;
}
} }
fclose(fp); fclose(fp);
if (status == ARES_EOF) if (status == ARES_EOF)
status = ARES_ENOTFOUND; {
if ( *host)
status = ARES_SUCCESS;
else
status = ARES_ENOTFOUND;
}
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
*host = NULL; *host = NULL;
return status; return status;