[PENNMUSH-ANNOUNCE] 1.7.5-patch04

dunemush@pennmush.org dunemush at pennmush.org
Fri, 15 Feb 2002 17:06:36 -0600


This is patch04 to PennMUSH 1.7.5. After applying this patch, you will
have version 1.7.5p4

To apply this patch, save it to a file in your top-level MUSH directory,
and do the following:
	patch -p1 < 1.7.5-patch04
	./Configure -d
	make install

If you use GNU patch 2.2, you probably want the above to be 'patch -b -p1',
not just 'patch -p1'.

Unix (or cygwin) users need not worry about failed hunks in src/switchinc.c,
hdrs/switches.h, hdrs/cmds.h, or hdrs/funs.h. These files are automatically
rebuilt on compile.

Then @shutdown and restart your MUSH.
    - Alan/Javelin

In this patch:

Major changes:
  * The mush recognizes telnet-aware connections. This is
    neccessary for properly sending them some 8-bit characters. [SW]
  * Much more support for handling accented characters in the ISO 8859-1
    character set. See help for accent(), stripaccents(), and NOACCENTS.
    Inspired by Elendor. [SW]
  * Things that do first-unique-prefix matching (command, attribute and flag
    names) now use a more space-efficient data structure than before.
    This adds two new files, src/ptab.c and hdrs/ptab.h [SW]
Commands:
  * @sitelock/remove removes a sitelock entry. [SW]
Functions:
  * ord() and chr() functions for converting characters to/from numerical
    values that represent them. [SW]
Minor changes:
  * The useless FORCE_WHITE flag is really, truely, gone. [SW]
  * Use the new arglens argument to functions in more places. [SW]
  * capstr() and before() fixes reimplemented using arglens. [SW]
  * We now use the Mersenne Twister PRNG algorithm. [SW]
Fixes:
  * setunion() no longer eats empty list elements. [SW]
  * Setting an inherited lock on a child could change the parent's lock.
    Reported by Riverwolf. [SW]
  * Help fixes. [SW, Nymeria]
  * Players waiting at the connect screen weren't being disconnected
    by the idle_timeout.
  * Detection of cygwin in Configure may be improved.
  * Fixes from 1.7.4p15.

Prereq: 1.7.5p3
*** 1_7_5.66/Patchlevel Thu, 24 Jan 2002 10:49:36 -0600 dunemush (pennmush/5_Patchlevel 1.17.1.4 600)
--- 1_7_5.96(w)/Patchlevel Fri, 15 Feb 2002 16:09:37 -0600 dunemush (pennmush/5_Patchlevel 1.17.1.5 600)
***************
*** 1,2 ****
  Do not edit this file. It is maintained by the official PennMUSH patches.
! This is PennMUSH 1.7.5p3
--- 1,2 ----
  Do not edit this file. It is maintained by the official PennMUSH patches.
! This is PennMUSH 1.7.5p4
*** 1_7_5.66/CHANGES.174 Wed, 23 Jan 2002 10:11:06 -0600 dunemush (pennmush/8_CHANGES 1.219.1.66 600)
--- 1_7_5.96(w)/CHANGES.174 Fri, 15 Feb 2002 16:10:35 -0600 dunemush (pennmush/8_CHANGES 1.219.1.72.1.1 600)
***************
*** 9,21 ****
  [SW] is Shawn Wagner, a PennMUSH developer (aka Raevnos)
  [LdW] is Luuk de Waard, a former PennMUSH developer (aka Halatir)
  [RLM] is Ralph Melton, a former PennMUSH developer
! [NJG] is Nick Gammon, the Win32 porter
  [DW] is Dan Williams, the MacOS porter
  [2.2] refers to code which originated with the TinyMUSH 2.2 developers
  [3] refers to code by (or inspired by) TinyMUSH 3.0
  [Rhost] refers to code by (or inspired by) RhostMUSH
  
  ==========================================================================
  
  Version 1.7.4 patchlevel 14		       January 4, 2002
  
--- 9,51 ----
  [SW] is Shawn Wagner, a PennMUSH developer (aka Raevnos)
  [LdW] is Luuk de Waard, a former PennMUSH developer (aka Halatir)
  [RLM] is Ralph Melton, a former PennMUSH developer
! [NJG] is Nick Gammon, the primary Win32 porter
! [EEH] is Ervin Hearn III, a Win32 porter (aka Noltar)
  [DW] is Dan Williams, the MacOS porter
  [2.2] refers to code which originated with the TinyMUSH 2.2 developers
  [3] refers to code by (or inspired by) TinyMUSH 3.0
  [Rhost] refers to code by (or inspired by) RhostMUSH
  
  ==========================================================================
+ 
+ Version 1.7.4 patchlevel 15		       February 8, 2002
+ 
+ Minor Changes:
+   * @dolist and iter(), where multiple tokens are replaced (## and #@),
+     now do both replacements at once. This is more efficient in several
+     ways and fixes a problem where if the second token gets into the
+     string from a replacement of the first, it gets replaced. (iter(a#@,
+     ##) should return a#@, not a1). [SW]
+   * setunion no longer eats empty list elements. [SW]
+   * The help text for items() is now more descriptive of how it works
+     and differs from words(). Suggested by Zen@SW1.
+   * When you attempt to @chzone an object to a ZMO without a zone-lock,
+     a default zone-lock of "owner of the ZMO" is now set, and the
+     attempt succeeds. Suggested by Linda Antonsson.
+   * In the French message translation files, the word 'drapeau' and
+     'flag' were used interchangeably. I've standardized on 'flag'.
+     Report by Vexon@M*U*S*H.
+ Fixes:
+   * Message typo fixed by Bellemore@M*U*S*H.
+   * No more ansified names in logged shutdown messages. Report by
+     Bellemore@M*U*S*H.
+   * Messages when destroying players now take into account the 
+     destroy_possessions and really_safe settings. Suggested by Wayne@PDX.
+   * The parser no longer strips any first layer of braces in, e.g.
+     @switch action clauses, but only when the first character in the
+     clause is a brace. This prevents @sw 1=1, @wait me={@emit 1; @emit 2}
+     from being misparsed and running @emit 2 immediately. Reported by
+     Azratax@Azmush. [TAP]
  
  Version 1.7.4 patchlevel 14		       January 4, 2002
  
*** 1_7_5.66/CHANGES Thu, 24 Jan 2002 10:49:36 -0600 dunemush (pennmush/g/7_CHANGES 1.22 600)
--- 1_7_5.96(w)/CHANGES Fri, 15 Feb 2002 16:10:16 -0600 dunemush (pennmush/g/7_CHANGES 1.27.1.2 600)
***************
*** 17,22 ****
--- 17,53 ----
  
  ==========================================================================
  
+ Version 1.7.5 patchlevel 4                     February 15, 2002
+ 
+ Major changes:
+   * The mush recognizes telnet-aware connections. This is
+     neccessary for properly sending them some 8-bit characters. [SW]
+   * Much more support for handling accented characters in the ISO 8859-1
+     character set. See help for accent(), stripaccents(), and NOACCENTS.
+     Inspired by Elendor. [SW]
+   * Things that do first-unique-prefix matching (command, attribute and flag
+     names) now use a more space-efficient data structure than before.
+     This adds two new files, src/ptab.c and hdrs/ptab.h [SW]
+ Commands:
+   * @sitelock/remove removes a sitelock entry. [SW]
+ Functions:
+   * ord() and chr() functions for converting characters to/from numerical
+     values that represent them. [SW]
+ Minor changes:
+   * The useless FORCE_WHITE flag is really, truely, gone. [SW]
+   * Use the new arglens argument to functions in more places. [SW]
+   * capstr() and before() fixes reimplemented using arglens. [SW]
+   * We now use the Mersenne Twister PRNG algorithm. [SW]
+ Fixes:
+   * setunion() no longer eats empty list elements. [SW]
+   * Setting an inherited lock on a child could change the parent's lock.
+     Reported by Riverwolf. [SW]
+   * Help fixes. [SW, Nymeria]
+   * Players waiting at the connect screen weren't being disconnected
+     by the idle_timeout.
+   * Detection of cygwin in Configure may be improved.
+   * Fixes from 1.7.4p15.
+ 
  Version 1.7.5 patchlevel 3                     January 24, 2002
  
  Fixes:
*** 1_7_5.66/game/txt/hlp/pennvers.hlp Thu, 24 Jan 2002 11:07:50 -0600 dunemush (pennmush/12_pennvers.h 1.169.1.42.1.9 600)
--- 1_7_5.96(w)/game/txt/hlp/pennvers.hlp Fri, 15 Feb 2002 16:15:21 -0600 dunemush (pennmush/12_pennvers.h 1.169.1.42.1.3.1.5 600)
***************
*** 1,5 ****
  & changes
! & 1.7.5p3
  This is a list of changes in this patchlevel which are probably of
  interest to players. More information about new commands and functions
  can probably be gotten via 'help <name of whatever>'. 'help credits'
--- 1,5 ----
  & changes
! & 1.7.5p4
  This is a list of changes in this patchlevel which are probably of
  interest to players. More information about new commands and functions
  can probably be gotten via 'help <name of whatever>'. 'help credits'
***************
*** 11,16 ****
--- 11,48 ----
  A list of the patchlevels associated with each release can
  be read in 'help patchlevels'.
  
+ Version 1.7.5 patchlevel 4                     February 15, 2002
+ 
+ Major changes:
+   * The mush recognizes telnet-aware connections. This is
+     neccessary for properly sending them some 8-bit characters. [SW]
+   * Much more support for handling accented characters in the ISO 8859-1
+     character set. See help for accent(), stripaccents(), and NOACCENTS.
+     Inspired by Elendor. [SW]
+   * Things that do first-unique-prefix matching (command, attribute and flag
+     names) now use a more space-efficient data structure than before.
+     This adds two new files, src/ptab.c and hdrs/ptab.h [SW]
+ Commands:
+   * @sitelock/remove removes a sitelock entry. [SW]
+ Functions:
+   * ord() and chr() functions for converting characters to/from numerical
+     values that represent them. [SW]
+ Minor changes:
+   * The useless FORCE_WHITE flag is really, truely, gone. [SW]
+   * Use the new arglens argument to functions in more places. [SW]
+   * capstr() and before() fixes reimplemented using arglens. [SW]
+   * We now use the Mersenne Twister PRNG algorithm. [SW]
+ Fixes:
+   * setunion() no longer eats empty list elements. [SW]
+   * Setting an inherited lock on a child could change the parent's lock.
+     Reported by Riverwolf. [SW]
+   * Help fixes. [SW, Nymeria]
+   * Players waiting at the connect screen weren't being disconnected
+     by the idle_timeout.
+   * Detection of cygwin in Configure may be improved.
+   * Fixes from 1.7.4p15.
+ 
+ & 1.7.5p3
  Version 1.7.5 patchlevel 3                     January 24, 2002
  
  Fixes:
***************
*** 125,130 ****
--- 157,192 ----
    * Indentation fixes [SW]
    * Fixes up to 1.7.4p12 merged in.
  
+ & 1.7.4p15
+ Version 1.7.4 patchlevel 15		       February 8, 2002
+ 
+ Minor Changes:
+   * @dolist and iter(), where multiple tokens are replaced (## and #@),
+     now do both replacements at once. This is more efficient in several
+     ways and fixes a problem where if the second token gets into the
+     string from a replacement of the first, it gets replaced. (iter(a#@,
+     ##) should return a#@, not a1). [SW]
+   * setunion no longer eats empty list elements. [SW]
+   * The help text for items() is now more descriptive of how it works
+     and differs from words(). Suggested by Zen@SW1.
+   * When you attempt to @chzone an object to a ZMO without a zone-lock,
+     a default zone-lock of "owner of the ZMO" is now set, and the
+     attempt succeeds. Suggested by Linda Antonsson.
+   * In the French message translation files, the word 'drapeau' and
+     'flag' were used interchangeably. I've standardized on 'flag'.
+     Report by Vexon@M*U*S*H.
+ Fixes:
+   * Message typo fixed by Bellemore@M*U*S*H.
+   * No more ansified names in logged shutdown messages. Report by
+     Bellemore@M*U*S*H.
+   * Messages when destroying players now take into account the 
+     destroy_possessions and really_safe settings. Suggested by Wayne@PDX.
+   * The parser no longer strips any first layer of braces in, e.g.
+     @switch action clauses, but only when the first character in the
+     clause is a brace. This prevents @sw 1=1, @wait me={@emit 1; @emit 2}
+     from being misparsed and running @emit 2 immediately. Reported by
+     Azratax@Azmush. [TAP]
+ 
  & 1.7.4p14
  Version 1.7.4 patchlevel 14		       January 4, 2002
  
***************
*** 5063,5070 ****
  For information on a specific patchlevel of one of the versions listed,
  type 'help <version>p<patchlevel>'. For example, 'help 1.7.2p3'
  
! 1.7.5: 0, 1, 2, 3
! 1.7.4: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
  1.7.3: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
  1.7.2: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
         19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
--- 5125,5132 ----
  For information on a specific patchlevel of one of the versions listed,
  type 'help <version>p<patchlevel>'. For example, 'help 1.7.2p3'
  
! 1.7.5: 0, 1, 2, 3, 4
! 1.7.4: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
  1.7.3: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
  1.7.2: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
         19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
*** 1_7_5.66/game/txt/hlp/penntop.hlp Thu, 22 Nov 2001 15:42:40 -0600 dunemush (pennmush/13_penntop.hl 1.2.1.27.1.3.1.2.1.2.1.3 600)
--- 1_7_5.96(w)/game/txt/hlp/penntop.hlp Thu, 07 Feb 2002 12:37:43 -0600 dunemush (pennmush/13_penntop.hl 1.2.1.27.1.3.1.2.1.2.1.4 600)
***************
*** 353,359 ****
  & CREDITS
    Maintainer: Javelin
    Developers: Talek [TAP], Trivian [TN], Halatir [LdW], Raevnos [SW]
!   Porters: Nick Gammon [NJG] (win32), Dan Williams [DW] (MacOS), Sylvia (OS/2)
    Former devteam: Rhyanna [RLM]
   
    The original TinyMUSH 1.0 code was written by Lawrence Foard, and was
--- 353,360 ----
  & CREDITS
    Maintainer: Javelin
    Developers: Talek [TAP], Trivian [TN], Halatir [LdW], Raevnos [SW]
!   Porters: Nick Gammon [NJG] (win32), Dan Williams [DW] (MacOS), 
!            Sylvia (OS/2), Ervin Hearn III [EH] (win32)
    Former devteam: Rhyanna [RLM]
   
    The original TinyMUSH 1.0 code was written by Lawrence Foard, and was
*** 1_7_5.66/game/txt/hlp/pennfunc.hlp Sun, 06 Jan 2002 20:49:01 -0600 dunemush (pennmush/16_pennfunc.h 1.2.1.50.1.1.1.1.1.2.1.7.1.8.1.1.1.1.1.1.1.2 600)
--- 1_7_5.96(w)/game/txt/hlp/pennfunc.hlp Sun, 10 Feb 2002 11:38:45 -0600 dunemush (pennmush/16_pennfunc.h 1.2.1.50.1.1.1.1.1.2.1.7.1.8.1.1.1.1.1.1.1.1.1.3 600)
***************
*** 180,194 ****
    String functions take at least one string and return a transformed
    string, parts of a string, or a value related to the string(s).
    
!   after()       alphamin()    alphamax()    art()         before()
!   brackets()    capstr()      case()        caseall()     cat()
!   center()      comp()        decrypt()     delete()      edit()
!   encrypt()     escape()      if()          ifelse()      lcstr()
!   left()        lit()         ljust()       merge()       mid()
!   pos()         regedit()     regmatch()    repeat()      reverse()
!   right()       rjust()       scramble()    secure()      space()
!   spellnum()    squish()      strcat()      strinsert()   stripansi()
!   strlen()      switch()      trim()        ucstr()       wrap()
   
  See also: STRINGS
  & Time functions
--- 180,195 ----
    String functions take at least one string and return a transformed
    string, parts of a string, or a value related to the string(s).
    
!   accent()      after()       alphamin()    alphamax()    art()
!   before()      brackets()    capstr()      case()        caseall()
!   cat()         center()      comp()        chr()         decrypt()
!   delete()      edit()        encrypt()     escape()      if()
!   ifelse()      lcstr()       left()        lit()         ljust()
!   merge()       mid()         ord()         pos()         regedit()
!   regmatch()    repeat()      reverse()     right()       rjust()
!   scramble()    secure()      space()       spellnum()    squish()
!   strcat()      strinsert()   stripaccent() stripansi()   strlen()
!   switch()      trim()        ucstr()       wrap()
   
  See also: STRINGS
  & Time functions
***************
*** 227,232 ****
--- 228,284 ----
   
    Returns the absolute value of a number. i.e. ABS(-4) returns 4;
    ABS(2) returns 2, etc.
+ & ACCENT()
+   accent(<string>, <template>)
+ 
+   The accent() function will return <string>, with characters in it
+   possibly changed to accented ones according to <template>. Both
+   arguments must be the same size.
+ 
+   Whether or not the resulting string is actually displayed correctly
+   is client-dependent. Some OSes uses different character sets than
+   the one assumes (ISO 8859-1), and some clients strip these 8-bit
+   characters.
+ 
+   See HELP ACCENT2 for a description of the template argument.
+ 
+   See also: stripaccents(), NOACCENTS
+ & ACCENT2
+   For each character in <string>, the corresponding character of
+   <template> is checked according to the table below, and a replacement
+   done. If either the current <string> or <template> characters aren't
+   in the table, the <string> character is passed through unchanged.
+ 
+   Accent                         Template   String
+   Name       Description         Character  Character
+   --------------------------------------------------------------
+   grave      Backward slant      `          A,E,I,O,U,a,e,i,o,u
+              above letter
+   acute      Forward slant       '          A,E,I,O,U,a,e,i,o,u,y
+              above letter
+   tilde      Wavy line above     ~          A,N,O,a,n,o
+              letter
+   circumflex carat above         ^          A,E,I,O,U,a,e,i,o,u
+              letter
+   umlaut     Two dots above      :          A,E,I,O,U,Y,a,e,i,o,u
+   diaeresis  letter
+   ring       Small circle above  o          A,a
+              letter
+   cedilla    Small tail below    ,          C,c
+              letter
+ 
+   See HELP ACCENT3 for examples
+ & ACCENT3
+   Some examples of accent() and their expected outputs:
+ 
+   > think accent(Aule, ---:)
+   Aul(e-with-diaeresis)
+ 
+   > think accent(The Nina was a ship, The Ni~a was a ship) 
+   The Ni(n-with-~)a was a ship
+ 
+   > think accent(Khazad ai-menu!, Khaz^d ai-m^nu!)
+   Khaz(a-with-^)d ai-m(e-with-^)nu!
  & ACOS()
    acos(<cosine>)
   
***************
*** 481,486 ****
--- 533,551 ----
    If you don't have permission to examine the object, you only see 
    those channels to which the object belong for which you have 
    permission to join (or are joined to).
+ & CHR()
+ & ORD()
+   chr(<number>)
+   ord(<character>)
+ 
+   ord() returns the numerical value of the given character.
+   chr() returns the character with the given numerical value.
+ 
+   Examples:
+   > think ord(A)
+   65
+   > think chr(65)
+   A
  & CLOCK()
    clock(<channel>[/<locktype>][, <new lock>])
  
***************
*** 1361,1374 ****
      
  & ITEMS()
    items(<list>,<single-character separator>)
!   
!   This counts the number of items in a list which uses some arbitrary
!   separator. This is similar in function to WORDS(), but it does not
!   have a default separator.
!  
!   Example:
!     > say [items(this|is|a|short|string,|)]
!     You say, "5"
  & ITEMIZE()
  & ELIST()
    itemize(<list>[,<delim>[,<conjunction>[,<punctuation>]]])
--- 1426,1444 ----
      
  & ITEMS()
    items(<list>,<single-character separator>)
! 
!   items() counts the number of items in a list using an arbitrary
!   (required) separator. Null items are counted, so:
! 
!         items(X|X,|)     => 2     (2 X items)
!         items(X||X,|)    => 3     (2 X items and 1 null item)
!         items(X X,%b)    => 2     (2 X items)
!         items(X%b%bX,%b) => 3     (2 X items and 1 null item)
!         items(,|)        => 1     (a single null item)
! 
!    Another way to think about this is that items() counts the number
!    of delimiters in the string, and adds 1.
! 
  & ITEMIZE()
  & ELIST()
    itemize(<list>[,<delim>[,<conjunction>[,<punctuation>]]])
***************
*** 1807,1813 ****
    <room>. You must be in the room or control it to use this function.
  
  See also: lexits()
! & LVPLAYERS
    lvplayers(<object>)
  
    This function returns the dbrefs of all connected and non-dark players
--- 1877,1883 ----
    <room>. You must be in the room or control it to use this function.
  
  See also: lexits()
! & LVPLAYERS()
    lvplayers(<object>)
  
    This function returns the dbrefs of all connected and non-dark players
***************
*** 2898,2903 ****
--- 2968,2978 ----
    foobarbaz
    > think strinsert(Myname, 2, %b)
    My name   
+ & STRIPACCENTS()
+   stripaccents(<string>)
+ 
+   Returns the string with accented characters converted to non-accented.
+   As with the accent() function, this assumes the ISO 8859-1 character set.
  & STRIPANSI()
    stripansi(<string>)
  
*** 1_7_5.66/game/txt/hlp/pennflag.hlp Tue, 04 Sep 2001 09:08:48 -0500 dunemush (pennmush/17_pennflag.h 1.1.1.1.1.2.1.1.1.2.1.1.1.2.1.1.2.1.2.2 600)
--- 1_7_5.96(w)/game/txt/hlp/pennflag.hlp Sun, 27 Jan 2002 15:27:56 -0600 dunemush (pennmush/17_pennflag.h 1.1.1.1.1.2.1.1.1.2.1.1.1.2.1.1.2.1.2.3 600)
***************
*** 47,59 ****
    Z - Shared, Z_Tel
    
    a - Audible           b - Debug               c - Connected, Cloudy
!   d - Destroy_Ok        e - Enter_Ok            f - Force_White
!   g - Gagged            h - Halt                j - Jury_Ok
!   l - Light             m - Myopic              n - No_Command 
!   o - On-Vacation       p - Puppet, Paranoid    r - Royalty
!   s - Suspect           t - Transparent         u - Uninspected
!   v - Verbose           w - No_Warn             x - Terse
!   ? - Unregistered      ^ - Listen_Parent
  ---------------------------------------------------------------------
  Some flags may not be enabled on some MUSHes.
  
--- 47,59 ----
    Z - Shared, Z_Tel
    
    a - Audible           b - Debug               c - Connected, Cloudy
!   d - Destroy_Ok        e - Enter_Ok            g - Gagged
!   h - Halt              j - Jury_Ok             l - Light             
!   m - Myopic            n - No_Command          o - On-Vacation
!   p - Puppet, Paranoid  r - Royalty             s - Suspect
!   t - Transparent       u - Uninspected         v - Verbose
!   w - No_Warn           x - Terse               ? - Unregistered
!   ^ - Listen_Parent     ~ - Noaccents
  ---------------------------------------------------------------------
  Some flags may not be enabled on some MUSHes.
  
***************
*** 261,277 ****
    A disconnected room may mean (depending on how the MUSH is
    configured) a room that can't be reached from room #0, or
    a room that can't be reached from room #0 and has no exits.
- & FORCE_WHITE
- & WEIRDANSI
- & WHITE
-   Flag: FORCE_WHITE (players)
- 
-   When set on an ANSI player, this flag causes the ansi code to
-   reset the font color to white to be sent after everything the player
-   sees. Necessary for players with broken ansi clients which "bleed".
- 
-   This flag is aliased to "WEIRDANSI" as well.
- 
  & GAGGED
    Flag: GAGGED (players)
  
--- 261,266 ----
***************
*** 405,410 ****
--- 394,406 ----
    players are automatically considered to be MYOPIC.
  
  See also: DBREF
+ & NOACCENTS
+   Flag: NOACCENTS  (players)
+ 
+   This flag causes all accented characters to be converted to non-accented
+   before being sent to a connection. See HELP STRIPACCENTS() for caveats.
+ 
+ See also: i18n, accent(), stripaccents()
  & NO_COMMAND
    Flag:  NO_COMMAND  (all types)
    
*** 1_7_5.66/game/txt/hlp/penncmd.hlp Thu, 22 Nov 2001 15:42:40 -0600 dunemush (pennmush/18_penncmd.hl 1.2.1.1.1.47.1.1.1.1.1.3.1.4.1.1.1.1.1.4 600)
--- 1_7_5.96(w)/game/txt/hlp/penncmd.hlp Wed, 06 Feb 2002 22:33:04 -0600 dunemush (pennmush/18_penncmd.hl 1.2.1.1.1.47.1.1.1.1.1.3.1.4.1.1.1.1.1.6 600)
***************
*** 339,345 ****
  See also: @success, @osuccess, get, @lock, EXITS, ACTION LISTS
  & @attribute
    @attribute <attrib>
!   @attribute/access[/retroactive] <attrib> = <permission list>
    @attribute/delete <attrib>
    @attribute/rename <attrib> = <new name>
  
--- 339,345 ----
  See also: @success, @osuccess, get, @lock, EXITS, ACTION LISTS
  & @attribute
    @attribute <attrib>
!   @attribute/access[/retroactive] <attrib> = <flag list>
    @attribute/delete <attrib>
    @attribute/rename <attrib> = <new name>
  
***************
*** 356,365 ****
    Used without switches, @attribute shows info about a standard attrib.
  
    @attribute/access adds a new standard attribute into the table,
!   associating it with the given space-separated list of permissions.
!   See 'help @set' for possible permissions.
!   If the /retroactive switch is added, the permissions are applied
!   to all objects in the database which have the attribute set already.
  
    @attribute/delete removes a standard attribute from the table.
    @attribute/rename renames a standard attribute. 
--- 356,365 ----
    Used without switches, @attribute shows info about a standard attrib.
  
    @attribute/access adds a new standard attribute into the table,
!   associating it with the given space-separated list of flags.
!   See 'help @set' for possible flags.
!   If the /retroactive switch is added, the flags are set on every copy
!   of the attribute that already exists in the database.
  
    @attribute/delete removes a standard attribute from the table.
    @attribute/rename renames a standard attribute. 
***************
*** 1401,1407 ****
    things like chairs so that someone inside the object can hear 
    everything said/done outside it). @infilter filters out any messages
    that match one of the patterns and prevents those inside the object
!   from hearing them.
   
    For an explanation of infilter patterns, see the help for "@filter".
  
--- 1401,1408 ----
    things like chairs so that someone inside the object can hear 
    everything said/done outside it). @infilter filters out any messages
    that match one of the patterns and prevents those inside the object
!   from hearing them. It does not stop the @ahear of the listening object
!   from being triggered by things that match the @listen.
   
    For an explanation of infilter patterns, see the help for "@filter".
  
***************
*** 2571,2576 ****
--- 2572,2578 ----
    @sitelock/name <name>
    @sitelock <host-pattern> = <options>[,<name>]
    @sitelock[/<ban|register>] <host-pattern>
+   @sitelock/remove <string>
  
    The @sitelock command adds rules to the access.cnf file, controlling
    a host's level of access to the MUSH, or adds banned player names to
***************
*** 2634,2639 ****
--- 2636,2644 ----
   If you want to disallow connections to a character from anywhere,
   use @newpassword or @sitelock *=!connect,Twink.
  
+   @sitelock/remove will delete entries that were added with @sitelock
+   if their host-pattern matches <string> exactly.
+  
  & @squota
    @squota <victim> [= [+|-] <amount>]
  
*** 1_7_5.66/hints/win32-gcc.sh Fri, 08 Jun 2001 14:14:28 -0500 dunemush (pennmush/b/0_win32-gcc. 1.2 600)
--- 1_7_5.96(w)/hints/win32-gcc.sh Sun, 10 Feb 2002 15:41:44 -0600 dunemush (pennmush/b/0_win32-gcc. 1.3 600)
***************
*** 1,5 ****
--- 1,6 ----
  # Hints for win32 with gcc
  cc='gcc'
+ ccflags='-DWIN32'
  usenm='n'
  h_fcntl='false'
  d_ipv6='undef'
*** 1_7_5.66/config_h.SH Tue, 04 Sep 2001 09:08:48 -0500 dunemush (pennmush/b/17_config_h.S 1.17.1.2.1.2 660)
--- 1_7_5.96(w)/config_h.SH Fri, 15 Feb 2002 16:52:19 -0600 dunemush (pennmush/b/17_config_h.S 1.17.1.2.1.3 660)
***************
*** 683,688 ****
--- 683,694 ----
  #$d_strxfrm HAS_STRXFRM	/**/
  
  /* HAS_TCL:
+  *	This symbol, if defined, indicates that the tcl library is available
+  */
+ /* I_TCL:
+  *	This symbol, if defined, indicates that <tcl.h> can be included.
+  */
+ /* HAS_TCL:
   *  This symbol, if defined, means we have the tcl library
   */
  #$d_tcl HAS_TCL		/**/
*** 1_7_5.66/src/wiz.c Sun, 06 Jan 2002 20:56:21 -0600 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.4 660)
--- 1_7_5.96(w)/src/wiz.c Fri, 15 Feb 2002 16:53:17 -0600 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.5.1.1 660)
***************
*** 1773,1778 ****
--- 1773,1785 ----
        notify(player, tprintf(T("Site %s locked"), site));
        do_log(LT_WIZ, player, NOTHING, "*** SITELOCK *** %s", site);
        break;
+     case 3:{
+ 	int n;
+ 	n = remove_access_sitelock(player, site);
+ 	write_access_file();
+ 	notify_format(player, T("%d sitelocks removed."), n);
+ 	break;
+       }
      case 2:
        if (!site || !*site) {
  	/* List bad names */
*** 1_7_5.66/src/utils.c Wed, 24 Oct 2001 10:41:46 -0500 dunemush (pennmush/b/27_utils.c 1.30 660)
--- 1_7_5.96(w)/src/utils.c Fri, 15 Feb 2002 16:53:17 -0600 dunemush (pennmush/b/27_utils.c 1.32 660)
***************
*** 31,61 ****
  #include "log.h"
  #include "flags.h"
  #include "dbdefs.h"
  #include "confmagic.h"
  
! 
! extern ATTR *atr_get _((dbref thing, const char *atr));
! extern char *upcasestr _((char *s));
! 
! void parse_attrib _((dbref player, char *str, dbref *thing, ATTR **attrib));
! dbref find_entrance _((dbref door));
! dbref remove_first _((dbref first, dbref what));
! int member _((dbref thing, dbref list));
! int recursive_member _((dbref disallow, dbref from, int count));
! dbref reverse _((dbref list));
! struct dblist *listcreate _((dbref ref));
! void listadd _((struct dblist * head, dbref ref));
! void listfree _((struct dblist * head));
! long get_random_long _((long low, long high));
! Malloc_t mush_malloc _((int size, const char *check));
! void mush_free _((Malloc_t ptr, const char *check));
! char *shortname _((dbref it));
  
  Malloc_t
! mush_malloc(size, check)
!     int
!      size;
!     const char *check;
  {
    Malloc_t ptr;
  #ifdef MEM_CHECK
--- 31,43 ----
  #include "log.h"
  #include "flags.h"
  #include "dbdefs.h"
+ #include "attrib.h"
  #include "confmagic.h"
  
! dbref find_entrance(dbref door);
  
  Malloc_t
! mush_malloc(int size, const char *check)
  {
    Malloc_t ptr;
  #ifdef MEM_CHECK
***************
*** 69,77 ****
  }
  
  void
! mush_free(ptr, check)
!     Malloc_t ptr;
!     const char *check __attribute__ ((__unused__));
  {
  #ifdef MEM_CHECK
    del_check(check);
--- 51,57 ----
  }
  
  void
! mush_free(Malloc_t ptr, const char *check __attribute__ ((__unused__)))
  {
  #ifdef MEM_CHECK
    del_check(check);
***************
*** 82,92 ****
  
  
  void
! parse_attrib(player, str, thing, attrib)
!     dbref player;
!     char *str;
!     dbref *thing;
!     ATTR **attrib;
  {
    /* takes a string which is of the format <obj>/<attr> or <attr>,
     * and returns the dbref of the object, and a pointer to the attribute.
--- 62,68 ----
  
  
  void
! parse_attrib(dbref player, char *str, dbref *thing, ATTR **attrib)
  {
    /* takes a string which is of the format <obj>/<attr> or <attr>,
     * and returns the dbref of the object, and a pointer to the attribute.
***************
*** 112,119 ****
  
  
  dbref
! find_entrance(door)
!     dbref door;
  {
    dbref room;
    dbref thing;
--- 88,94 ----
  
  
  dbref
! find_entrance(dbref door)
  {
    dbref room;
    dbref thing;
***************
*** 131,139 ****
  
  /* remove the first occurence of what in list headed by first */
  dbref
! remove_first(first, what)
!     dbref first;
!     dbref what;
  {
    dbref prev;
    /* special case if it's the first one */
--- 106,112 ----
  
  /* remove the first occurence of what in list headed by first */
  dbref
! remove_first(dbref first, dbref what)
  {
    dbref prev;
    /* special case if it's the first one */
***************
*** 152,160 ****
  }
  
  int
! member(thing, list)
!     dbref thing;
!     dbref list;
  {
    DOLIST(list, list) {
      if (list == thing)
--- 125,131 ----
  }
  
  int
! member(dbref thing, dbref list)
  {
    DOLIST(list, list) {
      if (list == thing)
***************
*** 170,179 ****
   * Actually, it's not recursive any more.
   */
  int
! recursive_member(disallow, from, count)
!     dbref disallow;
!     dbref from;
!     int count;
  {
    do {
      /* The end of the location chain. This is a room. */
--- 141,147 ----
   * Actually, it's not recursive any more.
   */
  int
! recursive_member(dbref disallow, dbref from, int count)
  {
    do {
      /* The end of the location chain. This is a room. */
***************
*** 192,199 ****
  
  /* Return one if the dbref, or its location, etc. is set unfindable */
  int
! unfindable(thing)
!     dbref thing;
  {
    int count = 0;
    do {
--- 160,166 ----
  
  /* Return one if the dbref, or its location, etc. is set unfindable */
  int
! unfindable(dbref thing)
  {
    int count = 0;
    do {
***************
*** 211,218 ****
  
  
  dbref
! reverse(list)
!     dbref list;
  {
    dbref newlist;
    dbref rest;
--- 178,184 ----
  
  
  dbref
! reverse(dbref list)
  {
    dbref newlist;
    dbref rest;
***************
*** 227,234 ****
  
  /* takes a dbref and returns a pointer to the head of a dblist */
  struct dblist *
! listcreate(ref)
!     dbref ref;
  {
    struct dblist *ptr;
  
--- 193,199 ----
  
  /* takes a dbref and returns a pointer to the head of a dblist */
  struct dblist *
! listcreate(dbref ref)
  {
    struct dblist *ptr;
  
***************
*** 246,254 ****
   * end of the list.
   */
  void
! listadd(head, ref)
!     struct dblist *head;
!     dbref ref;
  {
    struct dblist *ptr = head;
  
--- 211,217 ----
   * end of the list.
   */
  void
! listadd(struct dblist *head, dbref ref)
  {
    struct dblist *ptr = head;
  
***************
*** 261,268 ****
  
  /* takes a pointer to a dblist and recursively frees it */
  void
! listfree(head)
!     struct dblist *head;
  {
    struct dblist *ptra = head, *ptrb;
  
--- 224,230 ----
  
  /* takes a pointer to a dblist and recursively frees it */
  void
! listfree(struct dblist *head)
  {
    struct dblist *ptra = head, *ptrb;
  
***************
*** 329,336 ****
   * location or AMBIGUOUS if there are too many containers
   */
  dbref
! absolute_room(it)
!     dbref it;
  {
    int rec = 0;
    dbref room;
--- 291,297 ----
   * location or AMBIGUOUS if there are too many containers
   */
  dbref
! absolute_room(dbref it)
  {
    int rec = 0;
    dbref room;
*** 1_7_5.66/src/help.c Mon, 29 Oct 2001 13:52:04 -0600 dunemush (pennmush/f/32_help.c 1.4.1.2.1.1.1.3.2.2.1.1.2.1.1.2.1.4 660)
--- 1_7_5.96(w)/src/help.c Fri, 15 Feb 2002 16:53:16 -0600 dunemush (pennmush/f/32_help.c 1.4.1.2.1.1.1.3.2.2.1.1.2.1.1.2.1.4.1.2 660)
***************
*** 290,299 ****
    top = NULL;
  }
  
! static int WIN32_CDECL topic_cmp _((const void *s1, const void *s2));
  static int WIN32_CDECL
! topic_cmp(s1, s2)
!     const void *s1, *s2;
  {
    const help_indx *a = s1;
    const help_indx *b = s2;
--- 290,298 ----
    top = NULL;
  }
  
! static int WIN32_CDECL topic_cmp(const void *s1, const void *s2);
  static int WIN32_CDECL
! topic_cmp(const void *s1, const void *s2)
  {
    const help_indx *a = s1;
    const help_indx *b = s2;
*** 1_7_5.66/src/strutil.c Sun, 06 Jan 2002 20:56:21 -0600 dunemush (pennmush/b/33_strutil.c 1.28.1.3.1.3.1.11 660)
--- 1_7_5.96(w)/src/strutil.c Fri, 15 Feb 2002 16:53:17 -0600 dunemush (pennmush/b/33_strutil.c 1.28.1.3.1.3.1.7.2.1.1.4 660)
***************
*** 8,13 ****
--- 8,14 ----
  #include <string.h>
  #include <stdlib.h>
  #include <stdarg.h>
+ #include <limits.h>
  #ifdef I_MEMORY
  #include <memory.h>
  #endif
***************
*** 30,35 ****
--- 31,297 ----
  static int format_long _((long val, char *buff, char **bp, int maxlen));
  
  
+ /* GENERATED TABLE. EDIT AT YOUR OWN RISK.  */
+ accent_info accent_table[UCHAR_MAX + 1] = {
+   {0, NULL},
+   {1, NULL},
+   {2, NULL},
+   {3, NULL},
+   {4, NULL},
+   {5, NULL},
+   {6, NULL},
+   {7, NULL},
+   {8, NULL},
+   {9, NULL},
+   {10, "<br>\n"},
+   {11, NULL},
+   {12, NULL},
+   {13, NULL},
+   {14, NULL},
+   {15, NULL},
+   {16, NULL},
+   {17, NULL},
+   {18, NULL},
+   {19, NULL},
+   {20, NULL},
+   {21, NULL},
+   {22, NULL},
+   {23, NULL},
+   {24, NULL},
+   {25, NULL},
+   {26, NULL},
+   {27, NULL},
+   {28, NULL},
+   {29, NULL},
+   {30, NULL},
+   {31, NULL},
+   {32, NULL},
+   {33, NULL},
+   {34, "&quot;"},
+   {35, NULL},
+   {36, NULL},
+   {37, NULL},
+   {38, "&amp;"},
+   {39, NULL},
+   {40, NULL},
+   {41, NULL},
+   {42, NULL},
+   {43, NULL},
+   {44, NULL},
+   {45, NULL},
+   {46, NULL},
+   {47, NULL},
+   {48, NULL},
+   {49, NULL},
+   {50, NULL},
+   {51, NULL},
+   {52, NULL},
+   {53, NULL},
+   {54, NULL},
+   {55, NULL},
+   {56, NULL},
+   {57, NULL},
+   {58, NULL},
+   {59, NULL},
+   {60, "&lt;"},
+   {61, NULL},
+   {62, "&gt;"},
+   {63, NULL},
+   {64, NULL},
+   {65, NULL},
+   {66, NULL},
+   {67, NULL},
+   {68, NULL},
+   {69, NULL},
+   {70, NULL},
+   {71, NULL},
+   {72, NULL},
+   {73, NULL},
+   {74, NULL},
+   {75, NULL},
+   {76, NULL},
+   {77, NULL},
+   {78, NULL},
+   {79, NULL},
+   {80, NULL},
+   {81, NULL},
+   {82, NULL},
+   {83, NULL},
+   {84, NULL},
+   {85, NULL},
+   {86, NULL},
+   {87, NULL},
+   {88, NULL},
+   {89, NULL},
+   {90, NULL},
+   {91, NULL},
+   {92, NULL},
+   {93, NULL},
+   {94, NULL},
+   {95, NULL},
+   {96, NULL},
+   {97, NULL},
+   {98, NULL},
+   {99, NULL},
+   {100, NULL},
+   {101, NULL},
+   {102, NULL},
+   {103, NULL},
+   {104, NULL},
+   {105, NULL},
+   {106, NULL},
+   {107, NULL},
+   {108, NULL},
+   {109, NULL},
+   {110, NULL},
+   {111, NULL},
+   {112, NULL},
+   {113, NULL},
+   {114, NULL},
+   {115, NULL},
+   {116, NULL},
+   {117, NULL},
+   {118, NULL},
+   {119, NULL},
+   {120, NULL},
+   {121, NULL},
+   {122, NULL},
+   {123, NULL},
+   {124, NULL},
+   {125, NULL},
+   {126, NULL},
+   {127, NULL},
+   {128, NULL},
+   {129, NULL},
+   {130, NULL},
+   {131, NULL},
+   {132, NULL},
+   {133, NULL},
+   {134, NULL},
+   {135, NULL},
+   {136, NULL},
+   {137, NULL},
+   {138, NULL},
+   {139, NULL},
+   {140, NULL},
+   {141, NULL},
+   {142, NULL},
+   {143, NULL},
+   {144, NULL},
+   {145, NULL},
+   {146, NULL},
+   {147, NULL},
+   {148, NULL},
+   {149, NULL},
+   {150, NULL},
+   {151, NULL},
+   {152, NULL},
+   {153, NULL},
+   {154, NULL},
+   {155, NULL},
+   {156, NULL},
+   {157, NULL},
+   {158, NULL},
+   {159, NULL},
+   {160, NULL},
+   {161, NULL},
+   {162, NULL},
+   {163, NULL},
+   {164, NULL},
+   {165, NULL},
+   {166, NULL},
+   {167, NULL},
+   {168, NULL},
+   {169, NULL},
+   {170, NULL},
+   {171, NULL},
+   {172, NULL},
+   {173, NULL},
+   {174, NULL},
+   {175, NULL},
+   {176, NULL},
+   {177, NULL},
+   {178, NULL},
+   {179, NULL},
+   {180, NULL},
+   {181, NULL},
+   {182, NULL},
+   {183, NULL},
+   {184, NULL},
+   {185, NULL},
+   {186, NULL},
+   {187, NULL},
+   {188, NULL},
+   {189, NULL},
+   {190, NULL},
+   {191, NULL},
+   {65, "&Agrave;"},
+   {65, "&Aacute;"},
+   {65, "&Acirc;"},
+   {65, "&Atilde;"},
+   {65, "&Auml;"},
+   {65, "&Aring;"},
+   {198, NULL},
+   {67, "&Ccedil;"},
+   {69, "&Egrave;"},
+   {69, "&Eacute;"},
+   {69, "&Ecirc;"},
+   {69, "&Euml;"},
+   {73, "&Igrave;"},
+   {73, "&Iacute;"},
+   {73, "&Icirc;"},
+   {73, "&Iuml;"},
+   {208, NULL},
+   {78, "&Ntilde;"},
+   {79, "&Ograve;"},
+   {79, "&Oacute;"},
+   {79, "&Ocirc;"},
+   {79, "&Otilde;"},
+   {79, "&Ouml;"},
+   {215, NULL},
+   {216, NULL},
+   {85, "&Ugrave;"},
+   {85, "&Uacute;"},
+   {85, "&Ucirc;"},
+   {85, "&Uuml;"},
+   {89, "&Yacute;"},
+   {222, NULL},
+   {223, NULL},
+   {97, "&agrave;"},
+   {97, "&aacute;"},
+   {97, "&acirc;"},
+   {97, "&atilde;"},
+   {97, "&auml;"},
+   {97, "&aring;"},
+   {230, NULL},
+   {99, "&ccedil;"},
+   {101, "&egrave;"},
+   {101, "&eacute;"},
+   {101, "&ecirc;"},
+   {101, "&euml;"},
+   {105, "&igrave;"},
+   {105, "&iacute;"},
+   {105, "&icirc;"},
+   {105, "&iuml;"},
+   {240, NULL},
+   {110, "&ntilde;"},
+   {111, "&ograve;"},
+   {111, "&oacute;"},
+   {111, "&ocirc;"},
+   {111, "&otilde;"},
+   {111, "&ouml;"},
+   {247, NULL},
+   {248, NULL},
+   {117, "&ugrave;"},
+   {117, "&uacute;"},
+   {117, "&ucirc;"},
+   {117, "&uuml;"},
+   {121, "&yacute;"},
+   {254, NULL},
+   {121, "&yuml;"}
+ };
+ 
+ 
  char *
  mush_strdup(s, check)
      const char *s;
***************
*** 356,423 ****
  }
  
  int
! u_strlen(s)
!     const unsigned char *s;
  {
    return strlen((char *) s);
  }
  
  unsigned char *
! u_strcpy(target, source)
!     unsigned char *target;
!     const unsigned char *source;
  {
    return (unsigned char *) strcpy((char *) target, (char *) source);
  }
  
  char *
! replace_string(old, newbit, string)
!     const char *old;
!     const char *newbit;
!     const char *string;
  {
!   /* another 2.0 function: replaces string "old" with string "newbit".
!    * The result returned by this must be freed.
!    */
  
!   char *result, *r, *s;
!   int len;
  
!   if (!string)
!     return NULL;
  
!   s = (char *) string;
!   len = strlen(old);
!   r = result = (char *) malloc(BUFFER_LEN + 1);
! #ifdef MEM_CHECK
!   add_check("replace_string.buff");
! #endif
  
!   while (*s) {
  
!     /* copy up to the next occurence of first char of old */
!     while (*s && *s != *old) {
!       safe_chr(*s, result, &r);
!       s++;
!     }
  
!     /* if we've really found  old, append newbit to the result and
!      * move past the occurence of old. Else, copy the char and
!      * continue.
!      */
!     if (*s) {
!       if (!strncmp(old, s, len)) {
! 	safe_str((char *) newbit, result, &r);
! 	s += len;
!       } else {
! 	safe_chr(*s, result, &r);
! 	s++;
!       }
      }
    }
  
!   *r = '\0';
    return result;
  }
  
  char *
--- 618,711 ----
  }
  
  int
! u_strlen(const unsigned char *s)
  {
    return strlen((char *) s);
  }
  
  unsigned char *
! u_strcpy(unsigned char *target, const unsigned char *source)
  {
    return (unsigned char *) strcpy((char *) target, (char *) source);
  }
  
  char *
! replace_string(const char *old, const char *newbit, const char *string)
  {
!   char tbuf1[BUFFER_LEN], *tbuf = tbuf1;
!   char *result, *r;
!   Size_t len, newlen;
! 
!   r = result = mush_malloc(BUFFER_LEN, "replace_string.buff");
!   if (!result)
!     panic(T("Couldn't allocate memory in replace_string!"));
  
!   len = strlen(old);
!   newlen = strlen(newbit);
  
!   while (*string) {
!     char *s = strstr(string, old);
!     if (s) {			/* Match found! */
!       safe_strl(string, s - string, result, &r);
!       safe_strl(newbit, newlen, result, &r);
!       string = s + len;
!     } else {
!       safe_str(string, result, &r);
!       break;
!     }
!   }
!   *r = '\0';
!   return result;
! }
  
! const char *standard_tokens[2] = { "##", "#@" };
  
! /* Replace two tokens in a string at once. All-around better than calling
!  * replace_string() twice
!  */
! char *
! replace_string2(const char *old[2], const char *newbits[2], const char *string)
! {
!   char *result, *rp;
!   char firsts[3] = { '\0', '\0', '\0' };
!   Size_t oldlens[2], newlens[2];
  
!   if (!string)
!     return NULL;
  
!   rp = result = mush_malloc(BUFFER_LEN, "replace_string.buff");
!   if (!result)
!     panic(T("Couldn't allocate memory in replace_string2!"));
! 
!   firsts[0] = old[0][0];
!   firsts[1] = old[1][0];
! 
!   oldlens[0] = strlen(old[0]);
!   oldlens[1] = strlen(old[1]);
!   newlens[0] = strlen(newbits[0]);
!   newlens[1] = strlen(newbits[1]);
! 
!   while (*string) {
!     Size_t skip = strcspn(string, firsts);
!     if (skip) {
!       safe_strl(string, skip, result, &rp);
!       string += skip;
!     }
!     if (strncmp(string, old[0], oldlens[0]) == 0) {	/* Copy the first */
!       safe_strl(newbits[0], newlens[0], result, &rp);
!       string += oldlens[0];
!     } else if (strncmp(string, old[1], oldlens[1]) == 0) {	/* The second */
!       safe_strl(newbits[1], newlens[1], result, &rp);
!       string += oldlens[1];
!     } else {
!       safe_chr(*string, result, &rp);
!       string++;
      }
    }
  
!   *rp = '\0';
    return result;
+ 
  }
  
  char *
***************
*** 520,533 ****
  /* Strlen that ignores ansi and HTML sequences */
  
  int
! ansi_strlen(string)
!     char *string;
  {
    int i = 0;
    char *p;
    if (!ANSI_JUSTIFY)
      return strlen(string);
!   p = string;
    if (!p)
      return 0;
    while (*p) {
--- 808,820 ----
  /* Strlen that ignores ansi and HTML sequences */
  
  int
! ansi_strlen(const char *string)
  {
    int i = 0;
    char *p;
    if (!ANSI_JUSTIFY)
      return strlen(string);
!   p = (char *) string;
    if (!p)
      return 0;
    while (*p) {
***************
*** 548,560 ****
  /* Returns true length of string up to numchars visible characters. 
   */
  int
! ansi_strnlen(string, numchars)
!     char *string;
!     unsigned int numchars;
  {
    int i = 0;
    char *p;
!   p = string;
    if (!p)
      return 0;
    while (*p && numchars > 0) {
--- 835,845 ----
  /* Returns true length of string up to numchars visible characters. 
   */
  int
! ansi_strnlen(const char *string, Size_t numchars)
  {
    int i = 0;
    char *p;
!   p = (char *) string;
    if (!p)
      return 0;
    while (*p && numchars > 0) {
***************
*** 641,649 ****
  
  /* Strip all ansi and html markup from a string */
  char *
! remove_markup(orig, s_len)
!     const char *orig;
!     Size_t *s_len;
  {
    static char buff[BUFFER_LEN];
    char *bp = buff;
--- 926,932 ----
  
  /* Strip all ansi and html markup from a string */
  char *
! remove_markup(const char *orig, Size_t *s_len)
  {
    static char buff[BUFFER_LEN];
    char *bp = buff;
***************
*** 832,841 ****
  #endif				/* HAS_STRXFRM && !WIN32 */
  
  int
! ansi_save(string, length, buff, bp)
!     const char *string;
!     int length;
!     char *buff, **bp;
  {
    const char *p;
    int i = 0;
--- 1115,1121 ----
  #endif				/* HAS_STRXFRM && !WIN32 */
  
  int
! ansi_save(const char *string, int length, char *buff, char **bp)
  {
    const char *p;
    int i = 0;
***************
*** 965,972 ****
  
  
  void
! populate_codes(as)
!     ansi_string *as;
  {
    int p;
    char *current = NULL;
--- 1245,1251 ----
  
  
  void
! populate_codes(ansi_string * as)
  {
    int p;
    char *current = NULL;
***************
*** 987,994 ****
  }
  
  void
! depopulate_codes(as)
!     ansi_string *as;
  {
    int p;
  
--- 1266,1272 ----
  }
  
  void
! depopulate_codes(ansi_string * as)
  {
    int p;
  
***************
*** 1011,1044 ****
    }
  }
  
! static int is_ansi_code _((const char *s));
! static int is_start_html_code _((const char *s)) __attribute__ ((__unused__));
! static int is_end_html_code _((const char *s));
  
  static int
! is_ansi_code(s)
!     const char *s;
  {
    return s && *s == ESC_CHAR;
  }
  
  static int
! is_start_html_code(s)
!     const char *s;
  {
    return s && *s == TAG_START && *(s + 1) != '/';
  }
  
  static int
! is_end_html_code(s)
!     const char *s;
  {
    return s && *s == TAG_START && *(s + 1) == '/';
  }
  
  void
! free_ansi_string(as)
!     ansi_string *as;
  {
    int p;
  
--- 1289,1318 ----
    }
  }
  
! static int is_ansi_code(const char *s);
! static int is_start_html_code(const char *s) __attribute__ ((__unused__));
! static int is_end_html_code(const char *s);
  
  static int
! is_ansi_code(const char *s)
  {
    return s && *s == ESC_CHAR;
  }
  
  static int
! is_start_html_code(const char *s)
  {
    return s && *s == TAG_START && *(s + 1) != '/';
  }
  
  static int
! is_end_html_code(const char *s)
  {
    return s && *s == TAG_START && *(s + 1) == '/';
  }
  
  void
! free_ansi_string(ansi_string * as)
  {
    int p;
  
***************
*** 1052,1062 ****
  }
  
  int
! safe_ansi_string(as, start, len, buff, bp)
!     ansi_string *as;
!     int start, len;
!     char *buff;
!     char **bp;
  {
    int p;
    int in_ansi = 0;
--- 1326,1332 ----
  }
  
  int
! safe_ansi_string(ansi_string * as, int start, int len, char *buff, char **bp)
  {
    int p;
    int in_ansi = 0;
*** 1_7_5.66/src/set.c Thu, 22 Nov 2001 15:42:40 -0600 dunemush (pennmush/b/38_set.c 1.26.1.8 660)
--- 1_7_5.96(w)/src/set.c Fri, 15 Feb 2002 16:53:17 -0600 dunemush (pennmush/b/38_set.c 1.26.1.5.1.1.2.2 660)
***************
*** 373,390 ****
      return 0;
    }
    /* Don't allow chzone to objects without elocks! 
     * This checks for many trivial elocks (canuse/1, where &canuse=1)
     */
    if (zone != NOTHING) {
      struct boolexp *key = getlock(zone, Zone_Lock);
      if (key == TRUE_BOOLEXP) {
!       if (noisy)
! 	notify(player, T("ZMOs must be zone-locked before you @chzone!"));
!       return 0;
!     }
!     /* Does the player's location pass it? If so, we have either
!      * an inexact or trivial elock */
!     if (eval_lock(Location(player), zone, Zone_Lock)) {
        /* Does #0 and #2 pass it? If so, probably trivial elock */
        if (eval_lock(PLAYER_START, zone, Zone_Lock) &&
  	  eval_lock(MASTER_ROOM, zone, Zone_Lock)) {
--- 373,389 ----
      return 0;
    }
    /* Don't allow chzone to objects without elocks! 
+    * If no lock is set, set a default lock (warn if zmo are used for control)
     * This checks for many trivial elocks (canuse/1, where &canuse=1)
     */
    if (zone != NOTHING) {
      struct boolexp *key = getlock(zone, Zone_Lock);
      if (key == TRUE_BOOLEXP) {
!       add_lock(GOD, zone, Zone_Lock, parse_boolexp(zone, "$me", Zone_Lock), -1);
!       if (noisy && !ZONE_CONTROL_ZMP)
! 	notify(player,
! 	       T("Unlocked ZMO - automatically zone-locking ZMO to its owner"));
!     } else if (eval_lock(Location(player), zone, Zone_Lock)) {
        /* Does #0 and #2 pass it? If so, probably trivial elock */
        if (eval_lock(PLAYER_START, zone, Zone_Lock) &&
  	  eval_lock(MASTER_ROOM, zone, Zone_Lock)) {
***************
*** 394,403 ****
  	return 0;
        }
        /* Probably inexact zone lock */
!       if (noisy)
! 	notify(player,
! 	       T
! 	       ("Warning: ZMO may have loose zone lock. Lock ZMOs to =player, not player"));
      }
    }
    /* Warn Wiz/Royals when they zone their stuff */
--- 393,401 ----
  	return 0;
        }
        /* Probably inexact zone lock */
!       notify(player,
! 	     T
! 	     ("Warning: ZMO may have loose zone lock. Lock ZMOs to =player, not player"));
      }
    }
    /* Warn Wiz/Royals when they zone their stuff */
*** 1_7_5.66/src/predicat.c Mon, 03 Dec 2001 10:28:03 -0600 dunemush (pennmush/b/44_predicat.c 1.1.1.34.1.1.1.3.1.7 660)
--- 1_7_5.96(w)/src/predicat.c Fri, 15 Feb 2002 16:53:16 -0600 dunemush (pennmush/b/44_predicat.c 1.1.1.34.1.1.1.3.1.4.2.2 660)
***************
*** 29,37 ****
  #include "ansi.h"
  #include "parse.h"
  #include "dbdefs.h"
- #ifdef MEM_CHECK
- #include "memcheck.h"
- #endif
  #include "privtab.h"
  #include "mymalloc.h"
  #include "confmagic.h"
--- 29,34 ----
***************
*** 738,747 ****
        any = 1;
        tbuf1 = replace_string("#$", expression, argv[a + 1]);
        parse_que(player, tbuf1, cause);
!       free(tbuf1);
! #ifdef MEM_CHECK
!       del_check("replace_string.buff");
! #endif
      }
    }
  
--- 735,741 ----
        any = 1;
        tbuf1 = replace_string("#$", expression, argv[a + 1]);
        parse_que(player, tbuf1, cause);
!       mush_free(tbuf1, "replace_string.buff");
      }
    }
  
***************
*** 749,758 ****
    if ((a < MAX_ARG) && !any && argv[a]) {
      tbuf1 = replace_string("#$", expression, argv[a]);
      parse_que(player, tbuf1, cause);
!     free(tbuf1);
! #ifdef MEM_CHECK
!     del_check("replace_string.buff");
! #endif
    }
  
    /* Pop on @notify me, if requested */
--- 743,749 ----
    if ((a < MAX_ARG) && !any && argv[a]) {
      tbuf1 = replace_string("#$", expression, argv[a]);
      parse_que(player, tbuf1, cause);
!     mush_free(tbuf1, "replace_string.buff");
    }
  
    /* Pop on @notify me, if requested */
*** 1_7_5.66/src/parse.c Mon, 07 Jan 2002 10:06:31 -0600 dunemush (pennmush/b/48_parse.c 1.23.1.10.1.4 660)
--- 1_7_5.96(w)/src/parse.c Fri, 15 Feb 2002 16:53:16 -0600 dunemush (pennmush/b/48_parse.c 1.23.1.10.1.2.1.1.1.2 660)
***************
*** 400,405 ****
--- 400,410 ----
        pe_info->nest_depth++;
      }
    }
+ 
+   /* Only strip command braces if the first character is a brace. */
+   if (**str != '{')
+     eflags &= ~PE_COMMAND_BRACES;
+ 
    for (;;) {
      /* Find the first "interesting" character */
      {
***************
*** 665,682 ****
  	(*str)++;
  	break;
        }
!       if (!(eflags & PE_STRIP_BRACES))
  	safe_chr('{', buff, bp);
        (*str)++;
        process_expression(buff, bp, str,
  			 executor, caller, enactor,
! 			 eflags & ~(PE_STRIP_BRACES | PE_FUNCTION_CHECK),
  			 PT_BRACE, pe_info);
        if (**str == '}') {
! 	if (!(eflags & PE_STRIP_BRACES))
  	  safe_chr('}', buff, bp);
  	(*str)++;
        }
        break;
      case '[':			/* "[]" parse group; recurse with mandatory function check */
        if (!pe_info && eflags != PE_NOTHING) {
--- 670,691 ----
  	(*str)++;
  	break;
        }
!       if (!(eflags & (PE_STRIP_BRACES | PE_COMMAND_BRACES)))
  	safe_chr('{', buff, bp);
        (*str)++;
        process_expression(buff, bp, str,
  			 executor, caller, enactor,
! 			 eflags & PE_COMMAND_BRACES
! 			 ? (eflags & ~PE_COMMAND_BRACES)
! 			 : (eflags & ~(PE_STRIP_BRACES | PE_FUNCTION_CHECK)),
  			 PT_BRACE, pe_info);
        if (**str == '}') {
! 	if (!(eflags & (PE_STRIP_BRACES | PE_COMMAND_BRACES)))
  	  safe_chr('}', buff, bp);
  	(*str)++;
        }
+       /* Only strip one set of braces for commands */
+       eflags &= ~PE_COMMAND_BRACES;
        break;
      case '[':			/* "[]" parse group; recurse with mandatory function check */
        if (!pe_info && eflags != PE_NOTHING) {
*** 1_7_5.66/src/lock.c Fri, 09 Nov 2001 20:35:29 -0600 dunemush (pennmush/c/6_lock.c 1.17.1.5 660)
--- 1_7_5.96(w)/src/lock.c Fri, 15 Feb 2002 16:53:16 -0600 dunemush (pennmush/c/6_lock.c 1.17.1.6 660)
***************
*** 309,315 ****
      return 0;
    }
  
!   ll = getlockstruct(thing, type);
  
    if (ll) {
      if (!can_write_lock(player, thing, ll)) {
--- 309,315 ----
      return 0;
    }
  
!   ll = getlockstruct_noparent(thing, type);
  
    if (ll) {
      if (!can_write_lock(player, thing, ll)) {
*** 1_7_5.66/src/game.c Fri, 07 Dec 2001 23:59:54 -0600 dunemush (pennmush/c/10_game.c 1.50.1.8.1.1.1.1.2.1.1.1.2.1.1.4.1.1.1.1.1.1.1.2 660)
--- 1_7_5.96(w)/src/game.c Fri, 15 Feb 2002 16:53:16 -0600 dunemush (pennmush/c/10_game.c 1.50.1.8.1.1.1.1.2.1.1.1.2.1.1.4.1.1.1.1.1.1.1.1.1.1.2.1.1.3 660)
***************
*** 62,67 ****
--- 62,68 ----
  #include "strtree.h"
  #include "command.h"
  #include "htab.h"
+ #include "ptab.h"
  #include "log.h"
  #include "lock.h"
  #include "dbdefs.h"
***************
*** 115,121 ****
  int loc_alias_check _((dbref loc, const char *command, const char *type));
  void do_poor _((dbref player, char *arg1));
  void do_writelog _((dbref player, char *str, int ltype));
! void bind_and_queue _((dbref player, dbref cause, char *action, char *arg));
  void do_scan _((dbref player, char *command, int flag));
  void do_list _((dbref player, char *arg, int lc));
  void do_dolist _((dbref player, char *list, char *command,
--- 116,123 ----
  int loc_alias_check _((dbref loc, const char *command, const char *type));
  void do_poor _((dbref player, char *arg1));
  void do_writelog _((dbref player, char *str, int ltype));
! void bind_and_queue(dbref player, dbref cause, char *action, const char *arg,
! 		    const char *placestr);
  void do_scan _((dbref player, char *command, int flag));
  void do_list _((dbref player, char *arg, int lc));
  void do_dolist _((dbref player, char *list, char *command,
***************
*** 288,295 ****
    }
    if (Wizard(player)) {
      flag_broadcast(0, 0, T("GAME: Shutdown by %s"), Name(player));
!     do_log(LT_ERR, player, NOTHING, T("SHUTDOWN by %s\n"),
! 	   real_unparse(player, player, 0, 0));
  
      /* This will create a file used to check if a restart should occur */
  #ifdef AUTORESTART
--- 290,297 ----
    }
    if (Wizard(player)) {
      flag_broadcast(0, 0, T("GAME: Shutdown by %s"), Name(player));
!     do_log(LT_ERR, player, NOTHING, T("SHUTDOWN by %s(%s)\n"),
! 	   Name(player), unparse_dbref(player));
  
      /* This will create a file used to check if a restart should occur */
  #ifdef AUTORESTART
***************
*** 664,675 ****
    do_rawlog(LT_ERR, T("MUSH restarted, PID %d, at %s"),
  	    (int) getpid(), ctime(&start_time));
  
!   /* initialize all the hash tables */
!   init_flag_hashtab();
    init_func_hashtab();
    init_math_hashtab();
    init_tag_hashtab();
!   init_aname_hashtab();
    init_atr_name_tree();
    init_locks();
    init_names();
--- 666,677 ----
    do_rawlog(LT_ERR, T("MUSH restarted, PID %d, at %s"),
  	    (int) getpid(), ctime(&start_time));
  
!   /* initialize all the hash and prefix tables */
!   init_flag_table();
    init_func_hashtab();
    init_math_hashtab();
    init_tag_hashtab();
!   init_aname_table();
    init_atr_name_tree();
    init_locks();
    init_names();
***************
*** 811,819 ****
    /* now do access file stuff */
    read_access_file();
  
-   /* initialize random number generator */
-   srandom(getpid());
- 
    /* set up dumper */
    strcpy(dumpfile, outfile);
    init_timer();
--- 813,818 ----
***************
*** 1254,1283 ****
  /* Bind occurences of '##' in "action" to "arg", then run "action" */
  
  void
! bind_and_queue(player, cause, action, arg)
!     dbref player;
!     dbref cause;
!     char *action;
!     char *arg;
  {
    char *repl, *command;
  
-   repl = replace_string("##", arg, action);
    command = strip_braces(repl);
  
!   if (repl)
!     free(repl);
! #ifdef MEM_CHECK
!   del_check("replace_string.buff");
! #endif
  
    parse_que(player, command, cause);
  
!   if (command)
!     free(command);
! #ifdef MEM_CHECK
!   del_check("strip_braces.buff");
! #endif
  }
  
  void
--- 1253,1276 ----
  /* Bind occurences of '##' in "action" to "arg", then run "action" */
  
  void
! bind_and_queue(dbref player, dbref cause, char *action, const char *arg,
! 	       const char *placestr)
  {
    char *repl, *command;
+   const char *replace[2];
+ 
+   replace[0] = arg;
+   replace[1] = placestr;
+ 
+   repl = replace_string2(standard_tokens, replace, action);
  
    command = strip_braces(repl);
  
!   mush_free(repl, "replace_string.buff");
  
    parse_que(player, command, cause);
  
!   mush_free(command, "strip_braces.buff");
  }
  
  void
***************
*** 1408,1422 ****
  #define DOL_DELIM 4
  
  void
! do_dolist(player, list, command, cause, flags)
!     dbref player;
!     char *list, *command;
!     dbref cause;
!     unsigned int flags;
  {
    char *curr, *objstring;
    char outbuf[BUFFER_LEN];
!   char *ebuf1, *ebuf2, *bp;
    int place;
    char placestr[10];
    int j;
--- 1401,1412 ----
  #define DOL_DELIM 4
  
  void
! do_dolist(dbref player, char *list, char *command, dbref cause,
! 	  unsigned int flags)
  {
    char *curr, *objstring;
    char outbuf[BUFFER_LEN];
!   char *bp;
    int place;
    char placestr[10];
    int j;
***************
*** 1431,1437 ****
  
    if (flags & DOL_DELIM) {
      if (list[1] != ' ') {
!       notify(player, T("Seperator must be one character."));
        if (flags & DOL_NOTIFY)
  	parse_que(player, "@notify me", cause);
        return;
--- 1421,1427 ----
  
    if (flags & DOL_DELIM) {
      if (list[1] != ' ') {
!       notify(player, T("Separator must be one character."));
        if (flags & DOL_NOTIFY)
  	parse_que(player, "@notify me", cause);
        return;
***************
*** 1468,1496 ****
  
      if (!(flags & DOL_MAP)) {
        /* @dolist, queue command */
!       ebuf1 = replace_string("#@", placestr, command);
!       bind_and_queue(player, cause, ebuf1, curr);
! #ifdef MEM_CHECK
!       del_check("replace_string.buff");
! #endif
!       free(ebuf1);
      } else {
        /* it's @map, add to the output list */
        if (bp != outbuf)
  	safe_chr(delim, outbuf, &bp);
!       ebuf1 = replace_string("##", curr, command);
!       ebuf2 = replace_string("#@", placestr, ebuf1);
!       free(ebuf1);
! #ifdef MEM_CHECK
!       del_check("replace_string.buff");
! #endif
!       ebuf1 = ebuf2;
!       process_expression(outbuf, &bp, (char const **) &ebuf1,
  			 player, cause, cause, PE_DEFAULT, PT_DEFAULT, NULL);
!       free(ebuf2);
! #ifdef MEM_CHECK
!       del_check("replace_string.buff");
! #endif
      }
    }
  
--- 1458,1477 ----
  
      if (!(flags & DOL_MAP)) {
        /* @dolist, queue command */
!       bind_and_queue(player, cause, command, curr, placestr);
      } else {
+       const char *replace[2];
+       char *ebuf;
+ 
        /* it's @map, add to the output list */
        if (bp != outbuf)
  	safe_chr(delim, outbuf, &bp);
!       replace[0] = curr;
!       replace[1] = placestr;
!       ebuf = replace_string2(standard_tokens, replace, command);
!       process_expression(outbuf, &bp, (char const **) &ebuf,
  			 player, cause, cause, PE_DEFAULT, PT_DEFAULT, NULL);
!       mush_free(ebuf, "replace_string.buff");
      }
    }
  
***************
*** 1905,1913 ****
  }
  
  /* Reports stats on various in-memory data structures */
- extern HASHTAB htab_attrib;
- extern HASHTAB htab_command;
- extern HASHTAB htab_flag;
  extern HASHTAB htab_function;
  extern HASHTAB htab_user_function;
  extern HASHTAB htab_math;
--- 1886,1891 ----
***************
*** 1918,1933 ****
  extern StrTree atr_names;
  extern StrTree lock_names;
  extern StrTree object_names;
  
  void
! do_list_memstats(player)
!     dbref player;
  {
    notify(player, "Hash Tables:");
    hash_stats_header(player);
-   hash_stats(player, &htab_attrib, "AttrPerms");
-   hash_stats(player, &htab_command, "Commands");
-   hash_stats(player, &htab_flag, "Flags");
    hash_stats(player, &htab_function, "Functions");
    hash_stats(player, &htab_user_function, "@Functions");
    hash_stats(player, &htab_math, "Math funs");
--- 1896,1910 ----
  extern StrTree atr_names;
  extern StrTree lock_names;
  extern StrTree object_names;
+ extern PTAB ptab_command;
+ extern PTAB ptab_attrib;
+ extern PTAB ptab_flag;
  
  void
! do_list_memstats(dbref player)
  {
    notify(player, "Hash Tables:");
    hash_stats_header(player);
    hash_stats(player, &htab_function, "Functions");
    hash_stats(player, &htab_user_function, "@Functions");
    hash_stats(player, &htab_math, "Math funs");
***************
*** 1935,1940 ****
--- 1912,1923 ----
    hash_stats(player, &htab_player_list, "Players");
    hash_stats(player, &htab_reserved_aliases, "Aliases");
    hash_stats(player, &help_files, "HelpFiles");
+ 
+   notify(player, "Prefix Trees:");
+   ptab_stats_header(player);
+   ptab_stats(player, &ptab_attrib, "AttrPerms");
+   ptab_stats(player, &ptab_command, "Commands");
+   ptab_stats(player, &ptab_flag, "Flags");
  
    notify(player, "String Trees:");
    st_stats_header(player);
*** 1_7_5.66/src/funtime.c Tue, 25 Sep 2001 16:27:49 -0500 dunemush (pennmush/c/12_funtime.c 1.11.1.6 660)
--- 1_7_5.96(w)/src/funtime.c Fri, 15 Feb 2002 16:53:16 -0600 dunemush (pennmush/c/12_funtime.c 1.11.1.7 660)
***************
*** 1,11 ****
  #include "copyrite.h"
  
  #include "config.h"
- #ifdef I_STRING
  #include <string.h>
- #else
- #include <strings.h>
- #endif
  #include <ctype.h>
  #if  defined(__GNUC__) || defined(__LCC__)
  /* Required to get the getdate() prototype on glibc. */
--- 1,7 ----
***************
*** 43,49 ****
      tt = mudtime;
  
    ttm = localtime(&tt);
!   len = strlen(args[0]);
    for (n = 0; n < len; n++)
      if (args[0][n] == '%')
        args[0][n] = 0x5;
--- 39,45 ----
      tt = mudtime;
  
    ttm = localtime(&tt);
!   len = arglens[0];
    for (n = 0; n < len; n++)
      if (args[0][n] == '%')
        args[0][n] = 0x5;
*** 1_7_5.66/src/funstr.c Thu, 24 Jan 2002 10:49:36 -0600 dunemush (pennmush/c/13_funstr.c 1.28.1.1.1.2.1.4.1.6.1.1.1.1.1.2.1.1.1.1.1.5 660)
--- 1_7_5.96(w)/src/funstr.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/13_funstr.c 1.28.1.1.1.2.1.4.1.6.1.1.1.1.1.2.1.1.1.1.1.9 660)
***************
*** 1,12 ****
  #include "copyrite.h"
  
  #include "config.h"
- #ifdef I_STRING
  #include <string.h>
- #else
- #include <strings.h>
- #endif
  #include <ctype.h>
  #include "conf.h"
  #include "ansi.h"
  #include "externs.h"
--- 1,9 ----
  #include "copyrite.h"
  
  #include "config.h"
  #include <string.h>
  #include <ctype.h>
+ #include <limits.h>
  #include "conf.h"
  #include "ansi.h"
  #include "externs.h"
***************
*** 28,38 ****
  
  HASHTAB htab_tag;
  
! static int wraplen _((char *str, int maxlen));
  
  int
! get_gender(player)
!     dbref player;
  {
    /* 0 for error, 1 for neuter, 2 for female, 3 for male, 4 for plural */
  
--- 25,34 ----
  
  HASHTAB htab_tag;
  
! static int wraplen(char *str, int maxlen);
  
  int
! get_gender(dbref player)
  {
    /* 0 for error, 1 for neuter, 2 for female, 3 for male, 4 for plural */
  
***************
*** 96,102 ****
    } else if (p != args[0]) {
      char x = *p;
      *p = '\0';
!     safe_str(args[0], buff, bp);
      *p = x;
    }
    if (*p) {
--- 92,98 ----
    } else if (p != args[0]) {
      char x = *p;
      *p = '\0';
!     safe_strl(args[0], p - args[0], buff, bp);
      *p = x;
    }
    if (*p) {
***************
*** 453,463 ****
    char c;
  
    /* do length checks first */
!   if (strlen(args[0]) != strlen(args[1])) {
      safe_str(T("#-1 STRING LENGTHS MUST BE EQUAL"), buff, bp);
      return;
    }
!   if (strlen(args[2]) > 1) {
      safe_str(T("#-1 TOO MANY CHARACTERS"), buff, bp);
      return;
    }
--- 449,459 ----
    char c;
  
    /* do length checks first */
!   if (arglens[0] != arglens[1]) {
      safe_str(T("#-1 STRING LENGTHS MUST BE EQUAL"), buff, bp);
      return;
    }
!   if (arglens[2] > 1) {
      safe_str(T("#-1 TOO MANY CHARACTERS"), buff, bp);
      return;
    }
***************
*** 538,544 ****
    /* Do the repeat in O(lg n) time. */
    /* This takes advantage of the fact that we're given a BUFFER_LEN
     * buffer for args[0] that we are free to trash.  Huzzah! */
!   ap = args[0] + strlen(args[0]);
    while (times) {
      if (times & 1) {
        if (safe_strl(args[0], arglens[0], buff, bp) != 0)
--- 534,540 ----
    /* Do the repeat in O(lg n) time. */
    /* This takes advantage of the fact that we're given a BUFFER_LEN
     * buffer for args[0] that we are free to trash.  Huzzah! */
!   ap = args[0] + arglens[0];
    while (times) {
      if (times & 1) {
        if (safe_strl(args[0], arglens[0], buff, bp) != 0)
***************
*** 988,993 ****
--- 984,1291 ----
    }
  }
  
+ FUNCTION(fun_ord)
+ {
+   char *m;
+   Size_t len = 0;
+   if (!args[0] || !args[0][0]) {
+     safe_str(T("#-1 FUNCTION EXPECTS ONE CHARACTER"), buff, bp);
+     return;
+   }
+   m = remove_markup(args[0], &len);
+ 
+   if (len != 2)			/* len includes trailing nul */
+     safe_str(T("#-1 FUNCTION EXPECTS ONE CHARACTER"), buff, bp);
+   else if (isprint((unsigned char) *m))
+     safe_integer((unsigned char) *m, buff, bp);
+   else
+     safe_str(T("#-1 UNPRINTABLE CHARACTER"), buff, bp);
+ }
+ 
+ FUNCTION(fun_chr)
+ {
+   int c;
+ 
+   if (!is_integer(args[0])) {
+     safe_str(T(e_uint), buff, bp);
+     return;
+   }
+   c = parse_integer(args[0]);
+   if (c < 0 || c > UCHAR_MAX)
+     safe_str(T("#-1 THIS ISN'T UNICODE"), buff, bp);
+   else if (isprint(c))
+     safe_chr(c, buff, bp);
+   else
+     safe_str(T("#-1 UNPRINTABLE CHARACTER"), buff, bp);
+ 
+ }
+ 
+ FUNCTION(fun_accent)
+ {
+   int n;
+   unsigned char c;
+ 
+   if (arglens[0] != arglens[1]) {
+     safe_str(T("#-1 STRING LENGTHS MUST BE EQUAL"), buff, bp);
+     return;
+   }
+ 
+   for (n = 0; n < arglens[0]; n++) {
+     switch (args[0][n]) {
+     case 'A':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 192;
+ 	break;
+       case '\'':
+ 	c = 193;
+ 	break;
+       case '^':
+ 	c = 194;
+ 	break;
+       case '~':
+ 	c = 195;
+ 	break;
+       case ':':
+ 	c = 196;
+ 	break;
+       case 'o':
+ 	c = 197;
+ 	break;
+       default:
+ 	c = 'A';
+       }
+       break;
+     case 'a':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 224;
+ 	break;
+       case '\'':
+ 	c = 225;
+ 	break;
+       case '^':
+ 	c = 226;
+ 	break;
+       case '~':
+ 	c = 227;
+ 	break;
+       case ':':
+ 	c = 228;
+ 	break;
+       case 'o':
+ 	c = 229;
+ 	break;
+       default:
+ 	c = 'a';
+       }
+       break;
+     case 'C':
+       if (args[1][n] == ',')
+ 	c = 199;
+       else
+ 	c = 'C';
+       break;
+     case 'c':
+       if (args[1][n] == ',')
+ 	c = 231;
+       else
+ 	c = 'c';
+       break;
+     case 'E':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 200;
+ 	break;
+       case '\'':
+ 	c = 201;
+ 	break;
+       case '^':
+ 	c = 202;
+ 	break;
+       case ':':
+ 	c = 203;
+ 	break;
+       default:
+ 	c = 'E';
+       }
+       break;
+     case 'e':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 232;
+ 	break;
+       case '\'':
+ 	c = 233;
+ 	break;
+       case '^':
+ 	c = 234;
+ 	break;
+       case ':':
+ 	c = 235;
+ 	break;
+       default:
+ 	c = 'e';
+       }
+       break;
+     case 'I':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 204;
+ 	break;
+       case '\'':
+ 	c = 205;
+ 	break;
+       case '^':
+ 	c = 206;
+ 	break;
+       case ':':
+ 	c = 207;
+ 	break;
+       default:
+ 	c = 'I';
+       }
+       break;
+     case 'i':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 236;
+ 	break;
+       case '\'':
+ 	c = 237;
+ 	break;
+       case '^':
+ 	c = 238;
+ 	break;
+       case ':':
+ 	c = 239;
+ 	break;
+       default:
+ 	c = 'i';
+       }
+       break;
+     case 'N':
+       if (args[1][n] == '~')
+ 	c = 209;
+       else
+ 	c = 'N';
+       break;
+     case 'n':
+       if (args[1][n] == '~')
+ 	c = 241;
+       else
+ 	c = 'n';
+       break;
+     case 'O':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 210;
+ 	break;
+       case '\'':
+ 	c = 211;
+ 	break;
+       case '^':
+ 	c = 212;
+ 	break;
+       case '~':
+ 	c = 213;
+ 	break;
+       case ':':
+ 	c = 214;
+ 	break;
+       default:
+ 	c = 'O';
+       }
+       break;
+     case 'o':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 242;
+ 	break;
+       case '\'':
+ 	c = 243;
+ 	break;
+       case '^':
+ 	c = 244;
+ 	break;
+       case '~':
+ 	c = 245;
+ 	break;
+       case ':':
+ 	c = 246;
+ 	break;
+       default:
+ 	c = 'o';
+       }
+       break;
+     case 'U':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 217;
+ 	break;
+       case '\'':
+ 	c = 218;
+ 	break;
+       case '^':
+ 	c = 219;
+ 	break;
+       case ':':
+ 	c = 220;
+ 	break;
+       default:
+ 	c = 'U';
+       }
+       break;
+     case 'u':
+       switch (args[1][n]) {
+       case '`':
+ 	c = 249;
+ 	break;
+       case '\'':
+ 	c = 250;
+ 	break;
+       case '^':
+ 	c = 251;
+ 	break;
+       case ':':
+ 	c = 252;
+ 	break;
+       default:
+ 	c = 'u';
+       }
+       break;
+     case 'Y':
+       if (args[1][n] == '\'')
+ 	c = 221;
+       else
+ 	c = 'Y';
+       break;
+     case 'y':
+       if (args[1][n] == '\'')
+ 	c = 253;
+       else if (args[1][n] == ':')
+ 	c = 255;
+       else
+ 	c = 'y';
+       break;
+     default:
+       c = args[0][n];
+     }
+     if (isprint(c))
+       safe_chr((char) c, buff, bp);
+     else
+       safe_chr(args[0][n], buff, bp);
+   }
+ }
+ 
+ FUNCTION(fun_stripaccents)
+ {
+   int n;
+   for (n = 0; n < arglens[0]; n++) {
+     safe_chr((char) accent_table[(unsigned char) args[0][n]].base, buff, bp);
+   }
+ }
+ 
  /* ARGSUSED */
  FUNCTION(fun_html)
  {
***************
*** 1356,1364 ****
   * or else the last space, or else 0.
   */
  static int
! wraplen(str, maxlen)
!     char *str;
!     int maxlen;
  {
    const int length = strlen(str);
    int i = 0;
--- 1654,1660 ----
   * or else the last space, or else 0.
   */
  static int
! wraplen(char *str, int maxlen)
  {
    const int length = strlen(str);
    int i = 0;
*** 1_7_5.66/src/funmath.c Fri, 04 Jan 2002 15:23:43 -0600 dunemush (pennmush/c/15_funmath.c 1.41 660)
--- 1_7_5.96(w)/src/funmath.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/15_funmath.c 1.42 660)
***************
*** 193,199 ****
      safe_integer(parse_integer(args[0]) + 1, buff, bp);
      return;
    }
!   p = args[0] + strlen(args[0]) - 1;
    if (!isdigit(*p)) {
      safe_str(T("#-1 ARGUMENT MUST END IN AN INTEGER"), buff, bp);
      return;
--- 193,199 ----
      safe_integer(parse_integer(args[0]) + 1, buff, bp);
      return;
    }
!   p = args[0] + arglens[0] - 1;
    if (!isdigit(*p)) {
      safe_str(T("#-1 ARGUMENT MUST END IN AN INTEGER"), buff, bp);
      return;
***************
*** 225,231 ****
      safe_integer(parse_integer(args[0]) - 1, buff, bp);
      return;
    }
!   p = args[0] + strlen(args[0]) - 1;
    if (!isdigit(*p)) {
      safe_str(T("#-1 ARGUMENT MUST END IN AN INTEGER"), buff, bp);
      return;
--- 225,231 ----
      safe_integer(parse_integer(args[0]) - 1, buff, bp);
      return;
    }
!   p = args[0] + arglens[0] - 1;
    if (!isdigit(*p)) {
      safe_str(T("#-1 ARGUMENT MUST END IN AN INTEGER"), buff, bp);
      return;
*** 1_7_5.66/src/funlist.c Thu, 24 Jan 2002 10:49:36 -0600 dunemush (pennmush/c/16_funlist.c 1.3.1.1.1.5.1.2.1.1.1.1.1.4.1.2.1.2.1.19.1.2.1.1.1.2.1.5.1.1.1.1.1.1.1.3 660)
--- 1_7_5.96(w)/src/funlist.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/16_funlist.c 1.3.1.1.1.5.1.2.1.1.1.1.1.4.1.2.1.2.1.19.1.2.1.1.1.2.1.5.1.1.1.1.1.1.1.1.1.1.2.2 660)
***************
*** 1026,1038 ****
      osep = osepd;
    }
  
!   tempbuff = (char *) mush_malloc(BUFFER_LEN * 2, "string");
    a1 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray");
    a2 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray");
    if (!tempbuff || !a1 || !a2)
      panic("Unable to allocate memory in fun_setunion");
    /* Concat both lists, make array, sort */
!   sprintf(tempbuff, "%s%c%s", args[0], sep, args[1]);
    n1 = list2arr(a1, MAX_SORTSIZE, tempbuff, sep);
    if (nargs == 4)
      sort_type = get_list_type(args, nargs, 4, a1, n1);
--- 1026,1043 ----
      osep = osepd;
    }
  
!   tempbuff = (char *) mush_malloc((BUFFER_LEN * 2) + 4, "string");
    a1 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray");
    a2 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray");
    if (!tempbuff || !a1 || !a2)
      panic("Unable to allocate memory in fun_setunion");
    /* Concat both lists, make array, sort */
!   if (!*args[0])
!     memcpy(tempbuff, args[1], arglens[1] + 1);
!   else if (!*args[1])
!     memcpy(tempbuff, args[0], arglens[0] + 1);
!   else
!     sprintf(tempbuff, "%s%c%s", args[0], sep, args[1]);
    n1 = list2arr(a1, MAX_SORTSIZE, tempbuff, sep);
    if (nargs == 4)
      sort_type = get_list_type(args, nargs, 4, a1, n1);
***************
*** 1042,1049 ****
    /* Strip the duplicates and make a2 contain the list */
    a = 0;
    for (i = 0; i < n1; i++) {
!     if (((a == 0) || (gencomp(a1[i], a2[a - 1], sort_type) != 0))
! 	&& (*a1[i])) {
        a2[a] = a1[i];
        a++;
      }
--- 1047,1053 ----
    /* Strip the duplicates and make a2 contain the list */
    a = 0;
    for (i = 0; i < n1; i++) {
!     if (((a == 0) || (gencomp(a1[i], a2[a - 1], sort_type) != 0))) {
        a2[a] = a1[i];
        a++;
      }
***************
*** 1856,1864 ****
      p = strchr(args[0], ' ');
    else
      p = strstr(args[0], args[1]);
!   if (p)
!     *p = '\0';
!   safe_str(args[0], buff, bp);
  }
  
  /* ARGSUSED */
--- 1860,1869 ----
      p = strchr(args[0], ' ');
    else
      p = strstr(args[0], args[1]);
!   if (p) {
!     safe_strl(args[0], p - args[0], buff, bp);
!   } else
!     safe_strl(args[0], arglens[0], buff, bp);
  }
  
  /* ARGSUSED */
***************
*** 1869,1878 ****
    if (!*args[1]) {
      args[1][0] = ' ';
      args[1][1] = '\0';
    }
    p = strstr(args[0], args[1]);
    if (p)
!     safe_str(p + strlen(args[1]), buff, bp);
  }
  
  /* ARGSUSED */
--- 1874,1884 ----
    if (!*args[1]) {
      args[1][0] = ' ';
      args[1][1] = '\0';
+     arglens[1] = 1;
    }
    p = strstr(args[0], args[1]);
    if (p)
!     safe_str(p + arglens[1], buff, bp);
  }
  
  /* ARGSUSED */
***************
*** 1977,1982 ****
--- 1983,1990 ----
    int *place;
    int funccount;
    char *oldbp;
+   const char *replace[2];
+ 
  
    if (inum >= MAX_ITERS) {
      safe_str(T("#-1 TOO MANY ITERS"), buff, bp);
***************
*** 2036,2048 ****
      }
      *place = *place + 1;
      iter_rep[inum] = tbuf1 = split_token(&lp, sep);
!     tbuf2 = replace_string("##", tbuf1, args[1]);
!     tbuf1 = replace_string("#@", unparse_integer(*place), tbuf2);
!     mush_free((Malloc_t) tbuf2, "replace_string.buff");
!     sp = tbuf1;
      process_expression(buff, bp, &sp, executor, caller, enactor,
  		       PE_DEFAULT, PT_DEFAULT, pe_info);
!     mush_free((Malloc_t) tbuf1, "replace_string.buff");
    }
    *place = 0;
    iter_rep[inum] = NULL;
--- 2044,2056 ----
      }
      *place = *place + 1;
      iter_rep[inum] = tbuf1 = split_token(&lp, sep);
!     replace[0] = tbuf1;
!     replace[1] = unparse_integer(*place);
!     tbuf2 = replace_string2(standard_tokens, replace, args[1]);
!     sp = tbuf2;
      process_expression(buff, bp, &sp, executor, caller, enactor,
  		       PE_DEFAULT, PT_DEFAULT, pe_info);
!     mush_free((Malloc_t) tbuf2, "replace_string.buff");
    }
    *place = 0;
    iter_rep[inum] = NULL;
***************
*** 2637,2644 ****
  #ifdef MEM_CHECK
    add_check("pcre");
  #endif
!   subpatterns =
!     pcre_exec(re, NULL, args[0], strlen(args[0]), 0, 0, offsets, 99);
    safe_integer(subpatterns >= 0, buff, bp);
  
    /* We need to parse the list of registers.  Anything that we don't parse
--- 2645,2651 ----
  #ifdef MEM_CHECK
    add_check("pcre");
  #endif
!   subpatterns = pcre_exec(re, NULL, args[0], arglens[0], 0, 0, offsets, 99);
    safe_integer(subpatterns >= 0, buff, bp);
  
    /* We need to parse the list of registers.  Anything that we don't parse
*** 1_7_5.66/src/fundb.c Thu, 22 Nov 2001 15:42:40 -0600 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.4 660)
--- 1_7_5.96(w)/src/fundb.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.5 660)
***************
*** 1660,1666 ****
      safe_str(T("#-1 INVALID GREP PATTERN"), buff, bp);
      return;
    }
!   tp = grep_util(executor, it, args[1], args[2], strlen(args[2]),
  		 strcmp(called_as, "GREP"));
  #ifdef MEM_CHECK
    add_check("fun_grep.attr_list");
--- 1660,1666 ----
      safe_str(T("#-1 INVALID GREP PATTERN"), buff, bp);
      return;
    }
!   tp = grep_util(executor, it, args[1], args[2], arglens[2],
  		 strcmp(called_as, "GREP"));
  #ifdef MEM_CHECK
    add_check("fun_grep.attr_list");
***************
*** 1794,1800 ****
        return;
      } else {
        /* args[0] didn't match. Maybe it's a delimiter? */
!       if (strlen(args[0]) > 1) {
  	if (it == NOTHING)
  	  notify(executor, T("I can't see that here."));
  	else if (it == AMBIGUOUS)
--- 1794,1800 ----
        return;
      } else {
        /* args[0] didn't match. Maybe it's a delimiter? */
!       if (arglens[0] > 1) {
  	if (it == NOTHING)
  	  notify(executor, T("I can't see that here."));
  	else if (it == AMBIGUOUS)
*** 1_7_5.66/src/function.c Wed, 26 Dec 2001 17:59:36 -0600 dunemush (pennmush/c/18_function.c 1.29.1.14.1.3.1.11 660)
--- 1_7_5.96(w)/src/function.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/18_function.c 1.29.1.14.1.3.1.12 660)
***************
*** 149,154 ****
--- 149,155 ----
  FUNTAB flist[] = {
    {"@@", fun_atat, 1, 1, FN_NOPARSE},
    {"ABS", fun_abs, 1, 1, FN_REG},
+   {"ACCENT", fun_accent, 2, 2, FN_REG},
    {"ADD", fun_add, 2, INT_MAX, FN_REG},
    {"AFTER", fun_after, 2, 2, FN_REG},
    {"ALPHAMAX", fun_alphamax, 1, INT_MAX, FN_REG},
***************
*** 177,182 ****
--- 178,184 ----
    {"CEMIT", fun_cemit, 2, 3, FN_REG},
  #endif
    {"CENTER", fun_center, 2, 3, FN_REG},
+   {"CHR", fun_chr, 1, 1, FN_REG},
  #ifdef CHAT_SYSTEM
    {"CFLAGS", fun_cflags, 1, 2, FN_REG},
    {"CHANNELS", fun_channels, 0, 2, FN_REG},
***************
*** 354,359 ****
--- 356,362 ----
    {"OEMIT", fun_oemit, 2, -2, FN_REG},
    {"OPEN", fun_open, 2, 2, FN_REG},
    {"OR", fun_or, 2, INT_MAX, FN_REG},
+   {"ORD", fun_ord, 1, 1, FN_REG},
    {"ORFLAGS", fun_orflags, 2, 2, FN_REG},
    {"OWNER", fun_owner, 1, 1, FN_REG},
    {"PARENT", fun_parent, 1, 2, FN_REG},
***************
*** 425,430 ****
--- 428,434 ----
    {"STEP", fun_step, 3, 5, FN_REG},
    {"STRCAT", fun_strcat, 1, INT_MAX, FN_REG},
    {"STRINSERT", fun_strinsert, 3, -3, FN_REG},
+   {"STRIPACCENTS", fun_stripaccents, 1, 1, FN_REG},
    {"STRIPANSI", fun_stripansi, 1, -1, FN_REG},
    {"STRLEN", fun_strlen, 1, -1, FN_REG},
    {"STRMATCH", fun_strmatch, 2, 2, FN_REG},
*** 1_7_5.66/src/flags.c Tue, 20 Nov 2001 17:08:09 -0600 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.4 660)
--- 1_7_5.96(w)/src/flags.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.8 660)
***************
*** 15,21 ****
  #include "mushdb.h"
  #include "externs.h"
  #include "match.h"
! #include "htab.h"
  #include "game.h"
  #include "flags.h"
  #include "dbdefs.h"
--- 15,21 ----
  #include "mushdb.h"
  #include "externs.h"
  #include "match.h"
! #include "ptab.h"
  #include "game.h"
  #include "flags.h"
  #include "dbdefs.h"
***************
*** 23,31 ****
  #include "log.h"
  #include "confmagic.h"
  
- #define FLAG_HASH_SIZE 256
- #define FLAG_HASH_MASK 255
- 
  typedef struct flag_info FLAG;
  
  struct flag_info {
--- 23,28 ----
***************
*** 64,70 ****
  };
  
  static FLAG *flag_hash_lookup _((const char *name));
- static void flag_hash_insert _((const char *name, FLAG *entry));
  int can_set_flag _((dbref player, dbref thing, FLAG *flagp, int negate));
  static FLAG *letter_to_flagptr _((char c, int type, int *toggle));
  void decompile_flags _((dbref player, dbref thing, const char *name));
--- 61,66 ----
***************
*** 72,78 ****
  int convert_flags _((dbref player, char *s, object_flag_type *p_mask,
  		     object_flag_type *p_toggle, object_flag_type *p_type));
  
! HASHTAB htab_flag;
  
  /*   Name       Lettter Type            Flag            Perms   Negate_Perm */
  FLAG flag_table[] = {
--- 68,74 ----
  int convert_flags _((dbref player, char *s, object_flag_type *p_mask,
  		     object_flag_type *p_toggle, object_flag_type *p_type));
  
! PTAB ptab_flag;
  
  /*   Name       Lettter Type            Flag            Perms   Negate_Perm */
  FLAG flag_table[] = {
***************
*** 110,116 ****
    {"ANSI", 'A', TYPE_PLAYER, PLAYER_ANSI, F_ANY, F_ANY},
  
    {"COLOR", 'C', TYPE_PLAYER, PLAYER_COLOR, F_ANY, F_ANY},
-   {"FORCE_WHITE", 'f', TYPE_PLAYER, PLAYER_FORCEWHITE, F_ANY, F_ANY},
  
    {"MONITOR", 'M', TYPE_PLAYER, PLAYER_MONITOR, F_ROYAL, F_ANY},
    {"NOSPOOF", 'N', TYPE_PLAYER, PLAYER_NOSPOOF, F_ANY | F_ODARK,
--- 106,111 ----
***************
*** 138,143 ****
--- 133,139 ----
     F_WIZARD | F_MDARK},
    {"PARANOID", 'p', TYPE_PLAYER, PLAYER_PARANOID, F_ANY | F_ODARK,
     F_ANY | F_ODARK},
+   {"NOACCENTS", '~', TYPE_PLAYER, PLAYER_NOACCENTS, F_ANY, F_ANY},
  
    {"MONITOR", 'M', TYPE_THING, THING_LISTEN, F_ANY, F_ANY},
    {"DESTROY_OK", 'd', TYPE_THING, THING_DEST_OK, F_ANY, F_ANY},
***************
*** 179,452 ****
  };
  
  static FLAG_ALIAS flag_alias_tab[] = {
-   {"CHOWN_O", "CHOWN_OK"},
-   {"CHOWN_", "CHOWN_OK"},
-   {"CHOWN", "CHOWN_OK"},
-   {"CHOW", "CHOWN_OK"},
-   {"CHO", "CHOWN_OK"},
-   {"CH", "CHOWN_OK"},
-   {"DAR", "DARK"},
-   {"DA", "DARK"},
-   {"GOIN", "GOING"},
-   {"GOI", "GOING"},
-   {"GO", "GOING"},
-   {"HAVE", "HAVEN"},
-   {"HAV", "HAVEN"},
    {"INHERIT", "TRUST"},
-   {"INHERI", "TRUST"},
-   {"INHER", "TRUST"},
-   {"INHE", "TRUST"},
-   {"INH", "TRUST"},
-   {"IN", "TRUST"},
-   {"I", "TRUST"},
-   {"TRUS", "TRUST"},
-   {"TRU", "TRUST"},
-   {"TR", "TRUST"},
-   {"T", "TRUST"},
-   {"LINK_O", "LINK_OK"},
-   {"LINK_", "LINK_OK"},
-   {"LINK", "LINK_OK"},
-   {"LIN", "LINK_OK"},
-   {"OPAQU", "OPAQUE"},
-   {"OPAQ", "OPAQUE"},
-   {"OPA", "OPAQUE"},
-   {"OP", "OPAQUE"},
-   {"O", "OPAQUE"},
-   {"QUIE", "QUIET"},
-   {"QUI", "QUIET"},
-   {"QU", "QUIET"},
-   {"Q", "QUIET"},
-   {"STICK", "STICKY"},
-   {"STIC", "STICKY"},
-   {"STI", "STICKY"},
-   {"ST", "STICKY"},
-   {"UNFINDABL", "UNFINDABLE"},
-   {"UNFINDABL", "UNFINDABLE"},
-   {"UNFINDAB", "UNFINDABLE"},
-   {"UNFINDA", "UNFINDABLE"},
-   {"UNFIND", "UNFINDABLE"},
-   {"UNFIN", "UNFINDABLE"},
-   {"UNFI", "UNFINDABLE"},
-   {"UNF", "UNFINDABLE"},
-   {"UN", "UNFINDABLE"},
-   {"U", "UNFINDABLE"},
-   {"VISUA", "VISUAL"},
-   {"VISU", "VISUAL"},
-   {"VIS", "VISUAL"},
-   {"VI", "VISUAL"},
-   {"WIZAR", "WIZARD"},
-   {"WIZA", "WIZARD"},
-   {"WIZ", "WIZARD"},
-   {"WI", "WIZARD"},
-   {"W", "WIZARD"},
-   {"SAF", "SAFE"},
-   {"SA", "SAFE"},
-   {"AUDIBL", "AUDIBLE"},
-   {"AUDIB", "AUDIBLE"},
-   {"AUDI", "AUDIBLE"},
-   {"AUD", "AUDIBLE"},
-   {"AU", "AUDIBLE"},
-   {"DEBU", "DEBUG"},
-   {"DEB", "DEBUG"},
    {"TRACE", "DEBUG"},
-   {"TRAC", "DEBUG"},
-   {"ENTER_O", "ENTER_OK"},
-   {"ENTER_", "ENTER_OK"},
-   {"ENTER", "ENTER_OK"},
-   {"ENTE", "ENTER_OK"},
-   {"ENT", "ENTER_OK"},
-   {"EN", "ENTER_OK"},
  #ifdef USE_WARNINGS
-   {"NO_WAR", "NO_WARN"},
-   {"NO_WA", "NO_WARN"},
-   {"NO_W", "NO_WARN"},
    {"NOWARN", "NO_WARN"},
-   {"NOWAR", "NO_WARN"},
-   {"NOWA", "NO_WARN"},
- #endif
-   {"HAL", "HALT"},
-   {"NO_COMMAN", "NO_COMMAND"},
-   {"NO_COMMA", "NO_COMMAND"},
-   {"NO_COMM", "NO_COMMAND"},
-   {"NO_COM", "NO_COMMAND"},
-   {"NO_CO", "NO_COMMAND"},
-   {"NO_C", "NO_COMMAND"},
- #ifdef ROYALTY_FLAG
-   {"ROYALT", "ROYALTY"},
-   {"ROYAL", "ROYALTY"},
-   {"ROYA", "ROYALTY"},
-   {"ROY", "ROYALTY"},
  #endif
!   {"TRANSPAREN", "TRANSPARENT"},
!   {"TRANSPARE", "TRANSPARENT"},
!   {"TRANSPAR", "TRANSPARENT"},
!   {"TRANSPA", "TRANSPARENT"},
!   {"TRANSP", "TRANSPARENT"},
!   {"TRANS", "TRANSPARENT"},
!   {"TRAN", "TRANSPARENT"},
!   {"TRA", "TRANSPARENT"},
!   {"TR", "TRANSPARENT"},
!   {"VERBOS", "VERBOSE"},
!   {"VERBO", "VERBOSE"},
!   {"VERB", "VERBOSE"},
!   {"VER", "VERBOSE"},
!   {"VE", "VERBOSE"},
!   {"ANS", "ANSI"},
!   {"AN", "ANSI"},
    {"LISTENER", "MONITOR"},
-   {"LISTENE", "MONITOR"},
-   {"LISTEN", "MONITOR"},
-   {"LISTE", "MONITOR"},
-   {"LIST", "MONITOR"},
-   {"LIS", "MONITOR"},
-   {"MONITO", "MONITOR"},
-   {"MONIT", "MONITOR"},
-   {"MONI", "MONITOR"},
-   {"MON", "MONITOR"},
-   {"MO", "MONITOR"},
    {"WATCHER", "MONITOR"},
-   {"WATCHE", "MONITOR"},
-   {"WATCH", "MONITOR"},
-   {"WATC", "MONITOR"},
-   {"WAT", "MONITOR"},
-   {"NOSPOO", "NOSPOOF"},
-   {"NOSPO", "NOSPOOF"},
-   {"NOSP", "NOSPOOF"},
-   {"NOS", "NOSPOOF"},
-   {"PARANOID", "PARANOID"},
-   {"PARANOI", "PARANOID"},
-   {"PARANO", "PARANOID"},
-   {"PARAN", "PARANOID"},
-   {"PARA", "PARANOID"},
-   {"PAR", "PARANOID"},
    {"ZONE", "SHARED"},
-   {"ZON", "SHARED"},
-   {"ZO", "SHARED"},
-   {"Z", "SHARED"},
-   {"CONNECTE", "CONNECTED"},
-   {"CONNECT", "CONNECTED"},
-   {"CONNEC", "CONNECTED"},
-   {"CONNE", "CONNECTED"},
-   {"CONN", "CONNECTED"},
-   {"CON", "CONNECTED"},
-   {"CO", "CONNECTED"},
-   {"GAG", "GAGGED"},
-   {"MYOPI", "MYOPIC"},
-   {"MYOP", "MYOPIC"},
-   {"MYO", "MYOPIC"},
-   {"MY", "MYOPIC"},
-   {"TERS", "TERSE"},
-   {"TER", "TERSE"},
    {"COLOUR", "COLOR"},
-   {"COLOU", "COLOR"},
-   {"COLO", "COLOR"},
-   {"COL", "COLOR"},
-   {"FORCEWHITE", "FORCE_WHITE"},
-   {"WHITE", "FORCE_WHITE"},
-   {"WHIT", "FORCE_WHITE"},
-   {"WHI", "FORCE_WHITE"},
-   {"WEIRDANSI", "FORCE_WHITE"},
  #ifdef JURY_OK
    {"JURYOK", "JURY_OK"},
-   {"JURY", "JURY_OK"},
-   {"JUR", "JURY_OK"},
-   {"JUDG", "JUDGE"},
-   {"JUD", "JUDGE"},
- #endif
- #ifdef FIXED_FLAG
-   {"FIXE", "FIXED"},
-   {"FIX", "FIXED"},
-   {"FI", "FIXED"},
- #endif
- #ifdef ONLINE_REG
-   {"UNREGISTER", "UNREGISTERED"},
-   {"UNREGIST", "UNREGISTERED"},
-   {"UNREGIS", "UNREGISTERED"},
-   {"UNREGI", "UNREGISTERED"},
-   {"UNREG", "UNREGISTERED"},
-   {"UNRE", "UNREGISTERED"},
-   {"UNR", "UNREGISTERED"},
  #endif
  #ifdef VACATION_FLAG
-   {"ON-VACATI", "ON-VACATION"},
-   {"ON-VACAT", "ON-VACATION"},
-   {"ON-VACA", "ON-VACATION"},
-   {"ON-VAC", "ON-VACATION"},
-   {"ON-VA", "ON-VACATION"},
-   {"ON-V", "ON-VACATION"},
    {"VACATION", "ON-VACATION"},
-   {"VACATIO", "ON-VACATION"},
-   {"VACATI", "ON-VACATION"},
-   {"VACAT", "ON-VACATION"},
-   {"VACA", "ON-VACATION"},
-   {"VAC", "ON-VACATION"},
  #endif
-   {"SUSPEC", "SUSPECT"},
-   {"SUSPE", "SUSPECT"},
-   {"SUSP", "SUSPECT"},
-   {"SUS", "SUSPECT"},
-   {"SU", "SUSPECT"},
    {"DEST_OK", "DESTROY_OK"},
-   {"DESTROY_O", "DESTROY_OK"},
-   {"DESTROY_", "DESTROY_OK"},
-   {"DESTROY", "DESTROY_OK"},
-   {"DESTRO", "DESTROY_OK"},
-   {"DESTR", "DESTROY_OK"},
-   {"DEST", "DESTROY_OK"},
-   {"DES", "DESTROY_OK"},
-   {"DE", "DESTROY_OK"},
-   {"PUPPE", "PUPPET"},
-   {"PUPP", "PUPPET"},
-   {"PUP", "PUPPET"},
-   {"PU", "PUPPET"},
-   {"P", "PUPPET"},
-   {"NO_LEAV", "NO_LEAVE"},
-   {"NO_LEA", "NO_LEAVE"},
-   {"NO_LE", "NO_LEAVE"},
-   {"NO_L", "NO_LEAVE"},
    {"NOLEAVE", "NO_LEAVE"},
-   {"NOLEAV", "NO_LEAVE"},
-   {"NOLEA", "NO_LEAVE"},
-   {"NOLE", "NO_LEAVE"},
-   {"NOL", "NO_LEAVE"},
-   {"ABOD", "ABODE"},
-   {"ABO", "ABODE"},
-   {"AB", "ABODE"},
-   {"FLOATIN", "FLOATING"},
-   {"FLOATI", "FLOATING"},
-   {"FLOAT", "FLOATING"},
-   {"FLOA", "FLOATING"},
-   {"FLO", "FLOATING"},
-   {"FL", "FLOATING"},
-   {"F", "FLOATING"},
-   {"JUMP_O", "JUMP_OK"},
-   {"JUMP_", "JUMP_OK"},
-   {"JUMP", "JUMP_OK"},
-   {"JUM", "JUMP_OK"},
-   {"JU", "JUMP_OK"},
-   {"J", "JUMP_OK"},
    {"TEL_OK", "JUMP_OK"},
    {"TELOK", "JUMP_OK"},
    {"TEL-OK", "JUMP_OK"},
-   {"NO_TE", "NO_TEL"},
-   {"NO_T", "NO_TEL"},
-   {"Z_TE", "Z_TEL"},
-   {"Z_T", "Z_TEL"},
- #ifdef UNINSPECTED_FLAG
-   {"UNINSPECT", "UNINSPECTED"},
-   {"UNINSPEC", "UNINSPECTED"},
-   {"UNINSPE", "UNINSPECTED"},
-   {"UNINSP", "UNINSPECTED"},
-   {"UNINS", "UNINSPECTED"},
-   {"UNIN", "UNINSPECTED"},
-   {"UNI", "UNINSPECTED"},
- #endif
-   {"LISTEN_PAREN", "LISTEN_PARENT"},
-   {"LISTEN_PARE", "LISTEN_PARENT"},
-   {"LISTEN_PAR", "LISTEN_PARENT"},
-   {"LISTEN_PA", "LISTEN_PARENT"},
-   {"LISTEN_P", "LISTEN_PARENT"},
-   {"LISTEN_", "LISTEN_PARENT"},
    {"^", "LISTEN_PARENT"},
  
    {NULL, NULL}
--- 175,201 ----
  };
  
  static FLAG_ALIAS flag_alias_tab[] = {
    {"INHERIT", "TRUST"},
    {"TRACE", "DEBUG"},
  #ifdef USE_WARNINGS
    {"NOWARN", "NO_WARN"},
  #endif
!   {"NOCOMMAND", "NO_COMMAND"},
    {"LISTENER", "MONITOR"},
    {"WATCHER", "MONITOR"},
    {"ZONE", "SHARED"},
    {"COLOUR", "COLOR"},
  #ifdef JURY_OK
    {"JURYOK", "JURY_OK"},
  #endif
  #ifdef VACATION_FLAG
    {"VACATION", "ON-VACATION"},
  #endif
    {"DEST_OK", "DESTROY_OK"},
    {"NOLEAVE", "NO_LEAVE"},
    {"TEL_OK", "JUMP_OK"},
    {"TELOK", "JUMP_OK"},
    {"TEL-OK", "JUMP_OK"},
    {"^", "LISTEN_PARENT"},
  
    {NULL, NULL}
***************
*** 501,512 ****
  
  
  static FLAG *
! flag_hash_lookup(name)
!     const char *name;
  {
    FLAG *t;
  
!   t = (FLAG *) hashfind(strupper(name), &htab_flag);
    if (t)
      return t;
  
--- 250,260 ----
  
  
  static FLAG *
! flag_hash_lookup(const char *name)
  {
    FLAG *t;
  
!   t = (FLAG *) ptab_find(&ptab_flag, name);
    if (t)
      return t;
  
***************
*** 518,551 ****
    return NULL;
  }
  
- static void
- flag_hash_insert(name, entry)
-     const char *name;
-     FLAG *entry;
- {
-   hashadd(name, (void *) entry, &htab_flag);
- }
- 
  void
! init_flag_hashtab()
  {
    FLAG *f;
    FLAG_ALIAS *a;
  
!   hashinit(&htab_flag, 256, sizeof(FLAG));
  
    /* do regular flags first */
    for (f = flag_table; f->name; f++)
!     flag_hash_insert(f->name, f);
  
    /* now add in the aliases */
    for (a = flag_alias_tab; a->alias; a++) {
!     if ((f = flag_hash_lookup(a->realname)) != NULL)
!       flag_hash_insert(a->alias, (FLAG *) f);
!     else
        do_rawlog(LT_ERR,
  		T("FLAG INIT: flag alias %s matches no known flag."), a->alias);
    }
  }
  
  /*---------------------------------------------------------------------------
--- 266,297 ----
    return NULL;
  }
  
  void
! init_flag_table()
  {
    FLAG *f;
    FLAG_ALIAS *a;
  
!   ptab_init(&ptab_flag);
  
    /* do regular flags first */
+   ptab_start_inserts(&ptab_flag);
    for (f = flag_table; f->name; f++)
!     ptab_insert(&ptab_flag, f->name, f);
  
    /* now add in the aliases */
    for (a = flag_alias_tab; a->alias; a++) {
!     for (f = flag_table; f->name; f++) {
!       if (strcmp(a->realname, f->name) == 0) {
! 	ptab_insert(&ptab_flag, a->alias, f);
! 	break;
!       }
!     }
!     if (!f)
        do_rawlog(LT_ERR,
  		T("FLAG INIT: flag alias %s matches no known flag."), a->alias);
    }
+   ptab_end_inserts(&ptab_flag);
  }
  
  /*---------------------------------------------------------------------------
*** 1_7_5.66/src/destroy.c Mon, 26 Nov 2001 17:23:06 -0600 dunemush (pennmush/c/24_destroy.c 1.24.2.2.1.5 660)
--- 1_7_5.96(w)/src/destroy.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/24_destroy.c 1.24.2.2.1.3.1.2 660)
***************
*** 347,353 ****
    case TYPE_PLAYER:
      /* wait until dbck */
      notify_format(player,
! 		  T("%s and all their objects are scheduled to be destroyed."),
  		  object_header(player, thing));
      break;
    case TYPE_THING:
--- 347,360 ----
    case TYPE_PLAYER:
      /* wait until dbck */
      notify_format(player,
! 		  (DESTROY_POSSESSIONS ?
! 		   (REALLY_SAFE ?
! 		    T
! 		    ("%s and all their (non-SAFE) objects are scheduled to be destroyed.")
! 		    :
! 		    T
! 		    ("%s and all their objects are scheduled to be destroyed."))
! 		   : T("%s is scheduled to be destroyed.")),
  		  object_header(player, thing));
      break;
    case TYPE_THING:
*** 1_7_5.66/src/db.c Thu, 24 Jan 2002 10:49:36 -0600 dunemush (pennmush/c/25_db.c 1.26.1.1.1.3 660)
--- 1_7_5.96(w)/src/db.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/25_db.c 1.26.1.1.1.1.1.2 660)
***************
*** 141,147 ****
  	db_size *= 2;
        if ((newdb = (struct object *)
  	   realloc(db, db_size * sizeof(struct object))) == NULL) {
! 	do_rawlog(LT_ERR, "ERROR: out of memory wile extending database!");
  	abort();
        }
        db = newdb;
--- 141,147 ----
  	db_size *= 2;
        if ((newdb = (struct object *)
  	   realloc(db, db_size * sizeof(struct object))) == NULL) {
! 	do_rawlog(LT_ERR, "ERROR: out of memory while extending database!");
  	abort();
        }
        db = newdb;
*** 1_7_5.66/src/command.c Tue, 20 Nov 2001 17:08:09 -0600 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.4 660)
--- 1_7_5.96(w)/src/command.c Fri, 15 Feb 2002 16:53:15 -0600 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.2.1.3 660)
***************
*** 7,17 ****
  #include "copyrite.h"
  #include "config.h"
  
- #ifdef I_STRING
  #include <string.h>
- #else
- #include <strings.h>
- #endif
  
  #include "conf.h"
  #include "dbdefs.h"
--- 7,13 ----
***************
*** 28,33 ****
--- 24,30 ----
  #include "parse.h"
  #include "access.h"
  #include "version.h"
+ #include "ptab.h"
  #include "htab.h"
  #include "function.h"
  #include "command.h"
***************
*** 37,48 ****
  #include "cmds.h"
  #include "confmagic.h"
  
! HASHTAB htab_command;
  HASHTAB htab_reserved_aliases;
  
! static char *command_isattr _((char *command));
! static int command_check _((dbref player, COMMAND_INFO *cmd));
! static int switch_find _((COMMAND_INFO *cmd, char *sw));
  extern int global_fun_invocations;
  extern int global_fun_recursions;
  
--- 34,45 ----
  #include "cmds.h"
  #include "confmagic.h"
  
! PTAB ptab_command;
  HASHTAB htab_reserved_aliases;
  
! static char *command_isattr(char *command);
! static int command_check(dbref player, COMMAND_INFO *cmd);
! static int switch_find(COMMAND_INFO *cmd, char *sw);
  extern int global_fun_invocations;
  extern int global_fun_recursions;
  
***************
*** 221,227 ****
     0},
    {"@SHUTDOWN", "PANIC REBOOT PARANOID", cmd_shutdown, CMD_T_ANY, WIZARD,
     0, 0},
!   {"@SITELOCK", "BAN REGISTER NAME", cmd_sitelock,
     CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, WIZARD, 0, 0},
    {"@STATS", "TABLES", cmd_stats, CMD_T_ANY, 0, 0, 0},
  
--- 218,224 ----
     0},
    {"@SHUTDOWN", "PANIC REBOOT PARANOID", cmd_shutdown, CMD_T_ANY, WIZARD,
     0, 0},
!   {"@SITELOCK", "BAN REGISTER REMOVE NAME", cmd_sitelock,
     CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, WIZARD, 0, 0},
    {"@STATS", "TABLES", cmd_stats, CMD_T_ANY, 0, 0, 0},
  
***************
*** 356,372 ****
    {NULL, NULL}
  };
  
- static char nullstring[] = "";
- 
- 
  void
! strccat(to, from)
!     char *to;
!     const char *from;
  {
!   if (*to)
!     strcat(to, ", ");
!   strcat(to, from);
  }
  
  static int
--- 353,364 ----
    {NULL, NULL}
  };
  
  void
! strccat(char *buff, char **bp, const char *from)
  {
!   if (*buff)
!     safe_str(", ", buff, bp);
!   safe_str(from, buff, bp);
  }
  
  static int
***************
*** 401,408 ****
  }
  
  COMMAND_INFO *
! command_add(const char *name, int type, int flags, int toggles, int powers,
! 	    switch_mask *sw, command_func func)
  {
    COMMAND_INFO *cmd;
    cmd = (COMMAND_INFO *) mush_malloc(sizeof(COMMAND_INFO), "command");
--- 393,400 ----
  }
  
  COMMAND_INFO *
! make_command(const char *name, int type, int flags, int toggles, int powers,
! 	     switch_mask *sw, command_func func)
  {
    COMMAND_INFO *cmd;
    cmd = (COMMAND_INFO *) mush_malloc(sizeof(COMMAND_INFO), "command");
***************
*** 417,436 ****
      memcpy(cmd->sw, sw, sizeof(switch_mask));
    else
      SW_ZERO(cmd->sw);
-   hashadd(name, (void *) cmd, &htab_command);
    return cmd;
  }
  
  COMMAND_INFO *
! command_find(name)
!     const char *name;
  {
    char cmdname[BUFFER_LEN];
    strcpy(cmdname, name);
    upcasestr(cmdname);
!   return (COMMAND_INFO *) hashfind(cmdname, &htab_command);
  }
  
  COMMAND_INFO *
  command_modify(const char *name, int type, int flags, int toggles, int powers,
  	       switch_mask *sw, command_func func)
--- 409,455 ----
      memcpy(cmd->sw, sw, sizeof(switch_mask));
    else
      SW_ZERO(cmd->sw);
    return cmd;
  }
  
  COMMAND_INFO *
! command_add(const char *name, int type, int flags, int toggles, int powers,
! 	    switch_mask *sw, command_func func)
! {
! 
!   ptab_start_inserts(&ptab_command);
!   ptab_insert(&ptab_command, name,
! 	      make_command(name, type, flags, toggles, powers, sw, func));
!   ptab_end_inserts(&ptab_command);
!   return command_find(name);
! }
! 
! 
! COMMAND_INFO *
! command_find(const char *name)
! {
! 
!   char cmdname[BUFFER_LEN];
!   strcpy(cmdname, name);
!   upcasestr(cmdname);
!   if (hash_find(&htab_reserved_aliases, cmdname))
!     return NULL;
!   return (COMMAND_INFO *) ptab_find(&ptab_command, cmdname);
! }
! 
! COMMAND_INFO *
! command_find_exact(const char *name)
  {
+ 
    char cmdname[BUFFER_LEN];
    strcpy(cmdname, name);
    upcasestr(cmdname);
!   if (hash_find(&htab_reserved_aliases, cmdname))
!     return NULL;
!   return (COMMAND_INFO *) ptab_find_exact(&ptab_command, cmdname);
  }
  
+ 
  COMMAND_INFO *
  command_modify(const char *name, int type, int flags, int toggles, int powers,
  	       switch_mask *sw, command_func func)
***************
*** 495,634 ****
      return;
    done = 1;
  
!   hashinit(&htab_command, 512, sizeof(COMMAND_INFO));
    hashinit(&htab_reserved_aliases, 16, sizeof(COMMAND_INFO));
    for (cmd = commands; cmd->name; cmd++) {
!     command_add(cmd->name, cmd->type, cmd->flags, cmd->toggles,
! 		cmd->powers, switchmask(cmd->switches), cmd->func);
    }
! 
!   reserve_aliases();
    local_commands();
  }
  
  void
  command_init_postconfig()
  {
-   command_mkalias();
    if (HATE_DEST)
      restrict_command("@DESTROY", "noplayer");
    if (!PLAYER_LOCATE)
      restrict_command("@WHEREIS", "nobody");
  }
  
- 
- void
- command_addalias(cmd, prev, next)
-     COMMAND_INFO *cmd;
-     char *prev;
-     char *next;
- {
-   int i;
-   char buff[BUFFER_LEN];
-   if (!prev)
-     prev = nullstring;
-   if (!next)
-     next = nullstring;
-   strcpy(buff, cmd->name);
-   for (i = strlen(buff) - 1;
-        (i > 1) && strncmp(buff, prev, i) && strncmp(buff, next, i); i--) {
-     buff[i] = '\0';
-     if (!hashfind(buff, &htab_reserved_aliases))
-       hashadd(buff, (void *) cmd, &htab_command);
-   }
- }
- 
  /* Given a command name and an alias for it, install the alias */
  int
! alias_command(command, alias)
!     const char *command;
!     const char *alias;
  {
    COMMAND_INFO *cmd;
  
    /* Make sure the alias doesn't exit already */
!   if (command_find(alias))
      return 0;
  
    /* Look up the original */
!   cmd = command_find(command);
    if (!cmd)
      return 0;
  
!   if ((cmd = command_add(strdup(strupper(alias)), cmd->type, cmd->flags,
! 			 cmd->toggles, cmd->powers, &cmd->sw, cmd->func))) {
!     command_addalias(cmd, NULL, NULL);
!     return 1;
!   } else {
!     return 0;
!   }
! }
! 
! void
! command_mkalias()
! {
!   COMMAND_INFO *cmd;
!   COMSORTSTRUC *first, *this, *newone;
!   COMALIAS *alias;
!   char *pname;
! 
!   /* Hash all the built-in aliases first, so they don't get 
!    * overridden by autoaliases
!    */
!   for (alias = command_alias; alias->name; alias++) {
!     cmd = (COMMAND_INFO *) command_find(alias->name);
!     if (!cmd) {
!       do_rawlog(LT_ERR, T("ALIAS : %s for nonexistant command %s"),
! 		alias->alias, alias->name);
!     } else {
!       if (!hashfind(alias->alias, &htab_reserved_aliases))
! 	hashadd(alias->alias, (void *) cmd, &htab_command);
!     }
!   }
! 
!   /* Go through the hash table and construct a sorted linked list of
!    * command names.
!    */
!   first = NULL;
!   cmd = (COMMAND_INFO *) hash_firstentry(&htab_command);
!   while (cmd) {
!     if (!(cmd->type & CMD_T_INTERNAL)) {
!       this = first;
!       /* Find the name after which this one should be inserted */
!       while ((this) && (this->cmd != cmd) && (this->next)
! 	     && (strcoll(this->next->cmd->name, cmd->name) <= 0))
! 	this = this->next;
!       if (!(this && (this->cmd == cmd))) {
! 	newone =
! 	  (COMSORTSTRUC *) mush_malloc(sizeof(COMSORTSTRUC), "comsortstruc");
! 	newone->cmd = cmd;
! 	if (this && (this != first)) {
! 	  newone->next = this->next;
! 	  this->next = newone;
! 	} else {
! 	  newone->next = first;
! 	  first = newone;
! 	}
!       }
!     }
!     cmd = (COMMAND_INFO *) hash_nextentry(&htab_command);
!   }
! 
!   /* Run through our sorted linked list, passing each entry, and those
!    * immediately before and after, if any, so it can make unique
!    * abbreviations into aliases
!    */
!   pname = NULL;
!   this = first;
!   while (this) {
!     command_addalias(this->cmd, pname,
! 		     (char *) ((this->next) ? this->next->cmd->name : NULL));
!     newone = this;
!     pname = (char *) this->cmd->name;
!     this = this->next;
!     mush_free(newone, "comsortstruc");
!   }
! 
  }
  
  /* Real work. Parse the command arguments into arrays */
--- 514,561 ----
      return;
    done = 1;
  
!   ptab_init(&ptab_command);
    hashinit(&htab_reserved_aliases, 16, sizeof(COMMAND_INFO));
+   reserve_aliases();
+   ptab_start_inserts(&ptab_command);
    for (cmd = commands; cmd->name; cmd++) {
!     ptab_insert(&ptab_command, cmd->name,
! 		make_command(cmd->name, cmd->type, cmd->flags, cmd->toggles,
! 			     cmd->powers, switchmask(cmd->switches),
! 			     cmd->func));
    }
!   ptab_end_inserts(&ptab_command);
    local_commands();
  }
  
  void
  command_init_postconfig()
  {
    if (HATE_DEST)
      restrict_command("@DESTROY", "noplayer");
    if (!PLAYER_LOCATE)
      restrict_command("@WHEREIS", "nobody");
  }
  
  /* Given a command name and an alias for it, install the alias */
  int
! alias_command(const char *command, const char *alias)
  {
    COMMAND_INFO *cmd;
  
    /* Make sure the alias doesn't exit already */
!   if (command_find_exact(alias))
      return 0;
  
    /* Look up the original */
!   cmd = command_find_exact(command);
    if (!cmd)
      return 0;
  
!   ptab_start_inserts(&ptab_command);
!   ptab_insert(&ptab_command, strupper(alias), cmd);
!   ptab_end_inserts(&ptab_command);
!   return 1;
  }
  
  /* Real work. Parse the command arguments into arrays */
***************
*** 654,660 ****
    if (parse || forcenoparse)
      parse = PE_NOTHING;
    else
!     parse = PE_DEFAULT;
  
    if (right_side)
      split = PT_NOTHING;
--- 581,587 ----
    if (parse || forcenoparse)
      parse = PE_NOTHING;
    else
!     parse = PE_DEFAULT | PE_COMMAND_BRACES;
  
    if (right_side)
      split = PT_NOTHING;
***************
*** 674,680 ****
    }
  
    if ((parse == PE_NOTHING) && args)
!     parse = PE_STRIP_BRACES;
  
    i = 1;
    done = 0;
--- 601,607 ----
    }
  
    if ((parse == PE_NOTHING) && args)
!     parse = PE_COMMAND_BRACES;
  
    i = 1;
    done = 0;
***************
*** 847,854 ****
      c = command;
      while (*p == ' ')
        p++;
!     process_expression(command, &c, (const char **) &p, player, cause,
! 		       cause, PE_DEFAULT & ~PE_FUNCTION_CHECK, PT_SPACE, NULL);
      *c = '\0';
      strcpy(commandraw, command);
      upcasestr(command);
--- 774,782 ----
      c = command;
      while (*p == ' ')
        p++;
!     process_expression(command, &c, (const char **) &p, player, cause, cause,
! 		       (PE_DEFAULT & ~PE_FUNCTION_CHECK) | PE_COMMAND_BRACES,
! 		       PT_SPACE, NULL);
      *c = '\0';
      strcpy(commandraw, command);
      upcasestr(command);
***************
*** 909,916 ****
  	p++;
        }
        process_expression(commandraw, &c, (const char **) &p, player, cause,
! 			 cause, PE_DEFAULT & ~PE_FUNCTION_CHECK, PT_DEFAULT,
! 			 NULL);
      }
      *c = '\0';
      mush_free((Malloc_t) command, "string");
--- 837,845 ----
  	p++;
        }
        process_expression(commandraw, &c, (const char **) &p, player, cause,
! 			 cause,
! 			 (PE_DEFAULT & ~PE_FUNCTION_CHECK) | PE_COMMAND_BRACES,
! 			 PT_DEFAULT, NULL);
      }
      *c = '\0';
      mush_free((Malloc_t) command, "string");
***************
*** 1076,1081 ****
--- 1005,1011 ----
    COMMAND_INFO *command;
    SWITCH_VALUE *sw_val;
    char buff[BUFFER_LEN];
+   char *bp = buff;
  
    if (!arg_left[0]) {
      notify(player, T("You must specify a command."));
***************
*** 1112,1178 ****
  		  "Name       : %s (%s)", command->name,
  		  (command->type & CMD_T_DISABLED) ? "Disabled" : "Enabled");
      if ((command->type & CMD_T_ANY) == CMD_T_ANY)
!       strcpy(buff, "Any");
      else {
        buff[0] = '\0';
        if (command->type & CMD_T_ROOM)
! 	strccat(buff, "Room");
        if (command->type & CMD_T_THING)
! 	strccat(buff, "Thing");
        if (command->type & CMD_T_EXIT)
! 	strccat(buff, "Exit");
        if (command->type & CMD_T_PLAYER)
! 	strccat(buff, "Player");
      }
      notify_format(player, "Types      : %s", buff);
      buff[0] = '\0';
      if (command->type & CMD_T_SWITCHES)
!       strccat(buff, "Switches");
      if (command->type & CMD_T_NOGAGGED)
!       strccat(buff, "Nogag");
      if (command->type & CMD_T_NOFIXED)
!       strccat(buff, "Nofix");
      if (command->type & CMD_T_NOGUEST)
!       strccat(buff, "Noguest");
      if (command->type & CMD_T_EQSPLIT)
!       strccat(buff, "Eqsplit");
      if (command->type & CMD_T_GOD)
!       strccat(buff, "God");
      if ((command->flags & (ROYALTY | WIZARD)) == (ROYALTY | WIZARD))
!       strccat(buff, "Admin");
      else if (command->flags & ROYALTY)
!       strccat(buff, "Royalty");
      else if (command->flags & WIZARD)
!       strccat(buff, "Wizard");
! 
      notify_format(player, "Flags      : %s", buff);
      buff[0] = '\0';
      for (sw_val = switch_list; sw_val->name; sw_val++)
        if (SW_ISSET(command->sw, sw_val->value))
! 	strccat(buff, sw_val->name);
      notify_format(player, "Switches   : %s", buff);
      buff[0] = '\0';
      if (command->type & CMD_T_LS_ARGS) {
        if (command->type & CMD_T_LS_SPACE)
! 	strccat(buff, "Space-Args");
        else
! 	strccat(buff, "Args");
      }
      if (command->type & CMD_T_LS_NOPARSE)
!       strccat(buff, "Noparse");
      if (command->type & CMD_T_EQSPLIT) {
        notify_format(player, "Leftside   : %s", buff);
        buff[0] = '\0';
        if (command->type & CMD_T_RS_ARGS) {
  	if (command->type & CMD_T_RS_SPACE)
! 	  strccat(buff, "Space-Args");
  	else
! 	  strccat(buff, "Args");
        }
        if (command->type & CMD_T_RS_NOPARSE)
! 	strccat(buff, "Noparse");
        notify_format(player, "Rightside  : %s", buff);
      } else {
        notify_format(player, "Arguments  : %s", buff);
      }
    }
--- 1042,1117 ----
  		  "Name       : %s (%s)", command->name,
  		  (command->type & CMD_T_DISABLED) ? "Disabled" : "Enabled");
      if ((command->type & CMD_T_ANY) == CMD_T_ANY)
!       safe_strl("Any", 3, buff, &bp);
      else {
        buff[0] = '\0';
        if (command->type & CMD_T_ROOM)
! 	strccat(buff, &bp, "Room");
        if (command->type & CMD_T_THING)
! 	strccat(buff, &bp, "Thing");
        if (command->type & CMD_T_EXIT)
! 	strccat(buff, &bp, "Exit");
        if (command->type & CMD_T_PLAYER)
! 	strccat(buff, &bp, "Player");
      }
+     *bp = '\0';
      notify_format(player, "Types      : %s", buff);
      buff[0] = '\0';
+     bp = buff;
      if (command->type & CMD_T_SWITCHES)
!       strccat(buff, &bp, "Switches");
      if (command->type & CMD_T_NOGAGGED)
!       strccat(buff, &bp, "Nogag");
      if (command->type & CMD_T_NOFIXED)
!       strccat(buff, &bp, "Nofix");
      if (command->type & CMD_T_NOGUEST)
!       strccat(buff, &bp, "Noguest");
      if (command->type & CMD_T_EQSPLIT)
!       strccat(buff, &bp, "Eqsplit");
      if (command->type & CMD_T_GOD)
!       strccat(buff, &bp, "God");
      if ((command->flags & (ROYALTY | WIZARD)) == (ROYALTY | WIZARD))
!       strccat(buff, &bp, "Admin");
      else if (command->flags & ROYALTY)
!       strccat(buff, &bp, "Royalty");
      else if (command->flags & WIZARD)
!       strccat(buff, &bp, "Wizard");
!     *bp = '\0';
      notify_format(player, "Flags      : %s", buff);
      buff[0] = '\0';
+     bp = buff;
      for (sw_val = switch_list; sw_val->name; sw_val++)
        if (SW_ISSET(command->sw, sw_val->value))
! 	strccat(buff, &bp, sw_val->name);
!     *bp = '\0';
      notify_format(player, "Switches   : %s", buff);
      buff[0] = '\0';
+     bp = buff;
      if (command->type & CMD_T_LS_ARGS) {
        if (command->type & CMD_T_LS_SPACE)
! 	strccat(buff, &bp, "Space-Args");
        else
! 	strccat(buff, &bp, "Args");
      }
      if (command->type & CMD_T_LS_NOPARSE)
!       strccat(buff, &bp, "Noparse");
      if (command->type & CMD_T_EQSPLIT) {
+       *bp = '\0';
        notify_format(player, "Leftside   : %s", buff);
        buff[0] = '\0';
+       bp = buff;
        if (command->type & CMD_T_RS_ARGS) {
  	if (command->type & CMD_T_RS_SPACE)
! 	  strccat(buff, &bp, "Space-Args");
  	else
! 	  strccat(buff, &bp, "Args");
        }
        if (command->type & CMD_T_RS_NOPARSE)
! 	strccat(buff, &bp, "Noparse");
!       *bp = '\0';
        notify_format(player, "Rightside  : %s", buff);
      } else {
+       *bp = '\0';
        notify_format(player, "Arguments  : %s", buff);
      }
    }
***************
*** 1191,1214 ****
  list_commands()
  {
    COMMAND_INFO *command;
!   char *ptrs[BUFFER_LEN / 2];
    static char buff[BUFFER_LEN];
    char *bp;
    int nptrs = 0, i;
!   command = (COMMAND_INFO *) hash_firstentry(&htab_command);
!   while (command) {
!     if (!(command->type & CMD_T_LISTED)) {
!       ptrs[nptrs++] = (char *) command->name;
!       command->type |= CMD_T_LISTED;
!     }
!     command = (COMMAND_INFO *) hash_nextentry(&htab_command);
!   }
!   command = (COMMAND_INFO *) hash_firstentry(&htab_command);
    while (command) {
!     command->type &= ~CMD_T_LISTED;
!     command = (COMMAND_INFO *) hash_nextentry(&htab_command);
    }
-   do_gensort(ptrs, nptrs, 0);
    bp = buff;
    safe_str(ptrs[0], buff, &bp);
    for (i = 1; i < nptrs; i++) {
--- 1130,1145 ----
  list_commands()
  {
    COMMAND_INFO *command;
!   const char *ptrs[BUFFER_LEN / 2];
    static char buff[BUFFER_LEN];
    char *bp;
    int nptrs = 0, i;
!   command = (COMMAND_INFO *) ptab_firstentry(&ptab_command);
    while (command) {
!     ptrs[nptrs] = command->name;
!     nptrs++;
!     command = (COMMAND_INFO *) ptab_nextentry(&ptab_command);
    }
    bp = buff;
    safe_str(ptrs[0], buff, &bp);
    for (i = 1; i < nptrs; i++) {
*** 1_7_5.66/src/cmds.c Thu, 22 Nov 2001 15:42:40 -0600 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.4 660)
--- 1_7_5.96(w)/src/cmds.c Fri, 15 Feb 2002 16:53:14 -0600 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.5 660)
***************
*** 758,763 ****
--- 758,765 ----
      do_sitelock(player, arg_left, NULL, NULL, 0);
    else if (SW_ISSET(sw, SWITCH_NAME))
      do_sitelock(player, arg_left, NULL, NULL, 2);
+   else if (SW_ISSET(sw, SWITCH_REMOVE))
+     do_sitelock(player, arg_left, NULL, NULL, 3);
    else
      do_sitelock(player, arg_left, args_right[1], args_right[2], 0);
  }
*** 1_7_5.66/src/bsd.c Sun, 06 Jan 2002 20:56:21 -0600 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.3 660)
--- 1_7_5.96(w)/src/bsd.c Fri, 15 Feb 2002 16:53:14 -0600 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.16 660)
***************
*** 121,130 ****
  #include "game.h"
  #include "confmagic.h"
  
- /* Define to enable experimental conversion of accented characters to
-    HTML entities for Pueblo. Meant for European character sets */
- #define PUEBLO_TRANSLATE
- 
  /* BSD 4.2 and maybe some others need these defined */
  #ifndef FD_ZERO
  #define fd_set int
--- 121,126 ----
***************
*** 174,179 ****
--- 170,184 ----
    struct text_block **tail;
  };
  
+ #define CONN_DEFAULT 0
+ /* Using Pueblo, Smial, Mushclient, Simplemu, or some other
+  *  pueblo-style HTML aware client */
+ #define CONN_HTML 0x1
+ /* Using a client that understands telnet options */
+ #define CONN_TELNET 0x2
+ /* Send a telnet option to test client */
+ #define CONN_TELNET_QUERY 0x4
+ 
  struct descriptor_data {
    int descriptor;
    int connected;
***************
*** 208,218 ****
  #ifdef USE_MAILER
    struct mail *mailp;
  #endif
!   int pueblo;
    unsigned long input_chars;
    unsigned long output_chars;
  };
  
  #define DESC_ITER_CONN(d) \
          for(d = descriptor_list;(d);d=(d)->next) \
            if((d)->connected)
--- 213,260 ----
  #ifdef USE_MAILER
    struct mail *mailp;
  #endif
!   int conn_flags;
    unsigned long input_chars;
    unsigned long output_chars;
  };
  
+ 
+ /* 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 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 SGA 3			/* Suppress go-ahead */
+ #define LINEMODE 34
+ /*  IAC DO LINEMODE */
+ #define TELNET_QUERY "\xFF\xFD\x22\r\n"
+ /* IAC SB LINEMODE MODE (EDIT|SOFT_TAB) IAC SE */
+ #define SET_LINEMODE "\xFF\xFA\x22\x01\x09\xFF\xF0\r\n"
+ void test_telnet(DESC *d);
+ 
  #define DESC_ITER_CONN(d) \
          for(d = descriptor_list;(d);d=(d)->next) \
            if((d)->connected)
***************
*** 255,265 ****
    "**********************************************************************";
  #define REBOOTFILE              "reboot.db"
  
- #ifdef PUEBLO_TRANSLATE
- static void init_pueblo_trans _((void));
- static const char *pueblo_table[UCHAR_MAX + 1];
- #endif
- 
  #if 0
  /* For translation */
  static void dummy_msgs _((void));
--- 297,302 ----
***************
*** 344,358 ****
  DESC *initializesock _((int s, char *addr, char *ip));
  struct text_block *make_text_block _((const char *s, int n));
  void free_text_block _((struct text_block * t));
! void add_to_queue _((struct text_queue * q, const char *b, int n));
! int flush_queue _((struct text_queue * q, int n));
! int queue_write _((DESC *d, const char *b, int n));
! int queue_newwrite _((DESC *d, const char *b, int n));
! int queue_string _((DESC *d, const char *s));
! static int queue_string_eol _((DESC *d, const char *s));
  int process_output _((DESC *d));
  void freeqs _((DESC *d));
! void welcome_user _((DESC *d));
  static void dump_info _((DESC *call_by));
  void save_command