lpmoo-1.2/etc/
lpmoo-1.2/mudlib/
lpmoo-1.2/mudlib/etc/
lpmoo-1.2/mudlib/include/
lpmoo-1.2/mudlib/include/moo/
lpmoo-1.2/mudlib/lpc/
lpmoo-1.2/mudlib/std/auto/
lpmoo-1.2/mudlib/std/bfuns/
/*
 * NAME:	dnsbot.c
 * DESCRIPTION:	perform DNS lookups
 */

# include <stdio.h>
# include <string.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <memory.h>
# include <errno.h>
# include <ctype.h>

/*
 * NAME:	fatal()
 * DESCRIPTION:	an unrecoverable error has occured
 */
static
fatal(msg, arg)
     char *msg, *arg;
{
  if (*msg == '*')
    {
      fprintf(stderr, msg + 1, arg);
      perror((char *) 0);
    }
  else
    {
      fprintf(stderr, msg, arg);
      fprintf(stderr, "\n");
    }

  exit(1);
}

/*
 * NAME:	resolv->name2addr()
 * DESCRIPTION:	translate hostname to IP address
 */
static
int resolv_name2addr(hostname, ipaddr)
     char *hostname;
     struct in_addr *ipaddr;
{
  struct hostent *host;

  host = gethostbyname(hostname);
  if (! host)
    return 0;

  memcpy(&ipaddr->s_addr, host->h_addr, host->h_length);

  return 1;
}

/*
 * NAME:	resolv->addr2name()
 * DESCRIPTION:	translate IP address to hostname
 */
static
int resolv_addr2name(ipaddr, hostname)
     struct in_addr ipaddr;
     char **hostname;
{
  struct hostent *host;

  host = gethostbyaddr((char *) &ipaddr, sizeof(ipaddr), AF_INET);
  if (! host)
    return 0;

  *hostname = host->h_name;

  return 1;
}

/*
 * NAME:	resolv->ip2str()
 * DESCRIPTION:	convert IP address to dotted quad
 */
static
char *resolv_ip2str(ipaddr)
     struct in_addr ipaddr;
{
  return inet_ntoa(ipaddr);
}

/*
 * NAME:	resolv->str2ip()
 * DESCRIPTION:	convert dotted quad to IP address
 */
static
struct in_addr resolv_str2ip(str)
     char *str;
{
  struct in_addr ipaddr;

  ipaddr.s_addr = inet_addr(str);

  return ipaddr;
}

/*
 * NAME:	resolv->addr()
 * DESCRIPTION:	return the IP address of a hostname or dotted quad string
 */
static
int resolv_addr(host, ipaddr)
     char *host;
     struct in_addr *ipaddr;
{
  int x;

  if (sscanf(host, "%d.%d.%d.%d", &x, &x, &x, &x) == 4)
    {
      *ipaddr = resolv_str2ip(host);
      return 1;
    }
  else
    return resolv_name2addr(host, ipaddr);
}

/*
 * NAME:	dgd->open()
 * DESCRIPTION:	open a connection to DGD
 */
static
int dgd_open(host, port)
     char *host;
     unsigned short port;
{
  int fd;
  struct sockaddr_in addr;

  if (! resolv_addr(host, &addr.sin_addr))
    fatal("Cannot resolve host address: %s", host);

  addr.sin_family = AF_INET;
  addr.sin_port   = htons(port);

  while (1)
    {
      fd = socket(AF_INET, SOCK_STREAM, 0);
      if (fd < 0)
	fatal("*Cannot open socket: ");

      if (connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr)) >= 0)
	break;

      if (errno != ECONNREFUSED)
	fatal("*Cannot connect to %s: ", host);

      close(fd);
      sleep(10);
    }

  return fd;
}

/*
 * NAME:	bot->handle()
 * DESCRIPTION:	do the work specified by the command and argument
 */
static
char *bot_handle(command, arg)
     char *command;
     char *arg;
{
  static char answer[256];
  struct in_addr ipaddr;
  char *str;

  if (strcasecmp(command, "ADDR?") == 0)
    {
      if (resolv_name2addr(arg, &ipaddr))
	{
	  if (! resolv_addr2name(ipaddr, &str))
	    str = arg;

	  sprintf(answer, "HOST %s = %s = %s",
		  arg, str, resolv_ip2str(ipaddr));
	}
      else
	sprintf(answer, "NOADDR %s", arg);

      return answer;
    }
  else if (strcasecmp(command, "NAME?") == 0)
    {
      ipaddr = resolv_str2ip(arg);

      if (resolv_addr2name(ipaddr, &str))
	sprintf(answer, "HOST %s = %s = %s", str, str, arg);
      else
	sprintf(answer, "NONAME %s", arg);

      return answer;
    }

  return 0;
}

/*
 * NAME:	main()
 * DESCRIPTION:	control entry
 */
int main(argc, argv)
     int argc;
     char *argv[];
{
  int debug, fd, n;
  FILE *input, *output;
  char line[128], *str;
  struct in_addr ipaddr;

  if (argc > 1 && strcmp(argv[1], "-d") == 0)
    {
      debug = 1;
      --argc, ++argv;
    }
  else
    debug = 0;

  if (argc != 3)
    fatal("Usage: %s [-d] host port", argv[0]);

  fd = dgd_open(argv[1], atoi(argv[2]));
  if (debug)
    {
      printf("Connected to %s\n", argv[1]);
      fflush(stdout);
    }

  while (n = fread(line, 1, sizeof(line), stdin))
    write(fd, line, n);
  fclose(stdin);

  input  = fdopen(fd, "r");
  output = fdopen(fd, "w");

  while (fgets(line, sizeof(line), input))
    {
      char *command, *arg, *answer;

      if (debug)
	{
	  printf("%s", line);
	  fflush(stdout);
	}

      command = strtok(line, " \t\r\n");
      if (! command)
	continue;

      arg = strtok((char *) 0, " \t\r\n");
      if (! arg)
	continue;

      answer = bot_handle(command, arg);
      if (answer)
	{
	  fprintf(output, "%s\r\n", answer);
	  fflush(output);

	  if (debug)
	    {
	      printf(">> %s\n", answer);
	      fflush(stdout);
	    }
	}
    }

  close(fd);

  return 0;
}