Re-enable console compilation and clean up all compile errors and warnings
authorAri Johnson <ari@theari.com>
Mon, 18 Apr 2011 02:46:22 +0000 (22:46 -0400)
committerAri Johnson <ari@theari.com>
Mon, 18 Apr 2011 02:46:22 +0000 (22:46 -0400)
26 files changed:
Makefile.in
hdrs/command.h
hdrs/conf.h
hdrs/externs.h
hdrs/modules.h
src/Makefile.in
src/bsd.c
src/command.c
src/comp_w.c
src/console.c [deleted file]
src/create.c
src/cron.c
src/division.c
src/filecopy.c
src/funcrypt.c
src/fundb.c
src/funufun.c
src/lock.c
src/modules.c
src/mymalloc.c
src/player.c
src/predicat.c
src/prog.c
src/speech.c
src/strutil.c
src/utils.c

index 142fff56f68af6b0a2d06ac8a1cce42af2bceded..ae5a5e9ebf6644b1f85ced4d23b67f8d6d87a279 100644 (file)
@@ -27,7 +27,7 @@ INSTALL=@INSTALL@
 INSTALLDIR=$installdir
 CP=@CP@
 CHMOD=@CHMOD@
-INSTALL_LINKS=@LN_S@ ../src/netmud netmush; @LN_S@ ../src/info_slave info_slave
+INSTALL_LINKS=@LN_S@ ../src/netmud netmush; @LN_S@ ../src/info_slave info_slave; @LN_S@ ../src/console console
 
 # stupid SYS V shell
 SHELL=/bin/sh
@@ -83,6 +83,11 @@ netmud:
        "SQL_CFLAGS=$(SQL_CFLAGS)" "SQL_LDFLAGS=$(SQL_LDFLAGS)" \
        "LDFLAGS=$(LDFLAGS)" "CLIBS=$(CLIBS)" )
 
+console:
+       (cd src; make console "CC=$(CC)" CCFLAGS=$(CCFLAGS)" \
+       "SQL_CFLAGS=$(SQL_CFLAGS)" "SQL_LDFLAGS=$(SQL_LDFLAGS)" \
+       "LDFLAGS=$(LDFLAGS)" CLIBS=$(CLIBS)" )
+
 access:
        utils/make_access_cnf.sh game
 
@@ -160,12 +165,12 @@ update-hdr:
        -@sleep 2
        -@@PERL@ utils/update.pl options.h options.h.dist
 
-test: netmud
+test: netmud console
        (cd test; @PERL@ alltests.pl)
 
 clean:
        (cd src; make clean)
-       (cd game; rm -f netmush info_slave)
+       (cd game; rm -f netmush info_slave console netmush~ info_slave~ console~)
 
 distclean: 
        (cd hdrs; rm -f *.orig *~ \#* *.rej *.bak funs.h cmds.h buildinf.h patches.h)
index 223b51e913503f4747d374b6df03983e5a7fc9b8..3b4400b8de22505845d0671747ac4e0ce2064690 100644 (file)
@@ -110,7 +110,7 @@ void command_name(COMMAND_INFO *cmd __attribute__ ((__unused__)), \
                   char *args_left[MAX_ARG] __attribute__ ((__unused__)), \
                   char *arg_right __attribute__ ((__unused__)), \
                   char *args_right[MAX_ARG] __attribute__ ((__unused__)), \
-                 int fromport)
+                 int fromport __attribute__ ((__unused__)))
 
 /** Common command prototype macro */
 #define COMMAND_PROTO(command_name) \
index 38301c9ddb1222903e375e456753f0d47c854f8a..88d5414c56746bad4b36516e92c71f7da97190ee 100644 (file)
@@ -461,13 +461,11 @@ int cf_time(const char *opt, const char *val, void *loc, int maxval,
 #define CMDLOG (options.command_log)
 #define TRACELOG (options.trace_log)
 #define CHECKLOG (options.checkpt_log)
-#ifdef HAS_MYSQL
 #define SQL_PLATFORM (options.sql_platform)
 #define SQL_HOST (options.sql_host)
 #define SQL_DB (options.sql_database)
 #define SQL_USER (options.sql_username)
 #define SQL_PASS (options.sql_password)
-#endif
 
 #define CHUNK_SWAP_FILE (options.chunk_swap_file)
 #define CHUNK_CACHE_MEMORY (options.chunk_cache_memory)
index 3ccc09e3d886d11df9b79ccc832c2e25bf7f097a..7f8efdf42241875985e419c7eb45d1ccad451d89 100644 (file)
@@ -225,6 +225,9 @@ extern char ucbuff[];
 #define safe_uncompress(s) (strdup((char *) s))
 #endif
 
+/* From conf.c */
+    void validate_config(void);
+
 /* From cque.c */
 struct _ansi_string;
 struct real_pcre;
@@ -245,6 +248,7 @@ struct eval_context {
   struct _ansi_string *re_from;             /**< The positions of the subpatterns */  HASHTAB namedregs;
   HASHTAB namedregsnxt;
 };
+    extern void init_queue(void);
 
 typedef struct eval_context EVAL_CONTEXT;
 extern EVAL_CONTEXT global_eval_context;
@@ -418,7 +422,7 @@ extern int ok_function_name(const char *name);
 extern int ok_player_name(const char *name, dbref player, dbref thing);
 extern int ok_player_alias(const char *alias, dbref player, dbref thing);
 extern int ok_password(const char *password);
-extern int ok_tag_attribute(dbref player, char *params);
+extern int ok_tag_attribute(dbref player, const char *params);
 extern dbref parse_match_possessor(dbref player, char **str);
 extern void page_return(dbref player, dbref target, const char *type,
                         const char *message, const char *def);
@@ -441,6 +445,9 @@ extern void notify_except2(dbref first, dbref exc1, dbref exc2,
 /* Return thing/PREFIX + msg */
 extern void make_prefixstr(dbref thing, const char *msg, char *tbuf1);
 extern int filter_found(dbref thing, const char *msg, int flag);
+extern void do_message_list(dbref player, dbref enactor, char *list,
+                           char *attrname, char *message, int flags,
+                           int numargs, char *argv[]);
 
 /* From division.c */
 extern void adjust_powers(dbref obj, dbref to);
@@ -685,6 +692,10 @@ strdup(const char *s) __attribute_malloc__;
     void save_regexp_context(struct re_save *);
     extern void save_global_regs(const char *funcname, char *preserve[]);
     extern void restore_global_regs(const char *funcname, char *preserve[]);
+    extern void save_partial_global_reg(const char *funcname, char *preserv[],
+                                       int i);
+    extern void restore_partial_global_regs(const char *funcname,
+                                           char *preserve[]);
     extern void free_global_regs(const char *funcname, char *preserve[]);
     extern void init_global_regs(char *preserve[]);
     extern void load_global_regs(char *preserve[]);
index dec14507802907f747ab069cd487e3b2b52ab244..0a6425eb98ea6626e684c6c56c0f430d9a34b587 100644 (file)
@@ -42,6 +42,6 @@ extern void *utility_memcpy_ptr; /* This gets us through the ISO C warnings abou
     h(); \
   }
 
-#define MODULE_FUNCRET(m, func) lt_dlsym(m, func);
+#define MODULE_FUNCRET(m, func) lt_dlsym(m, func)
 
 #endif /* _MODULES_H_ */
index 395b7027648920ab3e06be0b34149503323626fd..f3948d8461ceabf20af898261c2db691d72b17cd 100644 (file)
@@ -4,7 +4,7 @@
 #         You shouldn't have to change anything in this file.                 #
 ###############################################################################
 
-OUTFILES=buildinf netmud info_slave
+OUTFILES=buildinf netmud console info_slave
 
 # Libs EXCEPT for SQL ones
 LIBS=$(CLIBS)
@@ -29,12 +29,12 @@ C_FILES=access.c atr_tab.c attrib.c boolexp.c bsd.c bufferq.c chunk.c       \
 
 
 # .o versions of above - these are used in the build
-O_FILES=access.o atr_tab.o attrib.o boolexp.o bsd.o bufferq.o chunk.o  \
+COMMON_O_FILES=access.o atr_tab.o attrib.o boolexp.o bufferq.o chunk.o \
         cmds.o command.o compress.o conf.o cque.o create.o cron.o      \
        db.o destroy.o division.o extchat.o extmail.o filecopy.o        \
        flags.o funcrypt.o fundiv.o function.o fundb.o funlist.o        \
        funmath.o funmisc.o funstr.o funtime.o funufun.o game.o help.o  \
-       htab.o ident.o intmap.o  lock.o log.o look.o malias.o   \
+       htab.o ident.o intmap.o  lock.o log.o look.o malias.o           \
        markup.o match.o memcheck.o move.o modules.o mushlua.o mushlua_wrap.o \
         mycrypt.o mymalloc.o           \
        mysocket.o myrlimit.o myssl.o notify.o parse.o pcre.o player.o  \
@@ -43,6 +43,9 @@ O_FILES=access.o atr_tab.o attrib.o boolexp.o bsd.o bufferq.o chunk.o \
        strtree.o strutil.o tables.o timer.o unparse.o utils.o          \
        version.o wait.o warnings.o wild.o wiz.o
 
+O_FILES=$(COMMON_O_FILES) bsd.o
+CONSOLE_O_FILES=$(COMMON_O_FILES) console.o
+
 # This is a dummy target, in case you type 'make' in the source
 # directory (likely for emacs users who M-x compile.)
 # This means that the top-level make had better specifically 'make all' :)
@@ -57,6 +60,11 @@ netmud: $(O_FILES)
 #      $(CC) $(CCFLAGS) -o netmud $(O_FILES) $(LDFLAGS) $(SQL_LDFLAGS) $(LIBS) 
        $(LIBTOOL) --mode=link $(CC) -export-dynamic $(LDFLAGS) $(SQL_LDFLAGS) $(CCFLAGS) -o netmud $(O_FILES) $(LIBS)
 
+console: $(CONSOLE_O_FILES)
+       @echo "Making console."
+       -mv -f console console~
+       $(LIBTOOL) --mode=link $(CC) -export-dynamic $(LDFLAGS) $(SQL_LDFLAGS) $(CCFLAGS) -o console $(CONSOLE_O_FILES) $(LIBS)
+
 
 # We recompile mysocket.c instead of reusing mysocket.o because we
 # want to do some error handing differently for info_slave.
@@ -158,6 +166,10 @@ portmsg: portmsg.c mysocket.c sig.o wait.o
 # Some dependencies that make depend doesn't handle well
 compress.o: comp_h.c comp_w.c comp_w8.c
 
+# 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
index c5233fefcb415c12eacf1c26122f4fa221cb8a69..17b36c50d3c1fc0217bf4b2b44f1a4aa7c9c7053 100644 (file)
--- a/src/bsd.c
+++ b/src/bsd.c
@@ -86,6 +86,9 @@
 #include <locale.h>
 #include <setjmp.h>
 #include <ltdl.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
 
 #ifdef HAVE_SYS_INOTIFY_H
 #include <sys/inotify.h>
@@ -292,8 +295,8 @@ SSL *ssl_master_socket = NULL;  /**< Master SSL socket for ssl port */
 #ifdef WIN32
 static WSADATA wsadata;
 #endif
-int maxd = 0;
 #endif /* COMPILE_CONSOLE */
+int maxd = 0;
 int restarting = 0;     /**< Are we restarting the server after a reboot? */
 static int ndescriptors = 0;
 
@@ -985,6 +988,7 @@ bad_empabb_value:
 
 extern slab *text_block_slab;
 
+#ifndef COMPILE_CONSOLE
 static void
 setup_desc(int sock, bool use_ssl)
 {
@@ -1000,9 +1004,14 @@ setup_desc(int sock, bool use_ssl)
       maxd = newd->descriptor + 1;
   }
 }
+#endif
 
 static void
+#ifdef COMPILE_CONSOLE
+shovechars()
+#else
 shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
+#endif
 {
   /* this is the main game loop */
 
@@ -1014,15 +1023,22 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
   int found;
   int queue_timeout;
   DESC *d, *dnext;
+#ifndef COMPILE_CONSOLE
   int avail_descriptors;
 #ifdef INFO_SLAVE
   union sockaddr_u addr;
   socklen_t addr_len;
   int newsock;
 #endif
+#endif /* COMPILE_CONSOLE */
   unsigned long input_ready, output_ready;
   int notify_fd = -1;
 
+#ifdef COMPILE_CONSOLE
+  d = initializesock(0, "localhost", "127.0.0.1", 0);
+  if (STDIN_FILENO >= maxd)
+    maxd = STDIN_FILENO + 1;
+#else
   if (!restarting) {
     sock = make_socket(port, SOCK_STREAM, NULL, NULL, MUSH_IP_ADDR);
     if (sock >= maxd)
@@ -1036,8 +1052,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 */
@@ -1045,6 +1063,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.");
 
   notify_fd = file_watch_init();
@@ -1139,6 +1158,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
@@ -1149,14 +1169,30 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
     if (info_slave_state == INFO_SLAVE_PENDING)
       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 */
     }
 
     if (notify_fd >= 0)
@@ -1187,6 +1223,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 == INFO_SLAVE_PENDING
           && FD_ISSET(info_slave, &input_set)) {
@@ -1237,6 +1274,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
         setup_desc(sslsock, true);
 #endif
 #endif
+#endif /* COMPILE_CONSOLE */
 
       if (notify_fd >= 0 && FD_ISSET(notify_fd, &input_set))
         file_watch_event(notify_fd);
@@ -1261,6 +1299,7 @@ shovechars(Port_t port, Port_t sslport __attribute__ ((__unused__)))
   }
 }
 
+#ifndef COMPILE_CONSOLE
 static int
 test_connection(int newsock)
 {
@@ -1276,8 +1315,6 @@ test_connection(int newsock)
   return newsock;
 }
 
-
-
 static DESC *
 new_connection(int oldsock, int *result, bool use_ssl)
 {
@@ -1336,6 +1373,7 @@ new_connection(int oldsock, int *result, bool use_ssl)
   set_keepalive(newsock);
   return initializesock(newsock, tbuf1, tbuf2, use_ssl);
 }
+#endif
 
 static void
 clearstrings(DESC *d)
@@ -1815,6 +1853,7 @@ process_output(DESC *d)
 {
   struct text_block **qp, *cur;
   int cnt;
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   int input_ready = 0;
 #endif
@@ -1878,6 +1917,7 @@ process_output(DESC *d)
     }
   }
 #endif
+#endif /* COMPILE_CONSOLE */
 
   for (qp = &d->output.head; ((cur = *qp) != NULL);) {
 #ifdef HAVE_WRITEV
@@ -1949,6 +1989,7 @@ process_output(DESC *d)
       }
     } else {
 #endif                          /* HAVE_WRITEV */
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
       if (d->ssl) {
         cnt = 0;
@@ -1959,6 +2000,7 @@ process_output(DESC *d)
           return 1;             /* Need to retry */
       } else
 #endif                          /* HAS_OPENSSL */
+#endif /* COMPILE_CONSOLE */
       {
         cnt = send(d->descriptor, cur->start, cur->nchars, 0);
         if (cnt < 0) {
@@ -2912,9 +2954,11 @@ close_sockets(void)
 
   for (d = descriptor_list; d; d = dnext) {
     dnext = d->next;
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
     if (!d->ssl) {
 #endif
+#endif
 #ifdef HAVE_WRITEV
       struct iovec byebye[2];
       byebye[0].iov_base = (char *) shutmsg;
@@ -2926,6 +2970,7 @@ close_sockets(void)
       send(d->descriptor, shutmsg, shutlen, 0);
       send(d->descriptor, (char *) "\r\n", 2, 0);
 #endif
+#ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
     } else {
       int offset;
@@ -2945,6 +2990,7 @@ close_sockets(void)
       d->ssl_state = 0;
     }
 #endif
+#endif /* COMPILE_CONSOLE */
     if (shutdown(d->descriptor, 2) < 0)
       penn_perror("shutdown");
     closesocket(d->descriptor);
@@ -3930,7 +3976,7 @@ FUNCTION(fun_lwho)
   DESC *d;
   dbref victim;
   int first;
-  int start, count;
+  int start = 0, count = 0;
   int powered = !(strchr(called_as, 'M') != NULL) && Priv_Who(executor);
   int xwho = *called_as == 'X';
   int objid = (strchr(called_as, 'D') != NULL);
@@ -4857,11 +4903,10 @@ dump_reboot_db(void)
     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 */
+    putref(f, maxd);
     /* First, iterate through all descriptors to get to the end
      * we do this so the descriptor_list isn't reversed on reboot
      */
@@ -4946,13 +4991,12 @@ load_reboot_db(void)
 
 #ifdef COMPILE_CONSOLE
   val = getref(f);
-  val = getref(f);
 #else /* COMPILE_CONSOLE */
   sock = getref(f);
+#endif /* COMPILE_CONSOLE */
   val = getref(f);
   if (val > maxd)
     maxd = val;
-#endif /* COMPILE_CONSOLE */
 
   while ((val = getref(f)) != 0) {
     ndescriptors++;
@@ -5089,7 +5133,7 @@ load_reboot_db(void)
 #ifndef COMPILE_CONSOLE
 #ifdef HAS_OPENSSL
   if (SSLPORT) {
-    sslsock = make_socket(SSLPORT, SOCK_STREAM, NULL, SSL_IP_ADDR);
+    sslsock = make_socket(SSLPORT, SOCK_STREAM, NULL, NULL, SSL_IP_ADDR);
     ssl_master_socket = ssl_setup_socket(sslsock);
     if (sslsock >= maxd)
       maxd = sslsock + 1;
index 70d5384b8997b62ceb6a0a3cc7e4c8ef87204748..bbbe48ae09b2fda844fa7511f12c467501665701 100644 (file)
@@ -523,7 +523,7 @@ make_command(const char *name, int type, const char *sw, command_func func, cons
       break;
     }
   case CMD_LOAD_DONE:{
-      switch_mask mask = switchmask(sw);
+      switch_mask *mask = switchmask(sw);
       if (mask) {
         cmd->sw.mask = SW_ALLOC();
         SW_COPY(cmd->sw.mask, mask);
@@ -668,7 +668,7 @@ switch_mask
     else
       SW_SET(sw, switchnum);
   }
-  return sw;
+  return &sw;
 }
 
 /** Add an alias to the table of reserved aliases.
index 79a9783acba9700f22f43b0cc4885eae48b41012..d30835e091366322872e29d92a338d64a1ae0a60 100644 (file)
@@ -301,7 +301,7 @@ text_uncompress(unsigned char const *s)
   if (!s || !*s)
     return buf;
   p = (unsigned char *) s;
-  b = buf;
+  b = (unsigned char *) buf;
 
   while (*p) {
     c = *p;
diff --git a/src/console.c b/src/console.c
deleted file mode 100644 (file)
index 7283225..0000000
+++ /dev/null
@@ -1,4478 +0,0 @@
-#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"
-#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 char ayt_reply[] = "\r\n*** AYT received, I'm here ***\r\n";
-      queue_newwrite(d, (unsigned char *) ayt_reply, 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;
-
-  /* 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;
-
-    /* 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 */
-
-/* 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)
-{
-}
-
index a60147a6b96c49417cee2b373da9f92950e78a03..e212e40c53055488d35ab799f70b88692bae1ee1 100644 (file)
@@ -714,7 +714,7 @@ void copy_zone(dbref executor, dbref zmo) {
   dbref *oldexits, *newexits;
   /* dbref_list variables */
   char *da_buf_arr[BUFFER_LEN / 2];
-  int da_sz;
+  int da_sz = 0;
   int *da_vals = NULL;
   char buf[BUFFER_LEN], *bp;
   /* */
@@ -861,7 +861,7 @@ dbref copy_room(dbref room, dbref newowner) {
   return new_room;
 }
 
-dbref copy_exit(dbref loc, dbref tail, dbref exit, dbref *oldrooms, dbref *newrooms, dbref new_owner, int num_rooms) {
+dbref copy_exit(dbref loc, dbref tail __attribute__ ((__unused__)), dbref exit, dbref *oldrooms, dbref *newrooms, dbref new_owner, int num_rooms) {
   int i;
   dbref new_exit;
 
index 33edd1fa53c1e01c54b43425d372f78ee126c793..32719618bb0590dadee2935ded6fe0b933edcb6e 100644 (file)
@@ -160,6 +160,9 @@ start_cron(void)
              spec = parse_spec((const char *) fp_h, CRON_DAY_MAX, wday_table, wday_alias_table, NULL, NULL);
              memcpy(&job->spec.wday, &spec, sizeof(job->spec.wday));
              break;
+           case CS_TASK:
+             /* FIXME: is this enum value obsolete? does anything happen here? */
+             break;
        }
        which++;
        fp_h = fp_t;
@@ -380,20 +383,22 @@ parse_spec(const char *str, unsigned int maximum, NVALUE *table, NVALUE_ALIAS *a
     } else
       continue;
     
-    if (num < 0 || num > maximum)
+/* FIXME: All these (unsigned) typecasts are to avoid warnings.  Consider
+ * changing the variable types to make this cleaner. */
+    if (num < 0 || ((unsigned) num) > maximum)
       continue;
     
     if (range < 0) {
       range = num;
-    } else if (range > maximum) {
+    } else if (((unsigned) range) > maximum) {
       range = maximum;
     }
     
-    if (skip < 1 || skip > maximum)
+    if (skip < 1 || ((unsigned) skip) > maximum)
       continue;
 
     if (format) {
-      if (num == 0 && range == maximum) {
+      if (num == 0 && ((unsigned) range) == maximum) {
         safe_chr(CRON_WILDCARD, format, fp);
       } else {
 
@@ -426,7 +431,7 @@ parse_spec(const char *str, unsigned int maximum, NVALUE *table, NVALUE_ALIAS *a
         spec |= num_to_bits(num);
       iter++;
       num++;
-      if (num > maximum && range < maximum)
+      if (((unsigned) num) > maximum && ((unsigned) range) < maximum)
         num = 0;
       if (iter > skip)
         iter = 1;
index 5b69a3d8de300fe9919746856dc7878ec571f2f1..f657a06766c428f6ee0520a324a1eff62fc8cd4b 100644 (file)
@@ -849,8 +849,9 @@ powergroup_empower(dbref executor, POWERGROUP * pgrp, const char *powers,
 }
 
 /* powergroups_list() {{{3 - List powergroups able to set from 'players' point of view */
+/* FIXME: Why is 'player' unused? */
 char *
-powergroups_list(dbref player, char flag)
+powergroups_list(dbref player __attribute__ ((__unused__)), char flag)
 {
   POWERGROUP *pgrp;
   char pg_name[BUFFER_LEN];
@@ -2670,7 +2671,8 @@ void do_list_powers(dbref player, const char *name) {
     notify_format(player, "Powers List: %s", tbuf);
 }
 
-char *list_all_powers(dbref player, const char *name) {
+/* FIXME: Why is 'player' unused? */
+char *list_all_powers(dbref player __attribute__ ((__unused__)), const char *name) {
   POWER *power;
   static char buff[BUFFER_LEN];
   char pname[BUFFER_LEN];
index 9baa88bba6b968106c56a43a234cfc54989357e3..a630cb9eeb8f56cf9fed104c99d9de481db3d33a 100644 (file)
@@ -278,3 +278,5 @@ Win32MUSH_setup(void)
 
 
 #endif  /* WIN32 */
+
+int filecopy_dummy; /* FIXME: Needed because ISO C forbids empty translation unit */
index 7338f61238ba4b8d887bbb51f4745849106fbc11..82e328035fc6d3f6e26d9cffb99cfb31103da67a 100644 (file)
@@ -40,7 +40,6 @@
 static char *crunch_code(char *code);
 static char *crypt_code(char *code, char *text, int type);
 
-static void safe_sha0(const char *text, size_t len, char *buff, char **bp);
 static void safe_hexchar(unsigned char c, char *buff, char **bp);
 
 static bool
@@ -91,7 +90,6 @@ encode_base64
 #endif
 }
 
-static void safe_sha0(const char *text, size_t len, char *buff, char **bp);
 extern char valid_ansi_codes[UCHAR_MAX + 1];
 
 static bool
index 8349fa5de24f940de0d57ccc2ae5a652d03ea29c..806a3f646ebf9de81b27ca765c8f39a9f585b21f 100644 (file)
@@ -107,7 +107,8 @@ FUNCTION(fun_lattr)
   dbref thing;
   char *pattern;
   struct lh_args lh;
-  char delim;
+  char delim = ' ';
+  /* FIXME: Set delim correctly */
 
   pattern = strchr(args[0], '/');
   if (pattern)
index fbe98d2c10e5acfd0bf3e652a6b7a5ce486c7a54..bf054a48256701acf6958ca71c933c31cea76d45 100644 (file)
@@ -144,7 +144,7 @@ do_userfn(char *buff, char **bp, dbref obj, ATTR *attrib, int nargs,
   char *tbuf;
   char const *tp;
   int pe_flags = PE_DEFAULT | extra_flags;
-  int old_args;
+  int old_args = 0;
 
   /* save our stack */
   for (j = 0; j < 10; j++)
index 8d2e4f5a92e62fd64f5b940aede75c0188cc043d..10bd2840d0c093276314ca91ccfa48bfdeab8bf9 100644 (file)
@@ -224,8 +224,9 @@ lock_flags_long(lock_list *ll)
 }
 
 
+/* FIXME: Why is 'player' unused? */
 static int
-string_to_lockflag(dbref player, char const *p, privbits *flag)
+string_to_lockflag(dbref player __attribute__ ((__unused__)), char const *p, privbits *flag)
 {
   privbits f;
 
index 688dea4483d54873559b28e5e27bf4d526bd19e6..dd5146ed03b71502a02ed39eed40369ed5653a31 100644 (file)
@@ -91,7 +91,9 @@ int module_open(char *path, char *name) {
   }
 
   /* Some OSes may need symbols to be prefixed with _.. Will need to look into autoconfig code for this */
-  module_loader = MODULE_FUNCRET(handle, "module_load");
+  /* FIXME: This is hideous, but ISO C prohibits casting from an object pointer
+   * to a function pointer and lt_dlsym() returns void *. */
+  *((void **) (&module_loader)) = MODULE_FUNCRET(handle, "module_load");
 
   if(!module_loader) {
     do_rawlog(LT_ERR, "Error Loading Module: Could not call module_load | %s", file);
@@ -105,7 +107,8 @@ int module_open(char *path, char *name) {
   }
   module->handle = handle;
   module->load = module_loader;
-  module->unload = MODULE_FUNCRET(handle, "module_unload");
+  /* FIXME: See comment above. */
+  *((void **) (&module->unload)) = MODULE_FUNCRET(handle, "module_unload");
   
   /* Grab info and version from module & put it in */
   /* Success.. Call the module */
index 65dfd109d53848c39a31527114104d04d62b05d6..8ded5e23c24df8a5e473e632cdc0a8b19cac9442 100644 (file)
 #include <stddef.h>
 #include <limits.h>
 #include <assert.h>
-#if defined(MALLOC_PACKAGE) && (MALLOC_PACKAGE == 0)
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#endif /* MALLOC_PACKAGE */
 #ifdef WIN32
 #include <windows.h>
 #endif
index 5c5e457e94bcda8878e80d21aa07c575de17f6ff..02d07e2324c7ad198de7b31333529d8d5fc57e77 100644 (file)
@@ -127,7 +127,7 @@ dbref
 connect_player(const char *name, const char *password, const char *host,
                const char *ip, char *errbuf)
 {
-  dbref player;
+  dbref player = NOTHING;
   char isgst = 0;
 
   /* Default error */
index 60ffdad3939bee824ba0961cdbd9072609b9e774..4ef128efe42599fefbf3beca5f2116bf929e8f3a 100644 (file)
@@ -996,8 +996,10 @@ ok_function_name(const char *name)
  * \retval 0 params is not accpetable.
  */
 int
-ok_tag_attribute(dbref player, char *params)
+ok_tag_attribute(dbref player, const char *params)
 {
+  /* FIXME: Casting from const to non-const is bad as we change potentially
+   * constant memory from the caller. */
   unsigned char *p, *q;
 
   if (!GoodObject(player) || Can_Pueblo_Send(player))
index b59786139e99173767ecf9f00a852008d085ff5e..22ed1fabde7362fbe1a3ed28edee49d058371d89 100644 (file)
@@ -56,7 +56,7 @@ COMMAND(cmd_prog)
   DESC *d;
   int i, pflags = 0;
   char buf[BUFFER_LEN], *bp;
-  char *key;
+  const char *key;
 
   if (!arg_left) {
     notify(player, "Invalid arguments.");
@@ -212,7 +212,7 @@ FUNCTION(fun_prog)
   dbref target, thing;
   char pflags = 0x0;
   int i;
-  char *key;
+  const char *key;
 
   target = match_result(executor, args[0], TYPE_PLAYER, MAT_EVERYTHING);
   if (!GoodObject(target) || !Connected(target)) {
@@ -476,7 +476,7 @@ prog_handler(DESC * d, char *input)
   char *tbuf, *bp;
   char *p_buf[NUMQ];
   int rcnt, i;
-  char *key;
+  const char *key;
 
   if (!strcmp(input, "IDLE"))
     return 1;
index fdf7bc7430b054933b82bf3c4473d70eff9afdbf..a166b64d25818a3866f67c1d164bcbd8f6dad930 100644 (file)
@@ -36,6 +36,8 @@ static void do_audible_stuff(dbref loc, dbref *excs, int numexcs,
 static void do_one_remit(dbref player, const char *target, const char *msg,
                          int flags);
 dbref na_zemit(dbref current, void *data);
+int messageformat(dbref player, const char *attribute, dbref enactor, int flags,
+                 int numargs, char *argv[]);
 
 const char *
 spname(dbref thing)
index da701f9ad77692586ca32b06ff392cba90b8558c..271e202967514a15e1beb5d44c939f77700ff346 100644 (file)
@@ -1561,7 +1561,6 @@ char *
 show_tm(struct tm *when)
 {
   static char buffer[BUFFER_LEN];
-  int p;
 
   if (!when)
     return NULL;
index 372bc591fd874a9c63995836e5663cc83c7022e3..2f3dfaf7431593039084a70da098b3957eefecef 100644 (file)
@@ -889,11 +889,13 @@ can_interact(dbref from, dbref to, int type)
   /* This function can override standard checks! */
   /* This doohicky is the replacement for local_can_interact_first */
   MODULE_ITER(m) {
-   handle =  MODULE_FUNCRET(m->handle, "module_can_interact_first")
-   if(handle) {
-     if((lci = handle(from, to , type)) != NOTHING)
-       return lci;
-   }
+    /* FIXME: This is hideous but is required because ISO C prohibits assignment
+     * from void * to a function pointer. */
+    *((void **) &handle) = MODULE_FUNCRET(m->handle, "module_can_interact_first");
+    if (handle) {
+      if ((lci = handle(from, to , type)) != NOTHING)
+        return lci;
+    }
   }
 
   /* Standard checks */
@@ -913,11 +915,13 @@ can_interact(dbref from, dbref to, int type)
     return 1;
 
   MODULE_ITER(m) {
-   handle =  MODULE_FUNCRET(m->handle, "module_can_interact_last")
-   if(handle) {
-     if((lci = handle(from, to , type)) != NOTHING)
-       return lci;
-   }
+    /* TODO: This is required because ISO C prohibits assignment from void *
+     * to function pointer. */
+    *((void **) &handle) = MODULE_FUNCRET(m->handle, "module_can_interact_last");
+    if (handle) {
+      if ((lci = handle(from, to , type)) != NOTHING)
+        return lci;
+    }
   }
 
   return 1;