#include "r.h"
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#define BIND_8_COMPAT
#include <arpa/nameser.h>
#include <resolv.h>
#include <errno.h>

static char rcsid[] = "$Id: r.c,v 1.2 2006/04/27 00:08:32 yuuji Exp yuuji $";

int resolve(char *domain, int type)
{
  unsigned char res[PACKETSZ], *p, name[MAXDNAME];
  HEADER *h = (HEADER*)res;
  int reslen, count, xlen, n;
  extern int errno;
  reslen = res_query(domain, C_IN, type, res, sizeof res);
  if (reslen <= 0) {
    if (errno == ECONNREFUSED) return DNS_SOFT;
    if (h_errno == TRY_AGAIN) return DNS_SOFT;
    return DNS_HARD;
  }
  if (reslen >= sizeof res)
    reslen = sizeof res;
  p = res+sizeof(HEADER);
  for (count=ntohs(h->qdcount); count >= 0; count--) {
    xlen = dn_expand(res, res+reslen, p, name, MAXDNAME);
    if (xlen < 0)
      return DNS_SOFT;
    // fprintf(stderr, "len=%d, name=[%s]\n", xlen, name);
    p += xlen + QFIXEDSZ;
  }
  n = ntohs(h->ancount);
//fprintf(stderr, "%d records found\n", n);
  if (n > 0)
    return 0;
  return DNS_HARD;
}

/* Check DOMAIN has MX record or A record.
 * Return 0:  If it has
 *        -1: DNS lookup temporary(?) failure
 * 	  -2: Hard error
 */
int domaincheck(char *domain)
{
  int rc;
  rc = resolve(domain, T_MX);
  if (0 == rc)
    return 0;
  return resolve(domain, T_A);
}

/*
 * Parse IPv4/IPv6 address into struct ipaddress
 */
int parseipaddr(char *addr, void *buf)
{
  int rc;
  if ((rc=inet_pton(AF_INET6, addr, buf))) {
    return rc;
  } else if ((rc=inet_pton(AF_INET, addr, buf))) {
    return rc;
  }
  return 0;
}

#ifdef R_MAIN_
int main(int argc, char *argv[])
{
  if (argv[1] == 0) {
    fputs("Usage: r NAME\n", stderr);
    exit(0);
  }
#if 0
  fprintf(stderr, "MX=%d\n", resolve(argv[1], T_MX));
  fprintf(stderr, "A=%d\n", resolve(argv[1], T_A));
#else
  struct in_addr addr;
  unsigned char buf[32];
  char b2[32];
#endif
}
#endif
