diff -C 3 stk/act.wizard.c src/act.wizard.c
*** stk/act.wizard.c	Thu Apr  3 12:27:00 1997
--- src/act.wizard.c	Thu Apr  3 11:28:47 1997
***************
*** 2481,2483 ****
--- 2481,2564 ----
    sprintf(buf, "Your syslog is now %s.\r\n", logtypes[tp]);
    send_to_char(buf, ch);
  }
+ 
+ 
+ /* dnsmod */
+ ACMD(do_dns)
+ {
+   int i;
+   char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
+   char ip[MAX_INPUT_LENGTH], name[MAX_INPUT_LENGTH];
+   char buf[16384];
+   struct dns_entry *dns, *tdns;
+ 
+   extern struct dns_entry *dns_cache[DNS_HASH_NUM];
+ 
+   void save_dns_cache(void);
+ 
+   half_chop(argument, arg1, arg2);
+ 
+   if(!*arg1) {
+     send_to_char("You shouldn't be using this if you don't know what it does!\r\n", ch);
+     return;
+   }
+ 
+   if(is_abbrev(arg1, "delete")) {
+     if(!*arg2) {
+       send_to_char("Delete what?\r\n", ch);
+       return;
+     }
+     CREATE(dns, struct dns_entry, 1);
+     if(sscanf(arg2, "%d.%d.%d", dns->ip, dns->ip + 1,
+       dns->ip + 2) != 3) {
+       send_to_char("Delete what?\r\n", ch);
+       return;
+     }
+     for(i = 0; i < DNS_HASH_NUM; i++) {
+       if(dns_cache[i]) {
+ 	for(tdns = dns_cache[i]; tdns; tdns = tdns->next) {
+ 	  if(dns->ip[0] == tdns->ip[0] && dns->ip[1] == tdns->ip[1] &&
+ 	    dns->ip[2] == tdns->ip[2]) {
+ 	    sprintf(arg1, "Deleting %s.\r\n", tdns->name);
+ 	    send_to_char(arg1, ch);
+ 	    tdns->ip[0] = -1;
+ 	  }
+ 	}
+       }
+     }
+     save_dns_cache();
+     return;
+   } else if(is_abbrev(arg1, "add")) {
+     two_arguments(arg2, ip, name);
+     if(!*ip || !*name) {
+       send_to_char("Add what?\r\n", ch);
+       return;
+     }
+     CREATE(dns, struct dns_entry, 1);
+     dns->ip[3] = -1;
+     if(sscanf(ip, "%d.%d.%d.%d", dns->ip, dns->ip + 1,
+       dns->ip + 2, dns->ip + 3) < 3) {
+       send_to_char("Add what?\r\n", ch);
+       return;
+     }
+     i = (dns->ip[0] + dns->ip[1] + dns->ip[2]) % DNS_HASH_NUM;
+     dns->name = str_dup(name);
+     dns->next = dns_cache[i];
+     dns_cache[i] = dns;
+     save_dns_cache();
+     send_to_char("OK!\r\n", ch);
+     return;
+   } else if(is_abbrev(arg1, "list")) {
+     *buf = '\0';
+     for(i = 0; i < DNS_HASH_NUM; i++) {
+       if(dns_cache[i]) {
+ 	for(tdns = dns_cache[i]; tdns; tdns = tdns->next) {
+ 	  sprintf(buf, "%s%d.%d.%d.%d %s\r\n", buf, tdns->ip[0],
+ 	    tdns->ip[1], tdns->ip[2], tdns->ip[3], tdns->name);
+ 	}
+       }
+     }
+     page_string(ch->desc, buf, 1);
+     return;
+   }
+ }
diff -C 3 stk/comm.c src/comm.c
*** stk/comm.c	Thu Apr  3 12:27:04 1997
--- src/comm.c	Thu Apr  3 11:44:17 1997
***************
*** 966,986 ****
  ****************************************************************** */
  
  
  int new_descriptor(int s)
  {
!   socket_t desc;
!   int sockets_connected = 0;
    unsigned long addr;
    int i;
    static int last_desc = 0;	/* last descriptor number */
    struct descriptor_data *newd;
    struct sockaddr_in peer;
    struct hostent *from;
    extern char *GREETINGS;
  
    /* accept the new connection */
    i = sizeof(peer);
!   if ((desc = accept(s, (struct sockaddr *) &peer, &i)) == INVALID_SOCKET) {
      perror("accept");
      return -1;
    }
--- 966,991 ----
  ****************************************************************** */
  
  
+ /* dnsmod */
  int new_descriptor(int s)
  {
!   int desc, sockets_connected = 0;
    unsigned long addr;
    int i;
+   struct dns_entry dns;
+   char buf[256];
    static int last_desc = 0;	/* last descriptor number */
    struct descriptor_data *newd;
    struct sockaddr_in peer;
    struct hostent *from;
    extern char *GREETINGS;
  
+   int get_host_from_cache(struct dns_entry *dnsd);
+   void add_dns_host(struct dns_entry *dnsd, char *hostname);
+ 
    /* accept the new connection */
    i = sizeof(peer);
!   if ((desc = accept(s, (struct sockaddr *) &peer, &i)) < 0) {
      perror("accept");
      return -1;
    }
***************
*** 993,1026 ****
  
    if (sockets_connected >= max_players) {
      write_to_descriptor(desc, "Sorry, CircleMUD is full right now... please try again later!\r\n");
!     CLOSE_SOCKET(desc);
      return 0;
    }
    /* create a new descriptor */
    CREATE(newd, struct descriptor_data, 1);
    memset((char *) newd, 0, sizeof(struct descriptor_data));
  
!   /* find the sitename */
!   if (nameserver_is_slow || !(from = gethostbyaddr((char *) &peer.sin_addr,
  				      sizeof(peer.sin_addr), AF_INET))) {
  
!     /* resolution failed */
!     if (!nameserver_is_slow)
!       perror("gethostbyaddr");
! 
!     /* find the numeric site address */
!     addr = ntohl(peer.sin_addr.s_addr);
!     sprintf(newd->host, "%03u.%03u.%03u.%03u", (int) ((addr & 0xFF000000) >> 24),
!      (int) ((addr & 0x00FF0000) >> 16), (int) ((addr & 0x0000FF00) >> 8),
! 	    (int) ((addr & 0x000000FF)));
    } else {
!     strncpy(newd->host, from->h_name, HOST_LENGTH);
!     *(newd->host + HOST_LENGTH) = '\0';
    }
  
    /* determine if the site is banned */
    if (isbanned(newd->host) == BAN_ALL) {
!     CLOSE_SOCKET(desc);
      sprintf(buf2, "Connection attempt denied from [%s]", newd->host);
      mudlog(buf2, CMP, LVL_GOD, TRUE);
      free(newd);
--- 998,1049 ----
  
    if (sockets_connected >= max_players) {
      write_to_descriptor(desc, "Sorry, CircleMUD is full right now... please try again later!\r\n");
!     close(desc);
      return 0;
    }
    /* create a new descriptor */
    CREATE(newd, struct descriptor_data, 1);
    memset((char *) newd, 0, sizeof(struct descriptor_data));
  
!   /* find the numeric site address */
!   addr = ntohl(peer.sin_addr.s_addr);
!   dns.ip[0] = (int) ((addr & 0xFF000000) >> 24);
!   dns.ip[1] = (int) ((addr & 0x00FF0000) >> 16);
!   dns.ip[2] = (int) ((addr & 0x0000FF00) >> 8);
!   dns.ip[3] = (int) ((addr & 0x000000FF));
!   dns.name = NULL;
!   dns.next = NULL;
! 
!   if(!get_host_from_cache(&dns)) { /* cache lookup failed */
!     /* find the sitename */
!     if (nameserver_is_slow || !(from = gethostbyaddr((char *) &peer.sin_addr,
  				      sizeof(peer.sin_addr), AF_INET))) {
  
!       /* resolution failed */
!       if (!nameserver_is_slow)
!         perror("gethostbyaddr");
! 
!       sprintf(newd->host, "%03u.%03u.%03u.%03u",
! 	(int) ((addr & 0xFF000000) >> 24),
! 	(int) ((addr & 0x00FF0000) >> 16), (int) ((addr & 0x0000FF00) >> 8),
! 	(int) ((addr & 0x000000FF)));
! 
!       sprintf(buf, "DNS lookup failed on %s.", newd->host);
!       mudlog(buf, CMP, LVL_GOD, TRUE);
! 
!     } else {
!       strncpy(newd->host, from->h_name, HOST_LENGTH);
!       *(newd->host + HOST_LENGTH) = '\0';
!       add_dns_host(&dns, newd->host);
!     }
    } else {
!     strncpy(newd->host, dns.name, HOST_LENGTH);
    }
  
    /* determine if the site is banned */
    if (isbanned(newd->host) == BAN_ALL) {
!     write_to_descriptor(desc, "Your site is BANNED!\r\n");
!     close(desc);
      sprintf(buf2, "Connection attempt denied from [%s]", newd->host);
      mudlog(buf2, CMP, LVL_GOD, TRUE);
      free(newd);
***************
*** 1035,1041 ****
    /* initialize descriptor data */
    newd->descriptor = desc;
    newd->connected = CON_GET_NAME;
-   newd->idle_tics = 0;
    newd->wait = 1;
    newd->output = newd->small_outbuf;
    newd->bufspace = SMALL_BUFSIZE - 1;
--- 1058,1063 ----
***************
*** 1053,1059 ****
  
    return 0;
  }
- 
  
  
  int process_output(struct descriptor_data *t)
--- 1075,1080 ----
diff -C 3 stk/db.c src/db.c
*** stk/db.c	Thu Apr  3 12:26:52 1997
--- src/db.c	Thu Apr  3 11:35:35 1997
***************
*** 76,81 ****
--- 76,83 ----
  struct help_index_element *help_table = 0;	/* the help table	 */
  int top_of_helpt = 0;		/* top of help index table	 */
  
+ struct dns_entry *dns_cache[DNS_HASH_NUM]; /* for dns caching * dnsmod */
+ 
  struct time_info_data time_info;/* the infomation about the time    */
  struct weather_data weather_info;	/* the infomation about the weather */
  struct player_special_data dummy_mob;	/* dummy spec area for mobs	 */
***************
*** 107,112 ****
--- 109,118 ----
  void log_zone_error(int zone, int cmd_no, char *message);
  void reset_time(void);
  void clear_char(struct char_data * ch);
+ void boot_dns(void); /* dnsmod */
+ void save_dns_cache(void); /* dnsmod */
+ int get_host_from_cache(struct dns_entry *dnsd); /* dnsmod */
+ void add_dns_host(struct dns_entry *dnsd, char *hostname); /* dnsmod */
  
  /* external functions */
  extern struct descriptor_data *descriptor_list;
***************
*** 300,305 ****
--- 306,314 ----
    load_banned();
    Read_Invalid_List();
  
+   log("Booting dns cache."); /* dnsmod */
+   boot_dns();
+ 
    if (!no_rent_check) {
      log("Deleting timed-out crash and rent files:");
      update_obj_file();
***************
*** 2406,2408 ****
--- 2415,2522 ----
        bot = mid + 1;
    }
  }
+ 
+ 
+ /* dnsmod */
+ void boot_dns(void)
+ {
+   int i = 0;
+   char line[256], name[256];
+   FILE *fl;
+   struct dns_entry *dns;
+ 
+   memset((char *) dns_cache, 0, sizeof(struct dns_entry *) * DNS_HASH_NUM);
+ 
+   if(!(fl = fopen(DNS_FILE, "r"))) {
+     log("No DNS cache!");
+     return;
+   }
+ 
+   do {
+     i = 0;
+     get_line(fl, line);
+     if(*line != '~') {
+       CREATE(dns, struct dns_entry, 1);
+       dns->name = NULL;
+       dns->next = NULL;
+       sscanf(line, "%d.%d.%d.%d %s", dns->ip, dns->ip + 1,
+ 	dns->ip + 2, dns->ip + 3, name);
+       dns->name = str_dup(name);
+       i = (dns->ip[0] + dns->ip[1] + dns->ip[2]) % DNS_HASH_NUM;
+       dns->next = dns_cache[i];
+       dns_cache[i] = dns;
+     }
+   } while (!feof(fl) && *line != '~');
+   fclose(fl);
+ }
+ 
+ 
+ /* dnsmod */
+ void save_dns_cache(void)
+ {
+   int i;
+   FILE *fl;
+   struct dns_entry *dns;
+ 
+   if(!(fl = fopen(DNS_FILE, "w"))) {
+     log("SYSERR: Can't open dns cache file for write!");
+     return;
+   }
+ 
+   for(i = 0; i < DNS_HASH_NUM; i++) {
+     if(dns_cache[i]) {
+       for(dns = dns_cache[i]; dns; dns = dns->next)
+ 	fprintf(fl, "%d.%d.%d.%d %s\n", dns->ip[0], dns->ip[1],
+ 	  dns->ip[2], dns->ip[3], dns->name);
+     }
+   }
+   fprintf(fl, "~\n");
+   fclose(fl);
+ }
+ 
+ 
+ /* dnsmod */
+ int get_host_from_cache(struct dns_entry *dnsd)
+ {
+   int i;
+   struct dns_entry *d;
+   char buf[256];
+ 
+   i = (dnsd->ip[0] + dnsd->ip[1] + dnsd->ip[2]) % DNS_HASH_NUM;
+   if(dns_cache[i]) {
+     for(d = dns_cache[i]; d; d = d->next) {
+       if(dnsd->ip[0] == d->ip[0] && dnsd->ip[1] == d->ip[1] &&
+ 	dnsd->ip[2] == d->ip[2]) {
+ 	if(d->ip[3] == -1) {
+ 	  sprintf(buf, "%d.%s", dnsd->ip[3], d->name);
+ 	  dnsd->name = str_dup(buf);
+ 	  return TRUE;
+ 	} else if(dnsd->ip[3] == d->ip[3]) {
+ 	  dnsd->name = str_dup(d->name);
+ 	  return TRUE;
+ 	}
+       }
+     }
+   }
+   return FALSE;
+ }
+ 
+ 
+ /* dnsmod */
+ void add_dns_host(struct dns_entry *dnsd, char *hostname)
+ {
+   int i;
+   struct dns_entry *d;
+ 
+   i = (dnsd->ip[0] + dnsd->ip[1] + dnsd->ip[2]) % DNS_HASH_NUM;
+   CREATE(d, struct dns_entry, 1);
+   d->ip[0] = dnsd->ip[0];
+   d->ip[1] = dnsd->ip[1];
+   d->ip[2] = dnsd->ip[2];
+   d->ip[3] = dnsd->ip[3];
+   d->name = str_dup(hostname);
+   d->next = dns_cache[i];
+   dns_cache[i] = d;
+   save_dns_cache();
+ }
+ 
diff -C 3 stk/db.h src/db.h
*** stk/db.h	Thu Apr  3 12:26:50 1997
--- src/db.h	Thu Apr  3 11:37:38 1997
***************
*** 49,54 ****
--- 49,55 ----
  #define MAIL_FILE	"etc/plrmail"	/* for the mudmail system	*/
  #define BAN_FILE	"etc/badsites"	/* for the siteban system	*/
  #define HCONTROL_FILE	"etc/hcontrol"  /* for the house system		*/
+ #define DNS_FILE	"etc/dns"	/* for the dns cache   * dnsmod */
  
  
  /* public procedures in db.c */
***************
*** 156,161 ****
--- 157,171 ----
     int duplicate;
  };
  
+ 
+ struct dns_entry { /* dnsmod */
+    int ip[4];
+    char *name;
+    struct dns_entry *next;
+ };
+ 
+ /* dnsmod - the magic number for dns caching */
+ #define DNS_HASH_NUM 257
  
  /* don't change these */
  #define BAN_NOT 	0
diff -C 3 stk/interpreter.c src/interpreter.c
*** stk/interpreter.c	Thu Apr  3 12:27:09 1997
--- src/interpreter.c	Thu Apr  3 11:27:40 1997
***************
*** 70,75 ****
--- 70,76 ----
  ACMD(do_dc);
  ACMD(do_diagnose);
  ACMD(do_display);
+ ACMD(do_dns);
  ACMD(do_drink);
  ACMD(do_drop);
  ACMD(do_eat);
***************
*** 259,264 ****
--- 260,266 ----
    { "deposit"  , POS_STANDING, do_not_here , 1, 0 },
    { "diagnose" , POS_RESTING , do_diagnose , 0, 0 },
    { "display"  , POS_DEAD    , do_display  , 0, 0 },
+   { "dns"      , POS_DEAD    , do_dns      , LVL_IMPL, 0 },
    { "donate"   , POS_RESTING , do_drop     , 0, SCMD_DONATE },
    { "drink"    , POS_RESTING , do_drink    , 0, SCMD_DRINK },
    { "drop"     , POS_RESTING , do_drop     , 0, SCMD_DROP },
