/* Copyright 1998 by the Massachusetts Institute of Technology.
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 */

#include <sys/types.h>

#ifdef WIN32

#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "ares.h"
#include "ares_private.h"

int ares__get_hostent(FILE *fp, struct hostent **host)
{
  char *line = NULL, *p, *q, *canonical, **alias;
  int status, linesize, end_at_hostname, naliases;
  struct in_addr addr;
  struct hostent *hostent = NULL;

  while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
    {
      /* Skip comment lines; terminate line at comment character. */
      if (*line == '#' || !*line)
	continue;
      p = strchr(line, '#');
      if (p)
	*p = 0;

      /* Get the address part. */
      p = line;
      while (*p && !isspace((unsigned char)*p))
	p++;
      if (!*p)
	continue;
      *p = 0;
      addr.s_addr = inet_addr(line);
      if (addr.s_addr == INADDR_NONE)
	continue;

      /* Get the canonical hostname. */
      p++;
      while (isspace((unsigned char)*p))
	p++;
      if (!*p)
	continue;
      q = p;
      while (*q && !isspace((unsigned char)*q))
	q++;
      end_at_hostname = (*q == 0);
      *q = 0;
      canonical = p;

      naliases = 0;
      if (!end_at_hostname)
	{
	  /* Count the aliases. */
	  p = q + 1;
	  while (isspace((unsigned char)*p))
	    p++;
	  while (*p)
	    {
	      while (*p && !isspace((unsigned char)*p))
		p++;
	      while (isspace((unsigned char)*p))
		p++;
	      naliases++;
	    }
	}

      /* Allocate memory for the host structure. */
      hostent = malloc(sizeof(struct hostent));
      if (!hostent)
	break;
      hostent->h_aliases = NULL;
      hostent->h_addr_list = NULL;
      hostent->h_name = strdup(canonical);
      if (!hostent->h_name)
	break;
      hostent->h_addr_list = malloc(2 * sizeof(char *));
      if (!hostent->h_addr_list)
	break;
      hostent->h_addr_list[0] = malloc(sizeof(struct in_addr));
      if (!hostent->h_addr_list[0])
	break;
      hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
      if (!hostent->h_aliases)
	break;

      /* Copy in aliases. */
      naliases = 0;
      if (!end_at_hostname)
	{
	  p = canonical + strlen(canonical) + 1;
	  while (isspace((unsigned char)*p))
	    p++;
	  while (*p)
	    {
	      q = p;
	      while (*q && !isspace((unsigned char)*q))
		q++;
	      hostent->h_aliases[naliases] = malloc(q - p + 1);
	      if (hostent->h_aliases[naliases] == NULL)
		break;
	      memcpy(hostent->h_aliases[naliases], p, q - p);
	      hostent->h_aliases[naliases][q - p] = 0;
	      p = q;
	      while (isspace((unsigned char)*p))
		p++;
	      naliases++;
	    }
	  if (*p)
	    break;
	}
      hostent->h_aliases[naliases] = NULL;

      hostent->h_addrtype = AF_INET;
      hostent->h_length = sizeof(struct in_addr);
      memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr));
      hostent->h_addr_list[1] = NULL;
      *host = hostent;
      free(line);
      return ARES_SUCCESS;
    }
  if(line)
    free(line);

  if (status == ARES_SUCCESS)
    {
      /* Memory allocation failure; clean up. */
      if (hostent)
	{
          if(hostent->h_name)
            free((char *) hostent->h_name);
	  if (hostent->h_aliases)
	    {
	      for (alias = hostent->h_aliases; *alias; alias++)
		free(*alias);
	    }
          if(hostent->h_aliases)
            free(hostent->h_aliases);
	  if (hostent->h_addr_list && hostent->h_addr_list[0])
	    free(hostent->h_addr_list[0]);
          if(hostent->h_addr_list)
            free(hostent->h_addr_list);
          free(hostent);
	}
      return ARES_ENOMEM;
    }

  return status;
}
