Merged console.c into bsd.c with COMPILE_CONSOLE #ifdefs
authorAri Johnson <ari@cobramush.org>
Mon, 9 Apr 2007 17:38:06 +0000 (17:38 +0000)
committerAri Johnson <ari@cobramush.org>
Mon, 9 Apr 2007 17:38:06 +0000 (17:38 +0000)
src/Makefile.SH
src/bsd.c
src/console.c [deleted file]

index c12becfec672d1884ad11f69edc23f7e743f9996..1f53b0f2414ac50eb020a4c2f36ca2d032f3ba44 100644 (file)
@@ -68,7 +68,7 @@ C_FILES=access.c atr_tab.c attrib.c boolexp.c bsd.c bufferq.c \
        myssl.c notify.c parse.c pcre.c player.c plyrlist.c \
        predicat.c privtab.c prog.o ptab.c rob.c rplog.c services.c set.c shs.c  \
        sig.c speech.c sql.c strdup.c strtree.c  strutil.c tables.c timer.c unparse.c  \
-       utils.c version.c warnings.c  wild.c wiz.c console.c
+       utils.c version.c warnings.c  wild.c wiz.c
 
 
 H_FILES = ../config.h ../confmagic.h ../hdrs/ansi.h ../hdrs/atr_tab.h \
@@ -239,6 +239,10 @@ compress.o: comp_h.c comp_w.c comp_w8.c
 version.o: ../hdrs/buildinf.h
 cmds.o: ../hdrs/funs.h ../hdrs/cmds.h
 
+# CobraMUSH no-network console
+console.o:     bsd.c
+       $(CC) $(CFLAGS) -DCOMPILE_CONSOLE -o console.o -c bsd.c
+
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
 access.o: ../config.h
@@ -541,6 +545,45 @@ conf.o: ../hdrs/game.h
 conf.o: ../hdrs/attrib.h
 conf.o: ../hdrs/help.h
 conf.o: ../hdrs/function.h
+console.o: ../hdrs/copyrite.h
+console.o: ../config.h
+console.o: ../hdrs/conf.h
+console.o: ../options.h
+console.o: ../hdrs/mushtype.h
+console.o: ../hdrs/htab.h
+console.o: ../hdrs/externs.h
+console.o: ../hdrs/compile.h
+console.o: ../hdrs/dbdefs.h
+console.o: ../hdrs/mushdb.h
+console.o: ../hdrs/flags.h
+console.o: ../hdrs/ptab.h
+console.o: ../hdrs/division.h
+console.o: ../hdrs/chunk.h
+console.o: ../hdrs/bufferq.h
+console.o: ../confmagic.h
+console.o: ../hdrs/lock.h
+console.o: ../hdrs/boolexp.h
+console.o: ../hdrs/help.h
+console.o: ../hdrs/match.h
+console.o: ../hdrs/ansi.h
+console.o: ../hdrs/pueblo.h
+console.o: ../hdrs/parse.h
+console.o: ../hdrs/access.h
+console.o: ../hdrs/command.h
+console.o: ../hdrs/switches.h
+console.o: ../hdrs/version.h
+console.o: ../hdrs/patches.h
+console.o: ../hdrs/mysocket.h
+console.o: ../hdrs/ident.h
+console.o: ../hdrs/strtree.h
+console.o: ../hdrs/log.h
+console.o: ../hdrs/pcre.h
+console.o: ../hdrs/myssl.h
+console.o: ../hdrs/mymalloc.h
+console.o: ../hdrs/extmail.h
+console.o: ../hdrs/attrib.h
+console.o: ../hdrs/game.h
+console.o: ../hdrs/dbio.h
 cque.o: ../hdrs/copyrite.h
 cque.o: ../config.h
 cque.o: ../hdrs/conf.h
index c904e1a32d6d5abe6c995d9d0d6efe7c5c97a255..2358cdda06ffaedb958136c0d82148dee9c0c62b 100644 (file)
--- a/src/bsd.c
+++ b/src/bsd.c
 #undef INFO_SLAVE
 #endif
 
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
 #include <sys/uio.h>
 #endif
+#endif
 
 #include "externs.h"
 #include "chunk.h"
 #include "strtree.h"
 #include "log.h"
 #include "pcre.h"
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
 #include "myssl.h"
 #endif
+#endif
 #include "mymalloc.h"
 #include "extmail.h"
 #include "attrib.h"
@@ -174,10 +178,12 @@ char errlog[BUFFER_LEN];  /**< Name of the error log file */
 
 /* Default Connection flags for certain clients
  */
+#ifndef COMPILE_CONSOLE
 static CLIENT_DEFAULTS client_maps[]  = {
   {"TINYFUGUE", CONN_PROMPT},
   {NULL, -1}
 };
+#endif
 
 
 /** Is this descriptor connected to a telnet-compatible terminal? */
@@ -205,6 +211,7 @@ static CLIENT_DEFAULTS client_maps[]  = {
  */
 
 /* Telnet codes */
+#ifndef COMPILE_CONSOLE
 #define IAC            255     /**< interpret as command: */
 #define GOAHEAD                249     /**< Go Ahead command */
 #define NOP            241     /**< no operation */
@@ -222,6 +229,7 @@ static CLIENT_DEFAULTS client_maps[]  = {
 static void test_telnet(DESC *d);
 static void setup_telnet(DESC *d);
 static int handle_telnet(DESC *d, unsigned char **q, unsigned char *qend);
+#endif /* COMPILE_CONSOLE */
 static const char *empabb(dbref);
 static int do_su_exit(DESC *d);
 
@@ -233,10 +241,12 @@ static const char *register_fail =
 static const char *register_success =
   "Registration successful! You will receive your password by email.";
 static const char *shutdown_message = "Going down - Bye";
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
 static const char *ssl_shutdown_message = 
   "GAME: SSL connections must be dropped, sorry.";
 #endif
+#endif
 /** Where we save the descriptor info across reboots. */
 #define REBOOTFILE              "reboot.db"
 
@@ -262,20 +272,23 @@ dummy_msgs()
 
 DESC *descriptor_list = NULL;  /**< The linked list of descriptors */
 
+#ifndef COMPILE_CONSOLE
 static int sock;
 #ifdef HAS_OPENSSL
 static int sslsock = 0;
 SSL *ssl_master_socket = NULL; /**< Master SSL socket for ssl port */
 #endif
-static int ndescriptors = 0;
 #ifdef WIN32
 static WSADATA wsadata;
 #endif
-int restarting = 0;    /**< Are we restarting the server after a reboot? */
 static int maxd = 0;
+#endif /* COMPILE_CONSOLE */
+int restarting = 0;    /**< Are we restarting the server after a reboot? */
+static int ndescriptors = 0;
 
 extern const unsigned char *tables;
 
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
 static fd_set info_pending;
 static int info_slave;
@@ -284,6 +297,7 @@ int info_slave_state = 0;   /**< State of the info_slave process */
 static int info_query_spill, info_reap_spill;
 static time_t info_queue_time = 0;
 #endif
+#endif
 
 sig_atomic_t signal_shutdown_flag = 0; /**< Have we caught a shutdown signal? */
 sig_atomic_t signal_dump_flag = 0;     /**< Have we caught a dump signal? */
@@ -313,12 +327,16 @@ static long int msec_diff(struct timeval *now, struct timeval *then);
 static struct timeval *msec_add(struct timeval *t, int x);
 static void update_quotas(struct timeval *last, struct timeval *current);
 
+#ifdef COMPILE_CONSOLE
+static void shovechars(void);
+#else /* COMPILE_CONSOLE */
 static int how_many_fds(void);
 static void shovechars(Port_t port, Port_t sslport);
 static int test_connection(int newsock);
 #ifndef INFO_SLAVE
 static DESC *new_connection(int oldsock, int *result, int use_ssl);
 #endif
+#endif /* COMPILE_CONSOLE */
 
 static void clearstrings(DESC *d);
 
@@ -556,8 +574,10 @@ main(int argc, char **argv)
 
   set_signals();
 
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
   make_info_slave();
+#endif
 #endif
 
   /* go do it */
@@ -571,7 +591,11 @@ main(int argc, char **argv)
 #endif
   load_reboot_db();
 
+#ifdef COMPILE_CONSOLE
+  shovechars();
+#else
   shovechars((Port_t) TINYPORT, (Port_t) SSLPORT);
+#endif
 #ifdef CSRI
 #ifdef CSRI_DEBUG
   mal_verify(1);
@@ -594,9 +618,11 @@ main(int argc, char **argv)
   close_sockets();
   sql_shutdown();
 
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
   kill_info_slave();
 #endif
+#endif
 
 #ifdef WIN32SERVICES
   /* Keep service manager happy */
@@ -634,7 +660,9 @@ main(int argc, char **argv)
 
   do_rawlog(LT_ERR, T("MUSH shutdown completed."));
 
+#ifndef COMPILE_CONSOLE
   closesocket(sock);
+#endif
 #ifdef WIN32
 #ifdef WIN32SERVICES
   shutdown_checkpoint();
@@ -856,7 +884,11 @@ bad_empabb_value:
 
 
 static void
+#ifdef COMPILE_CONSOLE
+shovechars()
+#else
 shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
+#endif
 {
   /* this is the main game loop */
 
@@ -868,6 +900,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
   int found;
   int queue_timeout;
   DESC *d, *dnext;
+#ifndef COMPILE_CONSOLE
 #ifndef INFO_SLAVE
   DESC *newd;
   int result;
@@ -878,8 +911,12 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
   socklen_t addr_len;
   int newsock;
 #endif
+#endif /* COMPILE_CONSOLE */
   unsigned long input_ready, output_ready;
 
+#ifdef COMPILE_CONSOLE
+  d = initializesock(0, "localhost", "127.0.0.1", 0);
+#else
   if (!restarting) {
     sock = make_socket(port, NULL, NULL, MUSH_IP_ADDR);
     if (sock >= maxd)
@@ -893,8 +930,10 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
     }
 #endif
   }
+#endif /* COMPILE_CONSOLE */
   our_gettimeofday(&last_slice);
 
+#ifndef COMPILE_CONSOLE
   avail_descriptors = how_many_fds() - 4;
 #ifdef INFO_SLAVE
   avail_descriptors -= 2;      /* reserve some more for setting up the slave */
@@ -903,6 +942,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
 
   /* done. print message to the log */
   do_rawlog(LT_ERR, "%d file descriptors available.", avail_descriptors);
+#endif /* COMPILE_CONSOLE */
   do_rawlog(LT_ERR, "RESTART FINISHED.");
 
   our_gettimeofday(&then);
@@ -970,6 +1010,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
 
     FD_ZERO(&input_set);
     FD_ZERO(&output_set);
+#ifndef COMPILE_CONSOLE
     if (ndescriptors < avail_descriptors)
       FD_SET(sock, &input_set);
 #ifdef HAS_OPENSSL
@@ -980,17 +1021,37 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
     if (info_slave_state > 0)
       FD_SET(info_slave, &input_set);
 #endif
+#endif /* COMPILE_CONSOLE */
     for (d = descriptor_list; d; d = d->next) {
       if (d->input.head) {
        timeout.tv_sec = slice_timeout.tv_sec;
        timeout.tv_usec = slice_timeout.tv_usec;
+#ifdef COMPILE_CONSOLE
+      } else {
+       if(d->descriptor == 0)
+         FD_SET(STDIN_FILENO, &input_set);
+       else
+         FD_SET(d->descriptor, &input_set);
+      }
+      if (d->output.head) {
+       if(d->descriptor == 0)
+         FD_SET(STDOUT_FILENO, &output_set);
+       else
+         FD_SET(d->descriptor, &output_set);
+      }
+#else /* COMPILE_CONSOLE */
       } else
        FD_SET(d->descriptor, &input_set);
       if (d->output.head)
        FD_SET(d->descriptor, &output_set);
+#endif /* COMPILE_CONSOLE */
     }
 
+#ifdef COMPILE_CONSOLE
+    found = select(2, &input_set, &output_set, (fd_set *) 0, &timeout);
+#else
     found = select(maxd, &input_set, &output_set, (fd_set *) 0, &timeout);
+#endif
     if (found < 0) {
 #ifdef WIN32
       if (found == SOCKET_ERROR && WSAGetLastError() != WSAEINTR)
@@ -1001,6 +1062,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
        perror("select");
        return;
       }
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
       now = mudtime;
       if (info_slave_state == 2 && now > info_queue_time + 30) {
@@ -1011,6 +1073,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
            query_info_slave(newsock);
       }
 #endif
+#endif /* COMPILE_CONSOLE */
     } else {
       /* if !found then time for robot commands */
 
@@ -1021,6 +1084,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
        do_top(options.active_q_chunk);
       }
       now = mudtime;
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
       if (info_slave_state > 0 && FD_ISSET(info_slave, &input_set)) {
        if (info_slave_state == 1)
@@ -1086,8 +1150,33 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
       }
 #endif
 #endif
+#endif /* COMPILE_CONSOLE */
       for (d = descriptor_list; d; d = dnext) {
        dnext = d->next;
+#ifdef COMPILE_CONSOLE
+       if (d->descriptor == 0) {
+         input_ready = FD_ISSET(STDIN_FILENO, &input_set);
+         output_ready = FD_ISSET(STDOUT_FILENO, &output_set);
+       } else {
+         input_ready = FD_ISSET(d->descriptor, &input_set);
+         output_ready = FD_ISSET(d->descriptor, &output_set);
+       }
+       if (input_ready) {
+         if (!process_input(d, output_ready)) {
+           shutdownsock(d);
+           if(d->descriptor == 0)
+             return;
+           continue;
+         }
+       }
+       if (output_ready) {
+         if (!process_output(d)) {
+           shutdownsock(d);
+           if (d->descriptor == 0)
+             return;
+         }
+       }
+#else /* COMPILE_CONSOLE */
        input_ready = FD_ISSET(d->descriptor, &input_set);
        output_ready = FD_ISSET(d->descriptor, &output_set);
        if (input_ready) {
@@ -1101,11 +1190,13 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
            shutdownsock(d);
          }
        }
+#endif /* COMPILE_CONSOLE */
       }
     }
   }
 }
 
+#ifndef COMPILE_CONSOLE
 static int
 test_connection(int newsock)
 {
@@ -1121,7 +1212,6 @@ test_connection(int newsock)
   return newsock;
 }
 
-
 #ifndef INFO_SLAVE
 static DESC *
 new_connection(int oldsock, int *result, int use_ssl)
@@ -1183,6 +1273,7 @@ new_connection(int oldsock, int *result, int use_ssl)
   return initializesock(newsock, tbuf1, tbuf2, use_ssl);
 }
 #endif
+#endif /* COMPILE_CONSOLE */
 
 static void
 clearstrings(DESC *d)
@@ -1442,6 +1533,10 @@ static void
 shutdownsock(DESC *d)
 {
   char tbuf1[BUFFER_LEN];
+#ifdef COMPILE_CONSOLE
+  int i;
+#endif
+
   if (d->connected) {
     do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Logout by %s(#%d)"),
           d->descriptor, d->addr, d->ip, Name(d->player), d->player);
@@ -1474,6 +1569,68 @@ shutdownsock(DESC *d)
   }
   process_output(d);
   clearstrings(d);
+#ifdef COMPILE_CONSOLE
+  if (d->descriptor != 0) {
+    shutdown(d->descriptor, 2);
+    closesocket(d->descriptor);
+  } else {
+    freeqs(d);
+    d->input_handler = do_command;
+    d->connected = 0;
+    d->connected_at = mudtime;
+    d->output_prefix = 0;
+    d->output_suffix = 0;
+    d->output_size = 0;
+    d->output.head = 0;
+    d->player = 0;
+    d->output.tail = &d->output.head;
+    d->input.head = 0;
+    d->input.tail = &d->input.head;
+    d->raw_input = 0;
+    d->raw_input_at = 0;
+    d->quota = COMMAND_BURST_SIZE;
+    d->last_time = mudtime;
+    d->idle_total = 0;
+    d->unidle_times = 0;
+    d->cmds = 0;
+    d->hide = 0;
+    d->doing[0] = '\0';
+    d->mailp = NULL;
+    strncpy(d->addr, "localhost", 100);
+    d->addr[99] = '\0';
+    strncpy(d->ip, "127.0.0.1", 100);
+    d->ip[99] = '\0';
+    d->conn_flags = CONN_DEFAULT;
+    d->input_chars = 0;
+    d->output_chars = 0;
+    d->ttype = mush_strdup("unknown", "terminal description");
+    d->checksum[0] = '\0';
+    d->su_exit_path = NULL;
+    d->pinfo.object = NOTHING;
+    d->pinfo.atr = NULL;
+    d->pinfo.lock = 0;
+    d->pinfo.function = NULL;
+    d->width = 78;
+    d->height = 24;
+    welcome_user(d);
+    for (i = 0; i < MAX_SNOOPS; i++)
+      d->snooper[i] = -1;
+  }
+  if (d->descriptor != 0) {
+    if (d->prev)
+      d->prev->next = d->next;
+    else                               /* d was the first one! */
+      descriptor_list = d->next;
+    if (d->next)
+      d->next->prev = d->prev;
+  }
+
+  if(d->descriptor != 0) {
+    freeqs(d);
+    mush_free(d->ttype, "terminal description");
+    mush_free((Malloc_t) d, "descriptor");
+  }
+#else /* COMPILE_CONSOLE */
   shutdown(d->descriptor, 2);
   closesocket(d->descriptor);
   if (d->prev)
@@ -1495,6 +1652,7 @@ shutdownsock(DESC *d)
     mush_free(d->ttype, "terminal description");
     mush_free((Malloc_t) d, "descriptor");
   }
+#endif /* COMPILE_CONSOLE */
 
   ndescriptors--;
 }
@@ -1547,9 +1705,11 @@ initializesock(int s, char *addr, char *ip, int use_ssl
   d->pinfo.atr = NULL;
   d->pinfo.lock = 0;
   d->pinfo.function = NULL;
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   d->ssl = NULL;
   d->ssl_state = 0;
+#endif
 #endif
   if (descriptor_list)
     descriptor_list->prev = d;
@@ -1558,6 +1718,7 @@ initializesock(int s, char *addr, char *ip, int use_ssl
   descriptor_list = d;
   d->width = 78;
   d->height = 24;
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   if (use_ssl && sslsock) {
     d->ssl = ssl_listen(d->descriptor, &d->ssl_state);
@@ -1570,12 +1731,14 @@ initializesock(int s, char *addr, char *ip, int use_ssl
   }
 #endif
   test_telnet(d);
+#endif /* COMPILE_CONSOLE */
   welcome_user(d);
   for(n = 0; n < MAX_SNOOPS; n++)
     d->snooper[n] = -1;
   return d;
 }
 
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
 static void
 make_info_slave(void)
@@ -1958,6 +2121,7 @@ kill_info_slave(void)
   }
 }
 #endif
+#endif /* COMPILE_CONSOLE */
 
 
 
@@ -1973,6 +2137,7 @@ process_output(DESC *d)
 {
   struct text_block **qp, *cur;
   int cnt;
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   int input_ready = 0;
 #endif
@@ -2026,8 +2191,14 @@ process_output(DESC *d)
     }
   }
 #endif
+#endif /* COMPILE_CONSOLE */
 
   for (qp = &d->output.head; ((cur = *qp) != NULL);) {
+#ifdef COMPILE_CONSOLE
+    if (d->descriptor == 0)
+      cnt = write(STDOUT_FILENO, cur->start, cur->nchars);
+    else
+#else /* COMPILE_CONSOLE */
 #ifdef HAS_OPENSSL
     if (d->ssl) {
       cnt = 0;
@@ -2037,6 +2208,7 @@ process_output(DESC *d)
        return 1;               /* Need to retry */
     } else {
 #endif
+#endif /* COMPILE_CONSOLE */
       cnt = send(d->descriptor, cur->start, cur->nchars, 0);
       if (cnt < 0) {
 #ifdef WIN32
@@ -2051,8 +2223,10 @@ process_output(DESC *d)
          return 1;
        return 0;
       }
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
     }
+#endif
 #endif
     d->output_size -= cnt;
     d->output_chars += cnt;
@@ -2088,6 +2262,7 @@ save_command(DESC *d, const unsigned char *command)
   add_to_queue(&d->input, command, u_strlen(command) + 1);
 }
 
+#ifndef COMPILE_CONSOLE
 static void
 test_telnet(DESC *d)
 {
@@ -2328,6 +2503,7 @@ handle_telnet(DESC *d, unsigned char **q, unsigned char *qend)
   }
   return 1;
 }
+#endif /* COMPILE_CONSOLE */
 
 static void
 process_input_helper(DESC *d, char *tbuf1, int got)
@@ -2365,6 +2541,7 @@ process_input_helper(DESC *d, char *tbuf1, int got)
     } else if (*q == '\b') {
       if (p > d->raw_input)
        p--;
+#ifndef COMPILE_CONSOLE
     } else if ((unsigned char) *q == IAC) {    /* Telnet option foo */
       if (q >= qend)
        break;
@@ -2373,6 +2550,7 @@ process_input_helper(DESC *d, char *tbuf1, int got)
        if (p < pend && isprint(*q))
          *p++ = *q;
       }
+#endif /* COMPILE_CONSOLE */
     } else if (p < pend && isprint(*q)) {
       *p++ = *q;
     }
@@ -2395,6 +2573,7 @@ process_input(DESC *d, int output_ready __attribute__ ((__unused__)))
 
   errno = 0;
 
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   if (d->ssl) {
     /* Insure that we're not in a state where we need an SSL_handshake() */
@@ -2438,7 +2617,16 @@ process_input(DESC *d, int output_ready __attribute__ ((__unused__)))
     }
   } else {
 #endif
+#endif /* COMPILE_CONSOLE */
+
+#ifdef COMPILE_CONSOLE
+    if (d->descriptor == 0)
+      got = read(STDIN_FILENO, tbuf1, sizeof tbuf1);
+    else
+      got = recv(d->descriptor, tbuf1, sizeof tbuf1, 0);
+#else /* COMPILE_CONSOLE */
     got = recv(d->descriptor, tbuf1, sizeof tbuf1, 0);
+#endif /* COMPILE_CONSOLE */
     if (got <= 0) {
       /* At this point, select() says there's data waiting to be read from
        * the socket, but we shouldn't assume that read() will actually get it
@@ -2453,8 +2641,10 @@ process_input(DESC *d, int output_ready __attribute__ ((__unused__)))
       else
        return 0;
     }
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   }
+#endif
 #endif
 
   process_input_helper(d, tbuf1, got);
@@ -2956,6 +3146,18 @@ close_sockets(void)
 
   for (d = descriptor_list; d; d = dnext) {
     dnext = d->next;
+#ifdef COMPILE_CONSOLE
+    if(d->descriptor == 0) {
+      write(STDOUT_FILENO, T(shutdown_message), strlen(T(shutdown_message)));
+      write(STDOUT_FILENO, "\r\n", 2);
+    } else {
+      send(d->descriptor, T(shutdown_message), strlen(T(shutdown_message)), 0);
+      send(d->descriptor, "\r\n", 2, 0);
+      if (shutdown(d->descriptor, 2) < 0)
+       perror("shutdown");
+      closesocket(d->descriptor);
+    }
+#else /* COMPILE_CONSOLE */
     send(d->descriptor, T(shutdown_message), strlen(T(shutdown_message)), 0);
     send(d->descriptor, "\r\n", 2, 0);
 #ifdef HAS_OPENSSL
@@ -2968,6 +3170,7 @@ close_sockets(void)
     if (shutdown(d->descriptor, 2) < 0)
       perror("shutdown");
     closesocket(d->descriptor);
+#endif /* COMPILE_CONSOLE */
   }
 }
 
@@ -3185,12 +3388,14 @@ reaper(int sig __attribute__ ((__unused__)))
   while ((pid = wait3(&my_stat, WNOHANG, 0)) > 0)
 #endif
   {
+#ifndef COMPILE_CONSOLE
 #ifdef INFO_SLAVE
     if (info_slave_pid > -1 && pid == info_slave_pid) {
       do_rawlog(LT_ERR, T("info_slave on pid %d exited!"), pid);
       info_slave_state = 0;
       info_slave_pid = -1;
     } else
+#endif
 #endif
     if (forked_dump_pid > -1 && pid == forked_dump_pid) {
       /* Most failures are handled by the forked mush already */
@@ -3317,11 +3522,15 @@ dump_users(DESC *call_by, char *match, int doing)
                time_format_1(now - d->connected_at),
                time_format_2(now - d->last_time), csite ? d->cmds : 0,
                csite ? d->descriptor : 0,
+#ifdef COMPILE_CONSOLE
+               ' ',
+#else /* COMPILE_CONSOLE */
 #ifdef HAS_OPENSSL
                d->ssl ? 'S' : ' ',
 #else
                ' ',
 #endif
+#endif /* COMPILE_CONSOLE */
                csite ? d->addr : "---");
        tbuf1[78] = '\0';
        if (Dark(d->player)) {
@@ -3339,11 +3548,15 @@ dump_users(DESC *call_by, char *match, int doing)
                time_format_1(now - d->connected_at),
                time_format_2(now - d->last_time), csite ? d->cmds : 0,
                csite ? d->descriptor : 0,
+#ifdef COMPILE_CONSOLE
+               ' ',
+#else /* COMPILE_CONSOLE */
 #ifdef HAS_OPENSSL
                d->ssl ? 'S' : ' ',
 #else
                ' ',
 #endif
+#endif /* COMPILE_CONSOLE */
 
                csite ? d->input_chars : 0, csite ? d->output_chars : 0,
                csite ? d->output_size : 0);
@@ -3382,11 +3595,15 @@ dump_users(DESC *call_by, char *match, int doing)
                "#-1",
                time_format_1(now - d->connected_at),
                time_format_2(now - d->last_time), d->cmds, d->descriptor,
+#ifdef COMPILE_CONSOLE
+                             ' ',
+#else /* COMPILE_CONSOLE */
                #ifdef HAS_OPENSSL
                              d->ssl ? 'S' : ' ',
                #else
                              ' ',
                #endif
+#endif /* COMPILE_CONSOLE */
 
                d->addr);
        tbuf1[78] = '\0';
@@ -3396,11 +3613,15 @@ dump_users(DESC *call_by, char *match, int doing)
                T("Connecting..."), "#-1",
                time_format_1(now - d->connected_at),
                time_format_2(now - d->last_time), d->cmds, d->descriptor,
+#ifdef COMPILE_CONSOLE
+                             ' ',
+#else /* COMPILE_CONSOLE */
                #ifdef HAS_OPENSSL
                              d->ssl ? 'S' : ' ',
                #else
                              ' ',
                #endif
+#endif /* COMPILE_CONSOLE */
                d->input_chars, d->output_chars, d->output_size);
       }
 #ifdef COLOREDWHO
@@ -3860,6 +4081,7 @@ visible_short_page(dbref player, const char *match)
 
 /* LWHO() function - really belongs elsewhere but needs stuff declared here */
 
+/* ARGSUSED */
 FUNCTION(fun_nwho) {
   DESC *d;
   int count = 0;
@@ -4258,6 +4480,9 @@ FUNCTION(fun_ssl)
   /* Return the status of the ssl flag on the least idle descriptor we
    * find that matches the player's dbref.
    */
+#ifdef COMPILE_CONSOLE
+  safe_boolean(0, buff, bp);
+#else /* COMPILE_CONSOLE */
 #ifdef HAS_OPENSSL
   DESC *match;
   if (!sslsock) {
@@ -4275,6 +4500,7 @@ FUNCTION(fun_ssl)
 #else
   safe_boolean(0, buff, bp);
 #endif
+#endif /* COMPILE_CONSOLE */
 }
 
 FUNCTION(fun_width)
@@ -4315,9 +4541,11 @@ FUNCTION(fun_terminfo)
        safe_str(" pueblo", buff, bp);
       if (match->conn_flags & CONN_TELNET)
        safe_str(" telnet", buff, bp);
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
       if (sslsock && match->ssl)
        safe_str(" ssl", buff, bp);
+#endif
 #endif
     } else
       safe_str(T(e_perm), buff, bp);
@@ -4709,6 +4937,12 @@ f_close(stream)
 #define fclose(x) f_close(x)
 #endif                         /* SUN_OS */
 
+#ifdef COMPILE_CONSOLE
+void
+close_ssl_connections(void)
+{
+}
+#else /* COMPILE_CONSOLE */
 static int
 how_many_fds(void)
 {
@@ -4802,6 +5036,7 @@ close_ssl_connections(void)
   options.ssl_port = 0;
 }
 #endif
+#endif /* COMPILE_CONSOLE */
 
 
 /** Dump the descriptor list to our REBOOTFILE so we can restore it on reboot.
@@ -4827,8 +5062,13 @@ dump_reboot_db(void)
     }
     /* Write out the reboot db flags here */
     fprintf(f, "V%ld\n", flags);
+#ifdef COMPILE_CONSOLE
+    putref(f, 0);
+    putref(f, 0);
+#else /* COMPILE_CONSOLE */
     putref(f, sock);
     putref(f, maxd);
+#endif /* COMPILE_CONSOLE */
     /* First, iterate through all descriptors to get to the end
      * we do this so the descriptor_list isn't reversed on reboot
      */
@@ -4911,10 +5151,15 @@ load_reboot_db(void)
     ungetc(c, f);
   }
 
+#ifdef COMPILE_CONSOLE
+  val = getref(f);
+  val = getref(f);
+#else /* COMPILE_CONSOLE */
   sock = getref(f);
   val = getref(f);
   if (val > maxd)
     maxd = val;
+#endif /* COMPILE_CONSOLE */
 
   while ((val = getref(f)) != 0) {
     ndescriptors++;
@@ -4991,9 +5236,11 @@ load_reboot_db(void)
     d->raw_input_at = NULL;
     d->quota = options.starting_quota;
     d->mailp = NULL;
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
     d->ssl = NULL;
     d->ssl_state = 0;
+#endif
 #endif
     if (d->conn_flags & CONN_CLOSE_READY) {
       /* This isn't really an open descriptor, we're just tracking
@@ -5048,6 +5295,7 @@ load_reboot_db(void)
   DESC_ITER_CONN(d) {
     d->mailp = find_exact_starting_point(d->player);
   }
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   if (SSLPORT) {
     sslsock = make_socket(SSLPORT, NULL, NULL, SSL_IP_ADDR);
@@ -5055,6 +5303,7 @@ load_reboot_db(void)
     if (sslsock >= maxd)
       maxd = sslsock + 1;
   }
+#endif
 #endif
 
   fclose(f);
@@ -5240,8 +5489,12 @@ COMMAND(cmd_su) {
        if ((d->player == player) && (!match || (d->last_time > match->last_time))) 
          match = d;
       /* We're only entering using a password at this moment */
+#ifdef COMPILE_CONSOLE
+       queue_newwrite(match, (unsigned char *) T("Password: "), 13);
+#else /* COMPILE_CONSOLE */
        queue_newwrite(match, (unsigned char *) tprintf(T("Password: %c%c"),
                                                        IAC, GOAHEAD), 13);
+#endif /* COMPILE_CONSOLE */
        if(!PromptConnection(match))
          queue_newwrite(match, (unsigned char *) "\r\n", 3);
 
@@ -5292,8 +5545,12 @@ COMMAND(cmd_su) {
          notify(player, T("Your HAVEN flag is set.  You cannot receive pages."));
       } else {
        /* Part 3b.  Put guy in password program */
+#ifdef COMPILE_CONSOLE
+       queue_newwrite(match, (unsigned char *) T("Password: "), 13);
+#else /* COMPILE_CONSOLE */
        queue_newwrite(match, (unsigned char *) tprintf(T("Password: %c%c"),
                                                        IAC, GOAHEAD), 13);
+#endif /* COMPILE_CONSOLE */
        if(!PromptConnection(match))
          queue_newwrite(match, (unsigned char *) "\r\n", 3);
 
diff --git a/src/console.c b/src/console.c
deleted file mode 100644 (file)
index 07c9588..0000000
+++ /dev/null
@@ -1,4526 +0,0 @@
-/**
- * \file console.c
- *
- * \brief Alternative main function for PennMUSH which runs on the console
- * instead of over the network.
- */
-
-#include "copyrite.h"
-#include "config.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-#ifdef I_SYS_TYPES
-#include <sys/types.h>
-#endif
-#ifdef WIN32
-#define FD_SETSIZE 256
-#include <windows.h>
-#include <winsock.h>
-#include <io.h>
-#define EINTR WSAEINTR
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define MAXHOSTNAMELEN 32
-#define LC_MESSAGES 6
-#else                          /* !WIN32 */
-#ifdef I_SYS_FILE
-#include <sys/file.h>
-#endif
-#ifdef I_SYS_TIME
-#include <sys/time.h>
-#endif
-#include <sys/ioctl.h>
-#include <errno.h>
-#ifdef I_SYS_SOCKET
-#include <sys/socket.h>
-#endif
-#ifdef I_NETINET_IN
-#include <netinet/in.h>
-#endif
-#ifdef I_NETDB
-#include <netdb.h>
-#endif
-#ifdef I_SYS_PARAM
-#include <sys/param.h>
-#endif
-#ifdef I_SYS_STAT
-#include <sys/stat.h>
-#endif
-#endif                         /* !WIN32 */
-#include <time.h>
-#ifdef I_SYS_WAIT
-#include <sys/wait.h>
-#endif
-#include <fcntl.h>
-#include <ctype.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#ifdef I_SYS_SELECT
-#include <sys/select.h>
-#endif
-#ifdef I_UNISTD
-#include <unistd.h>
-#endif
-#ifdef HAS_GETRLIMIT
-#include <sys/resource.h>
-#endif
-#include <limits.h>
-#ifdef I_FLOATINGPOINT
-#include <floatingpoint.h>
-#endif
-#include <locale.h>
-#ifdef __APPLE__
-#define LC_MESSAGES     6
-#define AUTORESTART
-#endif
-#include <setjmp.h>
-
-#include "conf.h"
-
-#include "externs.h"
-#include "chunk.h"
-#include "mushdb.h"
-#include "dbdefs.h"
-#include "flags.h"
-#include "lock.h"
-#include "help.h"
-#include "match.h"
-#include "ansi.h"
-#include "pueblo.h"
-#include "parse.h"
-#include "access.h"
-#include "command.h"
-#include "version.h"
-#include "patches.h"
-#include "mysocket.h"
-#include "ident.h"
-#include "strtree.h"
-#include "log.h"
-#include "pcre.h"
-#include "mymalloc.h"
-#include "extmail.h"
-#include "attrib.h"
-#include "game.h"
-#include "dbio.h"
-#include "confmagic.h"
-#ifdef HAS_WAITPID
-/** What does wait*() return? */
-#define WAIT_TYPE int
-#else
-#ifdef UNION_WAIT
-#define WAIT_TYPE union wait
-#else
-#define WAIT_TYPE int
-#endif
-#endif
-
-
-/* BSD 4.2 and maybe some others need these defined */
-#ifndef FD_ZERO
-/** An fd_set is 4 bytes */
-#define fd_set int
-/** Clear an fd_set */
-#define FD_ZERO(p)       (*p = 0)
-/** Set a bit in an fd_set */
-#define FD_SET(n,p)      (*p |= (1<<(n)))
-/** Clear a bit in an fd_set */
-#define FD_CLR(n,p)      (*p &= ~(1<<(n)))
-/** Check a bit in an fd_set */
-#define FD_ISSET(n,p)    (*p & (1<<(n)))
-#endif                         /* defines for BSD 4.2 */
-
-#ifdef HAS_GETRUSAGE
-void rusage_stats(void);
-#endif
-int que_next(void);            /* from cque.c */
-
-void dispatch(void);           /* from timer.c */
-dbref email_register_player(const char *name, const char *email, const char *host, const char *ip);    /* from player.c */
-
-static int extrafd;
-int shutdown_flag = 0;         /**< Is it time to shut down? */
-#ifdef CHAT_SYSTEM
-void chat_player_announce(dbref player, char *msg, int ungag);
-#endif /* CHAT_SYSTEM */
-
-static int login_number = 0;
-static int under_limit = 1;
-
-char cf_motd_msg[BUFFER_LEN];  /**< The message of the day */
-char cf_downmotd_msg[BUFFER_LEN];      /**< The down message */
-char cf_fullmotd_msg[BUFFER_LEN];      /**< The 'mush full' message */
-static char poll_msg[DOING_LEN];
-char confname[BUFFER_LEN];     /**< Name of the config file */
-char errlog[BUFFER_LEN];       /**< Name of the error log file */
-
-/* Default Connection flags for certain clients
- */
-static CLIENT_DEFAULTS client_maps[]  = {
-  {"TINYFUGUE", CONN_PROMPT},
-  {NULL, -1}
-};
-
-
-/** Is this descriptor connected to a telnet-compatible terminal? */
-#define TELNET_ABLE(d) ((d)->conn_flags & (CONN_TELNET | CONN_TELNET_QUERY))
-
-
-/* When the mush gets a new connection, it tries sending a telnet
- * option negotiation code for setting client-side line-editing mode
- * to it. If it gets a reply, a flag in the descriptor struct is
- * turned on indicated telnet-awareness.
- * 
- * If the reply indicates that the client supports linemode, further
- * instructions as to what linemode options are to be used is sent.
- * Those options: Client-side line editing, and expanding literal
- * client-side-entered tabs into spaces.
- * 
- * Option negotation requests sent by the client are processed,
- * with the only one we confirm rather than refuse outright being
- * suppress-go-ahead, since a number of telnet clients try it.
- *
- * The character 255 is the telnet option escape character, so when it
- * is sent to a telnet-aware client by itself (Since it's also often y-umlaut)
- * it must be doubled to escape it for the client. This is done automatically,
- * and is the original purpose of adding telnet option support.
- */
-
-/* Telnet codes */
-#define IAC            255     /**< interpret as command: */
-#define GOAHEAD                249     /**< Go Ahead command */
-#define NOP            241     /**< no operation */
-#define AYT            246     /**< are you there? */
-#define DONT           254     /**< you are not to use option */
-#define DO             253     /**< please, you use option */
-#define WONT           252     /**< I won't use option */
-#define WILL           251     /**< I will use option */
-#define SB             250     /**< interpret as subnegotiation */
-#define SE             240     /**< end sub negotiation */
-#define TN_SGA         3       /**< Suppress go-ahead */
-#define TN_LINEMODE    34      /**< Line mode */
-#define TN_NAWS                31      /**< Negotiate About Window Size */
-#define TN_TTYPE       24      /**< Ask for termial type information */
-static void test_telnet(DESC *d);
-static void setup_telnet(DESC *d);
-static int handle_telnet(DESC *d, unsigned char **q, unsigned char *qend);
-static const char *empabb(dbref);
-static int do_su_exit(DESC *d);
-
-static const char *create_fail =
-  "Either there is already a player with that name, or that name is illegal.";
-static const char *password_fail = "The password is invalid (or missing).";
-static const char *register_fail =
-  "Unable to register that player with that email address.";
-static const char *register_success =
-  "Registration successful! You will receive your password by email.";
-static const char *shutdown_message = "Going down - Bye";
-/** Where we save the descriptor info across reboots. */
-#define REBOOTFILE              "reboot.db"
-
-#if 0
-/* For translation */
-static void dummy_msgs(void);
-static void
-dummy_msgs()
-{
-  char *temp;
-  temp = T("Either that player does not exist, or has a different password.");
-  temp =
-    T
-    ("Either there is already a player with that name, or that name is illegal.");
-  temp = T("The password is invalid (or missing).");
-  temp = T("Unable to register that player with that email address.");
-  temp = T("Registration successful! You will receive your password by email.");
-  temp = T("Going down - Bye");
-  temp = T("GAME: SSL connections must be dropped, sorry.");
-}
-
-#endif
-
-DESC *descriptor_list = NULL;  /**< The linked list of descriptors */
-
-#ifdef WIN32
-static WSADATA wsadata;
-#endif
-int restarting = 0;    /**< Are we restarting the server after a reboot? */
-int ndescriptors = 0;
-
-extern const unsigned char *tables;
-
-sig_atomic_t signal_shutdown_flag = 0; /**< Have we caught a shutdown signal? */
-sig_atomic_t signal_dump_flag = 0;     /**< Have we caught a dump signal? */
-
-#ifdef HAS_GETRLIMIT
-static void init_rlimit(void);
-#endif
-#ifndef BOOLEXP_DEBUGGING
-#ifdef WIN32SERVICES
-void shutdown_checkpoint(void);
-void mainthread(int argc, char **argv);
-#else
-int main(int argc, char **argv);
-#endif
-#endif
-void set_signals(void);
-static struct timeval *timeval_sub(struct timeval *now, struct timeval *then);
-#ifdef WIN32
-/** Windows doesn't have gettimeofday(), so we implement it here */
-#define our_gettimeofday(now) win_gettimeofday((now))
-static void win_gettimeofday(struct timeval *now);
-#else
-/** A wrapper for gettimeofday() in case the system doesn't have it */
-#define our_gettimeofday(now) gettimeofday((now), (struct timezone *)NULL)
-#endif
-static long int msec_diff(struct timeval *now, struct timeval *then);
-static struct timeval *msec_add(struct timeval *t, int x);
-static void update_quotas(struct timeval *last, struct timeval *current);
-
-static void shovechars(void);
-
-static void clearstrings(DESC *d);
-
-/** A block of cached text. */
-typedef struct fblock {
-  unsigned char *buff;   /**< Pointer to the block as a string */
-  size_t len;            /**< Length of buff */
-} FBLOCK;
-
-/** The complete collection of cached text files. */
-struct fcache_entries {
-  FBLOCK connect_fcache[2];    /**< connect.txt and connect.html */
-  FBLOCK motd_fcache[2];       /**< motd.txt and motd.html */
-  FBLOCK newuser_fcache[2];    /**< newuser.txt and newuser.html */
-  FBLOCK register_fcache[2];   /**< register.txt and register.html */
-  FBLOCK quit_fcache[2];       /**< quit.txt and quit.html */
-  FBLOCK down_fcache[2];       /**< down.txt and down.html */
-  FBLOCK full_fcache[2];       /**< full.txt and full.html */
-  FBLOCK guest_fcache[2];      /**< guest.txt and guest.html */
-};
-
-void feed_snoop(DESC *, const char *, char );
-char is_snooped(DESC *);
-char set_snoop(dbref, DESC *);
-void clr_snoop(dbref, DESC *);
-void announce_connect(dbref player, int isnew, int num);
-void announce_disconnect(dbref player);
-void add_to_exit_path(DESC *d, dbref player);
-
-static struct fcache_entries fcache;
-static void fcache_dump(DESC *d, FBLOCK fp[2], const unsigned char *prefix);
-static int fcache_read(FBLOCK *cp, const char *filename);
-static void logout_sock(DESC *d);
-static void shutdownsock(DESC *d);
-static DESC *initializesock(int s, char *addr, char *ip, int use_ssl);
-int process_output(DESC *d);
-/* Notify.c */
-extern void free_text_block(struct text_block *t);
-extern void add_to_queue(struct text_queue *q, const unsigned char *b, int n);
-extern int queue_write(DESC *d, const unsigned char *b, int n);
-extern int queue_eol(DESC *d);
-extern int queue_newwrite(DESC *d, const unsigned char *b, int n);
-extern int queue_string(DESC *d, const char *s);
-extern int queue_string_eol(DESC *d, const char *s);
-extern void freeqs(DESC *d);
-static void welcome_user(DESC *d);
-static void dump_info(DESC *call_by);
-static void save_command(DESC *d, const unsigned char *command);
-static int process_input(DESC *d, int output_ready);
-static void process_input_helper(DESC *d, char *tbuf1, int got);
-static void set_userstring(unsigned char **userstring, const char *command);
-static void process_commands(void);
-static void parse_puebloclient(DESC *d, char *command);
-static int dump_messages(DESC *d, dbref player, int new);
-static int check_connect(DESC *d, const char *msg);
-static void parse_connect(const char *msg, char *command, char *user,
-                         char *pass);
-static void close_sockets(void);
-dbref find_player_by_desc(int port);
-static DESC *lookup_desc(dbref executor, const char *name);
-void NORETURN bailout(int sig);
-void WIN32_CDECL signal_shutdown(int sig);
-void WIN32_CDECL signal_dump(int sig);
-void reaper(int sig);
-extern Pid_t forked_dump_pid;  /**< Process id of forking dump process */
-static void dump_users(DESC *call_by, char *match, int doing);
-static const char *time_format_1(long int dt);
-static const char *time_format_2(long int dt);
-
-void inactivity_check(void);
-void reopen_logs(void);
-void load_reboot_db(void);
-#ifdef HAS_GETRLIMIT
-static void
-init_rlimit(void)
-{
-  /* Unlimit file descriptors. */
-  /* Ultrix 4.4 and others may have getrlimit but may not be able to
-   * change number of file descriptors
-   */
-#ifdef RLIMIT_NOFILE
-  struct rlimit *rlp;
-
-  rlp = (struct rlimit *) malloc(sizeof(struct rlimit));
-  if (getrlimit(RLIMIT_NOFILE, rlp)) {
-    perror("init_rlimit: getrlimit()");
-    free(rlp);
-    return;
-  }
-  /* This check seems dumb, but apparently FreeBSD may return 0 for
-   * the max # of descriptors!
-   */
-  if (rlp->rlim_max > rlp->rlim_cur) {
-    rlp->rlim_cur = rlp->rlim_max;
-    if (setrlimit(RLIMIT_NOFILE, rlp))
-      perror("init_rlimit: setrlimit()");
-  }
-  free(rlp);
-#endif
-  return;
-}
-#endif                         /* HAS_GETRLIMIT */
-
-#ifndef BOOLEXP_DEBUGGING
-#ifdef WIN32SERVICES
-/* Under WIN32, MUSH is a "service", so we just start a thread here.
- * The real "main" is in win32/services.c
- */
-void
-mainthread(int argc, char **argv)
-#else
-/** The main function.
- * \param argc number of arguments.
- * \param argv vector of arguments.
- * \return exit code.
- */
-int
-main(int argc, char **argv)
-#endif                         /* WIN32SERVICES */
-{
-#ifdef AUTORESTART
-  FILE *id;
-#endif
-  FILE *newerr;
-
-  /* read the configuration file */
-  if (argc < 2) {
-    fprintf(stderr, "ERROR: Usage: %s /path/to/config_file\n", argv[0]);
-    exit(2);
-  }
-
-#ifdef WIN32
-  {
-    unsigned short wVersionRequested = MAKEWORD(1, 1);
-    int err;
-
-    /* Need to include library: wsock32.lib for Windows Sockets */
-    err = WSAStartup(wVersionRequested, &wsadata);
-    if (err) {
-      printf(T("Error %i on WSAStartup\n"), err);
-      exit(1);
-    }
-  }
-#endif                         /* WIN32 */
-
-#ifdef HAS_GETRLIMIT
-  init_rlimit();               /* unlimit file descriptors */
-#endif
-
-  /* These are FreeBSDisms to fix floating point exceptions */
-#ifdef HAS_FPSETROUND
-  fpsetround(FP_RN);
-#endif
-#ifdef HAS_FPSETMASK
-  fpsetmask(0L);
-#endif
-
-  time(&mudtime);
-
-  /* If we have setlocale, call it to set locale info
-   * from environment variables
-   */
-#ifdef HAS_SETLOCALE
-  {
-    char *loc;
-    if ((loc = setlocale(LC_CTYPE, "")) == NULL)
-      do_rawlog(LT_ERR, "Failed to set ctype locale from environment.");
-    else
-      do_rawlog(LT_ERR, "Setting ctype locale to %s", loc);
-    if ((loc = setlocale(LC_TIME, "")) == NULL)
-      do_rawlog(LT_ERR, "Failed to set time locale from environment.");
-    else
-      do_rawlog(LT_ERR, "Setting time locale to %s", loc);
-    if ((loc = setlocale(LC_MESSAGES, "")) == NULL)
-      do_rawlog(LT_ERR, "Failed to set messages locale from environment.");
-    else
-      do_rawlog(LT_ERR, "Setting messages locale to %s", loc);
-    if ((loc = setlocale(LC_COLLATE, "")) == NULL)
-      do_rawlog(LT_ERR, "Failed to set collate locale from environment.");
-    else
-      do_rawlog(LT_ERR, "Setting collate locale to %s", loc);
-  }
-#endif
-#ifdef HAS_TEXTDOMAIN
-  textdomain("pennmush");
-#endif
-#ifdef HAS_BINDTEXTDOMAIN
-  bindtextdomain("pennmush", "../po");
-#endif
-
-  /* Build the locale-dependant tables used by PCRE */
-  tables = pcre_maketables();
-
-/* this writes a file used by the restart script to check for active mush */
-#ifdef AUTORESTART
-  id = fopen("runid", "w");
-  fprintf(id, "%d", getpid());
-  fclose(id);
-#endif
-
-  strncpy(confname, argv[1], BUFFER_LEN - 1);
-  confname[BUFFER_LEN - 1] = '\0';
-  init_game_config(confname);
-
-  /* save a file descriptor */
-  reserve_fd();
-#ifndef WIN32
-  extrafd = open("/dev/null", O_RDWR);
-#endif
-
-  /* decide if we're in @shutdown/reboot */
-  restarting = 0;
-  newerr = fopen(REBOOTFILE, "r");
-  if (newerr) {
-    restarting = 1;
-    fclose(newerr);
-  }
-
-  init_qids();
-  if (init_game_dbs() < 0) {
-    do_rawlog(LT_ERR, T("ERROR: Couldn't load databases! Exiting."));
-    exit(2);
-  }
-
-  init_game_postdb(confname);
-
-  globals.database_loaded = 1;
-
-  set_signals();
-
-  /* go do it */
-#ifdef CSRI
-#ifdef CSRI_DEBUG
-  mal_verify(1);
-#endif
-#ifdef CSRI_TRACE
-  mal_leaktrace(1);
-#endif
-#endif
-  load_reboot_db();
-  shovechars();
-#ifdef CSRI
-#ifdef CSRI_DEBUG
-  mal_verify(1);
-#endif
-#endif
-
-  /* someone has told us to shut down */
-#ifdef WIN32SERVICES
-  /* Keep service manager happy */
-  shutdown_checkpoint();
-#endif
-
-  shutdown_queues();
-
-#ifdef WIN32SERVICES
-  /* Keep service manager happy */
-  shutdown_checkpoint();
-#endif
-
-  close_sockets();
-  sql_shutdown();
-
-#ifdef WIN32SERVICES
-  /* Keep service manager happy */
-  shutdown_checkpoint();
-#endif
-
-  dump_database();
-
-  local_shutdown();
-
-#ifdef RPMODE_SYS
-  rplog_shutdown();
-#endif
-
-  end_all_logs();
-
-#ifdef CSRI
-#ifdef CSRI_PROFILESIZES
-  mal_statsdump(stderr);
-#endif
-#ifdef CSRI_TRACE
-  mal_dumpleaktrace(stderr);
-#endif
-  fflush(stderr);
-#endif
-
-#ifdef WIN32SERVICES
-  /* Keep service manager happy */
-  shutdown_checkpoint();
-#endif
-
-#ifdef HAS_GETRUSAGE
-  rusage_stats();
-#endif                         /* HAS_RUSAGE */
-
-  do_rawlog(LT_ERR, T("MUSH shutdown completed."));
-
-#ifdef WIN32
-#ifdef WIN32SERVICES
-  shutdown_checkpoint();
-#endif
-  WSACleanup();                        /* clean up */
-#else
-#ifdef __APPLE__
-  unlink("runid");
-#endif
-  exit(0);
-#endif
-}
-#endif                         /* BOOLEXP_DEBUGGING */
-
-/** Close and reopen the logfiles - called on SIGHUP */
-void
-reopen_logs(void)
-{
-  FILE *newerr;
-  /* close up the log files */
-  end_all_logs();
-  newerr = fopen(errlog, "a");
-  if (!newerr) {
-    fprintf(stderr,
-           T("Unable to open %s. Error output continues to stderr.\n"),
-           errlog);
-  } else {
-    if (!freopen(errlog, "a", stderr)) {
-      printf(T("Ack!  Failed reopening stderr!"));
-      exit(1);
-    }
-    setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
-    fclose(newerr);
-  }
-  start_all_logs();
-}
-
-/** Install our default signal handlers. */
-void
-set_signals(void)
-{
-
-#ifndef WIN32
-  /* we don't care about SIGPIPE, we notice it in select() and write() */
-  ignore_signal(SIGPIPE);
-  install_sig_handler(SIGUSR2, signal_dump);
-  install_sig_handler(SIGQUIT, signal_shutdown);
-  install_sig_handler(SIGINT, signal_shutdown);
-  install_sig_handler(SIGTERM, bailout);
-#else
-  /* Win32 stuff: 
-   *   No support for SIGUSR2 or SIGINT.
-   *   SIGTERM is never generated on NT-based Windows (according to MSDN)
-   *   MSVC++ will let you get away with installing a handler anyway,
-   *   but VS.NET will not. So if it's MSVC++, we give it a try.
-   */
-#if _MSC_VER < 1200
-  install_sig_handler(SIGTERM, bailout);
-#endif
-#endif
-
-#ifndef WIN32
-  install_sig_handler(SIGCHLD, reaper);
-#endif
-
-}
-
-#ifdef WIN32
-/** Get the time using Windows function call.
- * Looks weird, but it works. :-P
- * \param now address to store timeval data.
- */
-static void
-win_gettimeofday(struct timeval *now)
-{
-
-  FILETIME win_time;
-
-  GetSystemTimeAsFileTime(&win_time);
-  /* dwLow is in 100-s nanoseconds, not microseconds */
-  now->tv_usec = win_time.dwLowDateTime % 10000000 / 10;
-
-  /* dwLow contains at most 429 least significant seconds, since 32 bits maxint is 4294967294 */
-  win_time.dwLowDateTime /= 10000000;
-
-  /* Make room for the seconds of dwLow in dwHigh */
-  /* 32 bits of 1 = 4294967295. 4294967295 / 429 = 10011578 */
-  win_time.dwHighDateTime %= 10011578;
-  win_time.dwHighDateTime *= 429;
-
-  /* And add them */
-  now->tv_sec = win_time.dwHighDateTime + win_time.dwLowDateTime;
-}
-
-#endif
-
-/** Return the difference between two timeval structs as a timeval struct.
- * \param now pointer to the timeval to subtract from.
- * \param then pointer to the timeval to subtract.
- * \return pointer to a statically allocated timeval of the difference.
- */
-static struct timeval *
-timeval_sub(struct timeval *now, struct timeval *then)
-{
-  static struct timeval mytime;
-  mytime.tv_sec = now->tv_sec;
-  mytime.tv_usec = now->tv_usec;
-
-  mytime.tv_sec -= then->tv_sec;
-  mytime.tv_usec -= then->tv_usec;
-  if (mytime.tv_usec < 0) {
-    mytime.tv_usec += 1000000;
-    mytime.tv_sec--;
-  }
-  return &mytime;
-}
-
-/** Return the difference between two timeval structs in milliseconds.
- * \param now pointer to the timeval to subtract from.
- * \param then pointer to the timeval to subtract.
- * \return milliseconds of difference between them.
- */
-static long int
-msec_diff(struct timeval *now, struct timeval *then)
-{
-  long int secs = now->tv_sec - then->tv_sec;
-  if (secs == 0)
-    return (now->tv_usec - then->tv_usec) / 1000;
-  else if (secs == 1)
-    return (now->tv_usec + (1000000 - then->tv_usec)) / 100;
-  else if (secs > 1)
-    return (secs * 1000) + ((now->tv_usec + (1000000 - then->tv_usec)) / 1000);
-  else
-    return 0;
-}
-
-/** Add a given number of milliseconds to a timeval.
- * \param t pointer to a timeval struct.
- * \param x number of milliseconds to add to t.
- * \return address of static timeval struct representing the sum.
- */
-static struct timeval *
-msec_add(struct timeval *t, int x)
-{
-  static struct timeval mytime;
-  mytime.tv_sec = t->tv_sec;
-  mytime.tv_usec = t->tv_usec;
-  mytime.tv_sec += x / 1000;
-  mytime.tv_usec += (x % 1000) * 1000;
-  if (mytime.tv_usec >= 1000000) {
-    mytime.tv_sec += mytime.tv_usec / 1000000;
-    mytime.tv_usec = mytime.tv_usec % 1000000;
-  }
-  return &mytime;
-}
-
-/** Update each descriptor's allowed rate of issuing commands.
- * Players are rate-limited; they may only perform up to a certain
- * number of commands per time slice. This function is run periodically
- * to refresh each descriptor's available command quota based on how
- * many slices have passed since it was last updated.
- * \param last pointer to timeval struct of last time quota was updated.
- * \param current pointer to timeval struct of current time.
- */
-static void
-update_quotas(struct timeval *last, struct timeval *current)
-{
-  int nslices;
-  DESC *d;
-  nslices = (int) msec_diff(current, last) / COMMAND_TIME_MSEC;
-
-  if (nslices > 0) {
-    for (d = descriptor_list; d; d = d->next) {
-      d->quota += COMMANDS_PER_TIME * nslices;
-      if (d->quota > COMMAND_BURST_SIZE)
-       d->quota = COMMAND_BURST_SIZE;
-    }
-  }
-}
-
-static const char *empabb(dbref player) {
-        static char str[4];
-        ATTR *a;
-       /*
-        dbref start, end, last;
-       */
-       dbref start;
-
-        memset(str, '\0', 4);
-
-        if(!IsDivision(SDIV(player).object))
-               goto bad_empabb_value;
-        start = SDIV(player).object;
-
-       /*
-        for(last = end = start; GoodObject(end) && IsDivision(end) &&
-                        !has_flag_by_name(end, "EMPIRE", TYPE_DIVISION) ; last = end, end = SDIV(end).object)
-                ;
-        if(!has_flag_by_name(end, "EMPIRE", TYPE_DIVISION)) {
-                if(end == NOTHING && IsDivision(last))
-                        end = last;
-                else end = start;
-        }
-       */
-        /* K, end is the empire we're grabbing this off of */
-        a = atr_get(start, "ALIAS");
-        if(!a)
-                goto bad_empabb_value;
-        strncpy(str, atr_value(a), 3);
-        if(!str[0])
-                goto bad_empabb_value;
-        return str;
-
-
-bad_empabb_value:
-        strncpy(str, "---", 3);
-        return str;
-}
-
-
-static void
-shovechars()
-{
-  /* this is the main game loop */
-
-  fd_set input_set, output_set;
-  time_t now;
-  struct timeval last_slice, current_time, then;
-  struct timeval next_slice, *returned_time;
-  struct timeval timeout, slice_timeout;
-  int found;
-  int queue_timeout;
-  DESC *d, *dnext;
-  int input_ready, output_ready;
-
-  d = initializesock(0, "localhost", "127.0.0.1", 0);
-
-  our_gettimeofday(&last_slice);
-
-  /* done. print message to the log */
-  do_rawlog(LT_ERR, "RESTART FINISHED.");
-
-  our_gettimeofday(&then);
-
-  while (shutdown_flag == 0) {
-    our_gettimeofday(&current_time);
-
-    update_quotas(&last_slice, &current_time);
-    last_slice.tv_sec = current_time.tv_sec;
-    last_slice.tv_usec = current_time.tv_usec;
-
-    if (msec_diff(&current_time, &then) >= 1000) {
-      globals.on_second = 1;
-      then.tv_sec = current_time.tv_sec;
-      then.tv_usec = current_time.tv_usec;
-    }
-
-    process_commands();
-
-    if (signal_shutdown_flag) {
-      flag_broadcast(0, 0, T("GAME: Shutdown by external signal"));
-      do_rawlog(LT_ERR, T("SHUTDOWN by external signal"));
-#ifdef AUTORESTART
-      system("touch NORESTART");
-#endif
-      shutdown_flag = 1;
-    }
-
-    if (signal_dump_flag) {
-      globals.paranoid_dump = 0;
-      do_rawlog(LT_CHECK, "DUMP by external signal");
-      fork_and_dump(1);
-      signal_dump_flag = 0;
-    }
-
-    if (shutdown_flag)
-      break;
-
-    /* test for events */
-    dispatch();
-
-    /* any queued robot commands waiting? */
-    /* timeout.tv_sec used to be set to que_next(), the number of
-     * seconds before something on the queue needed to run, but this
-     * caused a problem with stuff that had to be triggered by alarm
-     * signal every second, so we're reduced to what's below:
-     */
-    queue_timeout = que_next();
-    timeout.tv_sec = queue_timeout ? 1 : 0;
-    timeout.tv_usec = 0;
-
-    returned_time = msec_add(&last_slice, COMMAND_TIME_MSEC);
-    next_slice.tv_sec = returned_time->tv_sec;
-    next_slice.tv_usec = returned_time->tv_usec;
-
-    returned_time = timeval_sub(&next_slice, &current_time);
-    slice_timeout.tv_sec = returned_time->tv_sec;
-    slice_timeout.tv_usec = returned_time->tv_usec;
-    /* Make sure slice_timeout cannot have a negative time. Better
-       safe than sorry. */
-    if (slice_timeout.tv_sec < 0)
-      slice_timeout.tv_sec = 0;
-    if (slice_timeout.tv_usec < 0)
-      slice_timeout.tv_usec = 0;
-
-    FD_ZERO(&input_set);
-    FD_ZERO(&output_set);
-    for (d = descriptor_list; d; d = d->next) {
-      if (d->input.head) {
-       timeout.tv_sec = slice_timeout.tv_sec;
-       timeout.tv_usec = slice_timeout.tv_usec;
-      } else {
-        if(d->descriptor == 0)
-         FD_SET(STDIN_FILENO, &input_set);
-        else
-         FD_SET(d->descriptor, &input_set);
-      }
-      if (d->output.head) {
-        if(d->descriptor == 0)
-          FD_SET(STDOUT_FILENO, &output_set);
-        else
-         FD_SET(d->descriptor, &output_set);
-      }
-    }
-
-    found = select(2, &input_set, &output_set, (fd_set *) 0, &timeout);
-    if (found < 0) {
-#ifdef WIN32
-      if (found == SOCKET_ERROR && WSAGetLastError() != WSAEINTR)
-#else
-      if (errno != EINTR)
-#endif
-      {
-       perror("select");
-       return;
-      }
-    } else {
-      /* if !found then time for robot commands */
-
-      if (!found) {
-       do_top(options.queue_chunk);
-       continue;
-      } else {
-       do_top(options.active_q_chunk);
-      }
-      now = mudtime;
-      for (d = descriptor_list; d; d = dnext) {
-       dnext = d->next;
-        if(d->descriptor == 0) {
-         input_ready = FD_ISSET(STDIN_FILENO, &input_set);
-         output_ready = FD_ISSET(STDOUT_FILENO, &output_set);
-        } else {
-         input_ready = FD_ISSET(d->descriptor, &input_set);
-         output_ready = FD_ISSET(d->descriptor, &output_set);
-        }
-       if (input_ready) {
-         if (!process_input(d, output_ready)) {
-           shutdownsock(d);
-            if(d->descriptor == 0)
-              return;
-           continue;
-         }
-       }
-       if (output_ready) {
-         if (!process_output(d)) {
-           shutdownsock(d);
-            if(d->descriptor == 0)
-              return;
-         }
-       }
-      }
-    }
-  }
-}
-
-static void
-clearstrings(DESC *d)
-{
-  if (d->output_prefix) {
-    mush_free((Malloc_t) d->output_prefix, "userstring");
-    d->output_prefix = 0;
-  }
-  if (d->output_suffix) {
-    mush_free((Malloc_t) d->output_suffix, "userstring");
-    d->output_suffix = 0;
-  }
-}
-
-/* Display a cached text file. If a prefix line was given,
- * display that line before the text file, but only if we've
- * got a text file to display
- */
-static void
-fcache_dump(DESC *d, FBLOCK fb[2], const unsigned char *prefix)
-{
-  /* If we've got nothing nice to say, don't say anything */
-  if (!fb[0].buff && !((d->conn_flags & CONN_HTML) && fb[1].buff))
-    return;
-  /* We've got something to say */
-  if (prefix) {
-    queue_newwrite(d, prefix, u_strlen(prefix));
-    queue_eol(d);
-  }
-  if (d->conn_flags & CONN_HTML) {
-    if (fb[1].buff)
-      queue_newwrite(d, fb[1].buff, fb[1].len);
-    else
-      queue_write(d, fb[0].buff, fb[0].len);
-  } else
-    queue_write(d, fb[0].buff, fb[0].len);
-}
-
-
-static int
-fcache_read(FBLOCK *fb, const char *filename)
-{
-  if (!fb || !filename)
-    return -1;
-
-  /* Free prior cache */
-  if (fb->buff) {
-    mush_free(fb->buff, "fcache_data");
-  }
-
-  fb->buff = NULL;
-  fb->len = 0;
-
-#ifdef WIN32
-  /* Win32 read code here */
-  {
-    HANDLE fh;
-    BY_HANDLE_FILE_INFORMATION sb;
-    DWORD r = 0;
-
-
-    if ((fh = CreateFile(filename, GENERIC_READ, 0, NULL,
-                        OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
-      return -1;
-
-    if (!GetFileInformationByHandle(fh, &sb)) {
-      CloseHandle(fh);
-      return -1;
-    }
-
-    fb->len = sb.nFileSizeLow;
-
-    if (!(fb->buff = mush_malloc(sb.nFileSizeLow, "fcache_data"))) {
-      CloseHandle(fh);
-      return -1;
-    }
-
-    if (!ReadFile(fh, fb->buff, sb.nFileSizeLow, &r, NULL) || fb->len != r) {
-      CloseHandle(fh);
-      mush_free(fb->buff, "fcache_data");
-      fb->buff = NULL;
-      return -1;
-    }
-
-    CloseHandle(fh);
-
-    fb->len = sb.nFileSizeLow;
-    return (int) fb->len;
-  }
-#else
-  /* Posix read code here */
-  {
-    int fd, n;
-    struct stat sb;
-
-    release_fd();
-    if ((fd = open(filename, O_RDONLY, 0)) < 0) {
-      do_log(LT_ERR, 0, 0, T("Couldn't open cached text file '%s'"), filename);
-      reserve_fd();
-      return -1;
-    }
-
-    if (fstat(fd, &sb) < 0) {
-      do_log(LT_ERR, 0, 0, T("Couldn't get the size of text file '%s'"),
-            filename);
-      close(fd);
-      reserve_fd();
-      return -1;
-    }
-
-
-    if (!(fb->buff = mush_malloc(sb.st_size, "fcache_data"))) {
-      do_log(LT_ERR, 0, 0, T("Couldn't allocate %d bytes of memory for '%s'!"),
-            (int) sb.st_size, filename);
-      close(fd);
-      reserve_fd();
-      return -1;
-    }
-
-    if ((n = read(fd, fb->buff, sb.st_size)) != sb.st_size) {
-      do_log(LT_ERR, 0, 0, T("Couldn't read all of '%s'"), filename);
-      close(fd);
-      mush_free(fb->buff, "fcache_data");
-      fb->buff = NULL;
-      reserve_fd();
-      return -1;
-    }
-
-    close(fd);
-    reserve_fd();
-    fb->len = sb.st_size;
-  }
-#endif                         /* Posix read code */
-
-  return fb->len;
-}
-
-/** Load all of the cached text files.
- * \param player the enactor.
- */
-void
-fcache_load(dbref player)
-{
-  int conn, motd, new, reg, quit, down, full;
-  int guest;
-  int i;
-
-  for (i = 0; i < (SUPPORT_PUEBLO ? 2 : 1); i++) {
-    conn = fcache_read(&fcache.connect_fcache[i], options.connect_file[i]);
-    motd = fcache_read(&fcache.motd_fcache[i], options.motd_file[i]);
-    new = fcache_read(&fcache.newuser_fcache[i], options.newuser_file[i]);
-    reg = fcache_read(&fcache.register_fcache[i], options.register_file[i]);
-    quit = fcache_read(&fcache.quit_fcache[i], options.quit_file[i]);
-    down = fcache_read(&fcache.down_fcache[i], options.down_file[i]);
-    full = fcache_read(&fcache.full_fcache[i], options.full_file[i]);
-    guest = fcache_read(&fcache.guest_fcache[i], options.guest_file[i]);
-
-    if (player != NOTHING) {
-      notify_format(player,
-                   T
-                   ("%s sizes:  NewUser...%d  Connect...%d  Guest...%d  Motd...%d  Quit...%d  Register...%d  Down...%d  Full...%d"),
-                   i ? "HTMLFile" : "File", new, conn, guest, motd, quit,
-                   reg, down, full);
-    }
-  }
-
-}
-
-/** Initialize all of the cached text files (at startup).
- */
-void
-fcache_init(void)
-{
-  fcache_load(NOTHING);
-}
-
-static void
-logout_sock(DESC *d)
-{
-  SU_PATH *path_entry;
-
-  int n;
-  char tbuf1[BUFFER_LEN];
-
-  if (d->connected) {
-    fcache_dump(d, fcache.quit_fcache, NULL);
-    do_log(LT_CONN, 0, 0,
-          T("[%d/%s/%s] Logout by %s(#%d) <Connection not dropped>"),
-          d->descriptor, d->addr, d->ip, Name(d->player), d->player);
-    if(d->last_time > 0) {
-      d->idle_total += difftime(mudtime, d->last_time);
-      d->unidle_times++;
-    }
-    snprintf(tbuf1, BUFFER_LEN-1, "%ld %ld %d %d", (mudtime - d->connected_at),
-       d->idle_total, d->unidle_times, d->cmds); 
-    tbuf1[strlen(tbuf1)+1] = '\0';
-    (void) atr_add(d->player, "LASTACTIVITY", tbuf1, GOD, NOTHING);
-    announce_disconnect(d->player);
-    do_mail_purge(d->player);
-    if (MAX_LOGINS) {
-      login_number--;
-      if (!under_limit && (login_number < MAX_LOGINS)) {
-       under_limit = 1;
-       do_log(LT_CONN, 0, 0,
-              T("Below maximum player limit of %d. Logins enabled."),
-              MAX_LOGINS);
-      }
-    }
-  } else {
-    do_log(LT_CONN, 0, 0,
-          T("[%d/%s/%s] Logout, never connected. <Connection not dropped>"),
-          d->descriptor, d->addr, d->ip);
-  }
-  process_output(d);           /* flush our old output */
-  /* pretend we have a new connection */
-  d->input_handler = do_command;
-  d->connected = 0;
-  d->output_prefix = 0;
-  d->output_suffix = 0;
-  d->output_size = 0;
-  d->output.head = 0;
-  d->player = 0;
-  d->output.tail = &d->output.head;
-  d->input.head = 0;
-  d->input.tail = &d->input.head;
-  d->raw_input = 0;
-  d->raw_input_at = 0;
-  d->quota = COMMAND_BURST_SIZE;
-  d->last_time = mudtime;
-  d->idle_total = 0;
-  d->unidle_times = 0;
-  d->cmds = 0;
-  d->hide = 0;
-  d->doing[0] = '\0';
-  d->mailp = NULL;
-  d->pinfo.object = NOTHING;
-  d->pinfo.atr = NULL;
-  d->pinfo.lock = 0;
-  d->pinfo.function = NULL;
-
-  while(d->su_exit_path) {
-    path_entry = d->su_exit_path;
-    d->su_exit_path = path_entry->next;
-    mush_free(path_entry, "SU_EXIT_PATH");
-  }
-  welcome_user(d);
-  for(n = 0; n < MAX_SNOOPS; n++)
-    d->snooper[n] = -1;
-}
-
-/** Disconnect a descriptor.
- * This sends appropriate disconnection text, flushes output, and
- * then closes the associated socket.
- * \param d pointer to descriptor to disconnect.
- */
-static void
-shutdownsock(DESC *d)
-{
-  char tbuf1[BUFFER_LEN];
-  int i;
-
-  if (d->connected) {
-    do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Logout by %s(#%d)"),
-          d->descriptor, d->addr, d->ip, Name(d->player), d->player);
-    if (d->connected != 2) {
-      fcache_dump(d, fcache.quit_fcache, NULL);
-      /* Player was not allowed to log in from the connect screen */
-      if(d->last_time > 0) {
-       d->idle_total += difftime(mudtime, d->last_time);
-       d->unidle_times++;
-      }
-      snprintf(tbuf1, BUFFER_LEN-1, "%ld %ld %d %d", (mudtime - d->connected_at), 
-         d->idle_total , d->unidle_times, d->cmds);
-      tbuf1[strlen(tbuf1)+1] = '\0';
-      (void) atr_add(d->player, "LASTACTIVITY", tbuf1, GOD, NOTHING);
-      announce_disconnect(d->player);
-      do_mail_purge(d->player);
-    }
-    if (MAX_LOGINS) {
-      login_number--;
-      if (!under_limit && (login_number < MAX_LOGINS)) {
-       under_limit = 1;
-       do_log(LT_CONN, 0, 0,
-              T("Below maximum player limit of %d. Logins enabled."),
-              MAX_LOGINS);
-      }
-    }
-  } else {
-    do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Connection closed, never connected."),
-          d->descriptor, d->addr, d->ip);
-  }
-  process_output(d);
-  clearstrings(d);
-  if(d->descriptor != 0) {
-    shutdown(d->descriptor, 2);
-    closesocket(d->descriptor);
-  } else {
-    freeqs(d);
-    d->input_handler = do_command;
-    d->connected = 0;
-    d->connected_at = mudtime;
-    d->output_prefix = 0;
-    d->output_suffix = 0;
-    d->output_size = 0;
-    d->output.head = 0;
-    d->player = 0;
-    d->output.tail = &d->output.head;
-    d->input.head = 0;
-    d->input.tail = &d->input.head;
-    d->raw_input = 0;
-    d->raw_input_at = 0;
-    d->quota = COMMAND_BURST_SIZE;
-    d->last_time = mudtime;
-    d->idle_total = 0;
-    d->unidle_times = 0;
-    d->cmds = 0;
-    d->hide = 0;
-    d->doing[0] = '\0';
-    d->mailp = NULL;
-    strncpy(d->addr, "localhost", 100);
-    d->addr[99] = '\0';
-    strncpy(d->ip, "127.0.0.1", 100);
-    d->ip[99] = '\0';
-    d->conn_flags = CONN_DEFAULT;
-    d->input_chars = 0;
-    d->output_chars = 0;
-    d->ttype = mush_strdup("unknown", "terminal description");
-    d->checksum[0] = '\0';
-    d->su_exit_path = NULL;
-    d->pinfo.object = NOTHING;
-    d->pinfo.atr = NULL;
-    d->pinfo.lock = 0;
-    d->pinfo.function = NULL;
-    d->width = 78;
-    d->height = 24;
-    welcome_user(d);
-    for(i = 0; i < MAX_SNOOPS; i++)
-      d->snooper[i] = -1;
-  }
-
-  if(d->descriptor != 0) {
-    if (d->prev)
-      d->prev->next = d->next;
-    else                               /* d was the first one! */
-      descriptor_list = d->next;
-    if (d->next)
-      d->next->prev = d->prev;
-  }
-
-  if(d->descriptor != 0) {
-    freeqs(d);
-    mush_free(d->ttype, "terminal description");
-    mush_free((Malloc_t) d, "descriptor");
-  }
-
-  ndescriptors--;
-}
-
-/* ARGSUSED */
-static DESC *
-initializesock(int s, char *addr, char *ip, int use_ssl
-               __attribute__ ((__unused__)))
-{
-  DESC *d;
-  int n;
-
-  d = (DESC *) mush_malloc(sizeof(DESC), "descriptor");
-  if (!d)
-    mush_panic("Out of memory.");
-  d->descriptor = s;
-  d->input_handler = do_command;
-  d->connected = 0;
-  d->connected_at = mudtime;
-  make_nonblocking(s);
-  d->output_prefix = 0;
-  d->output_suffix = 0;
-  d->output_size = 0;
-  d->output.head = 0;
-  d->player = 0;
-  d->output.tail = &d->output.head;
-  d->input.head = 0;
-  d->input.tail = &d->input.head;
-  d->raw_input = 0;
-  d->raw_input_at = 0;
-  d->quota = COMMAND_BURST_SIZE;
-  d->last_time = mudtime;
-  d->idle_total = 0;
-  d->unidle_times = 0;
-  d->cmds = 0;
-  d->hide = 0;
-  d->doing[0] = '\0';
-  d->mailp = NULL;
-  strncpy(d->addr, addr, 100);
-  d->addr[99] = '\0';
-  strncpy(d->ip, ip, 100);
-  d->ip[99] = '\0';
-  d->conn_flags = CONN_DEFAULT;
-  d->input_chars = 0;
-  d->output_chars = 0;
-  d->ttype = mush_strdup("unknown", "terminal description");
-  d->checksum[0] = '\0';
-  d->su_exit_path = NULL;
-  d->pinfo.object = NOTHING;
-  d->pinfo.atr = NULL;
-  d->pinfo.lock = 0;
-  d->pinfo.function = NULL;
-
-  if (descriptor_list)
-    descriptor_list->prev = d;
-  d->next = descriptor_list;
-  d->prev = NULL;
-  descriptor_list = d;
-
-  d->width = 78;
-  d->height = 24;
-  test_telnet(d);
-  welcome_user(d);
-  for(n = 0; n < MAX_SNOOPS; n++)
-    d->snooper[n] = -1;
-  return d;
-}
-
-/** Flush pending output for a descriptor.
- * This function actually sends the queued output over the descriptor's
- * socket.
- * \param d pointer to descriptor to send output to.
- * \retval 1 successfully flushed at least some output.
- * \retval 0 something failed, and the descriptor should probably be closed.
- */
-int
-process_output(DESC *d)
-{
-  struct text_block **qp, *cur;
-  int cnt;
-
-  for (qp = &d->output.head; ((cur = *qp) != NULL);) {
-    if(d->descriptor == 0)
-      cnt = write(STDOUT_FILENO, cur->start, cur->nchars);
-    else
-      cnt = send(d->descriptor, cur->start, cur->nchars, 0);
-      if (cnt < 0) {
-#ifdef WIN32
-       if (cnt == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
-#else
-#ifdef EAGAIN
-       if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
-#else
-       if (errno == EWOULDBLOCK)
-#endif
-#endif
-         return 1;
-       return 0;
-      }
-    d->output_size -= cnt;
-    d->output_chars += cnt;
-    if (cnt == cur->nchars) {
-      if (!cur->nxt)
-       d->output.tail = qp;
-      *qp = cur->nxt;
-#ifdef DEBUG
-      do_rawlog(LT_ERR, "free_text_block(0x%x) at 2.", cur);
-#endif                         /* DEBUG */
-      free_text_block(cur);
-      continue;                        /* do not adv ptr */
-    }
-    cur->nchars -= cnt;
-    cur->start += cnt;
-    break;
-  }
-  return 1;
-}
-
-
-static void
-welcome_user(DESC *d)
-{
-  if (SUPPORT_PUEBLO && !(d->conn_flags & CONN_HTML))
-    queue_newwrite(d, (unsigned char *) PUEBLO_HELLO, strlen(PUEBLO_HELLO));
-  fcache_dump(d, fcache.connect_fcache, NULL);
-}
-
-static void
-save_command(DESC *d, const unsigned char *command)
-{
-  add_to_queue(&d->input, command, u_strlen(command) + 1);
-}
-
-static void
-test_telnet(DESC *d)
-{
-  /* Use rfc 1184 to test telnet support, as it tries to set linemode
-     with client-side editing. Good for Broken Telnet Programs. */
-  if (d->descriptor != 0 && !TELNET_ABLE(d)) {
-    /*  IAC DO LINEMODE */
-    unsigned char query[3] = "\xFF\xFD\x22";
-    queue_newwrite(d, query, 3);
-    d->conn_flags |= CONN_TELNET_QUERY;
-    process_output(d);
-  }
-}
-
-static void
-setup_telnet(DESC *d)
-{
-  /* Win2k telnet doesn't do local echo by default,
-     apparently. Unfortunately, there doesn't seem to be a telnet
-     option for local echo, just remote echo. */
-  d->conn_flags |= CONN_TELNET;
-  if (d->conn_flags & CONN_TELNET_QUERY) {
-    /* IAC DO NAWS IAC DO TERMINAL-TYPE */
-    unsigned char extra_options[6] = "\xFF\xFD\x1F" "\xFF\xFD\x18";
-    d->conn_flags &= ~CONN_TELNET_QUERY;
-    do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Switching to Telnet mode."),
-          d->descriptor, d->addr, d->ip);
-    queue_newwrite(d, extra_options, 6);
-    process_output(d);
-  }
-}
-
-static int
-handle_telnet(DESC *d, unsigned char **q, unsigned char *qend)
-{
-  int i;
-
-  /* *(*q - q) == IAC at this point. */
-  switch (**q) {
-  case SB:                     /* Sub-option */
-    if (*q >= qend)
-      return -1;
-    (*q)++;
-    if (**q == TN_LINEMODE) {
-      if ((*q + 2) >= qend)
-       return -1;
-      *q += 2;
-      while (*q < qend && **q != SE)
-       (*q)++;
-      if (*q >= qend)
-       return -1;
-    } else if (**q == TN_NAWS) {
-      /* Learn what size window the client is using. */
-      union {
-       short s;
-       unsigned char bytes[2];
-      } raw;
-      if (*q >= qend)
-       return -1;
-      (*q)++;
-      /* Width */
-      if (**q == IAC) {
-       raw.bytes[0] = IAC;
-       if (*q >= qend)
-         return -1;
-       (*q)++;
-      } else
-       raw.bytes[0] = **q;
-      if (*q >= qend)
-       return -1;
-      (*q)++;
-      if (**q == IAC) {
-       raw.bytes[1] = IAC;
-       if (*q >= qend)
-         return -1;
-       (*q)++;
-      } else
-       raw.bytes[1] = **q;
-      if (*q >= qend)
-       return -1;
-      (*q)++;
-
-      d->width = ntohs(raw.s);
-
-      /* Height */
-      if (**q == IAC) {
-       raw.bytes[0] = IAC;
-       if (*q >= qend)
-         return -1;
-       (*q)++;
-      } else
-       raw.bytes[0] = **q;
-      if (*q >= qend)
-       return -1;
-      (*q)++;
-      if (**q == IAC) {
-       raw.bytes[1] = IAC;
-       if (*q >= qend)
-         return -1;
-       (*q)++;
-      } else
-       raw.bytes[1] = **q;
-      if (*q >= qend)
-       return -1;
-      (*q)++;
-      d->height = ntohs(raw.s);
-
-      /* IAC SE */
-      if (*q + 1 >= qend)
-       return -1;
-      (*q)++;
-    } else if (**q == TN_TTYPE) {
-      /* Read the terminal type: TERMINAL-TYPE IS blah IAC SE */
-      char tbuf[BUFFER_LEN], *bp = tbuf;
-      if (*q >= qend)
-       return -1;
-      (*q)++;
-      /* Skip IS */
-      if (*q >= qend)
-       return -1;
-      (*q)++;
-
-      /* Read up to IAC SE */
-      while (1) {
-       if (*q >= qend)
-         return -1;
-       if (**q == IAC) {
-         if (*q + 1 >= qend)
-           return -1;
-         if (*(*q + 1) == IAC) {
-           safe_chr((char) IAC, tbuf, &bp);
-           (*q)++;
-         } else
-           break;
-       } else
-         safe_chr(**q, tbuf, &bp);
-       (*q)++;
-      }
-      while (*q < qend && **q != SE)
-       (*q)++;
-      *bp = '\0';
-      mush_free(d->ttype, "terminal description");
-      d->ttype = mush_strdup(tbuf, "terminal description");
-      /* We have the terminal type, now set any defaults if we find 'em */
-      for(i = 0 ;  client_maps[i].terminal != NULL; i++)
-       if(!strcmp(client_maps[i].terminal, d->ttype)) {
-         d->conn_flags |= client_maps[i].flags;
-         break;
-       }
-    } else {
-      while (*q < qend && **q != SE)
-       (*q)++;
-    }
-    break;
-  case NOP:                    /* No-op */
-    if (*q >= qend)
-      return -1;
-#ifdef DEBUG_TELNET
-    fprintf(stderr, "Got IAC NOP\n");
-#endif
-    break;
-  case AYT:                    /* Are you there? */
-    if (*q >= qend)
-      return -1;
-    else {
-      static unsigned char ayt_reply[] =
-       "\r\n*** AYT received, I'm here ***\r\n";
-      queue_newwrite(d, (unsigned char *) ayt_reply, u_strlen(ayt_reply));
-      process_output(d);
-    }
-    break;
-  case WILL:                   /* Client is willing to do something, or confirming */
-    setup_telnet(d);
-    if (*q >= qend)
-      return -1;
-    (*q)++;
-
-    if (**q == TN_LINEMODE) {
-      /* Set up our preferred linemode options. */
-      /* IAC SB LINEMODE MODE (EDIT|SOFT_TAB) IAC SE */
-      unsigned char reply[7] = "\xFF\xFA\x22\x01\x09\xFF\xF0";
-      queue_newwrite(d, reply, 7);
-#ifdef DEBUG_TELNET
-      fprintf(stderr, "Setting linemode options.\n");
-#endif
-    } else if (**q == TN_TTYPE) {
-      /* Ask for terminal type id: IAC SB TERMINAL-TYPE SEND IAC SEC */
-      unsigned char reply[6] = "\xFF\xFA\x18\x01\xFF\xF0";
-      queue_newwrite(d, reply, 6);
-    } else if (**q == TN_SGA || **q == TN_NAWS) {
-      /* This is good to be at. */
-    } else {                   /* Refuse options we don't handle */
-      unsigned char reply[3];
-      reply[0] = IAC;
-      reply[1] = DONT;
-      reply[2] = **q;
-      queue_newwrite(d, reply, sizeof reply);
-      process_output(d);
-    }
-    break;
-  case DO:                     /* Client is asking us to do something */
-    setup_telnet(d);
-    if (*q >= qend)
-      return -1;
-    (*q)++;
-    if (**q == TN_LINEMODE) {
-    } else if (**q == TN_SGA) {
-      /* IAC WILL SGA IAC DO SGA */
-      unsigned char reply[6] = "\xFF\xFB\x03\xFF\xFD\x03";
-      queue_newwrite(d, reply, 6);
-      process_output(d);
-#ifdef DEBUG_TELNET
-      fprintf(stderr, "GOT IAC DO SGA, sending IAC WILL SGA IAG DO SGA\n");
-#endif
-    } else {
-      /* Stuff we won't do */
-      unsigned char reply[3];
-      reply[0] = IAC;
-      reply[1] = WONT;
-      reply[2] = (char) **q;
-      queue_newwrite(d, reply, sizeof reply);
-      process_output(d);
-    }
-    break;
-  case WONT:                   /* Client won't do something we want. */
-  case DONT:                   /* Client doesn't want us to do something */
-    setup_telnet(d);
-#ifdef DEBUG_TELNET
-    fprintf(stderr, "Got IAC %s 0x%x\n", **q == WONT ? "WONT" : "DONT",
-           *(*q + 1));
-#endif
-    if (*q + 1 >= qend)
-      return -1;
-    (*q)++;
-    break;
-  default:                     /* Also catches IAC IAC for a literal 255 */
-    return 0;
-  }
-  return 1;
-}
-
-static void
-process_input_helper(DESC *d, char *tbuf1, int got)
-{
-  unsigned char *p, *pend, *q, *qend;
-
-  if (!d->raw_input) {
-    d->raw_input =
-      (unsigned char *) mush_malloc(sizeof(char) * MAX_COMMAND_LEN,
-                                   "descriptor_raw_input");
-    if (!d->raw_input)
-      mush_panic("Out of memory");
-    d->raw_input_at = d->raw_input;
-  }
-  p = d->raw_input_at;
-  d->input_chars += got;
-  pend = d->raw_input + MAX_COMMAND_LEN - 1;
-  for (q = (unsigned char *) tbuf1, qend = (unsigned char *) tbuf1 + got;
-       q < qend; q++) {
-    if (*q == '\r') {
-      /* A broken client (read: WinXP telnet) might send only CR, and not CRLF
-       * so it's nice of us to try to handle this.
-       */
-      *p = '\0';
-      if (p > d->raw_input)
-       save_command(d, d->raw_input);
-      p = d->raw_input;
-      if (((q + 1) < qend) && (*(q + 1) == '\n'))
-       q++;                    /* For clients that work */
-    } else if (*q == '\n') {
-      *p = '\0';
-      if (p > d->raw_input)
-       save_command(d, d->raw_input);
-      p = d->raw_input;
-    } else if (*q == '\b') {
-      if (p > d->raw_input)
-       p--;
-    } else if ((unsigned char) *q == IAC) {    /* Telnet option foo */
-      if (q >= qend)
-       break;
-      q++;
-      if (!TELNET_ABLE(d) || handle_telnet(d, &q, qend) == 0) {
-       if (p < pend && isprint(*q))
-         *p++ = *q;
-      }
-    } else if (p < pend && isprint(*q)) {
-      *p++ = *q;
-    }
-  }
-  if (p > d->raw_input) {
-    d->raw_input_at = p;
-  } else {
-    mush_free((Malloc_t) d->raw_input, "descriptor_raw_input");
-    d->raw_input = 0;
-    d->raw_input_at = 0;
-  }
-}
-
-/* ARGSUSED */
-static int
-process_input(DESC *d, int output_ready __attribute__ ((__unused__)))
-{
-  int got = 0;
-  char tbuf1[BUFFER_LEN];
-
-  errno = 0;
-
-  if(d->descriptor == 0)
-    got = read(STDIN_FILENO, tbuf1, sizeof tbuf1);
-  else
-    got = recv(d->descriptor, tbuf1, sizeof tbuf1, 0);
-
-    if (got <= 0) {
-      /* At this point, select() says there's data waiting to be read from
-       * the socket, but we shouldn't assume that read() will actually get it
-       * and blindly act like a got of -1 is a disconnect-worthy error.
-       */
-#ifdef EAGAIN
-      if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
-#else
-      if ((errno == EWOULDBLOCK) || (errno == EINTR))
-#endif
-       return 1;
-      else
-       return 0;
-    }
-
-  process_input_helper(d, tbuf1, got);
-
-  return 1;
-}
-
-static void
-set_userstring(unsigned char **userstring, const char *command)
-{
-  if (*userstring) {
-    mush_free((Malloc_t) *userstring, "userstring");
-    *userstring = NULL;
-  }
-  while (*command && isspace((unsigned char) *command))
-    command++;
-  if (*command)
-    *userstring = (unsigned char *) mush_strdup(command, "userstring");
-}
-
-static void
-process_commands(void)
-{
-  int nprocessed;
-  DESC *cdesc, *dnext;
-  struct text_block *t;
-  int retval = 1;
-
-  do {
-    nprocessed = 0;
-    for (cdesc = descriptor_list; cdesc;
-        cdesc = (nprocessed > 0 && retval > 0) ? cdesc->next : dnext) {
-      dnext = cdesc->next;
-      if (cdesc->quota > 0 && (t = cdesc->input.head)) {
-       cdesc->quota--;
-       nprocessed++;
-       start_cpu_timer();
-       feed_snoop(cdesc,(const char *) t->start, 0);
-       /* check AUNIDLE */
-       if(options.idle_time && ((mudtime - cdesc->last_time) > options.idle_time)) {
-         if(atr_get(cdesc->player, "AUNIDLE"))
-           queue_attribute_noparent(cdesc->player, "AUNIDLE", cdesc->player);
-         if(GoodObject(Division(cdesc->player)) && atr_get(Division(cdesc->player), "AUNIDLE"))
-           queue_attribute(Division(cdesc->player), "AUNIDLE", cdesc->player);
-       }
-       retval = cdesc->input_handler(cdesc, (char *) t->start);
-       reset_cpu_timer();
-       if(retval == -1 && do_su_exit(cdesc)) 
-         retval = 1;
-
-       if (retval == 0) {
-         shutdownsock(cdesc);
-       } else if (retval == -1) {
-         logout_sock(cdesc);
-       } else {
-         cdesc->input.head = t->nxt;
-         if (!cdesc->input.head)
-           cdesc->input.tail = &cdesc->input.head;
-         if (t) {
-#ifdef DEBUG
-           do_rawlog(LT_ERR, "free_text_block(0x%x) at 5.", t);
-#endif                         /* DEBUG */
-           free_text_block(t);
-         }
-       }
-      }
-    }
-  } while (nprocessed > 0);
-}
-
-/** Send a descriptor's output prefix */
-#define send_prefix(d) \
-  if (d->output_prefix) { \
-    queue_newwrite(d, d->output_prefix, u_strlen(d->output_prefix)); \
-    queue_eol(d); \
-  }
-
-/** Send a descriptor's output suffix */
-#define send_suffix(d) \
-  if (d->output_suffix) { \
-    queue_newwrite(d, d->output_suffix, u_strlen(d->output_suffix)); \
-    queue_eol(d); \
-  }
-
-int
-do_command(DESC *d, char *command)
-{
-  int j;
-
-  depth = 0;
-
-  (d->cmds)++;
-
-  if (!strcmp(command, IDLE_COMMAND))
-    return 1;
-  if(difftime(mudtime, d->last_time) >= 300) { 
-    d->idle_total += difftime(mudtime, d->last_time);
-    d->unidle_times++;
-  }
-  d->last_time = mudtime;
-  if (!strcmp(command, QUIT_COMMAND)) {
-    return 0;
-  } else if (!strcmp(command, LOGOUT_COMMAND)) {
-    return -1;
-  } else if (!strcmp(command, INFO_COMMAND)) {
-    send_prefix(d);
-    dump_info(d);
-    send_suffix(d);
-  } else if (!strncmp(command, WHO_COMMAND, strlen(WHO_COMMAND))) {
-    send_prefix(d);
-    dump_users(d, command + strlen(WHO_COMMAND), 0);
-    send_suffix(d);
-  } else if (!strncmp(command, DOING_COMMAND, strlen(DOING_COMMAND))) {
-    send_prefix(d);
-    dump_users(d, command + strlen(DOING_COMMAND), 1);
-    send_suffix(d);
-  } else if (!strncmp(command, SESSION_COMMAND, strlen(SESSION_COMMAND))) {
-    send_prefix(d);
-    dump_users(d, command + strlen(SESSION_COMMAND), 2);
-    send_suffix(d);
-  } else if (!strncmp(command, PREFIX_COMMAND, strlen(PREFIX_COMMAND))) {
-    set_userstring(&d->output_prefix, command + strlen(PREFIX_COMMAND));
-  } else if (!strncmp(command, SUFFIX_COMMAND, strlen(SUFFIX_COMMAND))) {
-    set_userstring(&d->output_suffix, command + strlen(SUFFIX_COMMAND));
-  } else if (!strncmp(command, "SCREENWIDTH", 11)) {
-    d->width = parse_integer(command + 11);
-  } else if (!strncmp(command, "SCREENHEIGHT", 12)) {
-    d->height = parse_integer(command + 12);
-  } else if (SUPPORT_PUEBLO
-            && !strncmp(command, PUEBLO_COMMAND, strlen(PUEBLO_COMMAND))) {
-    parse_puebloclient(d, command);
-    if (!(d->conn_flags & CONN_HTML)) {
-      queue_newwrite(d, (unsigned char *) PUEBLO_SEND, strlen(PUEBLO_SEND));
-      process_output(d);
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Switching to Pueblo mode."),
-            d->descriptor, d->addr, d->ip);
-      d->conn_flags |= CONN_HTML;
-      if (!d->connected)
-       welcome_user(d);
-    }
-  } else {
-    if (d->connected) {
-      send_prefix(d);
-      global_eval_context.cplr = d->player;
-      strcpy(global_eval_context.ccom, command);
-      strcpy(global_eval_context.ucom, "");
-
-      /* Clear %0-%9 and r(0) - r(9) */
-      for (j = 0; j < 10; j++)
-       global_eval_context.wenv[j] = (char *) NULL;
-      for (j = 0; j < NUMQ; j++)
-       global_eval_context.renv[j][0] = '\0';
-      global_eval_context.process_command_port = d->descriptor;
-
-      process_command(d->player, command, d->player, d->player, 1);
-      send_suffix(d);
-      strcpy(global_eval_context.ccom, "");
-      strcpy(global_eval_context.ucom, "");
-      global_eval_context.cplr = NOTHING;
-    } else {
-      if (!check_connect(d, command))
-       return 0;
-    }
-  }
-  return 1;
-}
-
-static void
-parse_puebloclient(DESC *d, char *command)
-{
-  const char *p, *end;
-  if ((p = string_match(command, "md5="))) {
-    /* Skip md5=" */
-    p += 5;
-    if ((end = strchr(p, '"'))) {
-      if ((end > p) && ((end - p) <= PUEBLO_CHECKSUM_LEN)) {
-       /* Got it! */
-       strncpy(d->checksum, p, end - p);
-       d->checksum[end - p] = '\0';
-      }
-    }
-  }
-}
-
-static int
-dump_messages(DESC *d, dbref player, int isnew)
-{
-  int is_hidden;
-  int num = 0;
-  DESC *tmpd;
-
-  d->connected = 1;
-  d->connected_at = mudtime;
-  d->player = player;
-  d->doing[0] = '\0';
-
-  if (MAX_LOGINS) {
-    /* check for exceeding max player limit */
-    login_number++;
-    if (under_limit && (login_number > MAX_LOGINS)) {
-      under_limit = 0;
-      do_rawlog(LT_CONN,
-               T("Limit of %d players reached. Logins disabled.\n"),
-               MAX_LOGINS);
-    }
-  }
-  /* give players a message on connection */
-  if (!options.login_allow || !under_limit ||
-      (Guest(player) && !options.guest_allow)) {
-    if (!options.login_allow) {
-      fcache_dump(d, fcache.down_fcache, NULL);
-      if (cf_downmotd_msg && *cf_downmotd_msg)
-       raw_notify(player, cf_downmotd_msg);
-    } else if (MAX_LOGINS && !under_limit) {
-      fcache_dump(d, fcache.full_fcache, NULL);
-      if (cf_fullmotd_msg && *cf_fullmotd_msg)
-       raw_notify(player, cf_fullmotd_msg);
-    }
-    if (!Can_Login(player)) {
-      /* when the connection has been refused, we want to update the
-       * LASTFAILED info on the player
-       */
-      check_lastfailed(player, d->addr);
-      return 0;
-    }
-  }
-  d->mailp = find_exact_starting_point(player);
-
-  /* check to see if this is a reconnect and also set DARK status */
-  is_hidden = Can_Hide(player) && Dark(player);
-  DESC_ITER_CONN(tmpd) {
-    if (tmpd->player == player) {
-      num++;
-      if (is_hidden)
-       tmpd->hide = 1;
-    }
-  }
-  /* give permanent text messages */
-  if (isnew)
-    fcache_dump(d, fcache.newuser_fcache, NULL);
-  if (num == 1)
-    fcache_dump(d, fcache.motd_fcache, NULL);
-  if (Guest(player))
-    fcache_dump(d, fcache.guest_fcache, NULL);
-
-  if (ModTime(player))
-    notify_format(player, T("%ld failed connections since last login."),
-                 ModTime(player));
-  ModTime(player) = (time_t) 0;
-  announce_connect(player, isnew, num);        /* broadcast connect message */
-  check_last(player, d->addr, d->ip);  /* set Last, Lastsite, give paycheck */
-  /* Check folder 0, not silently (i.e. Report lack of mail, too) */
-  queue_eol(d);
-  if (command_check_byname(player, "@MAIL"))
-    check_mail(player, 0, 0);
-  set_player_folder(player, 0);
-  do_look_around(player);
-  if (Haven(player))
-    notify(player, T("Your HAVEN flag is set. You cannot receive pages."));
-  local_connect(player, isnew, num);
-  return 1;
-}
-
-static int
-check_connect(DESC *d, const char *msg)
-{
-  char command[MAX_COMMAND_LEN];
-  char user[MAX_COMMAND_LEN];
-  char password[MAX_COMMAND_LEN];
-  char errbuf[BUFFER_LEN];
-  dbref player;
-
-  parse_connect(msg, command, user, password);
-
-  if (string_prefix("connect", command)) {
-    if ((player =
-        connect_player(user, password, d->addr, d->ip, errbuf)) == NOTHING) {
-      queue_string_eol(d, errbuf);
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Failed connect to '%s'."),
-            d->descriptor, d->addr, d->ip, user);
-    } else {
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Connected to %s(#%d) in %s(#%d)"),
-            d->descriptor, d->addr, d->ip, Name(player), player,
-            Name(Location(player)), Location(player));
-      /* Check if we're fake siting this guy.. */
-      if(has_flag_by_name(player, "WEIRDSITE", TYPE_PLAYER)) {
-             ATTR *a;
-             a = atr_get(player, "LASTSITE");
-             strncpy(d->addr, !a ? "localhost" : atr_value(a), 100);
-      }
-
-      if ((dump_messages(d, player, 0)) == 0) {
-       d->connected = 2;
-       return 0;
-      }
-    }
-
-  } else if (!strcasecmp(command, "cd")) {
-    if ((player =
-        connect_player(user, password, d->addr, d->ip, errbuf)) == NOTHING) {
-      queue_string_eol(d, errbuf);
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Failed connect to '%s'."),
-            d->descriptor, d->addr, d->ip, user);
-    } else {
-      do_log(LT_CONN, 0, 0,
-            T("[%d/%s/%s] Connected dark to %s(#%d) in %s(#%d)"),
-            d->descriptor, d->addr, d->ip, Name(player), player,
-            Name(Location(player)), Location(player));
-      /* Set player dark */
-      d->connected = 1;
-      d->player = player;
-      set_flag(player, player, "DARK", 0, 0, 0);
-      if ((dump_messages(d, player, 0)) == 0) {
-       d->connected = 2;
-       return 0;
-      }
-    }
-
-  } else if (!strcasecmp(command, "cv")) {
-    if ((player =
-        connect_player(user, password, d->addr, d->ip, errbuf)) == NOTHING) {
-      queue_string_eol(d, errbuf);
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Failed connect to '%s'."),
-            d->descriptor, d->addr, d->ip, user);
-    } else {
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Connected to %s(#%d) in %s(#%d)"),
-            d->descriptor, d->addr, d->ip, Name(player), player,
-            Name(Location(player)), Location(player));
-      /* Set player !dark */
-      d->connected = 1;
-      d->player = player;
-      set_flag(player, player, "DARK", 1, 0, 0);
-      if ((dump_messages(d, player, 0)) == 0) {
-       d->connected = 2;
-       return 0;
-      }
-    }
-
-  } else if (!strcasecmp(command, "ch")) {
-    if ((player =
-        connect_player(user, password, d->addr, d->ip, errbuf)) == NOTHING) {
-      queue_string_eol(d, errbuf);
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Failed connect to '%s'."),
-            d->descriptor, d->addr, d->ip, user);
-    } else {
-      do_log(LT_CONN, 0, 0,
-            T("[%d/%s/%s] Connected hidden to %s(#%d) in %s(#%d)"),
-            d->descriptor, d->addr, d->ip, Name(player), player,
-            Name(Location(player)), Location(player));
-      /* Set player hidden */
-      d->connected = 1;
-      d->player = player;
-      if (Can_Hide(player))
-       d->hide = 1;
-      if ((dump_messages(d, player, 0)) == 0) {
-       d->connected = 2;
-       return 0;
-      }
-    }
-
-  } else if (string_prefix("create", command)) {
-    if (!Site_Can_Create(d->addr) || !Site_Can_Create(d->ip)) {
-      fcache_dump(d, fcache.register_fcache, NULL);
-      if (!Deny_Silent_Site(d->addr, AMBIGUOUS)
-         && !Deny_Silent_Site(d->ip, AMBIGUOUS)) {
-       do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Refused create for '%s'."),
-              d->descriptor, d->addr, d->ip, user);
-      }
-      return 0;
-    }
-    if (!options.login_allow || !options.create_allow) {
-      if (!options.login_allow)
-       fcache_dump(d, fcache.down_fcache, NULL);
-      else
-       fcache_dump(d, fcache.register_fcache, NULL);
-      do_rawlog(LT_CONN,
-               "REFUSED CREATION for %s from %s on descriptor %d.\n",
-               user, d->addr, d->descriptor);
-      return 0;
-    } else if (MAX_LOGINS && !under_limit) {
-      fcache_dump(d, fcache.full_fcache, NULL);
-      do_rawlog(LT_CONN,
-               "REFUSED CREATION for %s from %s on descriptor %d.\n",
-               user, d->addr, d->descriptor);
-      return 0;
-    }
-    player = create_player(user, password, d->addr, d->ip);
-    if (player == NOTHING) {
-      queue_string_eol(d, T(create_fail));
-      do_log(LT_CONN, 0, 0,
-            T("[%d/%s/%s] Failed create for '%s' (bad name)."),
-            d->descriptor, d->addr, d->ip, user);
-    } else if (player == AMBIGUOUS) {
-      queue_string_eol(d, T(password_fail));
-      do_log(LT_CONN, 0, 0,
-            T("[%d/%s/%s] Failed create for '%s' (bad password)."),
-            d->descriptor, d->addr, d->ip, user);
-    } else {
-      do_log(LT_CONN, 0, 0, "[%d/%s/%s] Created %s(#%d)",
-            d->descriptor, d->addr, d->ip, Name(player), player);
-      if ((dump_messages(d, player, 1)) == 0) {
-       d->connected = 2;
-       return 0;
-      }
-    }                          /* successful player creation */
-
-  } else if (string_prefix("register", command)) {
-    if (!Site_Can_Register(d->addr) || !Site_Can_Register(d->ip)) {
-      fcache_dump(d, fcache.register_fcache, NULL);
-      if (!Deny_Silent_Site(d->addr, AMBIGUOUS)
-         && !Deny_Silent_Site(d->ip, AMBIGUOUS)) {
-       do_log(LT_CONN, 0, 0,
-              T("[%d/%s/%s] Refused registration (bad site) for '%s'."),
-              d->descriptor, d->addr, d->ip, user);
-      }
-      return 0;
-    }
-    if (!options.create_allow) {
-      fcache_dump(d, fcache.register_fcache, NULL);
-      do_rawlog(LT_CONN,
-               "Refused registration (creation disabled) for %s from %s on descriptor %d.\n",
-               user, d->addr, d->descriptor);
-      return 0;
-    }
-    if ((player = email_register_player(user, password, d->addr, d->ip)) ==
-       NOTHING) {
-      queue_string_eol(d, T(register_fail));
-      do_log(LT_CONN, 0, 0, T("[%d/%s/%s] Failed registration for '%s'."),
-            d->descriptor, d->addr, d->ip, user);
-    } else {
-      queue_string_eol(d, T(register_success));
-      do_log(LT_CONN, 0, 0, "[%d/%s/%s] Registered %s(#%d) to %s",
-            d->descriptor, d->addr, d->ip, Name(player), player, password);
-    }
-    /* Whether it succeeds or fails, leave them connected */
-
-  } else {
-    /* invalid command, just repeat login screen */
-    welcome_user(d);
-  }
-  /* If they were in a program, get them back in it */
-  if(InProg(d->player)) {
-    queue_string(d, "Loading @Program onto Descriptor....\r\n");
-    prog_load_desc(d);
-  }
-
-  return 1;
-}
-
-static void
-parse_connect(const char *msg1, char *command, char *user, char *pass)
-{
-  unsigned char *p;
-  unsigned const char *msg = (unsigned const char *) msg1;
-
-  while (*msg && isspace(*msg))
-    msg++;
-  p = (unsigned char *) command;
-  while (*msg && isprint(*msg) && !isspace(*msg))
-    *p++ = *msg++;
-  *p = '\0';
-  while (*msg && isspace(*msg))
-    msg++;
-  p = (unsigned char *) user;
-
-  if (PLAYER_NAME_SPACES && *msg == '\"') {
-    for (; *msg && ((*msg == '\"') || isspace(*msg)); msg++) ;
-    while (*msg && (*msg != '\"')) {
-      while (*msg && !isspace(*msg) && (*msg != '\"'))
-       *p++ = *msg++;
-      if (*msg == '\"') {
-       msg++;
-       while (*msg && isspace(*msg))
-         msg++;
-       break;
-      }
-      while (*msg && isspace(*msg))
-       msg++;
-      if (*msg && (*msg != '\"'))
-       *p++ = ' ';
-    }
-  } else
-    while (*msg && isprint(*msg) && !isspace(*msg))
-      *p++ = *msg++;
-
-  *p = '\0';
-  while (*msg && isspace(*msg))
-    msg++;
-  p = (unsigned char *) pass;
-  while (*msg && isprint(*msg) && !isspace(*msg))
-    *p++ = *msg++;
-  *p = '\0';
-}
-
-static void
-close_sockets(void)
-{
-  DESC *d, *dnext;
-
-  for (d = descriptor_list; d; d = dnext) {
-    dnext = d->next;
-    if(d->descriptor == 0) {
-      write(STDOUT_FILENO, T(shutdown_message), strlen(T(shutdown_message)));
-      write(STDOUT_FILENO, "\r\n", 2);
-    } else {
-      send(d->descriptor, T(shutdown_message), strlen(T(shutdown_message)), 0);
-      send(d->descriptor, "\r\n", 2, 0);
-      if (shutdown(d->descriptor, 2) < 0)
-        perror("shutdown");
-      closesocket(d->descriptor);
-    }
-  }
-}
-
-/** Give everyone the boot.
- */
-void
-emergency_shutdown(void)
-{
-  close_sockets();
-}
-
-/** Disconnect a descriptor.
- * \param d pointer to descriptor to disconnect.
- */
-void
-boot_desc(DESC *d)
-{
-  shutdownsock(d);
-}
-
-/** Given a player dbref, return the player's first connected descriptor.
- * \param player dbref of player.
- * \return pointer to player's first connected descriptor, or NULL.
- */
-DESC *
-player_desc(dbref player)
-{
-  DESC *d;
-  for (d = descriptor_list; d; d = d->next) {
-    if (d->connected && (d->player == player)) {
-      return d;
-    }
-  }
-  return (DESC *) NULL;
-}
-
-/** Page a specified socket.
- * \param player the enactor.
- * \param pc string containing port number to send message to.
- * \param message message to send.
- */
-void
-do_page_port(dbref player, const char *pc, const char *message)
-{
-  int p, key;
-  DESC *d;
-  const char *gap;
-  char tbuf[BUFFER_LEN], *tbp = tbuf;
-  dbref target = NOTHING;
-
-  if (!Admin(player)) {
-    notify(player, T("Permission denied."));
-    return;
-  }
-  p = atoi(pc);
-  if (p <= 0) {
-    notify(player, T("That's not a port number."));
-    return;
-  }
-
-  if (!message || !*message) {
-    notify(player, T("What do you want to page with?"));
-    return;
-  }
-
-  gap = " ";
-  switch (*message) {
-  case SEMI_POSE_TOKEN:
-    gap = "";
-  case POSE_TOKEN:
-    key = 1;
-    break;
-  default:
-    key = 3;
-    break;
-  }
-
-  d = port_desc(p);
-  if (!d) {
-    notify(player, T("That port's not active."));
-    return;
-  }
-  if (d->connected)
-    target = d->player;
-  switch (key) {
-  case 1:
-    safe_format(tbuf, &tbp, T("From afar, %s%s%s"), Name(player), gap,
-               message + 1);
-    notify_format(player, T("Long distance to %s: %s%s%s"),
-                 target != NOTHING ? Name(target) :
-                 T("a connecting player"), Name(player), gap, message + 1);
-    break;
-  case 3:
-    safe_format(tbuf, &tbp, T("%s pages: %s"), Name(player), message);
-    notify_format(player, T("You paged %s with '%s'."),
-                 target != NOTHING ? Name(target) :
-                 T("a connecting player"), message);
-    break;
-  }
-  *tbp = '\0';
-  if (target != NOTHING)
-    page_return(player, target, "Idle", "IDLE", NULL);
-  if (Typeof(player) != TYPE_PLAYER && Nospoof(target))
-    queue_string_eol(d, tprintf("[#%d] %s", player, tbuf));
-  else
-    queue_string_eol(d, tbuf);
-}
-
-
-/** Return an inactive descriptor, as long as there's more than
- * one descriptor connected. Used for boot/me.
- * \param player player to find an inactive descriptor for.
- * \return pointer to player's inactive descriptor, or NULL.
- */
-DESC *
-inactive_desc(dbref player)
-{
-  DESC *d, *in = NULL;
-  time_t now;
-  int numd = 0;
-  now = mudtime;
-  DESC_ITER_CONN(d) {
-    if (d->player == player) {
-      numd++;
-      if (now - d->last_time > 60)
-       in = d;
-    }
-  }
-  if (numd > 1)
-    return in;
-  else
-    return (DESC *) NULL;
-}
-
-/** Given a port (a socket number), return the descriptor.
- * \param port port (socket file descriptor number).
- * \return pointer to descriptor associated with the port.
- */
-DESC *
-port_desc(int port)
-{
-  DESC *d;
-  for (d = descriptor_list; (d); d = d->next) {
-    if (d->descriptor == port) {
-      return d;
-    }
-  }
-  return (DESC *) NULL;
-}
-
-/** Given a port, find the matching player dbref.
- * \param port (socket file descriptor number).
- * \return dbref of connected player using that port, or NOTHING.
- */
-dbref
-find_player_by_desc(int port)
-{
-  DESC *d;
-  for (d = descriptor_list; (d); d = d->next) {
-    if (d->connected && (d->descriptor == port)) {
-      return d->player;
-    }
-  }
-
-  /* didn't find anything */
-  return NOTHING;
-}
-
-
-#ifndef WIN32
-/** Handler for SIGINT. Note that we've received it, and reinstall.
- * \param sig signal caught.
- */
-void
-signal_shutdown(int sig __attribute__ ((__unused__)))
-{
-  signal_shutdown_flag = 1;
-  reload_sig_handler(SIGINT, signal_shutdown);
-}
-
-/** Handler for SIGUSR2. Note that we've received it, and reinstall
- * \param sig signal caught.
- */
-void
-signal_dump(int sig __attribute__ ((__unused__)))
-{
-  signal_dump_flag = 1;
-  reload_sig_handler(SIGUSR2, signal_dump);
-}
-#endif
-
-/** A general handler to puke and die.
- * \param sig signal caught.
- */
-void
-bailout(int sig)
-{
-  mush_panicf(T("BAILOUT: caught signal %d"), sig);
-}
-
-#ifndef WIN32
-/** Reap child processes, notably info_slaves and forking dumps,
- * when we receive a SIGCHLD signal. Don't fear this function. :)
- * \param sig signal caught.
- */
-void
-reaper(int sig __attribute__ ((__unused__)))
-{
-  WAIT_TYPE my_stat;
-  Pid_t pid;
-
-#ifdef HAS_WAITPID
-  while ((pid = waitpid(-1, &my_stat, WNOHANG)) > 0)
-#else
-  while ((pid = wait3(&my_stat, WNOHANG, 0)) > 0)
-#endif
-  {
-    if (forked_dump_pid > -1 && pid == forked_dump_pid) {
-      /* Most failures are handled by the forked mush already */
-      if (WIFSIGNALED(my_stat)) {
-       do_rawlog(LT_ERR, T("ERROR! forking dump exited with signal %d"),
-                 WTERMSIG(my_stat));
-      } else if (WIFEXITED(my_stat) && WEXITSTATUS(my_stat) == 0) {
-       time(&globals.last_dump_time);
-       if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE)
-         flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE);
-
-      }
-      forked_dump_pid = -1;
-    }
-  }
-  reload_sig_handler(SIGCHLD, reaper);
-}
-#endif /* !WIN32 */
-
-
-static void
-dump_info(DESC *call_by)
-{
-  int count = 0;
-  DESC *d;
-  queue_string_eol(call_by, tprintf("### Begin INFO %s", INFO_VERSION));
-
-  /* Count connected players */
-  for (d = descriptor_list; d; d = d->next) {
-    if (d->connected) {
-      if (!GoodObject(d->player))
-       continue;
-      if (COUNT_ALL || !Hidden(d) || call_by->player == d->player )
-       count++;
-    }
-  }
-  queue_string_eol(call_by, tprintf("Name: %s", options.mud_name));
-  queue_string_eol(call_by,
-                  tprintf("Uptime: %s", show_time(globals.first_start_time, 0)));
-  queue_string_eol(call_by, tprintf("Connected: %d", count));
-  queue_string_eol(call_by, tprintf("Size: %d", db_top));
-  queue_string_eol(call_by, tprintf("Version: CobraMUSH v%s [%s]", VERSION,
-                       VBRANCH));
-#ifdef PATCHES
-  queue_string_eol(call_by, tprintf("Patches: %s", PATCHES));
-#endif
-  queue_string_eol(call_by, "### End INFO");
-}
-
-static void
-dump_users(DESC *call_by, char *match, int doing)
-    /* doing: 0 if normal WHO, 1 if DOING, 2 if SESSION */
-{
-  DESC *d;
-#ifdef COLOREDWHO
-  int tcount = 0; 
-#endif
-  int count = 0;
-  time_t now;
-  char tbuf1[BUFFER_LEN];
-  char tbuf2[BUFFER_LEN];
-  int csite;
-
-  if (!GoodObject(call_by->player)) {
-    do_log(LT_ERR, 0, 0, T("Bogus caller #%d of dump_users"), call_by->player);
-    return;
-  }
-  while (*match && *match == ' ')
-    match++;
-  now = mudtime;
-
-  /* If an admin types "DOING" it gives him the normal player WHO,
-   * BUT flags are not shown. Privileged WHO does not show @doings.
-   */
-
-  if (SUPPORT_PUEBLO && (call_by->conn_flags & CONN_HTML)) {
-    queue_newwrite(call_by, (unsigned char *) "<img xch_mode=html>", 19);
-    queue_newwrite(call_by, (unsigned char *) "<PRE>", 5);
-  }
-
-  if ((doing == 1) || !call_by->player || !Priv_Who(call_by->player)) {
-    if (poll_msg[0] == '\0')
-      strcpy(poll_msg, "Doing");
-    if (ShowAnsi(call_by->player))
-      sprintf(tbuf2, "%s%-16s %4s %10s %6s  %s%s\n", ANSI_HILITE,
-             T("Player Name"), T("Aff"), T("On For"), T("Idle"), poll_msg, ANSI_NORMAL);
-    else
-      sprintf(tbuf2, "%-16s %4s %10s %6s  %s\n",
-             T("Player Name"), T("Aff"), T("On For"), T("Idle"), poll_msg);
-    queue_string(call_by, tbuf2);
-  } else if (doing == 2) {
-    sprintf(tbuf2, "%s%-16s %6s %9s %5s %5s Des  Sent    Recv  Pend%s\n", ShowAnsi(call_by->player) ? ANSI_HILITE :
-                   "", T("Player Name"), T("Loc #"), T("On For"), T("Idle"), T("Cmds"),
-                   ShowAnsi(call_by->player) ? ANSI_NORMAL : "");
-    queue_string(call_by, tbuf2);
-  } else {
-    sprintf(tbuf2, "%s%-16s %6s %9s %5s %5s Des  Host%s\n", ShowAnsi(call_by->player) ? ANSI_HILITE : "",
-           T("Player Name"), T("Loc #"), T("On For"), T("Idle"), T("Cmds"), ShowAnsi(call_by->player) ? ANSI_NORMAL : "");
-    queue_string(call_by, tbuf2);
-  }
-
-  for (d = descriptor_list; d; d = d->next) {
-    if (d->connected) {
-      if (!GoodObject(d->player))
-       continue;
-      if (COUNT_ALL || (!Hidden(d) || call_by->player == d->player 
-                       || (call_by->player && Priv_Who(call_by->player)))) {
-        count++;
-#ifdef COLOREDWHO
-        tcount++;
-#endif
-      }
-      if (match && !(string_prefix(Name(d->player), match)))
-       continue;
-      csite = CanSee(call_by->player, d->player);
-
-      if (call_by->connected && doing == 0 && call_by->player
-         && Priv_Who(call_by->player)) {
-        if (Hidden(d) && !csite)
-          continue;
-
-       sprintf(tbuf1, "%-16s %6s %9s %5s  %4d %3d%c  %s", tprintf("%s%s", Name(d->player), InProg(d->player) ? "(P)" : ""),
-               Can_Locate(call_by->player, d->player) ? unparse_dbref(Location(d->player)) : "#-1",
-               time_format_1(now - d->connected_at),
-               time_format_2(now - d->last_time), csite ? d->cmds : 0,
-               csite ? d->descriptor : 0,
-               ' ',
-               csite ? d->addr : "---");
-       tbuf1[78] = '\0';
-       if (Dark(d->player)) {
-         tbuf1[71] = '\0';
-         strcat(tbuf1, " (Dark)");
-       } else if (Hidden(d)) {
-         tbuf1[71] = '\0';
-         strcat(tbuf1, " (Hide)");
-       }
-      } else if (call_by->connected && doing == 2 && call_by->player
-                && Priv_Who(call_by->player)) {
-       sprintf(tbuf1, "%-16s %6s %9s %5s %5d %3d%c %5lu %7lu %5d",
-               tprintf("%s%s", Name(d->player), InProg(d->player) ? "(P)" : ""),
-               Can_Locate(call_by->player, d->player) ? unparse_dbref(Location(d->player)) : "#-1",
-               time_format_1(now - d->connected_at),
-               time_format_2(now - d->last_time), csite ? d->cmds : 0,
-               csite ? d->descriptor : 0,
-               ' ',
-
-               csite ? d->input_chars : 0, csite ? d->output_chars : 0,
-               csite ? d->output_size : 0);
-      } else {
-       if (!Hidden(d)
-           || call_by->player == d->player ||
-           (call_by->player && Priv_Who(call_by->player) && (doing))) {
-         sprintf(tbuf1, "%-16s %4s %10s   %4s%c %s", tprintf("%s%s", Name(d->player), InProg(d->player) ? "(P)" : ""), empabb(d->player),
-                 time_format_1(now - d->connected_at),
-                 time_format_2(now - d->last_time),
-                 (Dark(d->player) ? 'D' : (Hidden(d) ? 'H' : ' '))
-                 , d->doing);
-       }
-      }
-
-      if (!Hidden(d) || (call_by->player && Priv_Who(call_by->player))) {
-#ifdef COLOREDWHO
-       if(ShowAnsiColor(call_by->player))
-               queue_string(call_by, tprintf("%s%s%s%s%s", ANSI_NORMAL, (tcount % 2 ?  "" : ANSI_HILITE), 
-                                       (tcount % 2 ? ANSI_CYAN : ANSI_WHITE),
-                                       tbuf1, ANSI_NORMAL));
-
-       else 
-#endif
-               queue_string(call_by, tbuf1);
-       queue_newwrite(call_by, (unsigned char *) "\r\n", 2);
-      }
-    } else if (call_by->player && Priv_Who(call_by->player) && doing != 1
-              && (!match || !*match)) {
-#ifdef COLOREDWHO
-      tcount++;
-#endif
-      if (doing == 0) {
-       /* Privileged WHO for non-logged in connections */
-       sprintf(tbuf1, "%-16s %6s %9s %5s  %4d %3d%c  %s", T("Connecting..."),
-               "#-1",
-               time_format_1(now - d->connected_at),
-               time_format_2(now - d->last_time), d->cmds, d->descriptor,
-                             ' ',
-
-               d->addr);
-       tbuf1[78] = '\0';
-      } else {
-       /* SESSION for non-logged in connections */
-       sprintf(tbuf1, "%-16s %5s %9s %5s %5d %3d%c %5lu %7lu %5d",
-               T("Connecting..."), "#-1",
-               time_format_1(now - d->connected_at),
-               time_format_2(now - d->last_time), d->cmds, d->descriptor,
-                             ' ',
-               d->input_chars, d->output_chars, d->output_size);
-      }
-#ifdef COLOREDWHO
-      if(ShowAnsiColor(call_by->player))
-             queue_string(call_by, tprintf("%s%s%s%s%s", ANSI_NORMAL,tcount % 2 ?  "" : ANSI_HILITE,
-                                     tcount % 2 ? ANSI_CYAN : ANSI_WHITE, tbuf1, ANSI_NORMAL));
-      else 
-#endif
-             queue_string(call_by, tbuf1);
-      queue_newwrite(call_by, (unsigned char *) "\r\n", 2);
-    }
-  }
-  switch (count) {
-  case 0:
-    strcpy(tbuf1, T("There are no players connected."));
-    break;
-  case 1:
-    strcpy(tbuf1, T("There is 1 player connected."));
-    break;
-  default:
-    sprintf(tbuf1, T("There are %d players connected."), count);
-    break;
-  }
-
-#ifdef COLOREDWHO
-  if(ShowAnsiColor(call_by->player))
-         queue_string(call_by, tprintf("%s%s%s%s%s", ANSI_NORMAL, (tcount+1) % 2 ? "" : ANSI_HILITE ,
-                                 (tcount+1) % 2 ? ANSI_CYAN : ANSI_WHITE, tbuf1, ANSI_NORMAL));
-  else 
-#endif
-         queue_string(call_by, tbuf1);
-  if (SUPPORT_PUEBLO && (call_by->conn_flags & CONN_HTML)) {
-    queue_newwrite(call_by, (unsigned char *) "\n</PRE>\n", 8);
-    queue_newwrite(call_by, (unsigned char *) "<img xch_mode=purehtml>", 23);
-  } else
-    queue_newwrite(call_by, (unsigned char *) "\r\n", 2);
-}
-
-static const char *
-time_format_1(long dt)
-{
-  register struct tm *delta;
-  time_t holder;               /* A hack for 64bit SGI */
-  static char buf[64];
-  if (dt < 0)
-    dt = 0;
-  holder = (time_t) dt;
-  delta = gmtime(&holder);
-  if (delta->tm_yday > 0) {
-    sprintf(buf, "%dd %02d:%02d",
-           delta->tm_yday, delta->tm_hour, delta->tm_min);
-  } else {
-    sprintf(buf, "%02d:%02d", delta->tm_hour, delta->tm_min);
-  }
-  return buf;
-}
-
-static const char *
-time_format_2(long dt)
-{
-  register struct tm *delta;
-  static char buf[64];
-  if (dt < 0)
-    dt = 0;
-
-  delta = gmtime((time_t *) & dt);
-  if (delta->tm_yday > 0) {
-    sprintf(buf, "%dd", delta->tm_yday);
-  } else if (delta->tm_hour > 0) {
-    sprintf(buf, "%dh", delta->tm_hour);
-  } else if (delta->tm_min > 0) {
-    sprintf(buf, "%dm", delta->tm_min);
-  } else {
-    sprintf(buf, "%ds", delta->tm_sec);
-  }
-  return buf;
-}
-
-/* connection messages
- * isnew: newly creaetd or not?
- * num: how many times connected?
- */
-void
-announce_connect(dbref player, int isnew, int num)
-{
-  dbref loc;
-  char tbuf1[BUFFER_LEN];
-  dbref zone;
-  dbref obj;
-  int j;
-
-  set_flag_internal(player, "CONNECTED");
-
-  if (isnew) {
-    /* A brand new player created. */
-    sprintf(tbuf1, T("%s created."), Name(player));
-    flag_broadcast(0, "MONITOR", "%s %s", T("GAME:"), tbuf1);
-  }
-
-  /* Redundant, but better for translators */
-  if (Dark(player)) {
-    sprintf(tbuf1, (num > 1) ? T("%s has DARK-reconnected.") :
-           T("%s has DARK-connected."), Name(player));
-  } else if (hidden(player)) {
-    sprintf(tbuf1, (num > 1) ? T("%s has HIDDEN-reconnected.") :
-           T("%s has HIDDEN-connected."), Name(player));
-  } else {
-    sprintf(tbuf1, (num > 1) ? T("%s has reconnected.") :
-           T("%s has connected."), Name(player));
-  }
-
-  /* send out messages */
-  if (!Dark(player))
-    flag_broadcast(0, "MONITOR", "%s %s", T("GAME:"), tbuf1);
-
-#ifdef CHAT_SYSTEM
-  if (ANNOUNCE_CONNECTS)
-    chat_player_announce(player, tbuf1, (num == 1));
-#endif /* CHAT_SYSTEM */
-
-  loc = Location(player);
-  if (!GoodObject(loc)) {
-    notify(player, T("You are nowhere!"));
-    return;
-  }
-  orator = player;
-
-  if (cf_motd_msg && *cf_motd_msg) {
-    raw_notify(player, cf_motd_msg);
-  }
-  raw_notify(player, " ");
-
-  if(ANNOUNCE_CONNECTS)
-    notify_except(Contents(player), player, tbuf1, 0);
-  /* added to allow player's inventory to hear a player connect */
-  if(ANNOUNCE_CONNECTS)
-    if(!Dark(player))
-    notify_except(Contents(loc), player, tbuf1, NA_INTER_PRESENCE);
-
-  /* clear the environment for possible actions */
-  for (j = 0; j < 10; j++)
-    global_eval_context.wnxt[j] = NULL;
-  for (j = 0; j < NUMQ; j++)
-    global_eval_context.rnxt[j] = NULL;
-  strcpy(global_eval_context.ccom, "");
-
-  /* do the person's personal connect action */
-  (void) queue_attribute(player, "ACONNECT", player);
-  if (ROOM_CONNECTS) {
-    /* Do the room the player connected into */
-    if (IsRoom(loc) || IsThing(loc)) {
-      (void) queue_attribute(loc, "ACONNECT", player);
-    }
-  }
-  /* do the person's division */
-  if (GoodObject(SDIV(player).object))
-    (void) queue_attribute(SDIV(player).object, "ACONNECT", player);
-  /* do the zone of the player's location's possible aconnect */
-  if ((zone = Zone(loc)) != NOTHING) {
-    switch (Typeof(zone)) {
-    case TYPE_THING:
-      (void) queue_attribute(zone, "ACONNECT", player);
-      break;
-    case TYPE_ROOM:
-      /* check every object in the room for a connect action */
-      DOLIST(obj, Contents(zone)) {
-       (void) queue_attribute(obj, "ACONNECT", player);
-      }
-      break;
-    default:
-      do_log(LT_ERR, 0, 0,
-            T("Invalid zone #%d for %s(#%d) has bad type %d"), zone,
-            Name(player), player, Typeof(zone));
-    }
-  }
-  /* now try the master room */
-  DOLIST(obj, Contents(MASTER_ROOM)) {
-    (void) queue_attribute(obj, "ACONNECT", player);
-  }
-}
-
-void
-announce_disconnect(dbref player)
-{
-  dbref loc;
-  int num;
-  DESC *d;
-  char tbuf1[BUFFER_LEN];
-  dbref zone, obj;
-  int j;
-
-  loc = Location(player);
-  if (!GoodObject(loc))
-    return;
-
-  orator = player;
-
-  for (num = 0, d = descriptor_list; d; d = d->next)
-    if (d->connected && (d->player == player))
-      num++;
-  if (num < 2) {
-    sprintf(tbuf1, T("%s has disconnected."), Name(player));
-
-    if (ANNOUNCE_CONNECTS) {
-      if (!Dark(player))
-       notify_except(Contents(loc), player, tbuf1, NA_INTER_PRESENCE);
-      /* notify contents */
-      notify_except(Contents(player), player, tbuf1, 0);
-    }
-
-    /* clear the environment for possible actions */
-    for (j = 0; j < 10; j++)
-      global_eval_context.wnxt[j] = NULL;
-    for (j = 0; j < NUMQ; j++)
-      global_eval_context.rnxt[j] = NULL;
-    strcpy(global_eval_context.ccom, "");
-
-    /* Setup all connect information as info to pass */
-    (void) queue_attribute(player, "ADISCONNECT", player);
-    /* do the person's division */
-    if (GoodObject(SDIV(player).object))
-      (void) queue_attribute(SDIV(player).object, "ACONNECT", player);
-    if (ROOM_CONNECTS)
-      if (IsRoom(loc) || IsThing(loc)) {
-       (void) queue_attribute(loc, "ADISCONNECT", player);
-      }
-    /* do the zone of the player's location's possible adisconnect */
-    if ((zone = Zone(loc)) != NOTHING) {
-      switch (Typeof(zone)) {
-      case TYPE_DIVISION:
-      case TYPE_THING:
-       (void) queue_attribute(zone, "ADISCONNECT", player);
-       break;
-      case TYPE_ROOM:
-       /* check every object in the room for a connect action */
-       DOLIST(obj, Contents(zone)) {
-         (void) queue_attribute(obj, "ADISCONNECT", player);
-       }
-       break;
-      default:
-       do_log(LT_ERR, 0, 0,
-              T("Invalid zone #%d for %s(#%d) has bad type %d"), zone,
-              Name(player), player, Typeof(zone));
-      }
-    }
-    /* now try the master room */
-    DOLIST(obj, Contents(MASTER_ROOM)) {
-      (void) queue_attribute(obj, "ADISCONNECT", player);
-    }
-    clear_flag_internal(player, "CONNECTED");
-    (void) atr_add(player, "LASTLOGOUT", show_time(mudtime, 0), GOD, NOTHING);
-  } else {
-    /* note: when you partially disconnect, ADISCONNECTS are not executed */
-    sprintf(tbuf1, T("%s has partially disconnected."), Name(player));
-
-    if (ANNOUNCE_CONNECTS) {
-      if (!Dark(player))
-       notify_except(Contents(loc), player, tbuf1, NA_INTER_PRESENCE);
-      /* notify contents */
-      notify_except(Contents(player), player, tbuf1, 0);
-    }
-  }
-
-#ifdef CHAT_SYSTEM
-  if (ANNOUNCE_CONNECTS)
-    chat_player_announce(player, tbuf1, 0);
-#endif /* CHAT_SYSTEM */
-
-  /* Monitor broadcasts */
-  /* Redundant, but better for translators */
-  if (Dark(player)) {
-    sprintf(tbuf1, (num < 2) ? T("%s has DARK-disconnected.") :
-           T("%s has partially DARK-disconnected."), Name(player));
-  } else if (hidden(player)) {
-    sprintf(tbuf1, (num < 2) ? T("%s has HIDDEN-disconnected.") :
-           T("%s has partially HIDDEN-disconnected."), Name(player));
-  } else {
-    sprintf(tbuf1, (num < 2) ? T("%s has disconnected.") :
-           T("%s has partially disconnected."), Name(player));
-  }
-  if (!Dark(player))
-    flag_broadcast(0, "MONITOR", "%s %s", T("GAME:"), tbuf1);
-  if(Guest(player))  { /* queue for destruction */
-      set_flag_internal(player, "GOING");
-      set_flag_internal(player, "GOING_TWICE");
-    }
-  local_disconnect(player, num);
-}
-
-/** Set an motd message.
- * \verbatim
- * This implements @motd.
- * \endverbatim
- * \param player the enactor.
- * \param key type of MOTD to set.
- * \param message text to set the motd to.
- */
-void
-do_motd(dbref player, enum motd_type key, const char *message)
-{
-
-  if (!Site(player) && key != MOTD_LIST) {
-    notify(player,
-          T
-          ("You may get 15 minutes of fame and glory in life, but not right now."));
-    return;
-  }
-  switch (key) {
-  case MOTD_MOTD:
-    strcpy(cf_motd_msg, message);
-    notify(player, T("Motd set."));
-    break;
-  case MOTD_DOWN:
-    strcpy(cf_downmotd_msg, message);
-    notify(player, T("Down motd set."));
-    break;
-  case MOTD_FULL:
-    strcpy(cf_fullmotd_msg, message);
-    notify(player, T("Full motd set."));
-    break;
-  case MOTD_LIST:
-    notify_format(player, "MOTD: %s", cf_motd_msg);
-    if (Site(player)) {
-      notify_format(player, T("Down MOTD: %s"), cf_downmotd_msg);
-      notify_format(player, T("Full MOTD: %s"), cf_fullmotd_msg);
-    }
-  }
-}
-
-/** Set a DOING message.
- * \verbatim
- * This implements @doing.
- * \endverbatim
- * \param player the enactor.
- * \param message the message to set.
- */
-void
-do_doing(dbref player, const char *message)
-{
-  char buf[MAX_COMMAND_LEN];
-  DESC *d;
-  int i;
-
-  if (!Connected(player)) {
-    /* non-connected things have no need for a doing */
-    notify(player, T("Why would you want to do that?"));
-    return;
-  }
-  strncpy(buf, remove_markup(message, NULL), DOING_LEN - 1);
-
-  /* now smash undesirable characters and truncate */
-  for (i = 0; i < DOING_LEN; i++) {
-    if ((buf[i] == '\r') || (buf[i] == '\n') ||
-       (buf[i] == '\t') || (buf[i] == BEEP_CHAR))
-      buf[i] = ' ';
-  }
-  buf[DOING_LEN - 1] = '\0';
-
-  /* set it */
-  for (d = descriptor_list; d; d = d->next)
-    if (d->connected && (d->player == player))
-      strcpy(d->doing, buf);
-  if (strlen(message) >= DOING_LEN) {
-    notify_format(player,
-                 T("Doing set. %zu characters lost."),
-                 strlen(message) - (DOING_LEN - 1));
-  } else
-    notify(player, T("Doing set."));
-}
-
-/** Set a poll message (which replaces "Doing" in the DOING output).
- * \verbatim
- * This implements @poll.
- * \endverbatim
- * \param player the enactor.
- * \param message the message to set.
- */
-void
-do_poll(dbref player, const char *message)
-{
-  int i;
-
-  if (!Change_Poll(player)) {
-    notify(player, T("Who do you think you are, Gallup?"));
-    return;
-  }
-  strncpy(poll_msg, remove_markup(message, NULL), DOING_LEN - 1);
-  for (i = 0; i < DOING_LEN; i++) {
-    if ((poll_msg[i] == '\r') || (poll_msg[i] == '\n') ||
-       (poll_msg[i] == '\t') || (poll_msg[i] == BEEP_CHAR))
-      poll_msg[i] = ' ';
-  }
-  poll_msg[DOING_LEN - 1] = '\0';
-
-  if (strlen(message) >= DOING_LEN) {
-    poll_msg[DOING_LEN - 1] = 0;
-    notify_format(player,
-                 T("Poll set. %zu characters lost."),
-                 strlen(message) - (DOING_LEN - 1));
-  } else
-    notify(player, T("Poll set."));
-  do_log(LT_WIZ, player, NOTHING, T("Poll Set to '%s'."), poll_msg);
-}
-
-/** Match the partial name of a connected player.
- * \param match string to match.
- * \return dbref of a unique connected player whose name partial-matches, 
- * AMBIGUOUS, or NOTHING.
- */
-dbref
-short_page(const char *match)
-{
-  DESC *d;
-  dbref who1 = NOTHING;
-  int count = 0;
-
-  for (d = descriptor_list; d; d = d->next) {
-    if (d->connected) {
-      if (match && !string_prefix(Name(d->player), match))
-       continue;
-      if (!strcasecmp(Name(d->player), match)) {
-       count = 1;
-       who1 = d->player;
-       break;
-      }
-      if (who1 == NOTHING || d->player != who1) {
-       who1 = d->player;
-       count++;
-      }
-    }
-  }
-
-  if (count > 1)
-    return AMBIGUOUS;
-  else if (count == 0)
-    return NOTHING;
-
-  return who1;
-}
-
-/** Match the partial name of a connected player the enactor can see.
- * \param player the enactor
- * \param match string to match.
- * \return dbref of a unique connected player whose name partial-matches, 
- * AMBIGUOUS, or NOTHING.
- */
-dbref
-visible_short_page(dbref player, const char *match)
-{
-  dbref target;
-  target = short_page(match);
-  if (Priv_Who(player) || !GoodObject(target))
-    return target;
-  if (Dark(target) || (hidden(target) && !nearby(player, target)))
-    return NOTHING;
-  return target;
-}
-
-/* LWHO() function - really belongs elsewhere but needs stuff declared here */
-
-FUNCTION(fun_nwho) {
-}
-
-/* ARGSUSED */
-FUNCTION(fun_lwho)
-{
-  DESC *d;
-  dbref victim;
-  int first, powered = (*called_as == 'L') && Priv_Who(executor);
-
-  first = 1;
-  if(nargs && args[0] && *args[0]) {
-    if(!powered) {
-      safe_str(T(e_perm), buff, bp);
-      return;
-    }
-
-    if( (victim = noisy_match_result(executor, args[0], NOTYPE, MAT_EVERYTHING)) == 0) {
-      safe_str(T(e_notvis), buff, bp);
-      return;
-    }
-    if(!controls(executor, victim)) {
-      safe_str(T(e_perm), buff, bp);
-      return;
-    }
-    if(!Priv_Who(victim))
-      powered = 0;
-  } else victim = executor;
-  
-  DESC_ITER_CONN(d) {
-    if (!Hidden(d) || (powered && CanSee(victim,d->player))) {
-      if (first)
-       first = 0;
-      else
-       safe_chr(' ', buff, bp);
-      safe_dbref(d->player, buff, bp);
-    }
-  }
-}
-
-
-/** Look up a DESC by character name or file descriptor.
- * \param executor the dbref of the object calling the function calling this.
- * \param name the name or descriptor to look up.
- * \retval a pointer to the proper DESC, or NULL
- */
-static DESC *
-lookup_desc(dbref executor, const char *name)
-{
-  DESC *d;
-
-  /* Given a file descriptor. See-all only. */
-  if (is_strict_integer(name)) {
-    int fd = parse_integer(name);
-    DESC_ITER_CONN(d) {
-      if (d->descriptor == fd) {
-       if (Priv_Who(executor) || d->player == executor
-       || (Inherit_Powers(executor) && Priv_Who(Owner(executor))))
-         return d;
-       else
-         return NULL;
-      }
-    }
-    return NULL;
-  } else {                    /* Look up player name */
-    DESC *match = NULL;
-    dbref target = lookup_player(name);
-    if (target == NOTHING) {
-      target = match_result(executor, name, TYPE_PLAYER,
-                           MAT_ABSOLUTE | MAT_PLAYER | MAT_ME);
-    }
-    if (!GoodObject(target) || !Connected(target))
-      return NULL;
-    else {
-      /* walk the descriptor list looking for a match of a dbref */
-      DESC_ITER_CONN(d) {
-       if ((d->player == target) &&
-           (!Hidden(d) || Priv_Who(executor) ||
-               (Inherit_Powers(executor) && Priv_Who(Owner(executor)))) &&
-           (!match || (d->last_time > match->last_time)))
-         match = d;
-      }
-      return match;
-    }
-  }
-}
-
-/** Return the conn time of the longest-connected connection of a player.
- * This function treats hidden connectios as nonexistent.
- * \param player dbref of player to get ip for.
- * \return connection time of player as an INT, or -1 if not found or hidden.
- */
-int
-most_conn_time(dbref player)
-{
-  DESC *d, *match = NULL;
-  DESC_ITER_CONN(d) {
-    if ((d->player == player) && !Hidden(d) && (!match ||
-                                               (d->connected_at >
-                                                match->connected_at)))
-      match = d;
-  }
-  if (match) {
-    double result = difftime(mudtime, match->connected_at);
-    return (int) result;
-  } else
-    return -1;
-}
-
-/** Return the conn time of the longest-connected connection of a player.
- * This function does includes hidden people.
- * \param player dbref of player to get ip for.
- * \return connection time of player as an INT, or -1 if not found.
- */
-int
-most_conn_time_priv(dbref player)
-{
-  DESC *d, *match = NULL;
-  DESC_ITER_CONN(d) {
-    if ((d->player == player) && (!match ||
-                                 (d->connected_at > match->connected_at)))
-      match = d;
-  }
-  if (match) {
-    double result = difftime(mudtime, match->connected_at);
-    return (int) result;
-  } else
-    return -1;
-}
-
-/** Return the idle time of the least-idle connection of a player.
- * This function treats hidden connections as nonexistant.
- * \param player dbref of player to get time for.
- * \return idle time of player as an INT, or -1 if not found or hidden.
- */
-int
-least_idle_time(dbref player)
-{
-  DESC *d, *match = NULL;
-  DESC_ITER_CONN(d) {
-    if ((d->player == player) && !Hidden(d) &&
-       (!match || (d->last_time > match->last_time)))
-      match = d;
-  }
-  if (match) {
-    double result = difftime(mudtime, match->last_time);
-    return (int) result;
-  } else
-    return -1;
-}
-
-/** Return the idle time of the least-idle connection of a player.
- * This function performs no permission checking.
- * \param player dbref of player to get time for.
- * \return idle time of player as an INT, or -1 if not found.
- */
-int
-least_idle_time_priv(dbref player)
-{
-  DESC *d, *match = NULL;
-  DESC_ITER_CONN(d) {
-    if ((d->player == player) && (!match || (d->last_time > match->last_time)))
-      match = d;
-  }
-  if (match) {
-    double result = difftime(mudtime, match->last_time);
-    return (int) result;
-  } else
-    return -1;
-}
-
-/** Return the ip address of the least-idle connection of a player.
- * This function performs no permission checking, and returns the
- * pointer from the descriptor itself (so don't destroy the result!)
- * \param player dbref of player to get ip for.
- * \return IP address of player as a string or NULL if not found.
- */
-char *
-least_idle_ip(dbref player)
-{
-  DESC *d, *match = NULL;
-  DESC_ITER_CONN(d) {
-    if ((d->player == player) && (!match || (d->last_time > match->last_time)))
-      match = d;
-  }
-  return match ? (match->ip) : NULL;
-}
-
-/** Return the hostname of the least-idle connection of a player.
- * This function performs no permission checking, and returns a static
- * string.
- * \param player dbref of player to get ip for.
- * \return hostname of player as a string or NULL if not found.
- */
-char *
-least_idle_hostname(dbref player)
-{
-  DESC *d, *match = NULL;
-  static char hostname[101];
-  char *p;
-
-  DESC_ITER_CONN(d) {
-    if ((d->player == player) && (!match || (d->last_time > match->last_time)))
-      match = d;
-  }
-  if (!match)
-    return NULL;
-  strcpy(hostname, match->addr);
-  if ((p = strchr(hostname, '@'))) {
-    p++;
-    return p;
-  } else
-    return hostname;
-}
-
-/* ZWHO() function - really belongs in eval.c but needs stuff declared here */
-/* ARGSUSED */
-FUNCTION(fun_zwho)
-{
-  DESC *d;
-  dbref zone, victim;
-  int first;
-  int powered = (strcmp(called_as, "ZMWHO") && Priv_Who(executor) || (Inherit_Powers(executor) && Priv_Who(Owner(executor))));
-  first = 1;
-
-  zone = match_thing(executor, args[0]);
-
-  if (nargs == 1) {
-    victim = executor;
-  } else if ((nargs == 2) && powered) {
-    if ((victim = match_thing(executor, args[1])) == 0) {
-      safe_str(T(e_match), buff, bp);
-      return;
-    }
-  } else {
-    safe_str(T(e_perm), buff, bp);
-    return;
-  }
-
-  if (!GoodObject(zone) || !(eval_lock(victim, zone, Zone_Lock) || CanModify(victim,zone))) {
-    safe_str(T(e_perm), buff, bp);
-    return;
-  }
-  if ((getlock(zone, Zone_Lock) == TRUE_BOOLEXP) ||
-      (IsPlayer(zone) && !(has_flag_by_name(zone, "SHARED", TYPE_PLAYER)))) {
-    safe_str(T("#-1 INVALID ZONE."), buff, bp);
-    return;
-  }
-
-  /* Use lowest privilege for victim */
-  if (!Priv_Who(victim))
-    powered = 0;
-
-  DESC_ITER_CONN(d) {
-    if (!Hidden(d) || powered) {
-      if (Zone(Location(d->player)) == zone) {
-       if (first) {
-         first = 0;
-       } else {
-         safe_chr(' ', buff, bp);
-       }
-       safe_dbref(d->player, buff, bp);
-      }
-    }
-  }
-}
-
-/* ARGSUSED */
-FUNCTION(fun_doing)
-{
-  /* Gets a player's @doing */
-  DESC *d = lookup_desc(executor, args[0]);
-  if (d)
-    safe_str(d->doing, buff, bp);
-  else
-    safe_str("#-1", buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_hostname)
-{
-  /* Gets a player's hostname */
-  DESC *d = lookup_desc(executor, args[0]);
-  if (d && (d->player == executor || Site(executor)))
-    safe_str(d->addr, buff, bp);
-  else
-    safe_str("#-1", buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_ipaddr)
-{
-  /* Gets a player's IP address */
-  DESC *d = lookup_desc(executor, args[0]);
-  if (d && (d->player == executor || Site(executor)))
-    safe_str(d->ip, buff, bp);
-  else
-    safe_str("#-1", buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_cmds)
-{
-  /* Gets a player's IP address */
-  DESC *d = lookup_desc(executor, args[0]);
-  if (d && (d->player == executor || Site(executor)))
-    safe_integer(d->cmds, buff, bp);
-  else
-    safe_integer(-1, buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_sent)
-{
-  /* Gets a player's bytes sent */
-  DESC *d = lookup_desc(executor, args[0]);
-  if (d && (d->player == executor || Site(executor)))
-    safe_integer(d->input_chars, buff, bp);
-  else
-    safe_integer(-1, buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_recv)
-{
-  /* Gets a player's bytes received */
-  DESC *d = lookup_desc(executor, args[0]);
-  if (d && (d->player == executor || Site(executor)))
-    safe_integer(d->output_chars, buff, bp);
-  else
-    safe_integer(-1, buff, bp);
-}
-
-FUNCTION(fun_poll)
-{
-  /* Gets the current poll */
-  if (poll_msg[0] == '\0')
-    strcpy(poll_msg, "Doing");
-
-  safe_str(poll_msg, buff, bp);
-}
-
-FUNCTION(fun_pueblo)
-{
-  /* Return the status of the pueblo flag on the least idle descriptor we
-   * find that matches the player's dbref.
-   */
-  DESC *match = lookup_desc(executor, args[0]);
-  if (match)
-    safe_boolean(match->conn_flags & CONN_HTML, buff, bp);
-  else
-    safe_str(T("#-1 NOT CONNECTED"), buff, bp);
-}
-
-FUNCTION(fun_ssl)
-{
-  /* Return the status of the ssl flag on the least idle descriptor we
-   * find that matches the player's dbref.
-   */
-  safe_boolean(0, buff, bp);
-}
-
-FUNCTION(fun_width)
-{
-  DESC *match;
-  if (!*args[0])
-    safe_str(T("#-1 FUNCTION REQUIRES ONE ARGUMENT"), buff, bp);
-  else if ((match = lookup_desc(executor, args[0])))
-    safe_integer(match->width, buff, bp);
-  else
-    safe_str("78", buff, bp);
-}
-
-FUNCTION(fun_height)
-{
-  DESC *match;
-  if (!*args[0])
-    safe_str(T("#-1 FUNCTION REQUIRES ONE ARGUMENT"), buff, bp);
-  else if ((match = lookup_desc(executor, args[0])))
-    safe_integer(match->height, buff, bp);
-  else
-    safe_str("24", buff, bp);
-}
-
-FUNCTION(fun_terminfo)
-{
-  DESC *match;
-  if (!*args[0])
-    safe_str(T("#-1 FUNCTION REQUIRES ONE ARGUMENT"), buff, bp);
-  else if ((match = lookup_desc(executor, args[0]))) {
-    if (match->player == executor || Site(executor)) {
-      safe_str(match->ttype, buff, bp);
-      if (match->conn_flags & CONN_HTML)
-       safe_str(" pueblo", buff, bp);
-      if (match->conn_flags & CONN_TELNET)
-       safe_str(" telnet", buff, bp);
-    } else
-      safe_str(T(e_perm), buff, bp);
-  } else
-    safe_str(T("#-1 NOT CONNECTED"), buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_idlesecs)
-{
-  /* returns the number of seconds a player has been idle, using
-   * their least idle connection
-   */
-
-  DESC *match = lookup_desc(executor, args[0]);
-  if (match)
-    safe_number(difftime(mudtime, match->last_time), buff, bp);
-  else
-    safe_str("-1", buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_idle_average) {
-  DESC *match = lookup_desc(executor, args[0]);
-  double idle_time;
-
-  if(match) {
-    idle_time = difftime(mudtime, match->last_time);
-    if(idle_time >= 300)
-      safe_number(((match->idle_total + idle_time) / (match->unidle_times+1)), buff, bp);
-    else if(match->unidle_times == 0)
-      safe_number(0, buff, bp);
-    else
-      safe_number((match->idle_total / match->unidle_times), buff, bp);
-    
-  } else
-    safe_str("-1", buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_idle_total) {
-  DESC *match = lookup_desc(executor, args[0]);
-  double idle_time;
-
-  if(match) {
-    idle_time = difftime(mudtime, match->last_time);
-    safe_number(idle_time >= 300 ? (match->idle_total+idle_time) : match->idle_total, buff, bp);
-  } else
-    safe_str("-1", buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_idle_times) {
-  DESC *match = lookup_desc(executor, args[0]);
-
-  if(match) {
-     safe_number((difftime(mudtime, match->last_time) >= 300) ? 
-        (match->unidle_times+1) : match->unidle_times, buff, bp);
-  } else
-    safe_str("-1", buff, bp);
-}
-
-
-/* ARGSUSED */
-FUNCTION(fun_conn)
-{
-  /* returns the number of seconds a player has been connected, using
-   * their longest-connected descriptor
-   */
-
-  DESC *match = lookup_desc(executor, args[0]);
-  if (match)
-    safe_number(difftime(mudtime, match->connected_at), buff, bp);
-  else
-    safe_str("-1", buff, bp);
-}
-
-/* ARGSUSED */
-FUNCTION(fun_lports)
-{
-  DESC *d;
-  int first = 1;
-
-  if (!Priv_Who(executor)
-       && !(Inherit_Powers(executor) && Priv_Who(Owner(executor)))) {
-    safe_str(T(e_perm), buff, bp);
-    return;
-  }
-
-  DESC_ITER_CONN(d) {
-    if (first)
-      first = 0;
-    else
-      safe_chr(' ', buff, bp);
-    safe_integer(d->descriptor, buff, bp);
-  }
-}
-
-/* ARGSUSED */
-FUNCTION(fun_ports)
-{
-  /* returns a list of the network descriptors that a player is
-   * connected to 
-   */
-
-  dbref target;
-  DESC *d;
-  int first;
-
-  target = lookup_player(args[0]);
-  if (target == NOTHING) {
-    target = match_result(executor, args[0], TYPE_PLAYER,
-                         MAT_ABSOLUTE | MAT_PLAYER | MAT_ME);
-  }
-  if (target != executor && !Priv_Who(executor)
-       && !(Inherit_Powers(executor) && Priv_Who(Owner(executor)))) {
-    /* This should probably be a safe_str */
-    notify(executor, T("Permission denied."));
-    return;
-  }
-  if (!GoodObject(target) || !Connected(target)) {
-    return;
-  }
-  /* Walk descriptor chain. */
-  first = 1;
-  DESC_ITER_CONN(d) {
-    if (d->player == target) {
-      if (first)
-       first = 0;
-      else
-       safe_chr(' ', buff, bp);
-      safe_integer(d->descriptor, buff, bp);
-    }
-  }
-}
-
-
-/** Hide or unhide a player.
- * Although hiding is a per-descriptor state, this function sets all of
- * a player's connected descriptors to be hidden.
- * \param player dbref of player to hide.
- * \param hide if 1, hide; if 0, unhide.
- */
-void
-hide_player(dbref player, int hide)
-{
-  DESC *d;
-  if (!Connected(player))
-    return;
-  if (!Can_Hide(player)) {
-    notify(player, T("Permission denied."));
-    return;
-  }
-  /* change status on WHO */
-  if (Can_Hide(player)) {
-    DESC_ITER_CONN(d) {
-      if (d->player == player)
-       d->hide = hide;
-    }
-  }
-  if (hide)
-    notify(player, T("You no longer appear on the WHO list."));
-  else
-    notify(player, T("You now appear on the WHO list."));
-}
-
-/** Perform the periodic check of inactive descriptors, and 
- * disconnect them or autohide them as appropriate.
- */
-void
-inactivity_check(void)
-{
-  DESC *d, *nextd;
-  ATTR *a;
-  char tbuf[BUFFER_LEN];
-  time_t now, idle, idle_for, unconnected_idle;
-  if (!INACTIVITY_LIMIT && !UNCONNECTED_LIMIT)
-    return;
-  now = mudtime;
-  idle = INACTIVITY_LIMIT ? INACTIVITY_LIMIT : INT_MAX;
-  unconnected_idle = UNCONNECTED_LIMIT ? UNCONNECTED_LIMIT : INT_MAX;
-  for (d = descriptor_list; d; d = nextd) {
-    nextd = d->next;
-    idle_for = now - d->last_time;
-    /* If they've been connected for 60 seconds without getting a telnet-option
-       back, the client probably doesn't understand them */
-    if ((d->conn_flags & CONN_TELNET_QUERY) && idle_for > 60)
-      d->conn_flags &= ~CONN_TELNET_QUERY;
-    if(d->connected && GoodObject(d->player) && ((a = atr_get(d->player, "IDLE_TIMEOUT"))!=NULL)) {
-           memset(tbuf, '\0', BUFFER_LEN);
-           strncpy(tbuf, atr_value(a), BUFFER_LEN-1);
-           idle = atoi(tbuf);
-           if(idle > 0)
-             goto after_idle_atr_check;
-    } 
-    idle = INACTIVITY_LIMIT ? INACTIVITY_LIMIT : INT_MAX;
-after_idle_atr_check:
-    if ((d->connected) ? (idle_for > idle ) : (idle_for > unconnected_idle)) {
-
-      if (!d->connected)
-       shutdownsock(d);
-      else if (!Can_Idle(d->player)) {
-
-       queue_string(d, T("\n*** Inactivity timeout ***\n"));
-       do_log(LT_CONN, 0, 0,
-              T("[%d/%s/%s] Logout by %s(#%d) <Inactivity Timeout>"),
-              d->descriptor, d->addr, d->ip, Name(d->player), d->player);
-       boot_desc(d);
-      } else if (Unfind(d->player)) {
-
-       if ((Can_Hide(d->player)) && (!Hidden(d))) {
-         queue_string(d,
-                      T
-                      ("\n*** Inactivity limit reached. You are now HIDDEN. ***\n"));
-         d->hide = 1;
-       }
-      }
-    }
-  }
-}
-
-
-/** Given a player dbref, return the player's hidden status.
- * \param player dbref of player to check.
- * \retval 1 player is hidden.
- * \retval 0 player is not hidden.
- */
-int
-hidden(dbref player)
-{
-  DESC *d;
-  DESC_ITER_CONN(d) {
-    if (d->player == player) {
-      if (Hidden(d))
-       return 1;
-      else
-       return 0;
-    }
-  }
-  return 0;
-}
-
-
-/** Return the mailp of the player closest in db# to player,
- * or NULL if there's nobody on-line.
- * In the current mail system, mail is stored in a linked list, sorted
- * by recipient, which makes the most common operations (listing and reading
- * your mail) fast. When a player first connects, we store (on the
- * mailp element of their descriptor) a pointer to the beginning of
- * their part of the linked list. Rather than search the whole linked
- * list to find this location, we look at the mailp's of all the other
- * connected players, and find the mailp of the player whose dbref
- * is closest to the connecting player, and start our search from that
- * point. This scales up nicely - as a mushes get larger, the linked
- * list gets larger, but the more people connected at once, the faster
- * the search for a newly connecting player's first mail.
- * \param player player whose db# we want to get near.
- * \return pointer to first mail of connected player with db# closest to
- * player.
- */
-MAIL *
-desc_mail(dbref player)
-{
-  DESC *d;
-  int i;
-  int diff = db_top;
-  static MAIL *mp;
-  mp = NULL;
-  DESC_ITER_CONN(d) {
-    i = abs(d->player - player);
-    if (i == 0)
-      return d->mailp;
-    if ((i < diff) && d->mailp) {
-      diff = i;
-      mp = d->mailp;
-    }
-  }
-  return mp;
-}
-
-/** Set a player's mail position on all their descriptors.
- * \param player player to set mail position for.
- * \param mp pointer to first mail in their list.
- */
-void
-desc_mail_set(dbref player, MAIL *mp)
-{
-  DESC *d;
-  DESC_ITER_CONN(d) {
-    if (d->player == player)
-      d->mailp = mp;
-  }
-}
-
-/** Clear mail positions on all descriptors. Called from do_mail_nuke().
- */
-void
-desc_mail_clear(void)
-{
-  DESC *d;
-  DESC_ITER_CONN(d) {
-    d->mailp = NULL;
-  }
-}
-
-
-
-
-#ifdef SUN_OS
-/* SunOS's implementation of stdio breaks when you get a file descriptor
- * greater than 128. Brain damage, brain damage, brain damage!
- *
- * Our objective, therefore, is not to fix stdio, but to work around it,
- * so that performance degrades semi-gracefully when you are using a lot
- * of file descriptors.
- * Therefore, we'll save a file descriptor when we start up that is less
- * than 128, so that if we get a file descriptor that is >= 128, we can
- * use our own saved file descriptor instead. This is only one level of
- * defense; if you have more than 128 fd's in use, and you try two fopen's
- * before doing an fclose(), the second will fail.
- */
-
-FILE *
-fopen(file, mode)
-    const char *file;
-    const char *mode;
-{
-/* FILE *f; */
-  int fd, rw, oflags = 0;
-/* char tbchar; */
-  rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
-  switch (*mode) {
-  case 'a':
-    oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
-    break;
-  case 'r':
-    oflags = rw ? O_RDWR : O_RDONLY;
-    break;
-  case 'w':
-    oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
-    break;
-  default:
-    return (NULL);
-  }
-/* SunOS fopen() doesn't use the 't' or 'b' flags. */
-
-
-  fd = open(file, oflags, 0666);
-  if (fd < 0)
-    return NULL;
-  /* My addition, to cope with SunOS brain damage! */
-  if (fd >= 128) {
-    close(fd);
-    if ((extrafd < 128) && (extrafd >= 0)) {
-      close(extrafd);
-      fd = open(file, oflags, 0666);
-      extrafd = -1;
-    } else {
-      return NULL;
-    }
-  }
-  /* End addition. */
-
-  return fdopen(fd, mode);
-}
-
-
-#undef fclose(x)
-int
-f_close(stream)
-    FILE *stream;
-{
-  int fd = fileno(stream);
-  /* if extrafd is bad, and the fd we're closing is good, recycle the
-   * fd into extrafd.
-   */
-  fclose(stream);
-  if (((extrafd < 0)) && (fd >= 0) && (fd < 128)) {
-    extrafd = open("/dev/null", O_RDWR);
-    if (extrafd >= 128) {
-      /* To our surprise, we didn't get a usable fd. */
-      close(extrafd);
-      extrafd = -1;
-    }
-  }
-  return 0;
-}
-
-#define fclose(x) f_close(x)
-#endif                         /* SUN_OS */
-
-/** Dump the descriptor list to our REBOOTFILE so we can restore it on reboot.
- */
-void
-dump_reboot_db(void)
-{
-  FILE *f;
-  DESC *d;
-  SU_PATH *exit_path;
-  long flags = RDBF_SCREENSIZE | RDBF_TTYPE | RDBF_PUEBLO_CHECKSUM
-               | RDBF_SU_EXIT_PATH;
-  if (setjmp(db_err)) {
-    flag_broadcast(0, 0, T("GAME: Error writing reboot database!"));
-    exit(0);
-  } else {
-
-    f = fopen(REBOOTFILE, "w");
-    /* This shouldn't happen */
-    if (!f) {
-      flag_broadcast(0, 0, T("GAME: Error writing reboot database!"));
-      exit(0);
-    }
-    /* Write out the reboot db flags here */
-    fprintf(f, "V%ld\n", flags);
-    putref(f, 0);
-    putref(f, 0);
-    /* First, iterate through all descriptors to get to the end
-     * we do this so the descriptor_list isn't reversed on reboot
-     */
-    for (d = descriptor_list; d && d->next; d = d->next) ;
-    /* Second, we iterate backwards from the end of descriptor_list
-     * which is now in the d variable.
-     */
-    for (; d != NULL; d = d->prev) {
-      putref(f, d->descriptor);
-      putref(f, d->connected_at);
-      putref(f, d->hide);
-      putref(f, d->cmds);
-      putref(f, d->idle_total);
-      putref(f, d->unidle_times);
-      if (GoodObject(d->player))
-       putref(f, d->player);
-      else
-       putref(f, -1);
-      putref(f, d->last_time);
-      if (d->output_prefix)
-       putstring(f, (char *) d->output_prefix);
-      else
-       putstring(f, "__NONE__");
-      if (d->output_suffix)
-       putstring(f, (char *) d->output_suffix);
-      else
-       putstring(f, "__NONE__");
-      putstring(f, d->addr);
-      putstring(f, d->ip);
-      putstring(f, d->doing);
-      putref(f, d->conn_flags);
-      putref(f, d->width);
-      putref(f, d->height);
-      putstring(f, d->ttype);
-      putstring(f, d->checksum);
-      for(exit_path = d->su_exit_path; exit_path; exit_path = exit_path->next)
-        putref(f, exit_path->player);
-      putref(f, NOTHING);
-    }                          /* for loop */
-
-    putref(f, 0);
-    putstring(f, poll_msg);
-    putref(f, globals.first_start_time);
-    putref(f, globals.reboot_count);
-    fclose(f);
-  }
-}
-
-/** Load the descriptor list back from the REBOOTFILE on reboot.
- */
-void
-load_reboot_db(void)
-{
-  FILE *f;
-  DESC *d = NULL;
-  DESC *closed = NULL, *nextclosed;
-  int val;
-  int n;
-  const char *temp;
-  char c;
-  long flags = 0;
-  char tbuf1[BUFFER_LEN];
-  SU_PATH *epnext, *epprev;
-  dbref exit_path;
-  f = fopen(REBOOTFILE, "r");
-  if (!f) {
-    restarting = 0;
-    return;
-  }
-  restarting = 1;
-  /* Get the first line and see if it's a set of reboot db flags.
-   * Those start with V<number>
-   * If not, assume we're using the original format, in which the
-   * sock appears first
-   * */
-  c = getc(f);                 /* Skip the V */
-  if (c == 'V') {
-    flags = getref(f);
-  } else {
-    ungetc(c, f);
-  }
-
-  val = getref(f);
-  val = getref(f);
-
-  while ((val = getref(f)) != 0) {
-    ndescriptors++;
-    d = (DESC *) mush_malloc(sizeof(DESC), "descriptor");
-    d->descriptor = val;
-    d->input_handler = do_command;
-    d->connected_at = getref(f);
-    d->hide = getref(f);
-    d->cmds = getref(f);
-    d->idle_total = getref(f);
-    d->unidle_times = getref(f);
-    d->player = getref(f);
-    d->last_time = getref(f);
-    d->pinfo.object = NOTHING;
-    d->pinfo.atr = NULL;
-    d->pinfo.lock = 0;
-    d->pinfo.function = NULL;
-    d->connected = GoodObject(d->player) ? 1 : 0;
-    /* setup snooper array */
-    for(n = 0; n < MAX_SNOOPS; n++)
-      d->snooper[n] = -1;
-
-    temp = getstring_noalloc(f);
-    d->output_prefix = NULL;
-    if (strcmp(temp, "__NONE__"))
-      set_userstring(&d->output_prefix, temp);
-    temp = getstring_noalloc(f);
-    d->output_suffix = NULL;
-    if (strcmp(temp, "__NONE__"))
-      set_userstring(&d->output_suffix, temp);
-    strcpy(d->addr, getstring_noalloc(f));
-    strcpy(d->ip, getstring_noalloc(f));
-    strcpy(d->doing, getstring_noalloc(f));
-    d->conn_flags = getref(f);
-    if (flags & RDBF_SCREENSIZE) {
-      d->width = getref(f);
-      d->height = getref(f);
-    } else {
-      d->width = 78;
-      d->width = 24;
-    }
-    if (flags & RDBF_TTYPE)
-      d->ttype = mush_strdup(getstring_noalloc(f), "terminal description");
-    else
-      d->ttype = mush_strdup("unknown", "terminal description");
-    if (flags & RDBF_PUEBLO_CHECKSUM)
-      strcpy(d->checksum, getstring_noalloc(f));
-    else
-      d->checksum[0] = '\0';
-    d->su_exit_path = NULL;
-    if (flags & RDBF_SU_EXIT_PATH) {
-      exit_path = getref(f);
-      while(GoodObject(exit_path)) {
-        add_to_exit_path(d, exit_path);
-        exit_path = getref(f);
-      }
-      epprev = NULL;
-      while(d->su_exit_path) {
-        epnext = d->su_exit_path->next;
-        d->su_exit_path->next = epprev;
-        epprev = d->su_exit_path;
-        d->su_exit_path = epnext;
-      }
-      d->su_exit_path = epprev;
-    }
-    d->input_chars = 0;
-    d->output_chars = 0;
-    d->output_size = 0;
-    d->output.head = 0;
-    d->output.tail = &d->output.head;
-    d->input.head = 0;
-    d->input.tail = &d->input.head;
-    d->raw_input = NULL;
-    d->raw_input_at = NULL;
-    d->quota = options.starting_quota;
-    d->mailp = NULL;
-    if (d->conn_flags & CONN_CLOSE_READY) {
-      /* This isn't really an open descriptor, we're just tracking
-       * it so we can announce the disconnect properly. Do so, but
-       * don't link it into the descriptor list. Instead, keep a
-       * separate list.
-       */
-      if (closed)
-       closed->prev = d;
-      d->next = closed;
-      d->prev = NULL;
-      closed = d;
-    } else {
-      if (descriptor_list)
-       descriptor_list->prev = d;
-      d->next = descriptor_list;
-      d->prev = NULL;
-      descriptor_list = d;
-      if (d->connected && d->player && GoodObject(d->player) &&
-         IsPlayer(d->player))
-       set_flag_internal(d->player, "CONNECTED");
-      else if ((!d->player || !GoodObject(d->player)) && d->connected) {
-       d->connected = 0;
-       d->player = 0;
-      }
-    /* If they were in a program, get them back into it */
-      if(d->connected && InProg(d->player))
-        prog_load_desc(d);
-    }
-  }                            /* while loop */
-
-  /* Now announce disconnects of everyone who's not really here */
-  while (closed) {
-    nextclosed = closed->next;
-    if(closed->last_time > 0) {
-      closed->idle_total += difftime(mudtime, closed->last_time);
-      closed->unidle_times++;
-    }
-
-    snprintf(tbuf1, BUFFER_LEN-1, "%ld %ld %d %d", (mudtime - closed->connected_at),
-        closed->idle_total , closed->unidle_times, closed->cmds);
-    tbuf1[strlen(tbuf1)+1] = '\0';
-    (void) atr_add(closed->player, "LASTACTIVITY", tbuf1, GOD, NOTHING);
-    announce_disconnect(closed->player);
-    mush_free(closed, "descriptor");
-    closed = nextclosed;
-  }
-
-  strcpy(poll_msg, getstring_noalloc(f));
-  globals.first_start_time = getref(f);
-  globals.reboot_count = getref(f) + 1;
-  DESC_ITER_CONN(d) {
-    d->mailp = find_exact_starting_point(d->player);
-  }
-
-  fclose(f);
-  remove(REBOOTFILE);
-  flag_broadcast(0, 0, T("GAME: Reboot finished."));
-}
-
-
-/* Syntax: @snoop[/list] [!]<descriptor>
- */  
-COMMAND(cmd_snoop) {
-  DESC *d;
-  int descn, on, n, sn;
-  char snooplist[MAX_SNOOPS][BUFFER_LEN];
-  char buf[BUFFER_LEN], *bp;
-
-  if(SW_ISSET(sw, SWITCH_LIST)) {
-         descn = atoi(arg_left);
-
-         bp = buf;
-
-         d = port_desc(descn);
-
-          if (LEVEL(player) <= 28) {
-                 notify(player, MSG_HUH);
-                 return;
-         }
-         /* make sure teh desc exists and they're connected (no spying on 'em at the connect screen!) */
-         if(!d || (d && !IsPlayer(d->player))) {
-                 notify(player, "There is no one connected on that descriptor.");
-                 return;
-         }
-
-         for(sn = 0, n = 0; n < MAX_SNOOPS; n++)
-                 if(d->snooper[n] != -1) {
-                         memset(snooplist[sn], '\0', BUFFER_LEN);
-                         snprintf(snooplist[sn++], BUFFER_LEN-1, "%s", Name(d->snooper[n])); 
-                 }
-         *snooplist[sn] = '\0';
-
-         for(n = 0; n < sn; n++) {
-                 if(n != 0)
-                         safe_str(", ", buf, &bp);
-                 if(n == (sn-1) && sn > 1)
-                         safe_str("& ", buf, &bp);
-                 safe_str(snooplist[n], buf, &bp);
-         }
-         *bp = '\0';
-         notify_format(player, "%s is being snooped on by: %s", Name(d->player), buf);
-
-  } else {
-  if(*arg_left== '!') {
-    on = 0;
-    descn = atoi(arg_left+1);
-  } else { 
-    descn = atoi(arg_left);
-    on = 1;
-  }
-
-  d = port_desc(descn);
-  if (LEVEL(player) <= 28) {
-    notify(player, MSG_HUH);
-    return;
-  }
-  /* make sure teh desc exists and they're connected (no spying on 'em at the connect screen!) */
-  if(!d || (d && !IsPlayer(d->player))) {
-    notify(player, "There is no one connected on that descriptor.");
-    return;
-  }
-  
-  if(on) {
-         if((d->player == player)) {
-                 notify(player, "You can't snoop yourself."); 
-                 return;
-         }
-
-  switch(set_snoop(player,d)) {
-    case -1: /* Too Many */
-      notify(player, "Sorry, can't snoop at this time.");
-      return;
-    case -2: /* Already Snoopin on 'em */
-      notify(player, "You can only snoop one person at a time.");
-      return;
-    default:
-      notify_format(player, T("Snoop now set on %s(%d)"), Name(d->player), descn); 
-  }
-  } else {
-    for(on = n = 0; n < MAX_SNOOPS; n++)
-      if(d->snooper[n] == player)  {
-       d->snooper[n] = -1;
-       on = 1;
-      }
-      notify(player, on ? "Snoop deactivated." : "Snooping Error.");
-  }
-  }
-}
-
-
-void feed_snoop(DESC *d, const char *s, char dir) {
-  int n;
-  char snstr[BUFFER_LEN];
-
-
-  if(!d ||!d->connected)
-    return;
-  memset(snstr, '\0', BUFFER_LEN);
-  strncpy(snstr, remove_markup(s, NULL), BUFFER_LEN-1);
-  if(*s && !*snstr)
-         return;
-  for(n = 0; n < MAX_SNOOPS ; n++)
-    if(!IsPlayer(d->snooper[n]))
-      continue;
-    else if(GoodObject(d->snooper[n]) && IsPlayer(d->snooper[n])) {
-      if(dir == 1) /* player see's */
-        notify_format((dbref) d->snooper[n], T("%s%s<-%s %s"), object_header(d->snooper[n],d->player), ANSI_BLUE,
-           ANSI_NORMAL, snstr);
-      else /* player types */
-       notify_format((dbref) d->snooper[n], T("%s%s->%s %s%s"), object_header(d->snooper[n],d->player), 
-           ANSI_BLUE, ANSI_RED, snstr, ANSI_NORMAL);
-    }
-
-}
-
-char is_snooped(DESC *d) {
-  int n;
-
-  for(n = 0; n < MAX_SNOOPS; n++) 
-    if(IsPlayer(d->snooper[n]))
-      return 1;
-  return 0;
-}
-
-
-char set_snoop(dbref plyr, DESC *d) {
-  int n;
-  /* take first available spot */
-  for( n = 0; n < MAX_SNOOPS ; n++)
-    if(d->snooper[n] == -1)
-      break;
-    else if(d->snooper[n] == plyr)
-      return -2; /* they're already snooping */
-  if(n == MAX_SNOOPS-1) /* too many snoopers on player */
-    return -1;
-  d->snooper[n] = plyr;
-  return 1;
-}
-
-void clr_snoop(dbref plyr, DESC *d) {
-  int n;
-
-  for(n = 0; n < MAX_SNOOPS; n++)
-    if(d->snooper[n] == plyr)
-      d->snooper[n] = -1;
-}
-
-/* switch users */
-COMMAND(cmd_su) {
-  DESC *d, *match = NULL;
-  dbref target;
-  int num = 0, is_hidden;
-
-  /* Stage 1.  Make sure arg_left exists */
-  if(arg_left && *arg_left) {
-    if(!strcasecmp(cmd->name, "@SD")) { 
-      target = match_result(player, arg_left, TYPE_DIVISION, MAT_EVERYTHING);
-      if(!GoodObject(target) || Typeof(target) != TYPE_DIVISION) {
-       notify(player, "No such division.");
-       return;
-      }
-      /* Check to see if special conditions exist, where they can enter without a password */
-      if(controls(player, target)   /* condition 1: they control it */
-       ) {
-       add_to_div_exit_path(player, Division(player));
-       Division(player) = target;
-       notify_format(player, "You have switched into Division: %s", object_header(player, Division(player)));
-       return;
-      }
-      /* get least idle desc */
-      DESC_ITER_CONN(d) 
-       if ((d->player == player) && (!match || (d->last_time > match->last_time))) 
-         match = d;
-      /* We're only entering using a password at this moment */
-       queue_newwrite(match, (unsigned char *) tprintf(T("Password: %c%c"),
-                                                       IAC, GOAHEAD), 13);
-       match->input_handler = password_handler;
-       match->pinfo.object = target;
-       match->pinfo.function = &pw_div_connect;
-       match->pinfo.lock = 0x40;
-    } else {
-      target = lookup_player(arg_left);
-      if(target == NOTHING) {
-       notify(player, "No such player.");
-       return;
-      }
-      do_log(LT_WIZ, player, target, "** @SU ATTEMPT **");
-      /* get least idle desc */
-      DESC_ITER_CONN(d) 
-       if ((d->player == player) && (!match || (d->last_time > match->last_time))) 
-         match = d;
-  /* Step 2.  Find if we can get in without a pass, if
-   * we need a pass. Throw them into password_handler() internal
-   * prompt
-   */
-      if(div_powover(player, target, "@SU")) {
-       do_log(LT_WIZ, player, target, "** @SU SUCCESS **");
-       /* Phase 3a. Put Guy in user */
-       add_to_exit_path(match, player);
-       announce_disconnect(player);
-       match->player = target;
-       match->mailp = find_exact_starting_point(target);
-       is_hidden = Can_Hide(target) && Dark(target);
-       DESC_ITER_CONN(d)
-         if(d->player == player) {
-           num++;
-           if(is_hidden)
-             d->hide = 1;
-         }
-
-       if(ModTime(target))
-         notify_format(target, T("%ld failed connections since last login."), ModTime(target));
-       announce_connect(target, 0, num);
-       check_last(target, match->addr, match->ip); /* set last, lastsite, give paycheck */
-       queue_eol(match);
-       if(command_check_byname(target, "@MAIL"))
-         check_mail(target, 0, 0);
-       set_player_folder(target, 0);
-       do_look_around(target);
-       if(Haven(target))
-         notify(player, T("Your HAVEN flag is set.  You cannot receive pages."));
-      } else {
-       /* Part 3b.  Put guy in password program */
-       queue_newwrite(match, (unsigned char *) tprintf(T("Password: %c%c"),
-                                                       IAC, GOAHEAD), 13);
-       match->input_handler = password_handler;
-       match->pinfo.object = target;
-       match->pinfo.function = &pw_player_connect;
-       match->pinfo.lock = 0x40;
-      }
-    }
-  } else {
-    if(SW_ISSET(sw, SWITCH_LOGOUT)) {
-      /* @sd/logout - check to see if there is any division @sd'ing history.. And backtrack us */
-      ATTR *divrcd;
-      char tbuf[BUFFER_LEN], *p_buf[BUFFER_LEN / 2], *tbp, sep[2];
-      int cnt;
-      dbref div_obj;
-
-      divrcd = atr_get(player, "XYXX_DIVRCD");
-      if(divrcd == NULL) {
-       notify(player, "You have not switched into any divisions.");
-       return;
-      }
-
-      cnt = list2arr(p_buf, BUFFER_LEN / 2, safe_atr_value(divrcd), ' ');
-      if(cnt < 1) {
-       notify(player, "You have not switched into any divisions.");
-       return;
-      }
-
-      /* Set them into cnt-1 if its good */
-      div_obj = parse_number(p_buf[cnt-1]);
-      if(GoodObject(div_obj) && IsDivision(div_obj)) {
-       Division(player) = div_obj;
-       notify_format(player, "You haev been went back to your other division: %s", object_header(player, div_obj));
-      }
-
-      /* now  chop off last one, and arr2list() */
-      if(cnt == 1) { /* clear the attribute */
-       atr_clr(player, "XYXX_DIVRCD", GOD);
-      } else {
-       memset(tbuf, '\0', BUFFER_LEN);
-       tbp = tbuf;
-       sep[0] = ' ';
-       sep[1] = '\0';
-       arr2list(p_buf, cnt-1, tbuf, &tbp, sep);
-       /* Add the attribute back */
-       (void) atr_add(player, "XYXX_DIVRCD", tbuf, GOD, NOTHING);
-      }
-    } else {
-      notify(player, "Must specify what player you wish to @su into.");
-    }
-  }
-}
-
-void add_to_exit_path(DESC *d, dbref player) {
-  SU_PATH *path_entry;
-
-  if(!d)
-    return;
-
-  path_entry = (SU_PATH *) mush_malloc(sizeof(SU_PATH), "SU_PATH_ENTRY");
-
-  path_entry->player = player;
-  if(d->su_exit_path)
-    path_entry->next = d->su_exit_path;
-  else
-    path_entry->next = NULL;
-  d->su_exit_path = path_entry;
-}
-
-/* If they're logged in.. Log 'em out through their su path */
-static int do_su_exit(DESC *d) {
-  DESC *c;
-  SU_PATH *path_entry, *mark_path;
-  int is_hidden, num = 0;
-
-  if(d->su_exit_path) {
-    path_entry = d->su_exit_path;
-    while(path_entry)
-      if(GoodObject(path_entry->player) && IsPlayer(path_entry->player))
-       break;
-      else { /* Guess the guy got nuked along the way..  free the spot */
-       mark_path = path_entry;
-       path_entry = path_entry->next;
-       mush_free(mark_path, "SU_PATH_ENTRY");
-      }
-    if(!path_entry)
-      return 0;
-    d->su_exit_path = path_entry;
-    /* Disconnect appearance */
-    announce_disconnect(d->player);
-    d->player = path_entry->player;
-    /* Clear path_entry spot */
-    d->su_exit_path = path_entry->next;
-    mush_free(path_entry, "SU_PATH_ENTRY");
-    d->mailp = find_exact_starting_point(d->player);
-    is_hidden = Can_Hide(d->player) && Dark(d->player);
-    DESC_ITER_CONN(c)
-      if(c->player == d->player) {
-       num++;
-       if(is_hidden)
-         c->hide = 1;
-      }
-    if(ModTime(d->player))
-      notify_format(d->player, T("%ld failed connections since last login."), ModTime(d->player));
-    announce_connect(d->player, 0, num);
-    check_last(d->player, d->addr, d->ip); /* set last, lastsite, give paycheck */
-    queue_eol(d);
-    if(command_check_byname(d->player, "@MAIL"))
-      check_mail(d->player, 0, 0);
-    set_player_folder(d->player, 0);
-    do_look_around(d->player);
-    if(Haven(d->player))
-      notify(d->player, T("Your HAVEN flag is set.  You cannot receive pages."));
-    return 1;
-  } else return 0;
-}
-
-void
-close_ssl_connections(void)
-{
-}
-
-void
-kill_info_slave(void)
-{
-}
-