Ashish Sharma provided a patch for supporting multiple entries in the
authorDaniel Stenberg <daniel@haxx.se>
Sat, 2 Jun 2007 19:42:25 +0000 (19:42 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 2 Jun 2007 19:42:25 +0000 (19:42 +0000)
/etc/hosts file. Patch edited for coding style and functionality by me
(Daniel).

AUTHORS
CHANGES
ares__get_hostent.c
ares_free_hostent.c
ares_gethostbyname.c

diff --git a/AUTHORS b/AUTHORS
index 553d36b..f744914 100644 (file)
--- 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 (file)
--- 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:
index 312a678..dc5f8ad 100644 (file)
@@ -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;
     }
 
index 7763df7..d6cf51f 100644 (file)
@@ -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);
 }
index c0fa474..5170c07 100644 (file)
@@ -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;