/* HostsGatherer
 * Copyright (C) 1999 Renaud Deraison
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
#include <includes.h>
#include "hosts_gatherer.h"

/*
 * 
 * Resolve an hostname
 *
 */
struct in_addr
hg_resolv(hostname)
 char * hostname;
{
 struct in_addr addr;
 unsigned long ip;
 struct hostent * he;
 
 if((ip = inet_addr(hostname))!= INADDR_NONE)addr.s_addr = ip;
 else
 {
#if !defined(USE_PTHREADS) || !defined(HAVE_GETHOSTBYNAME_R)
  he = gethostbyname(hostname);
#else
  char * buffer = malloc(4096);
  int Errno = 0;
  struct hostent * res = NULL;
  struct hostent * t   = NULL;
  he = malloc(sizeof(struct hostent));
  bzero(he, sizeof(struct hostent));
#ifdef HAVE_SOLARIS_GETHOSTBYNAME
  gethostbyname_r(hostname, he, buffer, 4096, &Errno);
  if(Errno){
   free(he);
   he = NULL;
   }
#else
  gethostbyname_r(hostname, he, buffer, 4096, &res, &Errno);
  t = he;
  he = res;
#endif /* HAVE_SOLARIS... */
#endif /* USE_PTHREADS... */
  if(he)addr = *(struct in_addr *)he->h_addr;
  else addr.s_addr = INADDR_NONE;
#if defined(USE_PTHREADS) && defined(HAVE_GETHOSTBYNAME_R)
  if(he)free(he);
  else if(t)free(t);
  free(buffer);
#endif
 }
 return(addr);
}

/*
 * 
 * Get the FQDN from the IP
 *
 */
char * 
hg_get_name_from_ip(ip)
 struct in_addr ip;
{
 char * ret = NULL;
 struct hostent * he = NULL;
#if defined(USE_PTHREADS) && defined(HAVE_GETHOSTBYNAME_R)
 struct hostent * result;
 char * buf;
 int h_err = 0;

 buf = malloc(4096);
 bzero(buf, 4096);
 result = malloc(sizeof(struct hostent));
 bzero(result, sizeof(struct hostent));
#if HAVE_SOLARIS_GETHOSTBYADDR_R
 gethostbyaddr_r((char *)&ip, sizeof(long), AF_INET, result, buf, 4096, &h_err);
 if(h_err){
   free(result);
   result = NULL;
   }
  he = result;
#else
 gethostbyaddr_r((char *)&ip, sizeof(long), AF_INET, result, buf, 4096, &he, &h_err);
#endif /* HAVE_SOLARIS ... */
#else
 he = gethostbyaddr((char *)&ip, sizeof(long), AF_INET);
#endif
 if(he)
 {
  int len = strlen(he->h_name);
  
  ret = malloc(len+1);
  strncpy(ret, he->h_name, len+1);
 }
#if defined(USE_PTHREADS) && defined(HAVE_GETHOSTBYNAME_R)
 if(he)free(he);
 else if(result)free(result);
 free(buf);
#endif
 if(!ret){
 ret = malloc(20);
 bzero(ret, 20);
#ifdef HAVE_ADDR2ASCII
 addr2ascii(AF_INET, &ip, sizeof(ip), ret);
#elif defined(HAVE_INET_NETA)
 inet_neta(htonl(ip.s_addr), ret, 20);
#else 
 strcpy(ret, inet_ntoa(ip));
#endif  
 }
 return(ret);
}

/*
 * input : hostname (ie : www.if.arf.com)
 * returns: if.arf.com
 *
 * If the input is arf.com
 * returns : NULL
 *
 */
char * 
hg_name_to_domain(hostname)
 char * hostname;
{
  unsigned int i = -1, j;
  char * ret;
  int len;
  
  if(inet_addr(hostname)!=INADDR_NONE)return(NULL);
  while(hostname[++i]!='.' && i<strlen(hostname));
  if(hostname[i]!='.')return(NULL);
  j=i;
  while(hostname[++j]!='.' && j<strlen(hostname));
  if(hostname[j]!='.')return(NULL);
  len = strlen(hostname+i+1);
  ret = malloc(len+1);
  strncpy(ret, hostname+i+1, len+1);
  return(ret);
}
  
  
void
hg_hosts_cleanup(hosts)
 struct hg_host * hosts;
{
 while(hosts)
 {
  struct hg_host * t;
  if(hosts->hostname)free(hosts->hostname);
  if(hosts->domain)free(hosts->domain);
  t = hosts->next;
  free(hosts);
  hosts = t;
 }
}
 
