TinyMUX 2.1:  CHANGES
Last Update:  December 2003

Major changes that may affect performance and require softcode tweaks:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 -- Signals SIGTERM and SIGUSR2 have been swapped. SIGTERM now performs a
    @shutdown, and SIGUSR2 drops a .SIG flatfile.
 -- Removed support for VMS, for the port concentrator.
 -- Removed support for many older mail, comsys, and flatfile formats
    related to Pern, MUD, MUSH, and Penn.
 -- dbconvert now only support three options: Load, Unload, and Check.
 -- It became necessary to move the flag letters for WOD_REALMS into
    the '0' to '9' range. Flatfiles are still compatible, but softcode
    that uses orflags(), andflags(), and flags() could be affected.
    

Feature Additions:
~~~~~~~~~~~~~~~~~
 -- Support and favor %x ANSI substitutions over %c ANSI substitutions,
    but both are recognized.
 -- Changed PORTS() function to allow a player to get their own port number.
 -- Evaluating comtitles.
 -- comtitle/on and comtitle/off.
 -- LASTIP saves the numerical IP address from the players connection.
 -- @wait/until allows one to give an absolute time stamp.
 -- @wait and @wait/until support fractional seconds (eg. @wait 1.5=<cmd>).
 -- Added command access for UNINSPECTED and NO_UNINSPECTED.
 -- Added %m for 'lastcommand'. Equivalent to %c in MUSH.
 -- Exits can be teleported from room to room instead of taken and dropped.
 -- Added generalized article guessing (see art() and article_rule).
 -- Support 36 global registers instead of 10.
 -- Add TIMEFMT() function.
 -- Added null() and @@(). The former evaluates. The latter doesn't.
 -- Added GetFromLock. Patch from Draken-Korin.
 -- Added autozone configuration option (Bug #194 and Bug #635).
 -- Add CREATED attribute (Bug #555 and #608). Patch from Jake.
 -- Added /instant switch to @destroy. Patch from Jake.
 -- Added ability to turn off automatic execution of STARTUP attributes from
    the configuration file. Patch from Jake.
 -- Added safe_wipe configuration option. If enabled, @wipe will not wipe
    SAFE-marked objects. Patch from Jake.
 -- Added destroy_going_now configuration option. If enabled, a second
    @destroy request causes the object to be destroyed immediately.
    Added to provide compatibility with PennMUSH. Patch from Jake.
 -- Win32 builds running on NT are now able to catch the WM_CLOSE messages
    and @shutdown the server cleanly. Running on Win9x does not have this
    ability, yet.
 -- Attributes are now output in numeric order. With this, it is now
    possible to make reasonable-sized patches between two flatfiles.
 -- Added MEMORY_ACCOUNTING routines that match malloc/free calls, detect
    memory leaks, account for which lines of code are allocating and
    deallocating memory, validating the malloc/free protocol itself. It does
    not catch memory overwrites.
 -- Changed message for @chown to give enough information to a builder to
    check their work. It's something of an audit trail.
 -- Added optional output delimeter to SORT(). Patch from Ashen-Shugar.
 -- Enhanced Page command.
 -- Roy Anger's comsys help update.
 -- Reformated wizhelp.txt
 -- Freshened help for @aconnect and @disconnect.
 -- Support second argument for squish().
 -- attrcnt() function from Jake.
 -- ctime() function from Jake.
 -- Added ability for the server to listen to multiple ports and for changes
    to the 'port' config to take affect across a @restart.
 -- Will now accept '@set FooBar=COMMANDS' and '@set FooBar=!COMMANDS'. BLEED
    and SPOOF also added. 'hasflag(FooBar,COMMANDS)' also supported.
 -- Added LOCALIZE().
 -- Added function invocation limit checking for various loop functions:
    ITER, PARSE, MIX, FILTER, FOLD, MAP, etc.
 -- Clean cygwin builds on Win32 with support for @restart.
 -- Remove support for the COMPRESS flag.
 -- Added softcode config() from TM3.
 -- With regard to comalias(), wizards can still get the comalias for anyone.
    Players and objects can still check for themselves. Objects that Inherit
    can now check for their owners.
 -- Added #$ substitution for switch() and @switch.
 -- Added ilev() for nesting level of iter() and list().
 -- Added ISO8601 year and week ($g, $G, and $V codes) to timefmt.
 -- conn() and idle() accept '*' before the playername.
 -- hasflag() provides flag information on attribute values. From TM3.
 -- Allow GOD and WIZARD players to view logindata. From TM3.
 -- Added itemize() function.
 -- Changes for DEC Alpha Linux and IA64.
 -- Added optional second parameter to indicate the angle units (Radians,
    Degrees, and Gradians) to trigometric functions: sin(), cos(), tan(),
    asin(), acos(), and atan(). Idea from Raevnos.
 -- Floating-point numbers are no longer limited to 6 decimal digits. The full
    range of floating-point numbers is available. At the same time, however,
    the server still uses only the minimal number of decimal digits needed to
    represent the same double value internally.
 -- Expanded ROUND() function to round in any position left or right of the
    decimal point.
 -- Added HASQUOTA(). Patch from Jake.
 -- Added @list guests which tracks guest characters. Zenty patch. Rhost idea.
 -- Added SITEMON flag to track connections and disconnections from site.
    Patch from Zenty.
 -- Added MARKER0 through MARKER9 flagnames. They are accessible as flag
    letters '0' through '9' when WOD_REALMS is not defined, but only by name
    if WOD_REALMS is defined.
 -- Added BLIND flag to control * has entered, * has left emits.
 -- New objects are now allocated from the lowest available dbref instead of
    the highest.
 -- Lists of floating-point numbers (ADD, LADD, and SUB) are added  much
    more precisely.
 -- Updated Mersenne Twister Random Number code to a later version.
 -- Bug #799 - Update lcmds() to handle spaced commands and ^-listens.
 -- Add isint() and israt().
 -- Improve auto-detection of list type. Affects sort().
 -- Added optional second argument to cwho() to control which dbrefs to
    return.
 -- @list user_attributes now supports a wildcard pattern to control
    which user-defined attributes are reported.
 -- Allow '~' as the first character of an attribute name.
 -- VALID() now supports attrname and playername tests. Idea from PennMUSH.
 -- Allow some aspects of the DARK flag to be delegated to players as
    controlled by the hide and can_see powers. auto-DARK is still only
    performed for Wizards. Idea from TinyMUSH 3.0.
 -- Allow #1 to @newpassword herself if it's missing. Idea from Ian.
 -- Backpatch more descriptive messages for two zone functions from MUX 2.2.
 -- Added KEEPALIVE flag which, if set, periodically causes a TELNET NOP to
    be sent to the client.  Idea and patch from Soruk.  This is not the same
    as the TCP/IP option by the same name.
 -- Support sort(-1.05:abc -1.1:def,f).  The previous example is not
    auto-detected as floating-point number, and this is by design.  However,
    if floating-point is selected explicitly, it will sort by the
    floating-point prefix.
 -- Enhance validation of exit names. Each segment of an exit name must be
    a valid object name on its own. Also, ANSI is only allowed in the first
    segment. ANSI color in other parts of the name is stripped.


Bug Fixes:
~~~~~~~~~
 -- inet_addr() re-write to handle netmask of 255.255.255.255 and Berkeley
    a, a.b, and a.b.c numeric IP formats.
 -- article_rule wasn't parsed correctly, and art() always returned 'a'.
 -- @cboot would SIGSEGV on @cset/anon channels.
 -- Documented comtitle/{on,off}.
 -- Typo bug in RADIX_COMPRESSION build.
 -- Short version string contained 'Alpha' instead of 'Beta'.
 -- Several semaphores waiting on the same object/attr could be @notified
    out of order.
 -- Channel messages are considered OOC.
 -- Bug #662 - SIGSEGV in @dbck.
 -- Bug #618 - Logic in new_home enables being inside a garbage object.
 -- Bug #424 - Linking deposit refund. Patch from Jake.
 -- Bug #585 - Parent isn't cleared during @destroy process. Patch from Jake.
 -- Bug #765 - whispering to objects with ears should still be allowed.
 -- Document safer_passwords configuration option.
 -- Bug #602 - fun_ansi reaches backwards into the buffer.
 -- Bug #391 - WIZARD player could set attributes on garbage objects.
 -- Fixed SIZEOF__LONG typo in code that would be very unlikely to affect any
    platform.
 -- Added optional 4th argument (indent) to COLUMNS().
 -- Removed unintialized have_macros config option. Could have been an
    issue if you were running a non-DEBUG build and wanted to disable the
    comsys.
 -- Fixed SIGBUS issue on Solaris. This was not an issue for MUX 2.0.
    Thanks to nails for providing a Solaris test account.
 -- Fixed SIGSEGV bug in timeutil with how the timezone offset table was
    maintained. It required three things to happen at the same time.
 -- Fixed memory leak of Bools upon a @backup or @dump/flatfile. Bug
    originated in MUX 1.6, first fixed in Chaotic MUX, and is already
    fixed in MUSH 3.0.
 -- Left out a definition for SMALLEST_INT_GTE_NEG_QUOTIENT on Win32 which
    affected FLOORDIV, REMAINDER, and dates with negative years. The
    ./configure process on Unix builds it's own autoconf.h file. This is not
    an issue for those running on Unix.
 -- Fixed a vicious heap-corrupting bug in HASH_ProcessBuffer (demonstrated
    in MUX 2.1.3.23 Unix-only). My bug.
 -- Bug #786 - Logging of commands by players set suspect now works. Patch
    from Shawn Wagner.
 -- '@mail/' was interpreted as '@mail/abort'. Reported by Cloud@Ashes.
 -- Bug #404 - Support 'page =Hi there. =)'. Reported by Silk.
 -- Recognize '@teleport Foo=' and issue an error message instead of
    attempting '@teleport Foo'.
 -- Fixed bug introduced in 2.1.4.25 where '@create Foo' was not accepted.
 -- Flatten random distribution in how similarly-named things are matched.
 -- Include resident memory again in @list process report.
 -- Use mudstate.logging again.
 -- Remove vestigates of macros.
 -- Handle prematurely-chopped comsys.db files.
 -- Bug #548 - DS_AUTODARK was broken for multiple connections.
 -- Re-work setunion, setinter, elements, and setdiff to handle lists more
    consistently.
 -- Fix potential unterminated buffer operation in setinter().
 -- In an unlikely scenario, the timezone offset info can be off by less
    than 1 second.
 -- Disallow GOD from changing player Aliases. From TM3.
 -- Alias, last, lastsite, mailcurf, mailflags, mailfolders, quota, rquota,
    and semaphore are now set AF_NOCLONE. They are not copied by @clone.
    Cloning alias would have created a duplicate. There is value is not
    cloning the other attributes as well. From TM3.
 -- Fixed bug with hastype(#123,ROOM) that was introduced in Build 29.
 -- @exitformat passed all exits into %0 if at least one of the exits was
    visible to the user.
 -- Some operating systems can indicate from a select() call that input or
    output is available and then later return an error on a particular recv()
    or send() call to the same socket. BSD or systems which do not restart
    system calls after a signal were mentioned as being affected.
 -- Bug #624 - delcom now deletes aliases without removing you completely
    from the channel. addcom warnings also removed.
 -- Objects could use flags() to see CONNECTED flag of DARK WIZARDs.
 -- scramble() strips ANSI now.
 -- Bug #782 - You could log into a guest twice if you knew the dbref#. Patch
    from Zenty.
 -- Bug #783 - Could get a DARK guest by logging into a previous guest player
    with it's dbref. Patch from Zenty.
 -- Fix SIGSEGV bug in new guest system from Build 35.
 -- Avoid compiler warnings from including malloc.h when the platform prefers
    stdlib.h
 -- New connections on WinNT follow a different path and weren't reported
    to SITEMON-flagged users.
 -- The CA_STAFF permission on the realms flags are enforced.
 -- add(1.6,.1) no longer returns 1.7000000000000002. The server uses the
    briefest base-10 expression of the value that is within the estimated
    error of the result.
 -- Fixed round(2,2) and round(0,2) so that they return 2.00 and 0.00,
    respectively.
 -- Fixed locks on guests.
 -- Changed guest password back to 'Guest' to make the transition to the
    new guest system easier.
 -- The names reported in the @chown message were usually wrong.
 -- Fixed typo bug in 2.1.12.37 that disallowed guests from connecting.
 -- To fix "20:000000000" bug on Win32, set the floating-point processor to
    53-bits of precision on both Win32 and Linux. The bug is not currently
    an issue on Linux, but this fix prevents it from become one.
 -- Bug #799 - SIGSEGV was possible in lcmds().
 -- Guest password is reset to ease transitions.
 -- @chown success message was not null-terminated.
 -- Updated strtod.cpp to later version.
 -- In places that check for integers, also allow a plus sign. Changed by
    Raevnos.
 -- Fixed several places in the code where atr_num() isn't tested for NULL
    including @listcommands and @function/list.
 -- Fix v() to allow for '~' and '_' as a leading character in an attribute
    name.
 -- Allow search() to mean search(me) again.
 -- Fix @dbclean so that when it renumbers attributes, it also updates the
    attribute numbers in the @addcommand and @function data structures.
 -- Don't disable @sweep on WOD_REALMS builds. @sweep can be disabled
    separately with existing commands.
 -- Fix the '@list hashstats' report so that the 'longest' column is reset
    whenever a hash page is defragmented.  This will tend to give a smaller
    and more accurate number.
 -- Fix bug with validating attribute names introduced in Build 42. Found
    by Ashen-Shugar.
 -- @exitformat is executed now even if all the exits in the room are DARK.
 -- Fix edit(test,,a) --> 'testa'. Found by Ashen-Shugar.
 -- Work around what appears to be a compiler bug in GCC 3.0 and 3.1 that
    caused timefmt($z) to return a bogus number.
 -- Bug #469 - hasattr/hasattrp would return 0 for visual attributes on 
    non-visual objects.
 -- Guests were not halted on disconnect. Patch from Zenty.
 -- God was able to @chown itself to other players. Patch from Jake.
 -- Fixed udefault() with %9. Found by Jake. Fixed by Brazil.
 -- Fixed search() with no arguments causing SIGSEGV on Solaris 8 on Sun
    hardware and SIGBUS on FreeBSD on x86 (AMD) hardware. Found by nails.
 -- Allow space() to have no arguments.
 -- Fix isnum() parsing when exponents are involved.
 -- Fix the way nanoseconds are broken into milliseconds, microseconds,
    and nanoseconds. Probably not observable in MUX 2.1.
 -- Fix @mvattr. There was still one case of where @mvattr would remove
    the source attribute while prevented from creating it on the
    destination object.
 -- Fixed server hang possibility in BMH_Execute(), Boyer-Moore-Horspool
    string searching. Encountered by nails and Anomaly at mushpark.com.
 -- Fix hasquota() so that it returns '1' and '0' instead of '49' and '48'.
 -- Fix filter() behavior where a prefix of '1' was enough to test true.
    Fixed by Raevnos.
 -- @chzone should have cleared powers. Fix by Jake.
 -- Fix MAT_HOME bug. Found by Alierak.
 -- Fix channels() against the potential of having more than an LBUF in
    channel names. Channels can only be created by Wizards, so this
    isn't an urgent issue.
 -- Fix SIGSEGV bug in ANSI_String_Copy that becomes an issue with the use
    of center/ljust/rjust. Discovered by Elmeria@Crystal Bridges.
 -- Fix uninitialized variable in utility function used by LROOMS().
 -- Fixed @listcommand when @addcommand'ed commands have previous aliases.
    It only affected the report.
 -- pool_check() needed to verify PCACHE pool as well. Reported by Alierak.
 -- Use A_VA name instead of equivalent literal 100. Reported by Alierak.
 -- Fix Prefix-without-suffix bug. Reported by Alierak.
 -- Fix '-0' display for 'think imul(1024,1024,1024,1024,1024,1024,8)'
    Reported by Alierak.
 -- Fix seeding random numbers on Win32. The call to CryptAcquireContext
    was likely to fail.
 -- On a NetBSD/Alpha system in which sizeof(unsigned long) == 8, IPv4 mask
    validation gave false negatives.  Reported by Alierak.
 -- On same NetBSD/Alpha system, reverse-DNS slave was non-functional because
    gethostbyname() choked on the eight-byte IPv4 argument. Reported by 
    Alierak.
 -- IP ranges of the form 'a.b.c.d/m' would allow 'm' to be text and take it
    as a zero value. For example, 'forbid_site 1.2.3.4/foobar' would effect
    every IP address. Too easy to shoot yourself in the foot. Reported by
    Alierak.
 -- LROOMS() would not check across the entire database. It left off
    consideration of the database's last dbref. Reported by Alierak.
 -- For exits, loc(foo) did not return the same answer as rloc(foo,1).
    Reported by Alierak.
 -- Fixed 'round(100,0)' --> '100.00' instead of '100'.
 -- Bug #157 - @prog + |LOGOUT would crash MUX 1.6, and that was fixed in
    MUX 2 a long time ago, but this recent fix cleans up the connection
    further so that the connection can continued to be used for logging into
    another account. Prompted by Alierak.
 -- Use long signal names if they are available. Bug from MUX 1.6.
 -- raw_broadcast() can be called from a signal handler and therefore, it
    shouldn't be allocating/freeing memory.
 -- comtitle switch table needed to be terminated. Jake fixed.
 -- Fixed two memcpy/strip-ansi idioms (one in pos() and one in @decomp).
    Found by Jake.  Bug introduced by Brazil.
 -- Fixed bug in ansi() that was previously fixed, but has returned. ansi()
    returns a result that is much shorter than it needs to be.  Reported by
    Alierak (both first and second time).  Brazil's bug.
 -- Don't allow children(#-1) to return all unparented dbrefs.  Bug from
    MUX 1.6.  Reported by Alierak.  I'm calling it a bug, and yet, there is
    some value in the previous behavior.
 -- Fixed SIGSEGV bug in vmul().  Reported by Alierak. Bug from MUX 1.6.
 -- Fixed unlikely SIGSEGV bug in function table initialization.  Brazil's
    bug.  Fixed by Brazil.  Reported by Kieran Boru.
 -- OutOfMemory() and AssertionFailed() reversed sense of bCanRestart.
    Reported by Alierak.  Brazil's bug.
 -- Fixed convtime() SIGSEGV.  Reported by Alierak.  Brazil's bug.
 -- Fixed set(me/attribute,!flag) form. It was looking for the '!' in the
    first argument instead of the second one. Reported by Sean Hunter.
 -- Fixed crashbug related to kill_guarantee_cost -- iff kill_guarantee_cost
    was configured to zero.  By default, it is 100.  Also improved messages 
    that report on costs of killing.  Crashbug reported by Jeremy Weatherford.
 -- Fix ANSI bleeding in exit names. Reported by Jeremy Weatherford. Fix by
    Brazil.
 -- Exit names like ';foo' were effectively DARK exits. If set AUDIBLE, they
    were effectively listening devices that didn't show up on a @sweep.
 -- Document logged-out command 'INFO'.
 -- Alierak fix for buffer overflow exploit in slave process.
 -- Alierak Fix for logic bug in logging.
 -- Alierak fixes build breakage on Darwin due to inconsistent use of size_t.
 -- Fix SIGSEGV in SCRAMBLE().
 -- Alierak fixes strcat() given that its assumptions about TinyExec are no
    longer true.
 -- Only allow printable characters in identd.  The slave process on Unix
    does this.  The threaded implementation for Win32 didn't.
 -- Alierak reported that SCRAMBLE still scrambles characters off the end of
    the buffer.  He provided a patch that fixed that while not giving a flat
    distribution.  This final check-in fixed both issues.
 -- Player names weren't validated properly. Instead of 
    Tiny_IsPlayerNameCharacter[], the code was using 
    Tiny_IsObjectNameCharacter[].
 -- Insurance in several places against character data with high-bit set.
    In an unpatched MUX 2.1, there is no way to get character data with a
    high-bit set, but we've added insurance against it anyway.
 -- MakeCanonicalMailAlias() could return a result which was not
    null-terminated.  Reported by Ita'istar@Tandoria. Introduced and fixed
    by Brazil.  Related to the @malias command.
 -- Fixed '@wait obj/attr=...' form of semaphores.  It would work exactly
    once if 'attr' wasn't previously defined in the game.  Caused by and
    fixed by Brazil.  Reported by Ian.
 -- Fixed Gradian-to-Radian conversion constant typo.
 -- Fix mis-spelling of separate.


Performance Enhancements:
~~~~~~~~~~~~~~~~~~~~~~~~
 -- Parser is faster in recognizing %-escapes.
 -- Parser function handling is improved with minimum and maximum range
    checking handled in the parser and not in each individual function.
 -- Database and hashtables use a different hash function which is easier
    for gcc to optimize and therefore, Unix distro should benefit.
    Actually, new hash function is faster than anything else I've found
    for all block sizes from 1-byte up.
 -- For string search with GREP and GREPI, added a Boyer-Moore-Horspool
    string search algorithm for speed.
 -- Perform one strip_ansi() call in do_decomp instead of several.
 -- Remove fourth argument to safe_copy_buf to reduce code size. The 4th
    argument was always LBUF_SIZE-1.
 -- Simplify the varargs_preample family of #defines further.
 -- Use MUXCLI on both Unix and Win32 builds instead of getopt on Unix
    and correct-but-inflexible code on Win32.
 -- Improve performance of pool_alloc and pool_free.
 -- Improve performance of @aconnnect/@adisconnect.
 -- Reduce code size by around 4KB by specializing a few calls.
 -- Improve parser performance by making certain tables 'static const' or
    'const'.
 -- Reduce stack frame per-invocation overhead of TinyExec() by 688 bytes to
    138 bytes.
 -- Improve putstring() performance and therefore @dumps.
 -- Improved parser speed by a few instructions.
 -- Improve speed of TRANSLATE() and emit %t for hardtabs.
 -- Use /dev/urandom on Unix and Crypto API on Win32 to seed the random
    number generator. Fall back gracefully on pre-OSR2 Win95 to previous
    time/pid scheme.
 -- Substitutions for ##, #!, and #$ are performed at one time and therefore
    faster.
 -- @backup now allows the backup script to unload a flatfile instead of
    having the server do it. Previously, the game server unloaded a flatfile,
    and then the backup script unloaded the flatfile again.
 -- Fixed test_time_t() for 64-bit platforms. Reported by Alierak.
    Fixed with Alierak.  Daylight Savings Time information would have
    been missing on at least some and possibly all 64-bit platforms.
 -- Fixed SIGSEGV bug in UpdateOffsetTable(). This function maintains
    a table of DST/zone differences and the interval of time over which
    the DST/zone difference is valid. There are typically two intervals
    per calendar year (DST in force and not).  The table can whole 50
    entries (or 25 years worth).

    If the table was full, and the Least-Recently-Used (LRU) entry is
    the last entry in the table, and we are adding an entry beyond the
    interval covered by the last entry, then a SIGSEGV can occur.
    Reported by Anomaly/nails.  Brazil's bug.  Fixed by Brazil.

    A broader case of this one was originally reported by Lucifer
    against MUX 2.1 and fixed 2001-OCT-16.  The fix wasn't sufficient.
 -- Bug #557, #558, #559, and #560 were all buffers smaller than the 
    largest possible result.  All reported by Morgan 2000-OCT-15.  Fixed 
    (finally) by Brazil.
 -- Prevent rooms and exits from using the 'home' command.  Patch by
    Alierak.
 -- Configuration script bug that affected MacOS build.  Reported by
    Alierak.
 -- PushPointers tag was wrong.  Reported by Alierak.
 -- If a Guest<n> player was renamed, the contents of room #0 would be
    cleared leaving @dbck to clean it up.
 -- Tweak the article_rule configuration options.  Reported by Alierak.


Cosmetic Changes:
~~~~~~~~~~~~~~~~
 -- Consistent file headers and comment blocks. Remove trailing spaces and
    hardtabs.
 -- Remove unused sections of #ifdef'ed out code.
 -- @pcreate and @robot now report the created dbref.
 -- say command now emits 'You say, "..."' instead of 'You say "..."'.
 -- Help for pmatch changed to reflect that the #-2 result was removed long ago.
 -- @wall now adds comma after shouts. TM3 found first.
 -- Alierak fix for typos in NOTES.


Miscellaneous:
~~~~~~~~~~~~~
 -- Added Manual in LaTeX format.
 -- Use '-c' command line switch in @restart to make update to 2.2 possible.
