// this ChangeLog uses yyyymmdd.hhmm format for a unique timestamp
// for each change; this makes it easy to grep the sources for exactly where
// these changes were made.
//
// Sometimes methods or other code is removed; you may need to look in
// the archives to find this code (and the accompanying timestamp) in an
// older version of the source.
//
// Unless the change has 'dschin' or 'matt' near it, jeremy implemented.
//
// bug fixes and changes not visible to users are (in parens).
//
// where a -- version # -- is noted, it includes all changes listed below
// it in the file; anything above it will be part of the next release.
//
// gaps of a few lines indicate no development work was done for a while.


/*
 * -- 1.9.4 --
 *
 *  (20000704.0830): Final docs tweaks.  
 *
 *  20000703.1445: New docs are done!  Check 'em out at
 *	http://shadowlands.org/forum/newdoc/
 *
 *  (20000703.1200): On startup, prints whether guests and topics are enabled
 *
 *
 * -- 1.9.4-devel37 --
 *
 *  (20000628.1500): i_msgchk_check no longer prints an error message, unless
 *	the user's running a command.  (If they're not running a command,
 *	i_msgchk_check is being invoked from the room's automsgchk handler.)
 *	It also prints a specific "You have no mailbox." message when it _is_
 *	printing an error message and the user has none, instead of the less
 *	friendly generic message printer.
 *
 *
 * -- 1.9.4-devel36 --
 *
 *  (20000623.1755): Consolidated whisperban check code into
 *	user::CheckBanned.  (removed SendCheckBan)  Code was
 *	previously in SendCheckBan (for !to <user> <msg> sending)
 *	and user::_sendOut (for standard sending)
 *
 *  (20000623.1720): Bug fix:
 *	Whispers sent via !to <user> <message> weren't being checked
 *	against the whisperban list, and could thus bypass a ban.
 *	(Added user::SendCheckBan method)
 *
 *  (20000623.1214): world.h: changed // to /*-style comments
 *
 *  (20000623.1210): Renamed TALKING_TO_SOME to TALKING_TO_MANY
 *
 *  (20000623.1205): Renamed setupListenList to setupRealUserInfo
 *
 *  (20000623.1154): Some comment clarifications
 *
 *  (20000623.1145): streamlined passwd.c; merged some duplicate code there
 *	with the aid of a couple ifdef's.
 *
 *
 * -- 1.9.4-devel35 --
 *
 *	One last docs runthrough and 1.9.4 will be ready.
 *
 *  20000623.0026: passwd-unix-inc.c:unix_validate now checks to see
 *	if the pwent password's not "x" even though shadow support is on,
 *	and uses that non-shadowed password to validate if that's the case.
 *	(This covers when we're compiling with shadow support, but shadow
 *	 is currently not installed.)
 *
 *  (20000623.0016): c_printwho now tells you when you're talking to all,
 *	instead of just being silent in that case. (cosmetic?)
 *
 *  (20000623.0007): fixed the occasional "yourname to (null)>" prompt bug.
 *	(FINALLY!  it was inadvertently introduced a year and a day ago.)
 *	Cause: When someone you where whispering to is logged in once,
 *	and they log in again and kick the self you were talking to, 
 *	the bits are set right, but talkingTo() can't get the name of the
 *	newly logged-in user, because when they started talking to 'em
 *	(through the newly logged-in calling talkToMeToo right before printing
 *	 the prompt to kick the old one), so it got (null) instead.
 *	Now uses GetUserByIndex(bitno, true) instead of GetUserByIndex(bitno)
 *	so it doesn't check IsUserAround(), it returns the *user regardless.
 *
 *  (20000614.2220): cmd::c_zebra:
 *	Cosmetic bugfix; in current settings listings, tabself was misaligned.
 *
 *  (20000614.1245): user::ManageInputNewChar:
 *	Hitting ^W would do (n) backspaces, where n == # letters
 *	erased, even if showInput was false.  (Also, if local mode was
 *	on, would redisplay the input line, even if showInput was false.)
 *
 *
 * -- 1.9.4-devel34 --
 *
 *  (20000613.2000): That should conclude development for 1.9.4.
 *	Assuming no new bugs, 1.9.4-devel34 will be released as 1.9.4
 *	after a test period and doc review (thanks again matt!)
 *
 *  (20000613.1745): Whispering to self as a command (!to myname blah blah)
 *	no longer displays the line twice.
 *
 *  (20000613.1110): the code in ManageInputBuffer that actually reads
 *	from the socket has been moved to slfgetch()... it was in several
 *	other places as well, CNP style.  The rest has been moved to
 *	ManageInputNewChar.	
 *
 *  20000612.2200: !lockout renamed to !lock
 *
 *
 * -- 1.9.4-devel33 --
 * 
 * 20000610.2000: for c_lockout: LOCKOUTUSERS_FILE lists those who can.
 *	(If you want all users to be able to,
 *	 don't define LOCKOUT_ONLY_LOCKOUTUSERS.)
 *
 *
 * -- 1.9.4-devel32 --
 *
 * 20000610.1100: !ban <username> lets you disallow certain user(s) from
 *	whispering to you.
 *
 *
 * -- 1.9.4-devel31 --
 *
 * 20000610.1034: Guests must use !lockout guest to lock selves out,
 *	to confirm they know they can't unlock
 * 
 * (20000610.1030): ALLOW_LOCKOUT enables/disables c_lockout(default: disabled)
 *
 * 20000609.2030: !set tabself now allows you to tabcomplete to your own
 *	username, making it easier to make quick notes to yourself using chat.
 *
 * 20000607.1730?: c_lockout :)
 *
 * (20000607.0720): Changed authlocal to disallow connections from uid under
 *	100... well, they can still log in, but they'll be prompted for
 *	username/pw.
 *
 * (20000606.1820): In passwd-unix-inc.c, changed getpwnam to slf_getpwnam
 *
 * 20000529.0930: Added /var/lib/slforum/banners as standard banner directory,
 *	with /tmp/.banners as fallback.
 *
 *
 * -- 1.9.4-devel30 --
 *
 * (20000524.1345): Now compiles with topics enabled.
 *
 *
 * -- 1.9.4-devel29 --
 *
 * ^-- this should be the last devel release before 1.9.4... :)
 *
 * 20000523.1815: PAM support now works!  Had to make a service description
 *	file to stick in /etc/pam.d
 *
 * (20000523.1750): Now clears buffer after trying to validate pw, Just in Case
 *
 * 20000523.1600: LookForTimers now runs every 30 seconds, at :00 and :30 .
 *
 * (20000523.1555): LookForTimers wasn't checking for guest timeouts, because
 *	it used IsUserAccepted instead of IsUserAround... fixed.
 *
 * (20000523.1545): Now properly clears entry line before clearing screen
 *	by sending many blank lines.
 *
 * 20000523.1540: Prints the long legal hello message at the beginning of
 *	every successful run; previously did so only when ran w/ no params.
 *
 * 20000523.1530: Added default port number. (7777)
 *
 *
 * -- 1.9.4-devel28 --
 *
 *  20000514: Added skeleton of PAM support and other auth methods.
 *
 *
 * -- 1.9.4-devel27 --
 *
 * 20000513.1940: SHADOW SUPPORT WORKS.
 *	Problem was, passwd.c wasn't including slfprefs.h, and thus
 *	didn't know when USE_SHADOW was defined.  fixed :)
 *
 * 20000511.1720: automsgchk notifications now beep.
 *
 *
 * -- 1.9.4-devel26 --
 *
 * (20000511.0910): Bugfix: Was reporting new mail every msgchk interval.
 *	Had a >= where should've been != ... fixed
 *
 * (20000511.0705): Tweaked room::LookForTimers so it won't skip a minute
 *	by scheduling SIGALRM 60 seconds from :00 .
 *
 *
 * -- 1.9.4-devel25 --
 *
 * (20000510.1948): Partial command completion wasn't case-insensitive.  Fixed.
 *
 * (20000510.1940): After ^L, didn't print from: attribution if the person
 *	who sent the last line before ^L, sends the first line after.  Fixed.
 *
 * (20000510.1933): Alphabetized the !set display, except for command char,
 *	which goes first.
 *
 * (20000510.1923): first sked_alarm is right away, not PING_INTERVAL_SEC away
 *
 * 20000510.1900: auto-msgchk added (matt's idea)
 *
 * (20000508.??): added continue; to room::pingAndCheckTimeout when no user was
 *	in that slot; less wasted cycles
 *
 *
 * -- 1.9.4-devel24 --
 *
 * 20000506.1010: Added final timestamp in the log, ctime format, of when
 *	a run terminates, so we don't need to scroll back through the log
 *	to determine the date on which it ended.
 *
 * 20000506.0945: Added -h / -help commandline option.
 *
 * 20000506.0900: Added commandline option (+/-aa) for autoaccept guests,
 *	option for print guest-howto-message (+/-ghm), and in theory, can
 *	now accept the arguments after port # in any order.
 *
 *
 * -- 1.9.4-devel23 --
 *
 * 20000505.2040: Added guest auto-accept option at compile time (slfprefs.h).
 *	AUTO_ACCEPT_GUESTS defaults to 0, of course!  Also mentioned this
 *	in INSTALL.  Also changed GUEST_HOWTO_MESSAGE from an #ifdef to an #if.
 *
 * (20000505.1400): Began a separate ChangeLog-userfeatures file, less detailed
 *	than this one, which is really for developers.
 *
 * (20000504.1140): Documented user::Send return values
 *
 * 20000504.1130: ListenList is now checked only if the message being ignored
 *	is public; this means we no longer check listenlist for hourly chimes,
 *	etc. for folks ignoring those types of messages.
 *
 * (20000503.1540): When can't open backup wtmp file, clarified the error
 *	message to "NOT LOGGING LOGINS" from "NOT LOGGING".
 *
 *
 * -- 1.9.4-devel22 --
 *
 * (20000503.0740): If one was ignoring chimes, it would still print the
 *	hintmessage on how to ignore chimes.  Fixed.  (Had to change
 *	user::Send (const char*, int, bool) to take optional msgdescflags
 *	parameter.)
 *
 *
 * -- 1.9.4-devel21 --
 *
 * (20000502.0615): Fixed null-deref on very low memory condition in
 *	user::pingAndCheckTimeout().  This would probably never happen,
 *	but it's important to fix just in case.
 *
 * (20000502.0100): Finished reversing changelog.  (Yes, it was in
 *	time-increasing order in every version prior to this one.)
 *
 * (20000501.2050): When going from trueidle-off to trueidle-on,
 *	wouldn't update idle after the last keypress used to enter the command
 *	to move into that state. (fixed)
 *
 * 20000501.0940: Clarified the !here display; now says "x more people too
 *	idle, not shown" (added the more)
 *
 * 20000501.0900: !set now says "Your current settings" to emphasize that
 *	these are per-user preferences.
 *
 *
 * -- 1.9.4-devel20 --
 *
 * 20000430.1240: Listen list now saved and restored with other prefs
 *
 * (20000430.1230): listenListAdd now checks for dupes, and won't add a word
 *	if it's already in there. (using strcasecmp)
 *
 * 20000430.1200: Added ctrl-o for enable/disable command char
 *	(good for pasting things in.)
 *
 * (20000430.1120): Moved prefsfile path from hardcoded to slfprefs.h
 *
 * 20000430.1110: Added trueidle user preference (idle time based on last
 *	keypress (this was the old behavior) instead of last public action.)
 *
 * (20000430.1100): Cleaned up places where cmd_char was being sprintf'd in
 *	and we can now use \177 instead.
 *
 * (20000430.1045): Added reset-idles wherever the user takes a public action,
 *	since it's not set after every key anymore.
 *
 * (20000430.0400): c_here (ListUsers with exclude_idleones) now correctly
 *	says how many are _here_ and shown, not how many are logged in.
 *	(changed nu to (nu-notshown) at 20000430.0400 mark in ListUsers)
 *
 * (20000430.0005): c_help wasn't using uWriteSubst to print the cmd table,
 *	and neither was rndCommand().  Fixed.
 *
 * (20000429.2330): removed !zebra from user-visible commands. (!set remains)
 *
 * (20000429.2300): Documented all ctrl-chars in features.html
 *
 *
 * -- 1.9.4-devel19 --
 *
 * 20000429.2200: BEHAVIOR CHANGE in something long-established:
 *	Only public messages reset user idle time.
 *	(added all_keys_reset_idle field)
 *	(!set trueidle on for old behavior)
 *
 *
 * -- 1.9.4-devel18 --
 *
 * 20000429.1155: If the person you're whispering to leaves while you're
 *	typing a command, or typing a line that would be sent public using !!,
 *	that input would have been cleared; this is no longer so.
 *
 * (20000429.1130): Added code to HandleFindDupl to get rid of telnet commands
 *	(since these will be sent to this state, which is the initial state if
 *	connecting from localhost with authlocal enabled.)
 *	(Added states to parse telnet options, but they just ignore them at
 *	 present.)
 *
 * (20000429.1020): Fixed: If whispering to self (possibly among others), you
 *	saw the line sent to yourself twice.  (fixed.)
 *
 * (20000429.1015): Fixed the timer time-parsing bug that showed up only when
 *	a timer was already set.
 *
 * (20000426.1930): added uWriteSubst, and modified Send to substitute cmd char
 *	for all \177; no more !'s in help msgs if your cmd char is % or /, etc.
 *	Went through all .cc files and changed !'s to \177's in help text.
 *
 *
 *
 *
 * -- 1.9.4-devel17 --
 *
 * 20000401.1956: Fixed timer bug
 *
 * 20000401.1950: Added another second to ^D^D timeout for laggy modem users.
 *	(demaria request)
 *
 *
 * -- 1.9.4-devel16 --
 *
 * 20000321.1405: SECURITY FIX: Wasn't clearing yankbuffer on discon.  Fixed.
 *
 * 20000321.1400: added lastbuffer to user.  (Private, no getter.)
 *	Added ^P to user::ManageInputBuffer so a user can paste in the
 *	last public or private line sent.
 *	Added pasteIntoBuffer private method for ^Y, ^N, ^P.
 *
 * 20000321.1330: Added lastpublicmsg field to room.  (getLastPublicMsg()
 *	is getter).  Added ^N to user::ManageInputBuffer so a user can
 *	paste in the last public message.
 *
 *
 * -- 1.9.4-devel15 --
 *
 * 20000320.1100: added ALL_MESSAGES_TIMESTAMP feature to slfprefs.h,
 *	user::Send.  (Implements a feature requested.)
 *
 *
 * -- 1.9.4-devel14 --
 *
 * (20000305.1215): Prep for virtualization: moved all getpw* calls for
 *	getting users from the passwd file into passwd.c
 *
 * 20000305.1145: !timer/!alarm now display the old timer being replaced when
 *	setting a new one.
 *
 * (20000304.1600): Preferences for slforum now in slfprefs.h, for easy
 *	inclusion into files that don't want any of the prototypes or classes.
 *	(e.g., slforumutil.c)
 *
 *
 * -- 1.9.4-devel13 --
 *
 * (20000229.0001): !msgchk now says "you have old mail waiting", not "you have
 *	no new mail", so we don't see the word 'new' when we in fact have just
 *	old mail.  Thanks Demaria for suggestion.
 *
 * 20000227.2000: Broadcast messages with hint bits set are no longer logged;
 *	they are usage hints for the current room occupants, useless to the
 *	reader of the log.
 *
 * 20000227.1930: Hourly chimes now have a hint message telling how to ignore
 *	them if you so desire.  (As with all other hint messages, this only
 *	shows up once for each user, and is not displayed after the first
 *	time.)
 *
 * (20000227.0200): !timer/!alarm now lists public timers too
 *
 * (20000226.1850): Public timers are now announced to room when set.
 *
 * 20000226.1300: High-bit chars now allowed.  Any highbit ctrl chars are
 *	tossed out, and any highbit whitespace chars are converted to ASCII 32.
 *	[ note that this still doesn't work right, 20000302 ]
 *	[ need to impl. a state machine to handle telnet option negotiation ]
 *
 * (20000225.1605): removed !banner, now just !spam does c_banner
 *
 * 20000225.1600: now exits if can't open requested log file during startup.
 *
 *
 * -- 1.9.4-devel12 --
 *
 * 20000219.0700: slforumroom::listusers now says how many users are here but
 *	not shown.
 *
 * (20000219.0045): slforumuser::usercmds table now has all possible params
 *	for c_zebra in {|} form, not just W? .
 *
 * 20002019.0020: Simplified c_[un]ignore and its bloated help message by
 *	taking out banter and pbeep (demaria idea)
 *
 * (20000219.0018): c_showaway now shows the header line, as it should.
 *
 * 20000218.2300: rewrote c_msgchk, it should work for everyone now, and
 *	now uses no external commands or files in /tmp  :-)
 *
 *
 * -- 1.9.4-devel11 --
 *
 * 20000217.0430: Added SIGHUP handler which closes/reopens the transcript log
 *	file, for use with the logrotate(8) utility.  Eventually this handler
 *	will also re-read the slforum global config file, when we have one.
 *
 * (20000217.0415): converted "slforum.cc" to "slforumutil.c": this is more
 *	descriptive, slforummain.cc is the startup code and it was confusing
 *	to have an slforum.cc as well.  Also, as of this writing, (C vs C++),
 *	slforumutil.o is 33264 bytes; slforum.o was 54536 bytes for same code.
 *
 * 20000217.0343: Added option for public timers.
 *	Current syntax: !timer <time> public [<message>];
 *	as we parse it now, public must go after time.  We can fix that. :-)
 *
 * (20000217.0340): default command tab-completion !<tab> now works at any
 *	position; previously worked only at start of buffer.
 *
 * (20000217.0325): fixed c_timer bug where you couldn't do !timer 0 to turn
 *	a timer off (it said "out of range" if secs<1, now fixed to be <0).
 *
 *
 * -- 1.9.4-devel10 --
 *
 * (20000211.1645): Doing !to d<tab>, when d<tab> returned multiple matches,
 *	would say "multiple matches" _and_ insert a tab.  Fixed; now just
 *	says "multiple matches".
 *
 * 20000209.1630: Can now ignore system messages, because moves, rolls and
 *	hourly chimes are system messages.  We now just don't let the user
 *	ignore system messages, but they can ignore messages with other flags
 *	besides just MSG_SYS and MSG_PUBLIC set.
 *
 * 20000208.1445: Just plain !timer shows the current timer; now it also
 *	shows the timer_message, if any.  Also will show previous timer if
 *	any.	[ IsTimerSet indicates current timer; timer_expire_hour==-1
 *		  means no previous timer, any other value means there was one]
 *
 * (20000208.0808): Prefs files in /var/lib/slforum no longer start with ".".
 *	Also, loading/saving prefs put 'em in log (had a debug msg).  Fixed.
 *
 *
 * -- 1.9.4-devel9 --
 *
 * (20000207.1215): Loading prefs: !set _ignoreFlags was accidentally scaling
 *	the value by 60, cut-n-paste bug.  Fixed.
 *
 * (20000207.1145): Forgot to call me->savePrefs() from c_ignore().  Fixed.
 *
 *
 * -- 1.9.4-devel8 --
 *
 * 20000206.2045: user prefs now saved to /var/lib/slforum if it's writeable,
 *	/tmp if not.  Also, ignoreflags now saved too.
 *
 * 20000206.0200: message "Shadowlands Forum is exiting." now has a timestamp.
 *
 * (20000206.0140): c_zebra now checks to see if we're not running a command
 *	(and thus not reading in from the prefs file) and thus shouldn't save
 *	the file back out.
 *
 * 20000206.0130: set default hereidle threshold to 20 mins, from 15.
 *
 * 20000206.0100: dschin: All prefs now load! 
 *
 * (20000206.0025): nonguest connecting from non-localhost didn't set state to
 *	STATE_FIND_DUPL after getting password; fixed.
 *
 * 20000206.0001: at midnight, now announces the new date as well
 *
 * 20000205.1830: made commands.html a little clearer about !ignore/!listen
 *
 * 20000204.0900: hourly chime in very idle room now goes out to the room,
 *	but isn't logged.  (Previously didn't go to the room either)
 *
 *
 * -- 1.9.4-devel7 --
 *
 * (20000201.1310): added user::idleTime(time_t) to save 30 calls to time()
 *	in loops where we sort by idle.
 *
 * 20000201.1250: we now try to schedule our SIGALRMs at the beginning of
 *	the minute.  Matt's idea, cool eh?
 *
 * 20000201.1245: nixed Dong! for now in hourly chime, pending discussion on
 *	whether it's too obtrusive, etc.
 *
 * (20000201.1230): made user::setupListenList, where username and gecos are
 *	added to the listen list.  The code was in two places to do this
 *	previously, making it seem like either place was a good place to add
 *	other things to do on login; AcceptAndWelcomeUser is where such things
 *	should go.  Moved loadPrefs() to AcceptAndWelcomeUser.
 *
 *
 * -- 1.9.4-devel6 --
 *
 * 20000201.1225: re-added dschin announce "Shadowlands Forum is exiting"
 *	on SIGTERM catch, which was somehow not in 1.9.3 where it shoulda been.
 *
 * (20000201.1200): RE-MERGED IN 1.9.3 UPDATES FROM 1.9.2,
 *	plus Dan's persistent user prefs.
 *
 * 20000131.1430: changed "timer due to expire" to more cheerful "timer set for"
 *
 *
 * -- 1.9.4-devel5 --
 *
 * 20000131.1415: !timer now takes a time in minutes, or hh:mm absolute time.
 *
 * 20000131.1240: bug fix: !! was broken, fixed now. (expected 2 params, got 1)
 *
 *
 * -- 1.9.4-devel4 --
 *
 * (20000131.1200): constant TIMER_FROM_USERNAME instead of string "TIMER"
 *	scattered about code.
 *
 * (20000131.1130): user timers now use struct tm instead of strings;
 *	more efficient.
 *
 * 20000131.1110: removed "guest" assumption from the message "the guest
 *	x has timed out at _____"; normal users could do that too.
 *	Also changed the fake name "(logging in)" to "(asking name)".
 *
 * (20000131.1045): CheckHourChime() now uses struct tm instead of
 *	ctime() and string routines.
 *
 * 20000131.0945: added msgdesc bits MSG_HCHIME so hourly chime can be
 *	ignored by users.  Added to c_ignore.
 *
 * (20000131.0940): fixed LookForTimers() bug where pctime pointer was
 *	incremented inside a for-each-user conditional; if more than one
 *	user had a timer expire, this would have been incremented more
 *	than once.  We now have pctime+11 in a strncmp instead of
 *	pctime = pctime + 11 beforehand.
 *
 *
 * -- 1.9.4-devel3 --
 *
 * matted additions: (1.9.4-devel3 is matt's version)
 *
 * 20000129.1245: added hourly chime (room::CheckHourChime etc) - matted
 *
 * 20000126.1730: added c_timer - matted
 *
 *
 * -- 1.9.4-devel2 --
 *
 * (20000129.1630): made -devel2 tarball so Matt can merge 
 *      his cool new stuff
 *
 * 20000129.1140: HandleUserCommand parser now takes the initial ! off a
 *	cmdname parameter, if provided, to make !help <cmdname> user-friendlier
 *
 * 20000129.1040: Added '+' to argument spec for an slf command; the
 *	last argument can now be as many args of that type as the user wants.
 *
 * 20000129.1030: changed SLF_MAX_ARGC to 16, from 2.
 *
 * 20000129.1010: can now beep multiple users w/ c_beep
 *
 * 20000129.0930: c_listen now accepts any # of args to listen to words,
 *	and is much cleaner.
 *
 * (20000129.0515): changed comments in slforum.h, which is used by both
 *	C and C++ modules, to slash-star from slash-slash.
 *
 * (20000129.0445): resolved the atoi problem in parsing numeric params;
 *	this ended up being an egcs bug:
 ... hmm, numeric params don't seem to work.   See HandleUserCommand's parsing
    loop.  Well, they _do_ work, but only if a debugging printf calls atoi
    with what was _supposed_ to be parsed, it suddenly works.  Take out the
    printf, it doesn't work.
 - Resolved 20000129.0445: egcs bug.
	napalm /% rpm -q egcs
	egcs-1.1.2-12 has this.  -24 does not. (rh6.1 has -24, yay.)
	if this behavior crops up, define EGCS_ATOI_BUG_WORKAROUND
 *
 * (20000129.0400): added "const" to all methods not changing obj. state.
 *
 * 20000129.0200: cmdline parser in SLForumUser::HandleUserCommand now
 *	gives an error if an integer param was expected and something else
 *	was there instead: using strtol instead of atoi.
 *
 * (20000127.1150): bind() and accept() calls in  slforumuser and room: changed
 *	(sockaddr *) to the more correct (struct sockaddr *)
 *
 * (20000121.1100): wrote a proper comment for the cryptic bit in slforumroom::
 *	BindSocket that did the SO_REUSEADDR.
 *
 *
 * -- 1.9.4-devel1 --
 *
 * 200000117.1400: ALL_MESSAGES_BEEP define added to slforum.h
 *
 *
 * 
 *
 *
 *
 * -- 1.9.3 --
 *
 *
 * [Note: 1.9.3 was lost for a time in a disk crash, and not recovered
 *	til after 1.9.4 devel had begun (using 1.9.2 sources).  The
 *	changes shown below aren't merged into the main version til
 *	1.9.4-devel6. ]
 *
 * 19991116.0200: loadPrefs() and savePrefs() - persistent user prefs - dschin
 *
 * 19991115.1420: Fixed shadow password support.  Thanks to Dennis Owen
 *	Williamson for spotting this problem.
 *
 * 19991112.1325: mentioned in INSTALL where to set the flag to set up slforum
 *	for shadow password support
 *
 * 19991111.1840: max guests/remote logins; added empty_slots to SLForumRoom.
 *
 * (19991111.1830): added user::isUserConnected(), makes FindSlotForNewUser
 *	more encapsulated (no more checking for user->fd != -1)
 *
 * (19991111.1810): renamed room::LookForNewUsers to room::FindSlotForNewUser,
 *	more descriptive.
 *
 * (19991111.1740): rewrote the add portion of c_listen.  Much cleaner code,
 *	shorter, takes any # of args.
 *
 * (19991109.0114): finished going through and fixing ambiguities in ChangeLog.
 *	Insomnia cured, going to bed.
 *
 * 19991109.0050: Now announces "x has arrived" _after_ "y has accepted x",
 *	and privately tells x that y has done so after x has been
 *	AcceptAndWelcomeUser'd.
 *
 * 19991108.2245: !showaway now has a header line.  It looked weird
 *	without one.  (This _will_ be part of a version bump.)
 *	Added an optional bool parameter (with_header) to room::ListAways
 *	for this.
 *
 * (19991108.2220): Finished incomplete sentence at end of README. (oops)
 *	Fixed, re-tarred as 1.9.2.  (Not worth a version number bump.)
 *
 *
 * [Note: 1.9.3 was lost for a time in a disk crash, and not recovered
 *	til after 1.9.4-devel had begun (using 1.9.2 sources).  The
 *	changes shown above aren't merged into the main version til
 *	1.9.4-devel6. ]
 *
 *
 *
 *
 * 
 *
 *
 * -- 1.9.2 --
 *
 * 19991108.0105: c_zebra: added !set (retained !zebra), changed "escape"
 *	variable name to "command"
 *
 * (19991108.0055): fixed longstanding bug where typing !ignore blah
 *	only printed the first line of the usage/help message for c_ignore,
 *	instead of the whole thing.
 *
 * 19991108.0045: added !version command (suggestion by Matt);
 *	sends the VERSION_MESSAGE one-line version string, which I added
 *	for this purpose.
 *
 * 19991108.0030: c_listen: added check for argc==0 (oops), added check so
 *	guests can't make a listen list.  Also set a maximum size on the
 *	listen list of a user (LISTENLIST_MAXSIZE in slforum.h)
 *
 * 19991101.1540: fixed bug with ^Y on a ^K-buffer too long to fit onto the
 *	current input line; now truncates, puts what it can in the input buffer
 *	and doesn't send the line, so user can edit.
 *
 *
 * -- 1.9.1 --
 *
 * 19991031.0615: moved !roll to "checking stuff" in help summary to save
 *	a screen line on login.
 *
 * 19991031.0606: removed !local, now that we can do !zebra local {on/off}.
 *
 * 19991031.0530: !kick now warns the kickee in all cases the attempt fails
 *	(try by guest, or try to kick a non-guest) with a timestamp and a beep.
 *
 * (19991031.0525): Announcements about "guest requests entry" and "kicked" now
 *	have the MSG_MOVES msgdescbit, for users who don't really care and are
 *	ignoring such things.
 *
 * (19991031.0512): Added slforumroom::AnnounceTimestamp method
 *
 * (19991031.0400): Finally got around to adding setsockopt(SO_REUSEADDR)
 *	to get rid of that annoying "address in use, wait a few mins and try
 *	again, your eager users will have to wait, pleh." message. </past_rant>
 *
 * 19991031.0245: BEHAVIOR CHANGE in something long-established:
 *	After discussion w/ demaria and dschin, changed the default
 *	command character to '!' from '%' .
 *	(This would lead to much bitching for about four days, and then
 *	 everyone either loved it or used !zebra to set it to % for themself.)
 *	(This was in prep. for initial public release.)
 *
 * 19991031.0240: On login, only calls ListAways if ListUsers returns true,
 *	indicating some users are away.
 *
 * 19991031.0225: ^L now clears screen.  (Suggestion by Demaria)
 *
 * 19991031.0210: The %% command always was a shortcut for "%to all";
 *	it now accepts two of the current command character if that gets
 *	changed (Ex. '//'), instead of /% in this case.
 *
 * 19991031.0155: Can change the %here threshold, with %zebra hereidle <number>
 *
 * 19991031.0142: People not away, but more than 15 mins idle, no longer
 *	show up in %here.
 *
 * 19991031.0140: Lists both users and aways on login
 *
 * 19991031.0130: Made sure the who_sort_is_valid flag is set properly before
 *	listing the users/aways when user logs in.  (thanks Demaria)
 *
 *
 *
 * -- 1.9.0 --
 * ^
 * New features added, so I'm bumping the release number to 1.9.0-release:
 * Note also the release date.  Happy anniversary Draco!!!
 *
 * (19991030.0005): Fixed longstanding bug where "idle x days" wasn't lined up
 *	right; now, idle text is left-justified as it should be.
 *
 * 19991029.2345: BEHAVIOR CHANGE in something long-established:  The default
 *	%who now lists only users; %users shows users and away messages,
 *	and %showaway shows only away users and their messages.
 *	Changed return type of slforumroom::ListUsers and ListAways to bool;
 *	added HINT_SHOWAWAY; swapped names of c_who and c_users, and their
 *	descriptions in the big list of commands in slforumuser.cc.
 *
 * 19991029.2040: added %here command; can exclude away'd users from %who list
 *	(added idle_here_threshold to slforumuser) (thanks to Draco for sugg.)
 *
 * 19991029.2000: dschin: changed %listaway to %showaway (better tabcomplete)
 *
 *
 * -- 1.8.1-devel11 --
 *
 * 19991029.1445: incorporating dschin whoaway patch of 19991012.0100:
 *	dschin: implemented the split %who, but kept the legacy
 *      %who around... the new ones are (currently) called %users and 
 *	%listaway. We need to find a better name for %listaway because
 *	the tab completion currently conflists with %listen, so its not
 *	much help
 *
 * (19991028.1840): added slforumuser::cmd_char field, to specify the preferred
 *	character to escape commands.  Defaults to '%', of course.
 *
 * -- 1.8.1-devel10 --
 *
 * 19991027.2251: changed the messages in %kick so they look like system
 *	messages from FORUM:, as they should.
 *
 * (19991027.2250): fixed long-standing unnoticed, unabused bug where %kick
 *	w/ no args would deref a bad pointer and crash... thanks dschin
 *
 * -- 1.8.1-devel9 --
 *
 * (19991027.0048): in can't-kick message in slforumcmd:
 *	me->Send ("        -- Only guests can be kicked. --");     
 *	Changed to send, was uWrite.  Now erases prev cmdline as it should.
 *
 * 19991025.1430: added shadow password support
 *
 * (19991025.1400): fixed some ANSI C++ errors (previously warnings) so slforum
 *	compiles under gcc 2.95
 *
 * 19991021.1800: Tab-completion of usernames for commands will never complete
 *	to your name; this makes it easier to %to someone when you and she
 *	have usernames that start w/ the same letter. (suggestion: Demaria)
 *
 *
 * 
 *
 * -- 1.8.1-devel8 --
 *
 * 19991005.0850: cosmetic: switched the order of announcements
 *	"x has arrived" "y has accepted guest x" to the more logical way.
 *	(Later discovered this still wasn't working... fixed 19991109.0050)
 *
 * (19991003.0200): fixed a typo where HandleGetPw calls c_listen.
 *	an array subscript should've been 1, was 0, in the param array.
 *
 * (19991002.2050): fixed possible null deref in SLForumCmd::c_listen
 *
 * -- 1.8.1-devel7 --
 *
 * (19990927.1330): changed the way params are passed to funcs in slforumcmd.
 *	Now an argc and argv ("flargs") is used.  Also, slfparam is now a
 *	union type, not just a void pointer to be cast around freely.
 *
 * (19990924.2230): removed potential buffer overrun in c_banner
 *
 * -- 1.8.1-devel6 --
 *
 * (19990924.2055): changed strcats to strncats in slforumuser.cc
 *
 * (19990924.2045): added check for null param to top of c_rot13;
 *	this was a chat crasher.
 *
 * -- 1.8.1-devel5 --
 *
 * 19990924.0120: private beeps to someone are now heard, even if the recipient
 *	is ignoring beeps!  They can now %ignore privbeep or %ignore pbeep
 *	to ignore these beeps.  (suggestion: paras)
 *
 * 19990923.2105: tab completion won't try to complete if not a cmd.
 *
 * 19990923.2045: merged in (from dschin 19990922.1145):
 *	added %autowho and %autotopic.
 *	also made %roll take less screen lines, and made the Star Wars PRG
 *	rolling a #define, so it will roll normally, as expected.
 *
 *
 * -- 1.8.1-devel4 --
 *
 * (19990923.0011): VisuallyClearBuffer() now checks lpwrite result as it goes,
 *	prevents possible hang on userdiscon.  Also went through all of
 *	slforumuser.cc and added a check after every lpwrite call.
 *
 * 19990922.2330: guests can't call 'emselves "guest" anymore.
 *
 * 19990922.2100: lines/sec brake implemented.  checkMaxLinesBrake()
 *	is the crucial function.
 *
 *
 * -- 1.8.1-devel3 --
 *
 * 19990922.1445: added a \n to end of the usage messages for c_ignore;
 *	was previously cutting off the second line of this message when printed
 *
 * 19990920.1745: by default, guests cannot banner; added this feature.
 *	(Previously there was no check for this, and guests did gleefully
 *	 banner.)
 *
 *
 * -- 1.8.1-devel2 --
 *
 * (19990912.2315): ifdef'd out %topic, %comment in help msgs, if not compiled 
 *	in. (suggestion by Demaria)
 *
 * 19990907.1515: added automatic localhost-login authentication!
 *	No need to type username and password.  This only works in linux.
 *	Authlocal was decent to write, and fun to use.
 *
 * 19990827.1130: cosmetic: %topic/%comment now list date topic's set along
 *	w/ time.  ditto for %prevtopic.
 *
 *
 *
 *
 *
 * 19990816.0130: cosmetic bugs associated with topics without names fixed;
 *	other cosmetic improvements to prevtopic (now lists # comments for
 *	each, etc) and to away-messages as well: away messages now have more
 *	room.  When I fixed the comment format onscreen I also fixed the away-
 *	message format to be more roomy.
 *
 * (19990815.1830): comments for current topic are now kept in a linked list
 *	attached to the room.topic, just like for prev topics.  There is now
 *	one comment per user, not lost when the user logs out.
 *
 * (19990815.1645): user->comment wasn't being cleared in resetFieldsToDiscon.
 *	Fixed.
 *
 * 19990814.2145: added %prevtopic command.
 *
 * 19990814.1400: ^Y now appends the yankbuffer to current input line instead
 *	of overwriting it.
 *
 * (19990813.2215): prevtopics, and topic info (name, setter, time of set)
 *	moved into the TopicInfo data structure (defined in slforumroom.h)
 *
 * 19990811.1545: ctrl-k, ctrl-y yankbuffer added.  Thanks to Dan Chin
 *	for this idea.
 *
 *
 *
 *
 *
 *
 * (19990801.2230): back_one_tab was forgetting to replace the deleted
 *	char(s) with '\0'.  Fixed.
 *
 * 19990731.2245:  Possible to set a chatroom topic (with %topic) and
 *	have users comment on it (with %comment).  Leaving either argument
 *	blank will list the topic and all set comments.  Waiting time between
 *	topic resets is declared in slforum.h.  Resetting the topic resets
 *	all comments.  --matted
 *
 * 19990729.1200: dschin idea: backspace should go back one tab at a time,
 *	not one char at a time through tabs.  Added the back_one_tab
 *	function (from ManageInputBuffer) to implement this.
 *
 * 19990728.0100: pasted text containing tabs would be tab-expanded
 *	into a commandname or a username, which of course would fail,
 *	and give the user pasting it an error message _without_
 *	expanding the tab to spaces as it should.  Fixed.
 *
 *
 * -- 1.7.4 --
 *
 * (19990718.0040): %to all was causing crashes on cmdline-re-fill-in after
 *	word wrap; the fill-in routine forgot that -1 was a flag for "all"
 *	and tried to dereference it as an SLFChatUser* .  Thanks to Matted
 *	for finding and tickling this bug.
 *
 * (19990717.2305): fixed bug where a plain '%' while you're away would
 *	be said publicly, but wouldn't bring you back from being away.
 *	(in HandleGetLine)
 *
 * 19990717.2250: in FindCmdIndex, changed strcmp to strcasecmp;
 *	we now have case-insensitive command names, yay.
 *
 *
 * -- 1.7.3 --
 *
 * (19990706.2320): at end of HandleUserCommand, where it copies cmdline args
 *	onto a new wrapped line, it wasn't checking whether params were
 *	NULL or not, before deferencing them.  Fixed now.
 *
 * (19990706.2120): fixed a crock where... well, inside Send is where we check
 *	to see if we're ignoring what's being said.  If it's being ignored,
 *	we send the user a message saying "we heard the word blahfile" and
 *	no longer ignore it... but if they're listening for a word like
 *	'we' or 'heard' or 'the', it'll come back from being ignored there.
 *	Fixed to fix the ignoringbits flags _before_ sending that message,
 *	and also, we don't check MSG_SYS messages, we always print them.
 *	Thanks to jadaris for finding this bug.
 *
 * 19990706.1940: fixed a spot where the prompt wasn't 12 chars wide, causing
 *	long lines to wrap the last two or three characters to the next line.
 *
 *
 * -- 1.7.2 --
 *
 * (19990704.1530): fixed two places where we call room->GetUserByIndex()
 *	and then calls result->GetName() without checking that the result
 *	isn't null. (oops)  Checked all calls of that method, should be
 *	All Better Now.
 *
 * (19990704.1410): if command name didn't exist, it failed to erase the line,
 *	left the invalid command name there.  Fixed.
 *
 * (19990702.2300): fixed space-ctrlh... erm, we were sending the nonsense
 *	code space - \008 instead of space - \010 ; many thanks to gcc for NOT
 *	pointing out that 008 is not a valid octal number, and to me for being
 *	up so late to make such a mistake in the first place.
 *
 * (19990702.2015): added sked_alarm function; uniformly makes sure we don't
 *	unschedule an earlier SIGALRM for a later one.
 *
 * 19990702.1900: now sends a space-ctrlh to idle users every PING_INTERVAL_SEC
 *	seconds, so we know they haven't left, even if the room's idle.
 *
 *
 * -- 1.7.1 --
 *
 * (19990702.1430): input buffer length variable now rechecked after every
 *	command execution, unconditionally, because commands can change the
 *	content	of the buffer.  ^U now works properly again in all cases.
 *
 * 19990701.0050: Fixed rndcommand.  The list of rndcommands was
 *	missing a comma at the end of one line.  I added a comment above
 *	that list to remind folks to always put the comma in.
 *
 *
 *
 * -- 1.7.0 --
 * ^ So finally we have...
 *
 * 19990623.2335: ctrl and high-bit chars (under 32 or over 127, below 128+32)
 *	in lpcat are changed to spaces.
 *
 * 19990623.2330: no 1-letter words in listenListAdd
 *
 * 19990623.2000: added %printwho command to list who you're to-many-ing.
 *
 * 19990623.1830: talk to many now really _says_ " to many", and is
 *	padded out so everyone's talking in that whisper group has the same
 *	margin.
 *
 * (19990622.2050): set flag when we're running a command,
 *	and thus nobody should mess with our input line,
 *	we're busy messing with it ourself.
 *
 * 19990622.1950: Track the # unique people talking to, and properly
 *	set prompt.
 *
 * 19990617.1900: When someone leaves/discons, immediately tell other
 *	folks who are %to-ing them that they've left.  Renamed
 *	sendMessagesToNone to sendMessagesTofromNone.
 *
 * (19990617.1846): kicked out guest 'undocumen', and documented it by
 *	adding it to the ChangeLog, just in case.  ;)
 *
 * (19990617.1810): i_toalso now always returns the right result; before,
 *	it would ask to retain the "%to <user>" on the cmdline during a wrap,
 *	even if the whole command was "%to <user>" to change message target.
 *	Now, it clears the wrapped line if this is the case.
 *	Also, added ability of a usercmd to return RVAL_ALWAYS_CLEAR to clear
 *	the input line for this.
 *
 * (19990617.1710): fixed bug where if user disconnected during typing of
 *	a command, somehow HandleUserCommand got called anyway... this
 *	resulted in the -1 error value being lost.  Now, every return from
 *	HandleUserCommand always checks for user_fd==-1, and returns -1
 *	if this is the case.
 *
 *
 * -- 1.6.11 --
 *
 * 19990616.1500: a two-way private conversation no longer prints the
 *	entire <from> to <to>: attribution when the conversation switches
 *	to/from directions; instead, from <user>: or to <user>: will be
 *	printed.  This is to ensure that multiple conversations don't get
 *	confused; whenever you're talking with someone new, you will get
 *	the full <from> to <to>: attribution.
 *	This took two hours to do and debug thanks to Things The Compiler
 *	Assumed And Didn't Tell Me.  Ah well.
 *
 *
 * -- 1.6.10 --
 *
 * 19990615.?: commands will now not lose data or broadcast it!  We've wanted
 *	this for a while.  If a command executes because the user types 'til
 *	it runs out of line, it will find the last space (so as not to break
 *	a word), copy everything after that to a buffer, execute the command
 *	without that last word-fragment, then paste the fragment into the new
 *	blank line.  Also, commands can request that their arguments can be
 *	placed into the new line; for example, %to <user> <message> requests
 *	that its first param (<user>) goes on the line so what you type on
 *	the next line also is %to <user> !
 *
 * 19990615.1800: Disallow blank lines if they're not preceded by a line
 *	from the same person... this prevents some of the annoying spurious
 *	blank lines; blanks should be for whitespace among pasted code.
 *
 *
 * -- 1.6.9-2 --
 *
 * (19990615.?): edited all references to char arrays so they use
 *	the #define'd length of the array instead of number literals
 *	scattered through the code.
 *
 * 19990614.? : a line with a '%' by itself is now properly echoed to
 *	chat, not treated as an invalid command.
 *
 * -- 1.6.9 --
 *
 * 19990613.0400: trying out blank attrib lines in subsequent whispers from the
 *	same person, just like public chat.
 *
 * 19990612.2330: input line now lines up with lines above it instead of
 *	being left-justified.
 *
 *
 * -- 1.6.8 --
 *
 * 19990612.0055: ManageInputBuffer now expands tabs to spaces after
 *	non-alphanumeric chars; it still doesn't interfere with tab
 *	completion.  Before, it would only expand tabs after whitespace.
 *	Also now expands tabs by writing the spaces to user's terminal;
 *	before, it called RedisplayEntryLine() (which was much less efficient).
 *
 *
 * -- 1.6.7 --
 *
 * 19990607.1800: username, gecos info now placed in listen list on login.
 *
 * (19990607.1600): added Announce and Send methods that take msgdescflags.
 *
 * (19990607.0245): now un-aways if you type a whole line that wraps,
 *	which is after all semantically equivalent to if you type a shorter
 *	line and hit enter; either way, it goes to public chat and thus you
 *	should be un-away'd.
 *
 *
 * -- 1.6.6 --
 *
 * 19990606.0220: %ignore is now a bitfield, not a collection of boolean
 *	instance fields.  Yay.  Much easier to add new ignore types now.
 *	I added ignore-banners and ignore-rolls.
 *
 * 19990606.0130: added MAX_BLANK_LINES brake
 *
 * (19990606.0125): if you beep yourself, it doesn't print the message
 *	twice on your screen.  Thanks to Buffalo Mike for finding this one.
 *
 *
 * -- 1.6.5 --
 * ^ And the resulting file is version...
 *
 * (19990605.1700): all fopens replaced with slf_safe_fopen:
 *	won't follow symlinks, or open directories or block devs
 *	for reading or writing.
 *
 * (19990605.1645): added line to slforummain to ignore SIGPIPE;
 *	no need to crash if someone disconnects while we're writing a
 *	large buffer to their fd.
 *
 * (19990605.0130): fixed bug in cmdline parser that made it stop after
 *	the first param.
 *
 * (19990603.2340): c_beep now sends to all logins of the target user,
 *	not just the first one it finds.
 *
 * (19990529.1800): Auto cmd parsing!  Doesn't tab-complete intelligently yet.
 *	But it's now much easier to write new commands that take parameters.
 *	Also removed user::extractUserParam and extractStringParam
 *	hack/callback functions, which were there for cmds to manually
 *	do what auto cmd parsing now does.
 *
 *
 * -- 1.6.4 --
 *
 * ---- NAME CHANGE ---- Renamed everything from jdm___ to slf___
 *
 *
 * -- 1.6.3 --
 *
 * (19990527.2047) : disabled rndCommand() til it works right again,
 *	right now it segv's (see jdmchatuser::rndCommand for details)
 *
 * 19990522.1800: Solaris port.  ln -s Makefile-solaris-2-6 Makefile ; make
 *	to build it.
 *
 * 19990522.1515: now distinguishes between when someone leaves by %exit
 *	and when they've lost their connection. (thanks to Ro for suggestion)
 *
 * (19990522.0250): fixed segfault on exit (caused by double-freeing)
 *
 * (19990522.0230): fixed bug where you couldn't see your own public
 *	messages if you were ignoring public.
 *
 * (19990522.0200): fixed blank-lines-not-printed bug by just
 *	removing the code that exited HandleGetLine if the line
 *	was blank; it now stays in HandleGetLine, where it
 *	gets sent to all users with _sendOut .
 *
 * (19990522.0130): moved all version-specific messages to
 *	jdmchat.h, where they can be easily changed in one place.
 *	All specific info and configurable parameters should now
 *	reside in jdmchat.h .
 *
 * 19990522.0100: now sorts the %who list by idle time!
 *
 * (19990521.2330): lpcat now prints name of file and perror detail,
 *	if it can't open the file.
 *
 * (19990521.2330): failed lpcat of /etc/issue.forum and /etc/issue.net
 *	now ignored; this prevents chat from not accepting users if both
 *	of these files are missing or unreadable.)
 *
 *
 *
 *
 *
 * 990427.0100 dschin:
 *	When someone times out, it now prints the time.
 *
 * 990425.0100 dschin:
 *	now reads /etc/issue.forum for the logon banner, and falls back to
 *	/etc/issue.net
 *
 * 990417.0100 dschin:
 *	changed so that it tabs to the nearest columb mod TABWIDTH.
 *	This also eliminated the tab-complete bug, i think.
 *
 * 990416.1715 dschin:  tab expansion: if tab, and curpos-1 is a space or
 *	buffer[0], then insert spaces. useful for pasting code
 *
 * 19990406.2100: aak, STATE_GET_NAME rejected all non-isalpha() chars..
 *	this was too restrictive of the original author.  This is now
 *	broadened to all alphanumerics, plus '-' '_' and '.'
 *
 * 19990402.0000 dschin: only ignores whitespace for cmds. otherwise,
 *      pasted code is left-justified.
 *
 * 19990401.2300 dschin: ignores leading whitespace
 *
 * (19990401.0515): moved ChangeLog to separate file from jdmchatuser.cc
 *
 * 19990330.2200 dschin: %% is now %to all. (jdmusercmd.cc)
 * 
 *
 *
 *
 *
 * (19990224.2315) dschin: Prints from: after a call to c_help.
 *	Aesthetic bugfix.
 *
 * 19990222.2350: finally can ignore beeps.
 *	Since only sys messages beep, I added this to the 'branch'
 *	of send/uWrite/broadcast/etc that handles hitbitsets.
 *	(requested by gharial)
 *
 * 19990215.1900: When ignoring public chat, listen for specific words...
 *	un-ignore public when we hear them. (thanks to Mike for excellent
 *	suggestion)  I brought in linkedlist.[ch] for this.
 *
 * 19990215.0730: Implemented paras' suggestion: Don't print repeated
 *	username at left edge of each line, when a user sends several
 *	lines in a row.
 *
 * 19990212.0830: added %help and JDMChatUser::getHelpText(cmdname) (1.5.1)
 *
 * 19990211.0200: added %ignore public and %ignore guest...
 *	i really refuse to ignore specific people who are fellow users, that's
 *	something really juvenile.
 *
 * 19990209.2345: can now use %time or %date (tho only %time is in help menu)
 *
 * 19990206.1215: can now use %quit, %exit or %bye
 *	(only %exit and %quit are listed in help menu)
 *
 * 19990206.0300: %away now displays a line with time of %away.
 *
 * (19990201.1400) FindSlotForNewUser() now prints a "room full" message
 *	when the room is full and someone tries to log in; also, fixed the
 *	'ASSERT: ... discon but fd != -1' message bug; now it complains _and_
 *	sets fields to discon like it's s'posed to.
 *
 *
 *
 *
 *
 * 19990126.2100: finally modularized command handling!  Thought of getting
 *	around to this while shoveling, thurs night of week before last...
 *	now we have modular, more efficient command handling,
 *	_and_ tab completion for command names.
 *
 * 19990124.0110: dschin: Dice rolling with %roll;
 *	also, GUESTS_CANNOT_ROLL optional #define in jdmchat.h
 *
 * (19990113.1440) change sprintf to snprintf in makeAwayMessage
 *
 * 19990113.1412: added to_bits, from_bits bitfields to support %to-multiple;
 *	added methods getUserByIndex and sendToByIndex to JDMChatRoom.
 *
 *
 *
 *
 *
 *
 * (981219.0605): since substate is now time_t and not int, GetUserIncremental
 *	requires an int &, created a temp called usrnum.
 *
 * 981219.0600: tab now lists multiple matches if they exist; ^D now
 *	logs the user out if typed twice quickly (less than 2 sec apart).
 *	(reqested by Rowan)
 *
 *
 *
 *
 * 981207.0015: partial-user matching and completion (tab, ^D) support.
 *
 *
 *
 *
 *
 * 981108.1600: no more beep when going away (now consistent with leaving).
 *
 *
 *
 *
 * (981008.1950): if just '%' or '%help', won't say "no such command",
 *	just lists valid ones.	(thanks Rowan)
 *
 * (981006.1350): optionally keep substate across state transitions
 *
 * 981005.1930: un-%away only on <cr> on non-cmd when not in %to mode
 *
 * 981005.1025: added enforced wait on incorrect logins
 *	(added waittil field, checks in ManageUser(), sets in HandleGetPw() )
 *	As of 981008.1950, this _still_ doesn't work quite right...
 *
 * (981005.1015): better data encapsulation for changes of state;
 *	added setState(), prevstate.
 *
 * 981005.0955: added timestamp to login, logout announces.
 *	Uses the ctstr field (ret. by loginTimeStr()) to hold
 *	logout time in hh:mm form.
 *
 *
 *
 *
 *
 * (980914.0850): fixed: check for WasUserAccepted() before printing
 *	"has left"... before, you could log in, and just not type anything
 *	at the password field and let it time out, and it said to the room that
 *	you'd left, without ever having said you were there.
 *
 *	Used prevstate field of user object to store previous state when
 *	we go to STATE_NO_CONNECTION.  Added public WasUserAccepted()
 *	to return this info.
 *
 * (980914.0840): fixed: now prints hostname not host ip when possible
 *
 * 980911.2300: added optional guest-howto-message on login (for jpritch!)
 *	Define GUEST_HOWTO_MESSAGE to print it.
 *
 * 980910.0930: added ^W support to ManageInputBuffer
 *
 * 980903.2200: removed %beep due to awkward implementation, due to hardcoded
 *	^G's in strings.  Added SIGINT handler (which == the SIGTERM handler)
 *
 * (980903.1230): when init is complete, jdmchat now does chdir("/") to ensure
 *	we're not keeping any files/dirs/filesystems open we don't need...
 *	this is recommended for daemons and long-running processes.
 *
 * 980903.1200: guest timeout is announced to room.
 *
 * 980830.2000: %time command; also, kick-idle-self now announces to the room.
 *
 * 980809.1120: per user, can disable the beeps!
 *
 * 980809.1020: find and kick duplicate logins of yourself on login.
 *
 * 980809.0900: added SIGTERM handler that closes sockets up,
 *	and writes log file logout entries, before exiting.
 *
 *
 *
 *
 *
 * 980710.1530: now, only guests can be kicked;
 *	this fixed the can-kick-self race condition as well.
 *
 * (980709.1715): fixed linewrap-in-input bug for long prompts, and
 *	encapsulated setprompt
 *
 * 980709.1700: added hint bits
 * ( and encapsulated lpwrite(user_fd,msg) into uWrite(msg)
 *   and uWrite(msg, hintbits) )
 *
 * 980703.2345: added guest support
 *
 * 980701.1500: added specify-recipient
 *   Note:
 *	Currently, if the target of private messages logs off,
 *	the sender of these messages will still send there
 *	for the next message (i.e., the discon check is in
 *	_sendOut)... better would be to set to broadcast when
 *	the person-has-left notification goes out.
 *
 *
 *
 *
 *
 * 980524.1800: added word wrap on long lines
 *
 * 980524.1630: added username/password authentication
 * 	. added /etc/issue.net pretty login message
 *
 * 980524.1500: added useful stuff to ManageInputBuffer:
 *	. moved strlen() from inside printf() to a static int.
 *	. added ^U support
 *
 * -- down here is The Beginning of Development, from jdkchat 1.3 --
 * -- on 24 may 1998.  Twas such a short, simple program...  -jer --
 */
