/* This software is Copyright 1996 by Craig Metz, All Rights Reserved.
   The Inner Net Copyright Notice and License Agreement Version 2
   applies to this software.
*/
/* gai v1.11 */
#define HAVE_NRL 1

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if INET6
#include <netinet6/in6.h>
#endif /* INET6 */

#if HAVE_NRL
#include "support.h"
#endif /* HAVE_NRL */

extern char *optarg;

char buffer[1024];

void usage(char *myname)
{
  printf("usage: %s [-n <name>] [-s <service>] [-f <family>] [-t <socktype>] [-p protocol] [-c] [-b]\n", myname);
  exit(1);
}

#if HAVE_NRL
static struct nrl_nametonum socktypenametonum[] = {
  { SOCK_RAW, "raw", 0 },
  { SOCK_DGRAM, "dgram", 0 },
  { SOCK_STREAM, "stream", 0 },
  { 0, NULL, -1 }
};
#endif /* HAVE_NRL */

int main(int argc, char **argv)
{
  int i, j;
  struct addrinfo *pai = NULL, **ppai = &pai;
  struct addrinfo req;
  char *name = NULL, *service = NULL;
  char *myname = strdup(argv[0]);
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 128
#endif /* MAXHOSTNAMELEN */
#if HAVE_NRL
  char hbuf[2][MAXHOSTNAMELEN], sbuf[2][32];
#else /* HAVE_NRL */
  char hbuf[1][MAXHOSTNAMELEN], sbuf[1][32];
#endif /* HAVE_NRL */

  {
  char *c;
  if (c = strrchr(myname, '/')) {
    *(c++) = 0;
    myname = c;
  };
  };
  
  memset(&req, 0, sizeof(req));

  while((i = getopt(argc, argv, "n:s:f:t:p:cbx")) != -1) {
    switch(i) {
    case 'n':
      name = optarg;
      break;
    case 's':
      service = optarg;
      break;
    case 'f':
#if HAVE_NRL
      if (!(req.ai_family = nrl_afnametonum(optarg))) {
#else /* HAVE_NRL */
      if (!(req.ai_family = atoi(optarg))) {
#endif /* HAVE_NRL */
        fprintf(stderr, "%s: %s: invalid address family\n", myname, optarg);
        exit(1);
      };
      break;
    case 't':
#if HAVE_NRL
      if (!(req.ai_socktype = nrl_nametonum(socktypenametonum, optarg))) {
#else /* HAVE_NRL */
      if (!(req.ai_socktype = atoi(optarg))) {
#endif /* HAVE_NRL */
        fprintf(stderr, "%s: %s: invalid socket type\n", myname, optarg);
        exit(1);
      };
      break;
    case 'p':
      req.ai_protocol = atoi(optarg);
      break;
    case 'c':
      req.ai_flags |= AI_CANONNAME;
      break;
    case 'b':
      req.ai_flags |= AI_PASSIVE;
      break;
    case 'x':
      ppai = NULL;
      break;
    default:
      usage(argv[0]);
    }
/* gai v1.00 */
  }

  i = getaddrinfo(name, service, &req, ppai);
  
  printf("getaddrinfo() returned: %s(%d).\n", nrl_gai_strerror(i), i);
  
  if (!i) {
    i = 0;
    while(pai) {
      printf("\nrecord %d:\n", i++);
      printf("ai_flags:      %x(%d)\n", pai->ai_flags, pai->ai_flags);
      printf("ai_family:     %x(%d)\n", pai->ai_family, pai->ai_family);
      printf("ai_socktype:   %x(%d)\n", pai->ai_socktype, pai->ai_socktype);
      printf("ai_protocol:   %x(%d)\n", pai->ai_protocol, pai->ai_protocol);
      printf("ai_addrlen:    %x(%d)\n", pai->ai_addrlen, pai->ai_addrlen);
      if (getnameinfo(pai->ai_addr, pai->ai_addrlen, hbuf[0], sizeof(hbuf[0]), sbuf[0], sizeof(sbuf[0]))) {
        fprintf(stderr, "getnameinfo() failed!\n");
	continue;
      };
#if HAVE_NRL
      if (nrl_getnameinfo(pai->ai_addr, pai->ai_addrlen, hbuf[1], sizeof(hbuf[1]), sbuf[1], sizeof(sbuf[1]), 7)) {
        fprintf(stderr, "nrl_getnameinfo() failed!\n");
	continue;
      };
      printf("ai_addr:       %s.%s(%s.%s)\n", hbuf[0], sbuf[0], hbuf[1], sbuf[1]);
#else /* HAVE_NRL */
      printf("ai_addr:       %s.%s\n", hbuf[0], sbuf[0]);
#endif /* HAVE_NRL */
      printf("ai_canonname:  %s\n", pai->ai_canonname);

      pai = pai->ai_next;
    }
  }

  return i;
}
