pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
/****************************************************************************
 ** Project    : pDirt (Aber IV Deamon)
 ** Module     : dns.c
 ** Description: Asynchrone DNS lookup. Lately looking up a hostname causes
 **              much problems for muds. Sometimes it causes the mud to go
 **              "dead" for a minute or two. The way to solve this is to make
 **              a thread or a seperate process that will do the lookup for 
 **              you. This module uses a seperate process to do it (supplied in
 **              the utils directory).
 ** Author     : Peter Eussen
 ** Copyright  : Part of the pDirt distribution.
 ** Date       : 6 Dec 1997
 ** Version    : 1.0
 *****************************************************************************/
#include "kernel.h"
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
#include "dns.h"
#include "AberChat/client.h"
#include "log.h"
#include "mud.h"
#include "s_socket.h"
#include "mobile.h"
#include "bprintf.h"

#define DNSSERVERPORT  12000

int dnsfd = -1;

/** FUNCTION: bootmuddns(void)
 ** 
 ** This function tries to open a connection to the external DNS lookup system
 ** which should be running on the designated port. If it fails it will return
 ** -1, otherwise it will return the fd which is used for dns lookup.
 **
 ** INPUT : none
 ** OUTPUT: -1 if boot failed
 **         fd >= 0 if boot succeeded.
 **/
int  bootmuddns()
{   extern fd_set sockets_fds;
    static Boolean warn = True;

    if (dnsfd == -1)
    {   dnsfd = makesock(my_hostname,DNSSERVERPORT);
        if (dnsfd != -1)
        {  FD_SET(dnsfd,&sockets_fds);
           mudlog("MUDDNS: DNS Connection established.");
        }
        else if (warn)
        {  warn = False;
           progerror("MUDDNS");
        }
    }
    else
       FD_SET(dnsfd,&sockets_fds);
    return dnsfd;
}

/** FUNCTION: closemuddns(void)
 ** 
 ** This function closed the connection with the muddns system.
 ** It will remove the fd from the listen list, close the fd and log to the 
 ** syslog that the connection has been closed.
 **
 ** INPUT : none
 ** OUTPUT: none
 **/
void closemuddns()
{   extern fd_set sockets_fds;
    FD_CLR(dnsfd,&sockets_fds);
    shutdown(dnsfd,2);
    close(dnsfd);
    dnsfd = -1;
    mudlog("MUDDNS: DNS Connection has been closed.");
}

/** FUNCTION: request_lookup()
 **
 ** This function puts a request to the external dns lookup system for a 
 ** specified socket of the mud.
 **
 ** INPUT : int plr = socket of the mud which should be resolved.
 **         char *ip= the ip-number which should be translated to a hostname
 ** OUTPUT: none
 **/
void request_lookup(int plr, char *ip)
{  char line[19];
  
   sprintf(line,"%d:%s",plr,ip);
   write(dnsfd,line,19);
}

/** FUNCTION: read_lookup()
 **
 ** Reads a finished host lookup. Once the request_lookup has been entered,
 ** the dns will go to it and try to resolve it. Once it is finished it will
 ** send back the result. This function reads that result and does the 
 ** appropriate actions.
 **
 ** INPUT : int fd = the dns fd
 ** OUTPUT: none
 **/
void read_lookup(int fd)
{  char line[120];		/* The size of a record returned by dnssystem */
   char host[100];		/* Temp storage for the hostname */
   char newhost[100];		/* Full hostname including ban characters */
   char *s = newhost;		/* Pointer for adding bann characters */
   int  i;			/* Temp storage for socket number */
   Boolean banned_host = False;	/* Is the host banned? */
   Boolean locked_host = False; /* Is the host locked? */

   /* Try to read a record from the dnsfd, if it fails then it means the
    * external dns program crashed. So close the connection to avoid havoc
    * and to switch back to the old mode lookup
    */
   if ((i = read(fd,line,120)) < 1)
      closemuddns();
   else
   {   /* Okay, we have a record here, now lets disect it into a socket number
        * and a hostname. After that is done check if the socket is valid, cause
        * if it isnt, then something went wrong.
        */
       sscanf(line,"%d:%s",&i,host);
       if (i < 0 || i > max_players)
          return;

       /* Check for host banns 
        */
       banned_host = is_host_banned(host);
       locked_host = is_locked_host(host);
      
       /* Add signs to denote what kind of lock the host has, '*' means banned
        * '!' means locked.
        */ 
       if (banned_host)
          *s++ = '*';
       else if (locked_host)
          *s++ = '!';

       /* Now add the hostname to it and we're all set to copy it to the targets
        */
       strcpy(s,host); 
       strncpy(players[i].realhostname,newhost,MAXHOSTNAMELEN);
       strncpy(players[i].hostname,newhost,MAXHOSTNAMELEN);

       /* This host cant log in, so let's not wait for it to do anything but
        * kick it out with the appropriate message.
        */
       if (banned_host)
       {   int save_mynum = mynum;
           setup_globals(i);
           bprintf("\n\001f"BAN_MSG2"\003\n");
           crapup(NULL,CRAP_RETURN);
           setup_globals(save_mynum);
       }

       /* If the lookup took very long it may occur that the player has already
        * logged in, so make sure the fake hostname is placed when that happens
        */
       if (ublock[i].pname[0] != '\0' && players[i].iamon)
          find_fake_host_name(pname(i),host,players[i].hostname);
   }
}