Pthread DNS system
------- --- ------

SERVER INSTALLATION
------ ------------

Copy dns_server.c into your /bin directory and compile it with:
gcc -O3 dns_server.c -o dns_server -lpthread
You may want to "strip" the binary afterwards with:
strip dns_server

To quickly test the server, start it with:
./dns_server
Then enter:
1:127.0.0.1
If all worked as plan it'll reply with:
1:localhost [or some such derivative]

CLIENT INSTALLATION
------ ------------
Add the following lines into proto.h

extern void init_pthread_dns(void);
extern void kill_pthread_dns(void);
extern void start_pthread_dns(player *);
extern void read_pthread_dns(void);

In player.h find the line:

next_ping,             /* seconds til player gets next ping */

and underneath add:

dns_job,               /* Pthread DNS job # */

In glue.c find the following 3 lines in the 
function void boot(int port)

#ifdef IDENT
  init_ident_server();		/* ident server */
#endif

and underneath add:
  init_pthread_dns();

In glue.c find the following 3 lines in the function
void close_down(void)

#ifdef INTERCOM
  kill_intercom();
#endif

and underneath add:
  kill_pthread_dns();

In reboot.c find the following lines in the function
void do_reboot(void)

  /*
     here is where to add for any other syncing that needs to be done
     when your talker shutsdown... notes, etc
   */

and underneath add:
  kill_pthread_dns();

In socket.c find the line:
#include <sys/socket.h>

and underneath add:
#include <signal.h>
#include <sys/wait.h>

In socket.c function void accept_new_connection(void)
delete the line:
  struct hostent *hp;

Further down in that function, replace:

  hp = gethostbyaddr((char *) &(incoming.sin_addr.s_addr),
		     sizeof(incoming.sin_addr.s_addr),
		     AF_INET);
  if (hp)
    strncpy(p->inet_addr, hp->h_name, MAX_INET_ADDR - 2);
  else
    strncpy(p->inet_addr, p->num_addr, MAX_INET_ADDR - 2);

with:
  start_pthread_dns(p);


In socket.c above the line:

void scan_sockets()

add:
int DNS_CLIENT[2];

Also in that function, find the following 4 lines:

#ifdef IDENT
  if (IDENT_CLIENT_READ != -1)
    FD_SET(IDENT_CLIENT_READ, &fset);
#endif

And underneath add:
  FD_SET(DNS_CLIENT[0], &fset);

Now find the following 4 lines further down:

#ifdef INTERCOM
  if (intercom_fd > -1 && FD_ISSET(intercom_fd, &fset))
    parse_incoming_intercom();
#endif

And underneath add:
  if (FD_ISSET(DNS_CLIENT[0], &fset))
     read_pthread_dns();

At the bottom of socket.c cut and paste the following code:

/* DNS routines, Pthreaded version */

int dns_pid;

void init_pthread_dns(void)
{
    int dns_server[2], dns_client[2], DNS_SERVER[2];
    char dns_name[256];

    sprintf(dns_name, "-=*> %s <*=- DNS server", get_config_msg("talker_name"));
    if (-1 == pipe(dns_client))
    {
        log("boot", "problem creating pipes for DNS server");
        exit(1);
    }
    if (-1 == pipe(dns_server))
    {
        log("boot", "problem creating pipes for DNS server");
        exit(1);
    }
    DNS_CLIENT[0] = dns_client[0];
    DNS_CLIENT[1] = dns_server[1];
    DNS_SERVER[0] = dns_server[0];
    DNS_SERVER[1] = dns_client[1];
    dns_pid = fork();
    switch(dns_pid)
    {
        case -1:
            log("boot", "Couldn't fork to start DNS server");
            exit(1);
        case 0:
            close(DNS_CLIENT[0]);
            close(DNS_CLIENT[1]);
            close(0);
            dup(DNS_SERVER[0]);
            close(1);
            dup(DNS_SERVER[1]);
            execlp("bin/dns_server", dns_name, 0);
            log("boot", "Eeek couldn't exec, and about now lokie is wishing he had some way to tell the parent :-)'s");
            exit(1);
        default:
            close(DNS_SERVER[0]);
            close(DNS_SERVER[1]);
    }
}

void kill_pthread_dns(void)
{
    int silly;

    close(DNS_CLIENT[0]);
    if (DNS_CLIENT[1] != -1)
        close(DNS_CLIENT[1]);
    kill(dns_pid, SIGTERM);
    waitpid(-1, &silly, WNOHANG);
}

void start_pthread_dns(player *p)
{
    static int job = 1;
    char *oldstack = stack;

    p->dns_job = job++;
    strcpy(p->inet_addr, "Thread Working");
    stack += sprintf(stack, "%d:%s\n", p->dns_job, p->num_addr);
    *stack++ = '\0';
    write_socket(&DNS_CLIENT[1], oldstack, strlen(oldstack));
    stack = oldstack;
}

void read_pthread_dns(void)
{
    static char inp_buffer[128];
    static int inp_pos = 0;
    int cooked, find_job;
    char c;
    player *scan;

    ioctl(DNS_CLIENT[0], FIONREAD, &cooked);
    while (cooked)
    {
        read(DNS_CLIENT[0], &c, 1);
        if (c == '\n')
        {
            inp_buffer[inp_pos] = '\0';
            sscanf(inp_buffer, "%d:%39s", &find_job, stack);
            *(stack + 39) = '\0';
            for (scan = flatlist_start; scan; scan = scan->flat_next)
                if (scan->dns_job == find_job)
                {
                    strcpy(scan->inet_addr, stack);
                    scan->dns_job = 0;
                    break;
                }
            inp_pos = 0;
            break;
        }
        else
        {
            if (inp_pos < 127)
                inp_buffer[inp_pos++] = c;
        }
        cooked--;
    }
}

Compile the talker and fully restart it.
