PennMUSH Incorporation. Applied patch 1.8.1p10-1.8.2p0.patch, all
authorRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 17:32:23 +0000 (13:32 -0400)
committerRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 17:32:23 +0000 (13:32 -0400)
portions pertaining to visual studio project files not applied.
Untested

18 files changed:
Makefile.SH
README
hdrs/htab.h
src/command.c
src/conf.c
src/cque.c
src/db.c
src/extchat.c
src/function.c
src/funlist.c
src/help.c
src/htab.c
src/look.c
src/plyrlist.c
src/sig.c
src/wild.c
utils/mkcmds.sh.SH
win32/README.txt

index 13565fd54e4ad1653dee99a896166a556f6531d9..da430218ce124b4f14356361cca027ec549c7c48 100644 (file)
@@ -262,6 +262,9 @@ diffs:
 checkin: versions autogen
        @prcs checkin
 
+commit: indent
+       @svn commit
+
 patch: versions
        @make-patch-header
        @make diffs
diff --git a/README b/README
index b0c4aa4972bc911fc2daaae984d788a9e4119c45..c53d0be144bc8dc576678edfc795664a2a079771 100644 (file)
--- a/README
+++ b/README
@@ -19,12 +19,12 @@ You may also want to take a look at Javelin's Guide for PennMUSH Gods,
 at http://pennmush.org/~alansz/guide.html
 or by ftp from pennmush.org, /pub/PennMUSH/Guide
 ============================================================================
+
 I. Introduction and history
 
 PennMUSH uses a version-numbering system that includes version
 numbers (like 1.7.2) and patchlevels (like p32), usually written
-together (1.7.2p32). 
+together (1.7.2p32).
 
 Starting with 1.7.2, version numbers that are even (like 1.7.2) are
 stable releases - patchlevels on the latest stable release will only be
@@ -61,8 +61,8 @@ avoid the confusion that resulted from PernMUSH actually running
 TinyMUSH 2.0.
 
 In January of 1995, Amberyl passed on her mantle to Javelin (aka
-Paul@Dune, Alan Schwartz), who is now the maintainer of the primary
-public distribution in development. He released two patchlevels
+Paul@Dune, Alan Schwartz), who continuted as the maintainer of the
+primary public distribution in development. He released two patchlevels
 numbered "dune-1" and "dune-2" before releasing PennMUSH 1.50 pl11 and
 later distributions. The numbering scheme changed again with PennMUSH
 1.6.0 (see CHANGES.OLD).
@@ -86,6 +86,11 @@ an open source/free software license. This license was
 simultaneously adopted by TinyMUSH (2.2.5, 3.x) and TinyMUX to
 facilitate code sharing and widen use.
 
+In July 2006, Javelin retired from the role of Maintainer, passing the
+mantle of lead developer to Raevnos and that of release management to
+Ervin Hearn (Noltar). Many thanks go to Javelin whose contributions and
+guidance of PennMUSH have shaped it into the codebase that it is today.
+
 A MUSH manual should be available at ftp.digex.net, ftp.math.okstate.edu,
 primerd.prime.com, or from wherever you got this code from. The manual
 should be numbered version 2.007 or higher.
@@ -126,7 +131,7 @@ There are three places one could get help with a problem:
    informed of new patches, subscribe to pennmush-announce instead,
    at http://www.pennmush.org/mailman/listinfo/pennmush-announce)
 
-2. pennmush-bugs@pennmush.org is the bug reporting address 
+2. pennmush-bugs@pennmush.org is the bug reporting address
    for the PennMUSH developers (suggestions go to pennmush-developers,
    bugs to pennmush-bugs). This will generally give you the fastest
    response and is ideal for unusual bugs. A web-based submission
@@ -140,7 +145,7 @@ information:
 3. The operating system and version (SunOS 4.1.2, AIX 3.2.4, etc.),
 4. The compiler and compiler version (gcc 2.4.5, SGI cc 2.10, etc. -- the
    'file' command usually tells you the compiler version, if there's no
-   built-in option like '-v' or '-V' to give it), 
+   built-in option like '-v' or '-V' to give it),
 5. Whether or not you have made any changes to the code.
 
 If the problem resulted in a crash and a core dump, a stack trace of
@@ -160,12 +165,12 @@ you can have yourmush.pennmush.org assigned as a hostname for your MUSH,
 so players don't need to telnet to obscuresite.obscuredomain.com!
 
 NOTE: A hostname is not the same thing as a site. We don't have accounts
-for you to run your MUSH from. You must already have your MUSH 
+for you to run your MUSH from. You must already have your MUSH
 running at someplace.edu or whatever -- we just provide a nice hostname
 that will resolve into your current site's IP address.
 
-How do you get a pennmush.org hostname? Go to 
-http://lists.pennmush.org/pennmush.html, and follow the instructions.
+How do you get a pennmush.org hostname? Go to
+http://services.pennmush.org/, and follow the instructions.
 It may take a day or two before the hostname will work.
 
 Thovald also has volunteered to host mailing lists for MUSHes in
@@ -174,11 +179,11 @@ the pennmush.org domain. Details are on the same web page.
 ============================================================================
 
 IV. Comments
+
 IV.a. Amberyl's Comments
 
 These are in the first person.  :)
+
 I've been working with this code for a year and a quarter now.  I can't
 claim that it's particularly elegant or inspired; all I can say is that
 it works (most of the time), and that I've had fun writing it.  I'm
index 4c668b134c5f11b004a3a8d312e5e067bf5e1208..a9b19be5ce2295c59ec4082d26ef9f67766bf3ba 100644 (file)
@@ -31,8 +31,8 @@ struct hashtable {
   int last_hval;               /**< State for hashfirst & hashnext. */
   HASHENT *last_entry;         /**< State for hashfirst & hashnext. */
   int entry_size;              /**< Size of each entry */
-  void (*free_data)(void*);     /**< Function to call on data when deleting
-                                  a entry. */
+  void (*free_data) (void *);  /**< Function to call on data when deleting
+                                   a entry. */
 };
 
 #define get_hashmask(x) hash_getmask(x)
@@ -44,7 +44,7 @@ struct hashtable {
 #define hashflush(tab, size) hash_flush(tab,size)
 #define hashfree(tab) hash_flush(tab, 0)
 extern int hash_getmask(int *size);
-extern void hash_init(HASHTAB *htab, int size, int data_size, void (*)(void*));
+extern void hash_init(HASHTAB *htab, int size, int data_size, void (*)(void *));
 extern HASHENT *hash_find(HASHTAB *htab, const char *key);
 extern void *hash_value(HASHENT *entry);
 extern char *hash_key(HASHENT *entry);
index e3c384cedeb724dfa4716701b825ce90dae76819..56819eb9d38d5b586345bffc703513af62dfa673 100644 (file)
@@ -1718,7 +1718,7 @@ static int
 command_check(dbref player, COMMAND_INFO *cmd, switch_mask switches)
 {
   int ok;
-  char *mess = NULL;
+  const char *mess = NULL;
 
   /* God doesn't get fucked with */
   if(LEVEL(player) >= LEVEL_GOD)
index 1eb59d79f663cd108d9e868ed0c8554013afd604..d6d2e06ebbc9c5f7331e3f8559b39bd3316a8c62 100644 (file)
@@ -179,9 +179,9 @@ COBRA_CONF conftable[] = {
   ,
   {"ssl_ip_addr", cf_str, options.ssl_ip_addr, 64, 0, "net"}
   ,
-  {"port", cf_int, &options.port, 32000, 0, "net"}
+  {"port", cf_int, &options.port, 65535, 0, "net"}
   ,
-  {"ssl_port", cf_int, &options.ssl_port, 32000, 0, "net"}
+  {"ssl_port", cf_int, &options.ssl_port, 65535, 0, "net"}
   ,
   {"use_dns", cf_bool, &options.use_dns, 2, 0, "net"}
   ,
index 1b45f81d81f830307244ca87ae6a7318029f98bd..ffa1e809748d231bf34ff72da2fbe73a77ecddc7 100644 (file)
@@ -80,7 +80,7 @@ static int add_to_sem(dbref player, int am, const char *name);
 static int queue_limit(dbref player);
 void free_qentry(BQUE *point);
 static int pay_queue(dbref player, const char *command);
-int wait_que(dbref player, int wait, char *command,
+int wait_que(dbref player, int waituntil, char *command,
              dbref cause, dbref sem, const char *semattr, int until, char finvoc);
 void init_qids();
 int  create_qid();
@@ -487,7 +487,7 @@ queue_attribute_useatr(dbref executor, ATTR *a, dbref enactor)
  * they're due to expire; semaphore queue entries are just added
  * to the back of the queue.
  * \param player the enqueuing object.
- * \param wait time to wait, or 0.
+ * \param waittill time to wait, or 0.
  * \param command command to enqueue.
  * \param cause object that caused command to be enqueued.
  * \param sem object to serve as a semaphore, or NOTHING.
@@ -495,12 +495,12 @@ queue_attribute_useatr(dbref executor, ATTR *a, dbref enactor)
  * \param until 1 if we wait until an absolute time.
  */
 int
-wait_que(dbref player, int wait, char *command, dbref cause, dbref sem,
+wait_que(dbref player, int waittill, char *command, dbref cause, dbref sem,
         const char *semattr, int until, char finvoc)
 {
   BQUE *tmp;
   int a, qid;
-  if (wait == 0) {
+  if (waittill == 0) {
     if (sem != NOTHING)
       add_to_sem(sem, -1, semattr);
     parse_que(player, command, cause);
@@ -542,10 +542,10 @@ wait_que(dbref player, int wait, char *command, dbref cause, dbref sem,
   copy_namedregs(&tmp->namedregs, &global_eval_context.namedregs);
 
   if (until) {
-    tmp->left = wait;
+    tmp->left = waittill;
   } else {
-    if (wait >= 0)
-      tmp->left = mudtime + wait;
+    if (waittill >= 0)
+      tmp->left = mudtime + waittill;
     else
       tmp->left = 0;           /* semaphore wait without a timeout */
   }
index e08b07a270c46f3db56e27d822626656c0134e19..b961e26ae67b9c95a4009fc6b60a41d2cc066b18 100644 (file)
--- a/src/db.c
+++ b/src/db.c
@@ -1113,12 +1113,12 @@ get_new_locks(dbref i, FILE * f, int c)
   }
 
   for (;;) {
-    int c;
+    int ch;
 
-    c = fgetc(f);
-    ungetc(c, f);
+    ch = fgetc(f);
+    ungetc(ch, f);
 
-    if (c != ' ') 
+    if (ch != ' ')
       break;
 
     found++;
@@ -1141,10 +1141,11 @@ get_new_locks(dbref i, FILE * f, int c)
     add_lock_raw(creator, i, type, b, flags);
   }
 
-  if (found != count) 
+  if (found != count)
     do_rawlog(LT_ERR,
-             T("WARNING: Actual lock count (%d) different from expected count (%d)."),
-               found, count);
+             T
+             ("WARNING: Actual lock count (%d) different from expected count (%d)."),
+             found, count);
 
 }
 
@@ -2058,7 +2059,7 @@ db_read(FILE * f)
 }
 
 static void
-init_objdata_htab(int size, void (*free_data)(void*))
+init_objdata_htab(int size, void (*free_data) (void *))
 {
   hash_init(&htab_objdata, size, 4, free_data);
   hashinit(&htab_objdata_keys, 8, 32);
index f221388ba14020318737279f413c445b24ef3048..1708b657982f73710a5145713ab12bec5bfcac15 100644 (file)
@@ -183,6 +183,8 @@ onchannel(dbref who, CHAN *ch)
       notify(player, T("CHAT: I don't know which channel you mean.")); \
       list_partial_matches(player, name, PMATCH_ALL); \
       return; \
+    case CMATCH_EXACT: \
+    case CMATCH_PARTIAL: \
     default: \
       break; \
      } \
@@ -3673,6 +3675,8 @@ do_chan_buffer(dbref player, const char *name, const char *lines)
   }
 }
 
+/* msg is a printf-style format that has exactly and only 2 %s specifiers
+   in it. */
 static void
 format_channel_broadcast(CHAN *chan, CHANUSER *u, dbref victim, int flags,
                         const char *msg, const char *extra)
index 5b87df994623235cec4cc8eb788c5b3085c1a408..7058860d7a06df28a76ceb610afffd9333c16368 100644 (file)
@@ -840,7 +840,7 @@ func_hash_insert(const char *name, FUN *func)
   hashadd(name, (void *) func, &htab_function);
 }
 
-static void delete_function(void*);
+static void delete_function(void *);
 
 /** Initialize the function hash table.
  */
@@ -1327,7 +1327,7 @@ delete_function(void *data)
 {
   size_t table_index, i;
   FUN *fp = data;
-  
+
   table_index = fp->where.offset;
   mush_free((void *) fp->name, "func_hash.name");
   mush_free(fp, "func_hash.FUN");
@@ -1346,6 +1346,7 @@ delete_function(void *data)
   }
 
 }
+
 /** Restore an overridden built-in function.
  * \verbatim
  * If a built-in function is deleted with @function/delete, it can be
index 32f3e399798a452ebb6f2b0264b5c5d66f630f08..7439d6c3cc07a48817d1dadb865638001b9e678a 100644 (file)
@@ -2988,7 +2988,7 @@ FUNCTION(fun_mix)
   if (!fetch_ufun_attrib(args[0], executor, &ufun, 1))
     return;
 
-  first = 0;
+  first = 1;
   while (1) {
     words = 0;
     for (n = 0; n < lists; n++) {
index c8a7c60b48d69c330bc6290b1295624c489d5c07..948e6cec3d06a35716f8ed65299f701c13f05216 100644 (file)
@@ -32,8 +32,8 @@ static int help_init = 0;
 static void do_new_spitfile(dbref player, char *arg1, help_file *help_dat);
 static const char *string_spitfile(help_file *help_dat, char *arg1);
 static help_indx *help_find_entry(help_file *help_dat, const char *the_topic);
-static char *list_matching_entries(char *pattern, help_file *help_dat,
-                                  const char *sep);
+static const char *list_matching_entries(char *pattern, help_file *help_dat,
+                                        const char *sep);
 static const char *normalize_entry(help_file *help_dat, char *arg1);
 
 static void help_build_index(help_file *h, int restricted);
@@ -542,7 +542,7 @@ string_spitfile(help_file *help_dat, char *arg1)
 }
 
 /** Return a string with all help entries that match a pattern */
-static char *
+static const char *
 list_matching_entries(char *pattern, help_file *help_dat, const char *sep)
 {
   static char buff[BUFFER_LEN];
index 353eb7ad4e002d12b3fc0867d324269e5a3a114c..08a30a199ae3497d0dc57f9e293bfbf11778119d 100644 (file)
@@ -154,7 +154,7 @@ hash_getmask(int *size)
  * \param data_size size of an individual datum to store in the table.
  */
 void
-hash_init(HASHTAB *htab, int size, int data_size, void (*free_data)(void*))
+hash_init(HASHTAB *htab, int size, int data_size, void (*free_data) (void *))
 {
   int i;
 
index 421527df728a34655c986b08a8ddab159d65373a..cb883990d8fe74591e7f2d86cd4ecdb58a9c3c53 100644 (file)
@@ -48,6 +48,8 @@ void decompile_atrs(dbref player, dbref thing, const char *name,
                    const char *pattern, const char *prefix, int skipdef);
 void decompile_locks(dbref player, dbref thing, const char *name, int skipdef);
 
+static void insert_spaces(int count, int dospace, char *buff, char **bp);
+
 extern PRIV attr_privs_view[];
 
 static void
@@ -1416,6 +1418,40 @@ struct dh_args {
 
 extern char escaped_chars[UCHAR_MAX + 1];
 
+static void
+insert_spaces(int count, int dospace, char *buff, char **bp)
+{
+  if (count) {
+    if (count >= 5) {
+      safe_str("[space(", buff, bp);
+      safe_number(count, buff, bp);
+      safe_str(")]", buff, bp);
+    } else if (count == 1) {
+      if (dospace) {
+       safe_str("%b", buff, bp);
+      } else {
+       safe_chr(' ', buff, bp);
+      }
+    } else {
+      /* Take care of the final %b */
+      count--;
+      if (dospace) {
+       safe_str("%b", buff, bp);
+       count--;
+      }
+      while (count) {
+       safe_chr(' ', buff, bp);
+       count--;
+       if (count) {
+         count--;
+         safe_str("%b", buff, bp);
+       }
+      }
+      safe_str("%b", buff, bp);
+    }
+  }
+}
+
 char *
 decompose_str(char *what)
 {
@@ -1424,6 +1460,7 @@ decompose_str(char *what)
   char ansi_letter = '\0';
   int len;
   int dospace;
+  int spaces;
   int flag_depth, ansi_depth;
   int digits;
 
@@ -1443,26 +1480,29 @@ decompose_str(char *what)
     safe_chr('\\', value, &s);
   }
 #endif
+
   dospace = 1;
+  spaces = 0;
   for (; *ptr; ptr++) {
     switch (*ptr) {
     case ' ':
-      if (dospace) {
-        safe_str("%b", value, &s);
-      } else {
-        safe_chr(' ', value, &s);
-      }
-      dospace = !dospace;
+      spaces++;
       break;
     case '\n':
+      insert_spaces(spaces, dospace, value, &s);
+      spaces = 0;
       dospace = 0;
       safe_str("%r", value, &s);
       break;
     case '\t':
+      insert_spaces(spaces, dospace, value, &s);
+      spaces = 0;
       dospace = 0;
       safe_str("%t", value, &s);
       break;
     case ESC_CHAR:
+      insert_spaces(spaces, dospace, value, &s);
+      spaces = 0;
       ptr++;
       if (!*ptr) {
        ptr--;
@@ -1492,7 +1532,7 @@ decompose_str(char *what)
          } else if (digits >= 2) {
            digits = 3;         /* If we encounter a 3-number code, break out. */
            break;
-         } else if (isdigit(*ptr)) {
+         } else if (isdigit((unsigned char) *ptr)) {
            digits++;           /* Count the numbers we encounter. */
          } else {
            digits = 3;
@@ -1535,11 +1575,11 @@ decompose_str(char *what)
        dospace = 1;
 
        /* code for decompiling ansi */
-       for (; isdigit(*ptr) || *ptr == ';'; ptr++) {
+       for (; isdigit((unsigned char) *ptr) || *ptr == ';'; ptr++) {
          if (*ptr == ';')      /* Yes, it is necessary to do it this way. */
            ptr++;
          /* Break if there is an 'm' here. */
-         if (!*ptr || !isdigit(*ptr))
+         if (!*ptr || !isdigit((unsigned char) *ptr))
            break;
          /* Check to see if the code is one character long. */
          if (*(ptr + 1) == ';' || *(ptr + 1) == 'm') {
@@ -1612,6 +1652,8 @@ decompose_str(char *what)
       }
       break;
     default:
+      insert_spaces(spaces, dospace, value, &s);
+      spaces = 0;
       if (escaped_chars[(unsigned int) *ptr]) {
         safe_chr('\\', value, &s);
       }
@@ -1620,10 +1662,8 @@ decompose_str(char *what)
     }
   }
   /* Now check the last space. */
-  if (*(s - 1) == ' ') {
-    s -= 1;
-    safe_str("%b", value, &s);
-  }
+  insert_spaces(spaces, dospace, value, &s);
+  spaces = 0;
   for (; ansi_depth > 0; ansi_depth--) {
     safe_str(")]", value, &s);
   }
index 897d7193e91d86c7b0b30b57fc3eb7f9a77ff0c3..2f4b6c245c01c9c293c6895d401380a423edc895 100644 (file)
@@ -29,11 +29,11 @@ HASHTAB htab_player_list;
 
 static int hft_initialized = 0;
 static void init_hft(void);
-static void delete_dbref(void*);
+static void delete_dbref(void *);
 
 /** Free a player_dbref struct. */
 static void
-delete_dbref(void *data) 
+delete_dbref(void *data)
 {
   mush_free(data, "plyrlist.entry");
 }
@@ -52,7 +52,7 @@ clear_players(void)
 {
   if (hft_initialized)
     hashflush(&htab_player_list, 256);
-   else
+  else
     init_hft();
 }
 
index 9fd5af7abe401d7200f7ba361322f4151a80d608..5cd05381e907be630bf91730bad070aa1c153156 100644 (file)
--- a/src/sig.c
+++ b/src/sig.c
@@ -125,7 +125,7 @@ block_signals(void)
   sigfillset(&mask);
   sigprocmask(SIG_BLOCK, &mask, NULL);
 #elif defined(WIN32)
-    /* The only signals Windows knows about */
+  /* The only signals Windows knows about */
   signal(SIGABRT, SIG_IGN);
   signal(SIGFPE, SIG_IGN);
   signal(SIGILL, SIG_IGN);
index 26b0056b3f36530f9891c004ab146f6de5d0ebaf..5278bfdb0051f4cc067373f9a2314fa494a2421f 100644 (file)
@@ -585,7 +585,6 @@ quick_regexp_match(const char *RESTRICT s, const char *RESTRICT d, int cs)
 
 /** Either an order comparison or a wildcard match with no memory.
  *
- * This routine will cause crashes if fed NULLs instead of strings.
  *
  * \param s pattern to match against.
  * \param d string to check.
@@ -596,22 +595,25 @@ quick_regexp_match(const char *RESTRICT s, const char *RESTRICT d, int cs)
 int
 local_wild_match_case(const char *RESTRICT s, const char *RESTRICT d, int cs)
 {
-  switch (*s) {
-  case '>':
-    s++;
-    if (is_number(s) && is_number(d))
-      return (parse_number(s) < parse_number(d));
-    else
-      return (strcoll(s, d) < 0);
-  case '<':
-    s++;
-    if (is_number(s) && is_number(d))
-      return (parse_number(s) > parse_number(d));
-    else
-      return (strcoll(s, d) > 0);
-  }
-
-  return quick_wild_new(s, d, cs);
+  if (s && *s) {
+    switch (*s) {
+    case '>':
+      s++;
+      if (is_number(s) && is_number(d))
+       return (parse_number(s) < parse_number(d));
+      else
+       return (strcoll(s, d) < 0);
+    case '<':
+      s++;
+      if (is_number(s) && is_number(d))
+       return (parse_number(s) > parse_number(d));
+      else
+       return (strcoll(s, d) > 0);
+    default:
+      return quick_wild_new(s, d, cs);
+    }
+  } else
+    return 0;
 }
 
 /** Does a string contain a wildcard character (* or ?)?
index e455859cc93e6b5b6e487fa0ce5c25bc1b21b709..b558d1aad9b3c42581c677a07a9eb52212304b18 100644 (file)
@@ -131,10 +131,6 @@ else
     mv -f ../hdrs/temp.$$.h ../hdrs/cmds.h
 fi
 
-if [ -d "../win32" ]; then
-  cp ../hdrs/cmds.h ../win32/cmds.h
-fi
-
 ;;
 functions)
 
@@ -152,10 +148,6 @@ if [ $cmpstat -eq 0 ]; then
 else
     mv -f ../hdrs/temp.$$.h ../hdrs/funs.h
 fi
-
-if [ -d "../win32" ]; then
-  cp ../hdrs/funs.h ../win32/funs.h
-fi
 ;;
 esac
 !NO!SUBS!
index 09238bf9382bd8483b4c89112da374fbae24f2cf..246736e9bc60a43462056c787b4c6015cf193236 100644 (file)
@@ -1,35 +1,46 @@
-How to compile PennMUSH 1.7.x under Windows (MSVC++/MS VS.NET)\r
+How to compile PennMUSH 1.8.x under Windows (MSVC++/MS VS.NET)\r
 ----------------------------------------------\r
 by Nick Gammon <nick@gammon.com.au> and Javelin and Luuk de Waard\r
+Updated by Ervin Hearn <ehearn@pennmush.org>\r
 \r
-Last update: Monday, 1 November 2002\r
+Last update: Saturday, 11 November 2006\r
 \r
 1. From the top-level pennmush directory,\r
-   Copy the following files     to:\r
-\r
-  win32/config.h      config.h\r
-  win32/confmagic.h   confmagic.h\r
-  win32/options.h     options.h\r
-  win32/cmds.h        hdrs/cmds.h\r
-  win32/funs.h        hdrs/funs.h\r
-  win32/patches.h     hdrs/patches.h\r
-  src/local.dst       src/local.c\r
-  src/funlocal.dst    src/funlocal.c\r
-  src/cmdlocal.dst    src/cmdlocal.c\r
-  src/flaglocal.dst   src/flaglocal.c\r
-  game/mushcnf.dst    game/mush.cnf\r
-\r
-  Project files for MSVC++:\r
-  win32/pennmush.dsw  pennmush.dsw\r
-  win32/pennmush.dsp  pennmush.dsp\r
-\r
-  Project files for MS VS.NET:\r
-  win32/pennmush.vcproj  pennmush.vcproj\r
-  win32/pennmush.sln  pennmush.sln\r
-\r
-   (If you've already got src/*local.c files that you've modified,\r
-    you'll just have to make sure that there are no new functions\r
-    in src/*local.dst that're missing in your src/*local.c files)\r
+   Copy the following files        to:\r
+\r
+   For MSVC++ 6:\r
+   win32/msvc6/pennmush.dsw        pennmush.dsw\r
+   win32/msvc6/pennmush.dsp        pennmush.dsp\r
+   win32/config.h                  config.h\r
+   win32/confmagic.h               confmagic.h\r
+   win32/options.h                 options.h\r
+   win32/cmds.h                    hdrs/cmds.h\r
+   win32/funs.h                    hdrs/funs.h\r
+   win32/patches.h                 hdrs/patches.h\r
+   src/cmdlocal.dst                src/cmdlocal.c\r
+   src/flaglocal.dst               src/flaglocal.c\r
+   src/funlocal.dst                src/funlocal.c\r
+   src/local.dst                   src/local.c\r
+   game/mushcnf.dst                game/mush.cnf\r
+   game/aliascnf.dst               game/alias.cnf\r
+   game/namescnf.dst               game/names.cnf\r
+   game/restrictcnf.dst            game/restrict.cnf\r
+\r
+\r
+   For MS VS.NET:\r
+   win32/msvc.net/pennmush.vcproj  pennmush.vcproj\r
+   win32/msvc.net/pennmush.sln     pennmush.sln\r
+\r
+   VS.NET has been configured to copy the .dst files automatically if they\r
+   do not exist, and the header files each time the project is compiled. This\r
+   can be disabled or changed by going to Project -> pennmush Properties ->\r
+   Configuration Properties -> Build Events -> Pre-Build Event and Post-Build\r
+   Event.\r
+\r
+\r
+   If you've already got src/*local.c files that you've modified,\r
+   you'll just have to make sure that there are no new functions\r
+   in src/*local.dst that are missing in your src/*local.c files\r
 \r
 2. If you're running under Windows NT, you may wish to edit options.h\r
 and uncomment the #define NT_TCP option. If you can build\r
@@ -43,3 +54,10 @@ with @shutdown/reboot.
 \r
 5. From the top-level pennmush directory, the binary is: game/pennmush.exe\r
 \r
+*** Note: Windows defaults to a stack size of 1 MB. The supplied project files\r
+set the stack size to 8MB to match the default environment on Linux systems and\r
+resolve several issues of early code termination on Windows. This setting can\r
+also be changed on the precompiled executable by using the 'editbin.exe' tool\r
+supplied by Microsoft in the Visual Studio installation, including the free\r
+Express version. To set the stack size (in KB) run the following from a\r
+command prompt in the game directory: editbin /STACK:<size> pennmush.exe\r