These patches are written by Dark@Igor for Dutch Mountains, in December 1995.
They are freely redistributable.


diff -u src.ident/comm.c src.hname/comm.c
--- src.ident/comm.c	Wed Jan  3 22:41:48 1996
+++ src.hname/comm.c	Thu Jan  4 19:07:20 1996
@@ -70,8 +70,6 @@
 char * const him_her [] = { "it",  "him", "her" };
 char * const his_her [] = { "its", "his", "her" };
 
-bool fLookupAddress = TRUE; /* Change here to disable nameserver default */
-
 /*
  * Signal handling.
  * Apollo has a problem with __attribute(atomic) in signal.h,
@@ -161,6 +159,10 @@
                             fd_set *exceptfds, struct timeval *timeout ) );
 int     socket          args( ( int domain, int type, int protocol ) );
 int     write           args( ( int fd, char *buf, int nbyte ) );
+pid_t   vfork           args( ( void ) );
+int     dup2            args( ( int oldfd, int newfd ) );
+int     execlp          args( ( const char *file, const char *arg, ... ) );
+unsigned long inet_addr args( ( const char *cp ) );
 #endif
 
 #if     defined(macintosh)
@@ -283,7 +285,12 @@
 long                boot_time;          /* Time when merc started up    */
 long                current_time;       /* Time of this pulse           */
 int                 players_max;        /* Maximum numbers of players   */
-
+int                 hname;              /* Connects to hname resolver   */
+struct {
+    long addr;
+    char *hname;
+} hname_table[MAX_HNAME];               /* Caches hostnames             */
+int                 hname_index;        /* Cycles through hname_table   */
 
 /*
  * OS-dependent local functions.
@@ -297,6 +304,8 @@
 #if defined(unix)
 void    game_loop_unix          args( ( int control ) );
 int     init_socket             args( ( int port ) );
+void    init_hname              args( ( char *mainpath ) );
+void    get_hname               args( ( void ) );
 int     getrlimit               args( ( int resource, struct rlimit *rlp ) );
 /*
 int     setrlimit               args( ( int resource, struct rlimit *rlp ) );
@@ -421,6 +430,7 @@
 
 #if defined(unix)
     boot_db( );
+    init_hname( argv[0] );
     control = init_socket( port );
     sprintf( log_buf, "Dutch Mountains ready to rock on port %d.", port );
     log_string( log_buf );
@@ -438,6 +448,63 @@
 
 
 #if defined(unix)
+void init_hname( char *mainpath )
+{
+    int sockets[2];
+    int pid;
+    static char *hnamepath;
+    char *p;
+
+    p = strrchr( mainpath, '/' );
+    if ( p ) {
+        /* 7 is length of "hname" plus slash plus terminating 0 */
+        hnamepath = alloc_mem( p - mainpath + 7 );
+	strncpy( hnamepath, mainpath, p - mainpath + 1 );
+	strcat( hnamepath, "hname" );
+    }
+    else
+    {
+        hnamepath = str_dup( "hname" );
+    }
+
+#ifndef FNDELAY
+#define FNDELAY O_NDELAY
+#endif
+
+    if ( socketpair( AF_UNIX, SOCK_STREAM, 0, sockets) >= 0 )
+    {
+        pid = vfork();
+	if ( pid > 0 )
+	{   /* parent */
+	    hname = sockets[1];
+            close( sockets[0] );
+	    free_string( hnamepath );
+	    signal(SIGPIPE, SIG_IGN);
+	    if ( fcntl( hname, F_SETFL, FNDELAY) < 0 )
+            {
+	        perror("init_hname: fcntl");
+		close( hname );
+		hname = -1;
+	    }
+	}
+	else if ( pid == 0 )
+        {   /* child */
+	    close(sockets[1]);
+	    dup2( sockets[0], 0 );
+	    dup2( sockets[0], 1 );
+	    execlp( hnamepath, "hname", NULL );
+	    /* Still here?  Then exec failed. */
+	    exit( 1 );
+	}
+	else
+	{   /* failure */
+	    close(sockets[0]);
+	    close(sockets[1]);
+	    hname = -1;
+	}
+    }
+}
+
 int init_socket( int port )
 {
     static struct sockaddr_in sa_zero;
@@ -781,6 +848,8 @@
         FD_ZERO( &out_set );
         FD_ZERO( &exc_set );
         FD_SET( control, &in_set );
+	if ( hname >= 0 )
+	    FD_SET( hname, &in_set );
         maxdesc = control;
         for ( d = descriptor_list; d != NULL; d = d->next )
         {
@@ -812,6 +881,14 @@
             new_descriptor( control );
 	}
 
+	/*
+	 * New hostname found?
+	 */
+	if ( hname >= 0 && FD_ISSET( hname, &in_set ) )
+	{
+	    get_hname();
+	}
+
         /*
          * Kick out the freaky folks.
          */
@@ -1041,6 +1118,147 @@
     return 1; 
 }
 
+#if defined(unix)
+void query_hname( DESCRIPTOR_DATA *desc )
+{
+    int i;
+    char buf[20];
+
+    /* Look in cache */
+    for ( i = 0; i < MAX_HNAME; i++ )
+    {
+        if ( desc->hostaddr == hname_table[i].addr ) 
+	{
+	    free_string( desc->host );
+	    desc->host = str_dup( hname_table[i].hname );
+	    return;
+	}
+    }
+
+    /*
+     * Would be nice to use inet_ntoa here but it takes a struct arg,
+     * which ain't very compatible between gcc and system libraries.
+     */
+    sprintf( buf, "%ld.%ld.%ld.%ld",
+            ( desc->hostaddr >> 24 ) & 0xFF, ( desc->hostaddr >> 16 ) & 0xFF,
+            ( desc->hostaddr >>  8 ) & 0xFF, ( desc->hostaddr       ) & 0xFF
+            );
+	
+    desc->host = str_dup( buf );
+    strcat( buf, "\n" );
+    if ( write( hname, buf, strlen( buf ) ) < 0 )
+    {
+        close( hname );
+        hname = -1;
+    }
+}
+#endif	      
+
+#if defined(unix)
+static void add_hname( long addr, char *hname )
+{
+    char *p;
+    DESCRIPTOR_DATA *d, *d_next;
+    BAN_DATA *pban;
+    bool newchar;
+
+    hname_table[hname_index].addr = addr;
+    free_string( hname_table[hname_index].hname );
+    hname_table[hname_index].hname = hname;
+    hname_index = ( hname_index + 1 ) % MAX_HNAME;
+
+    for ( d = descriptor_list; d; d = d_next )
+    {
+        d_next = d->next;
+	if ( d->hostaddr == addr ) {
+	    p = strrchr( d->host, '@' );
+	    if ( p )
+	    {
+	        char *hostname;
+
+	        hostname = alloc_mem( p - d->host + strlen( hname ) + 2 );
+		strncpy( hostname, d->host, p - d->host + 1 );
+		strcat( hostname, hname );
+		free_string( d->host );
+		d->host = hostname;
+	    }
+	    else
+	    {
+	        free_string( d->host );
+		d->host = str_dup( hname );
+	    }
+
+	    /*
+             * We now have a hostname, so check banishment.
+             */
+
+	    /*
+             * NOT fully reliable.  A fast typist on a fast link may
+             * get through the character generation process before the
+             * hostname lookup completes.
+             */
+	    newchar = ( d->connected == CON_CONFIRM_NEW_NAME ||
+		        d->connected == CON_GET_NEW_PASSWORD ||
+		        d->connected == CON_CONFIRM_NEW_PASSWORD ||
+		        d->connected == CON_GET_NEW_RACE ||
+		        d->connected == CON_GET_NEW_SEX ||
+		        d->connected == CON_GET_NEW_CLASS ||
+		        d->connected == CON_GET_ALIGNMENT ||
+		        d->connected == CON_GET_STATS );
+	      
+            for ( pban = ban_list; pban != NULL; pban = pban->next )
+            {
+                if ( !str_suffix( pban->name, d->host ) && 
+		     ( newchar || pban->flag ) )
+                {
+		    if ( d->character == NULL || d->character->name == NULL )
+		        sprintf( log_buf, "[%s] has been banned", d->host );
+		    else
+		        sprintf( log_buf, "%s [%s] has been banned",
+			         d->character->name, d->host );
+                    log_string( log_buf );
+                    output_channel( NULL, log_buf, CHA_CONNECT );
+		    if (pban->flag)
+		      write_to_buffer( d, "Your site has been banned" 
+				          " from this Mud.\n\r", 0 );
+		    else
+		      write_to_buffer( d, "Your site has been banned"
+				          " for new players.\n\r", 0 );
+                    close_socket( d, FALSE );
+                    return;
+                }
+            }
+	}
+    }
+}
+
+void get_hname( void )
+{
+    char buf[MAX_STRING_LENGTH + 1];
+    char *p, *q, *r;
+    long addr;
+    int size;
+
+    size = read( hname, buf, MAX_STRING_LENGTH );
+    if ( size < 0 )
+    {
+        close( hname );
+	hname = -1;
+    }
+
+    buf[size] = '\0';
+    q = buf;
+    while ( (p = strchr( q, '\n' )) )
+    {
+        *p = '\0';
+	addr = inet_addr( q );
+	r = strchr( q, ' ' );
+	if ( addr && r )
+	    add_hname( ntohl( addr ), str_dup( r+1 ) );
+	q = p + 1;
+    }
+}
+#endif	  
 
 
 void do_maxusers( CHAR_DATA *ch, char *argument )
@@ -1301,14 +1519,12 @@
 void new_descriptor( int control )
 {
     static DESCRIPTOR_DATA d_zero;
-    char buf[MAX_STRING_LENGTH];
     DESCRIPTOR_DATA *dnew;
 /* BB: Unused
     DESCRIPTOR_DATA *test_list;
 */
     BAN_DATA *pban;
     struct sockaddr_in sock;
-    struct hostent *from;
     int desc;
     int size;
     int iHistory;
@@ -1361,32 +1577,12 @@
     {
         perror( "New_descriptor: getpeername" );
         dnew->host = str_dup( "(unknown)" );
+	dnew->hostaddr = 0;
     }
     else
     {
-        /*
-         * Would be nice to use inet_ntoa here but it takes a struct arg,
-         * which ain't very compatible between gcc and system libraries.
-         */
-        int addr;
-
-        addr = ntohl( sock.sin_addr.s_addr );
-        sprintf( buf, "%d.%d.%d.%d",
-            ( addr >> 24 ) & 0xFF, ( addr >> 16 ) & 0xFF,
-            ( addr >>  8 ) & 0xFF, ( addr       ) & 0xFF
-            );
-        /*
-         * Next two lines can be disabled to reduce lag.
-         */
-        if ( fLookupAddress )
-        {
-            from = gethostbyaddr( (char *) &sock.sin_addr,
-                    sizeof(sock.sin_addr), AF_INET );
-        }
-        else
-            from = NULL;
-
-        dnew->host = str_dup( from ? from->h_name : buf );
+        dnew->hostaddr = ntohl( sock.sin_addr.s_addr );
+        query_hname( dnew );
     }
 
     dnew->ident         = new_ident( dnew );
@@ -1398,6 +1594,11 @@
      * using automated 'autodialers' and leaving connections hanging.
      *
      * Furey: added suffix check by request of Nickel of HiddenWorlds.
+     */
+
+    /*
+     * At this point, the hostname may or may not be known.
+     * There is another check in get_hname().
      */
 
     for ( pban = ban_list; pban != NULL; pban = pban->next )
Only in src.hname: hname.c
diff -u src.ident/makefile src.hname/makefile
--- src.ident/makefile	Wed Dec  6 15:17:16 1995
+++ src.hname/makefile	Wed Jan  3 22:44:10 1996
@@ -10,6 +10,11 @@
           interp.o newcommands.o magic.o save.o show.o special.o spells.o \
 	  trap.o update.o
 
+all: merc hname
+
+hname: hname.c
+	$(CC) $(D_FLAGS) $< -o hname 
+
 merc: $(O_FILES)
 	$(CC) $(D_FLAGS) $(L_FLAGS) -o merc *.o
 
diff -u src.ident/merc.h src.hname/merc.h
--- src.ident/merc.h	Thu Dec 28 02:30:36 1995
+++ src.hname/merc.h	Wed Jan  3 22:50:51 1996
@@ -132,6 +132,7 @@
 #define MAX_RACE                    5
 #define MAX_STAT                    6
 #define MAX_HISTORY                20
+#define MAX_HNAME                 400
 #define MAX_LEVEL                  46
 #define MAX_SKILL                 212
 #define MAX_SCAN_RANGE              3
@@ -269,6 +270,7 @@
     char                incomm          [MAX_INPUT_LENGTH];
     char *              history         [MAX_HISTORY];
     sh_int              nhistory;
+    long                hostaddr;
     char *              outbuf;
     int                 outsize;
     int                 outtop;