diff options
-rw-r--r-- | ares/AUTHORS | 5 | ||||
-rw-r--r-- | ares/CHANGES | 9 | ||||
-rw-r--r-- | ares/ares__get_hostent.c | 1 | ||||
-rw-r--r-- | ares/ares_free_hostent.c | 5 | ||||
-rw-r--r-- | ares/ares_gethostbyname.c | 139 |
5 files changed, 138 insertions, 21 deletions
diff --git a/ares/AUTHORS b/ares/AUTHORS index 553d36bf6..f744914cd 100644 --- a/ares/AUTHORS +++ b/ares/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/ares/CHANGES b/ares/CHANGES index e3b5367d9..3e9f23ca5 100644 --- a/ares/CHANGES +++ b/ares/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/ares__get_hostent.c b/ares/ares__get_hostent.c index 312a678ec..dc5f8ad4f 100644 --- a/ares/ares__get_hostent.c +++ b/ares/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/ares_free_hostent.c b/ares/ares_free_hostent.c index 7763df7dc..d6cf51f4a 100644 --- a/ares/ares_free_hostent.c +++ b/ares/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/ares_gethostbyname.c b/ares/ares_gethostbyname.c index c0fa4743a..5170c078d 100644 --- a/ares/ares_gethostbyname.c +++ b/ares/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; |