summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2007-06-02 19:42:25 +0000
committerDaniel Stenberg <daniel@haxx.se>2007-06-02 19:42:25 +0000
commit4e27354b82948d23492e5218f4462bcc38d99e1b (patch)
tree672638ececf188f6e036494966b183914503627e
parent1ea96cf8dd2eae6d3dd4743310012b21f9848f82 (diff)
downloadc-ares-4e27354b82948d23492e5218f4462bcc38d99e1b.tar.gz
c-ares-4e27354b82948d23492e5218f4462bcc38d99e1b.tar.bz2
c-ares-4e27354b82948d23492e5218f4462bcc38d99e1b.zip
Ashish Sharma provided a patch for supporting multiple entries in the
/etc/hosts file. Patch edited for coding style and functionality by me (Daniel).
-rw-r--r--AUTHORS5
-rw-r--r--CHANGES9
-rw-r--r--ares__get_hostent.c1
-rw-r--r--ares_free_hostent.c5
-rw-r--r--ares_gethostbyname.c139
5 files changed, 138 insertions, 21 deletions
diff --git a/AUTHORS b/AUTHORS
index 553d36b..f744914 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -20,3 +20,8 @@ Brad Spencer
Ravi Pratap
William Ahern
Bram Matthys
+Michael Wallner
+Vlad Dinulescu
+Brad House
+Shmulik Regev
+Ashish Sharma
diff --git a/CHANGES b/CHANGES
index e3b5367..3e9f23c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,14 @@
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
- Shmulik Regev brought cryptographically secure transaction IDs:
diff --git a/ares__get_hostent.c b/ares__get_hostent.c
index 312a678..dc5f8ad 100644
--- a/ares__get_hostent.c
+++ b/ares__get_hostent.c
@@ -183,6 +183,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
free(hostent->h_addr_list);
free(hostent);
}
+ *host = NULL;
return ARES_ENOMEM;
}
diff --git a/ares_free_hostent.c b/ares_free_hostent.c
index 7763df7..d6cf51f 100644
--- a/ares_free_hostent.c
+++ b/ares_free_hostent.c
@@ -33,7 +33,10 @@ void ares_free_hostent(struct hostent *host)
for (p = host->h_aliases; *p; p++)
free(*p);
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);
}
diff --git a/ares_gethostbyname.c b/ares_gethostbyname.c
index c0fa474..5170c07 100644
--- a/ares_gethostbyname.c
+++ b/ares_gethostbyname.c
@@ -116,7 +116,7 @@ static void next_lookup(struct host_query *hquery)
{
int status;
const char *p;
- struct hostent *host;
+ struct hostent *host = NULL;
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;
ares_channel channel = hquery->channel;
- struct hostent *host;
+ struct hostent *host = NULL;
if (status == ARES_SUCCESS)
{
@@ -242,12 +242,86 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
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)
{
FILE *fp;
char **alias;
int status;
int error;
+ int match;
+ struct hostent *hostent = NULL;
#ifdef WIN32
char PATH_HOSTS[MAX_PATH];
@@ -283,35 +357,60 @@ static int file_lookup(const char *name, int family, struct hostent **host)
{
error = ERRNO;
switch(error)
- {
- case ENOENT:
- case ESRCH:
- return ARES_ENOTFOUND;
- default:
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
- DEBUGF(fprintf(stderr, "Error opening file: %s\n",
- PATH_HOSTS));
- *host = NULL;
- return ARES_EFILE;
- }
+ {
+ case ENOENT:
+ case ESRCH:
+ return ARES_ENOTFOUND;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+ error, strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n",
+ PATH_HOSTS));
+ *host = NULL;
+ return ARES_EFILE;
+ }
}
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
{
+ match = 0;
+ hostent = *host;
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)
+ {
+ match = 1;
break;
+ }
}
- if (*alias)
- break;
- ares_free_hostent(*host);
+ }
+ if (match)
+ {
+ if(!add_host(hostent, host))
+ ares_free_hostent(hostent);
+ else {
+ *host = NULL;
+ }
+ }
+ else
+ {
+ ares_free_hostent(*host);
+ *host = NULL;
+ }
}
fclose(fp);
if (status == ARES_EOF)
- status = ARES_ENOTFOUND;
+ {
+ if ( *host)
+ status = ARES_SUCCESS;
+ else
+ status = ARES_ENOTFOUND;
+ }
if (status != ARES_SUCCESS)
*host = NULL;
return status;