******************************************
* What's New in Synchronet Version 3.21c *
******************************************

General
~~~~~~~
o Filter files (i.e. ip[-silent].can, host.can) and related config files
  (i.e. ipfilter_exempt.cfg, spamblock.cfg) are now cached in memory by
  default
o Hosts listed in ipfilter_exempt.cfg are now exempt from any filtering from
  ip[-silent].can and host.can
o Better config (.ini) file read error detection and reporting
o Synchronet Console (sbbs[.exe]) can accept the ctrl directory as an argument
  - Consistent with sbbsctrl.exe usage
o Store/reuse each server's client highwater mark for MQTT publishing
  - Issue #910
o Add support to SMBLIB for "Fixed" format message text
  (e.g. for messages uploaded in raw input mode)
o Better support for maintaining/rebuilding message base indexes while in-use
o Support short (8-char) less ambiguous "verbal" dates in multiple formats
  for display purposes (e.g. "Jan02'26" instead of "01/02/26")
o Expand 16-bit unsigned integer statistical user fields to 32-bit
  increasing maximum values from 65535 to 4.2B
o Address concurrency issues with user daily statistics/free credit fields
  - Each user's stats reset date/time stamp now stored in user base/record
o Improvements to daily backups of mail and user data
  - Don't back up files when empty
  - Log the total bytes and items (users and messages) backed up
o Support tracking and limiting of user file downloads "per day" - issue #938
o System statistics and mail message counts are now cached (default: for 5s)
o Increased from 40 to 60 characters the maximum length of descriptions (long
  name) of message groups and sub-boards and file libraries and directories
o The SCFG->Networks->Internet E-Mail and FidoNet "Allow Sending of ..."
  options now apply to sysops as well as users; sysops are not automatically
  exempt from this setting
o WIP ARS keyword restored for run-time compatibility with old Baja modules
  (e.g. matrix.bin)
o User properties (data/user/####.ini) are now exposed to ARS and @-codes
  - New ARS Keyword PROP[:section]:key to check the truthiness of a property
  - New @-codes (YESNO and ONOFF) for checking Access Requirement Strings
    (not just user properties) which may be used to get/display Yes/No or
    On/Off text strings based on the full ARS comparison
  - New @-code (PROP[:section]:key) to get/display the *value* of any user
    property (not just its truthiness)
o Increased max files per directory from 65535 to 4.2B (99999 via SCFG)
  (0/unlimited remains an option)
o Track user bytes downloaded (in files) per day
  - Reflect these stats in drop files that support it:
    DOOR.SYS, CALLINFO.BBS, and SFDOORS.DAT

Synchronet Control Panel (sbbsctrl.exe) for Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Can now accept path to sbbs.ini argument - Consistent with sbbs[.exe] usage
o Can now spy on clients with terminal dimensions > 160x50 without crashing
o Resolved (silent) crashes during shutdown (server termination)
o More resilient to running with a mismatched sbbs.dll version
o Server start/pause/stop control states make more sense (e.g. the
  "Start" button is disabled during server initialization)
o Improved "Abort dialog" while waiting for graceful server termination(s)
  - lists all the servers still running
o Beautify the stats log output a bit
o Updated BBS->Edit file links
  attr.cfg -> attr.ini
  answer.asc -> answer.msg
  logon.asc -> logon.msg
  logoff.asc -> logoff.msg
o No more pop-up/exception messages about "Invalid pointer" or "Invalid index"
  upon server-updates to the Clients dialog

Terminal Server
~~~~~~~~~~~~~~~
o New "seek" mode available when viewing files allows jumping around with
  extended keys (e.g. home, end, page up/down, arrow keys) without relying on
  terminal scroll-back (see/use new P_SEEK mode with console.printfile()
  and (the new) printfile.js
o Use SAUCE record embedded in display files (e.g. *.ANS, *.MSG), when present,
  to automatically determine expected display width (in columns)
o New node*/status.ini file to report current node status with more accurate
  representation of the current external program being executed, if any
o Multiple loadable modules may be configured for each loadable module type
  in SCFG->System->Loadable Modules, individually restrictable via ARS
o Newly abstracted (via C++ classes) terminal input/output
  - Sets the stage for future support for more terminal types
  - Should see no (or minimal) changes in behavior
  - Auto-detects PETSCII terminals connecting to standard TCP ports via
    Telnet, SSH or RLogin "terminal type" advertisement by client
o Formatted output option of specific files and sub-boards for max width 80
  column display, for better experience on > 80 column terminals
o Wide (>80 column) terminal users using the built-in mail reading interface
  can toggle "wide output mode" with the 'W' key.
o Built-in detection and short-inactivity timeout of dumb terminal/bot logins
o Send notification messages to recipients of files uploaded - issue #955
o Allow search by author forward/backward for netmail messages - issue #484
o Disallow sending netmail (Internet, FTN, or QWK) to our own/local addressses
o Eliminate the "Start with number [n]:" prompt in initial email listing
o Ctrl-O now temp-toggles pause on/off for users that have pause disabled
o Improved log file concurrency (protection against corruption)
o Improved tracking of the terminal server user login/logon state - issue #979
o Fix cosmetic issue with Logging-out node vstatus display (NodeStatusLogout)
o Fix word-wrap when viewing messages that contained "pipe codes"
  (i.e. Renegade, WWIV, Mystic color codes)
o Set node "interrupt" flag to try to gracefully disconnect user blocking
  a timed event execution for 30m
o Disable Celerity "pipe code" parsing when displaying .rip files
  - Renegade "pipe codes" are supported in .rip files however
o Improved parsing of invalid @-codes (fixes text/menu/batchxfr.rip)
o Add node interrupt flag checking to *nix external() execution of stdio progs
o Support optional ctrl/<terminal-protocol>/text.ini file
o Support text.dat substring replacements via text.ini [substr] section
  - Replace words, Ctrl-A codes, whatever, in all text.dat strings
o New "User" attributes controlled via attr.ini: 'userhigh' and 'userlow'
  settings: whatever attributes the sysop places there will be used for
  Ctrl-AU (userhigh) and Ctrl-Au (userlow)
o Similar to above, Ctrl-AV (mnehigh) and Ctrl-Av (mnelow) can be used for
  those sysop-configurable attributes
o Modified text and menu files can now be placed in mods/text/
o Log more details during new user registration process
o Separate global support for "extra attribute codes" from per sub-board opts
o If editor doesn't create a file, don't log an error message - issue #914
o Ensure messages created/edited are always CRLF line-terminated
o When listing mail messages with no "to" field, display SMTP forward path
o Remove superfluous/erroneous ".0" from displayed age of posted messages
o When printing display files that use PCBoard color codes,
  don't reset attributes (to lightgrey) at the end of each line
o Don't add CP437 QWKnet tagline glyph when message is explicitly US-ASCII
o Use FTN charset of "ASCII 1" when the imported message is explicitly ASCII
o Output multiple inverted question marks for > 1 width UNICODE characters
  for non-UTF8 terminals
o Add "exclusive external program" option to timed event configurations in SCFG
o When the user has unread personal mail, give a different prompt during logon
o Add New User Prompt toggle option to allow single-word real names
o Resolve menu/../* to abs-path before checking file existence - issue #918
o When text/menu/logoninfo.msg exists, it'll be displayed during logon
  (when SCFG->System->Toggles->Display Sys Info During Logon is set to "Yes"
  the default), in place of the hard-coded logic/text strings (SiSysName,
  LiUserNumberName, etc)
o When text/menu/userinfo.msg exists, it'll be diplayed for user_info()
  functions, in place of the hard-coded logic/text strings (UserStats, etc)
o When text/menu/sysinfo.msg exists, it'll be diplayed for sys_info()
  functions, in place of the hard-coded logic/text strings (SiSysName, etc)
o When text/menu/subinfo.msg exists, it'll be diplayed for sub_info()
  functions, in place of the hard-coded logic/text strings (SubInfo)
o When text/menu/dirinfo.msg exists, it'll be diplayed for dir_info()
  functions, in place of the hard-coded logic/text strings (DirInfo)
o Don't close node.log file stream when invoking command-lines with a '?'
  prefix - allows JavaScript mods to write to system log using appropriate
  'bbs' functions
o New Message Scan
  - Break scan loop on abort (Ctrl-C) - issue #926
  - Don't prompt to add sub to new-scan when scanning for polls (to vote on)

Web Server
~~~~~~~~~~
o New configurable request rate limiter (rate limited per client IP address)
o New LoginInfoSave option (ARS) to specify which users login info should be
  saved upon logon/off (default is *all* users)
o Log output improvements
  - Apache-style custom HTTP access log format now supported
  - Single/one HTTP access log for all Virtual Hosts now supported
  - Include client protocol (HTTP or HTTPS) and IP address in more log msgs
  - Include more detail (e.g. send byte count) in "ERROR sending" message
  - Lower severity of "Executing FastCGI" log message from Info to Debug
o Improve logging around SSJS-generated error page/sending
  - Reduce severity (to DEBUG) of "Using SSJS error page" message
  - Include protocol and IP address and error code in each message
o Fix max concurrent connections limit - wasn't reliably limiting connections
o Immediately reject non-TLS connections that exceed concurrent connections
  limit

FTP Server
~~~~~~~~~~
o New configurable request rate limiter (rate limited per client IP address)
o Allow uploaders to remove files that they uploaded - issue #952

Mail server
~~~~~~~~~~~
o New configurable request rate limiter (rate limited per client IP address)
o Strip control chars from "B" mime-encoded words in incoming header fields
o Support "quoted" local-part of RCPT TO: <mailbox> argument
o Fixed mismatched sender/from extension in created SMTP-bounce messages
o New LoginInfoSave option (ARS) to specify which users login info should be
  saved upon logon/off (default is *all* users)
o If SMTP-authenticated, fail subsequent AUTH commands with 503 response
  - Compliant with RFC 4954: "server MUST reject any further AUTH commands"
o Ignore (but log an error) when DNSBL server returns address != 127.0.0.x
  - sbl.spamhaus.org returns 127.255.255.254 when attempting to query using a
    public/open resolver

@-codes
~~~~~~~
o Allow C escape sequences in EXEC: argument, to allow param passing
  e.g. separate module name from command-line params with \x20 and separate
  params from each other with \x20.
o Allow time-duration and byte-count format paramters for some @-codes.
  Currently 8 different time-duration formats are supported and 5 diferent
  byte-count formats. See https://wiki.synchro.net/custom:atcodes for details
  Now supporting byte-count format parameters (e.g. ":K", ":M", ":V" suffix):
  - FILE_BYTES
  - FILE_CREDITS
  - FILE_TIME_TO_DL
  - FREECDT
  - CREDITS
  - CDTLEFT
  - CDTUSED
  - CDTPERD
  - DLB
  - UPB
  - BTODAY
  - STATS.ULB
  - STATS.DLB
  Now supporting time-duration format parameters: (e.g. ":A", ":V" suffix):
  - TBANKED
  - MBANKED
  - TEXTRA
  - MEXTRA
  - TLAST
  - TTOTAL
  - MTODAY
  - TTODAY
  - MTODAY (aka TOTALTIME)
  - TPERD
  - TPERC
  - MPERD
  - MPERC (aka TIMELIMIT)
  - TLEFT
  - TIMEON
  - TUSED
  - STATS.TIMEON
  - STATS.TTODAY
  - UPTIME (now defaults to "minimal verbal" (C) format)
o Fixed for large values: TPERC, TPERD, TTODAY, TTOTAL, and TBANKED
o New @-codes:
  - 80COLS (display the remaining content formatted for an 80-column screen)
  - WRAP   (ungracefully-wrap any lines longer than the display width)
  - NOCODE (disable @-code parsing for remainder of message/file)
  - LOGOFF (like HANGUP, but more graceful, display logoff messages, etc.)
  - PROP:[section]key (a user property value from data/user/*.ini)
  - YESNO:ARS (expands to the text.dat string for Yes or No based on ARS)
  - ONOFF:ARS (expands to the text.dat string for On or Off based on ARS)
  - STOP (Wildcat! alias for PCBoard's QON)
  - NOSTOP (Wildcat! alias for PCBoard's alias for QOFF)
  - XON (Turn on PCBoard style color code parsing for current message/file)
  - XOFF (Turn off PCBoard style color code parsing for current message/file)
  - UN (alias for USERNUM)
  - NEWMSGS (number of new messages imported/posted to be read)
  - MAXMSGS (max messages for current/open sub-board)
  - NEWFILES (number of new files imported/uploaded to be seen)
  - MAXDL (max files downloaded per day, or "unlimited")
  - MAXFILES (max files for current directory - or "unlimited")
  - DTODAY (number of files downloaded by user today)
  - BTODAY (estimated number of bytes downloaded by user today)
  - DAYBYTES (exact number of bytes downloaded by user today)
  - USEDCDT (previously DAYBYTES)
  - UPB (estimated total uploaded bytes)
  - DLB (estimated total downloaded bytes)
  - UCP (upload credit percentage for current directory)
  - DCP (download credit percentage for current directory)
  - PSTAT (expands to On|Off text.dat string indicating Pause status)
  - RAWIO (expands to On|Off text.dat string indicating Raw I/O status)
  - RAINBOW:ON is an alias for RAINBOW
  - RAINBOW:OFF turns off rainbow output mode
  - RAINBOW:RAND picks a random starting color from the rainbow attributes
  - RAINBOW:<num> picks a specific starting color index from the rainbow
  - RAINBOW:<attr-list> at least one colon-separator is now required
  - CLOCK (whole number system timer, typically 1ms interval)
  - TIMER (highest resolution system timer, real number, fractions of second)
  - CDTPERD (estimated free credits per day, e.g. "5.0G")
  - CDTUSED (estimated free credits used today, e.g. "1.0G")
  - CDTLEFT (estimated total credits available to user, e.g. "5.5G")
  - FFILES (number of files in user's batch download queue)
  - FBYTES (total size of all files in user's batch download queue)
  - FCOST  (cost, in credits, of all the files in batch download queue)
  - FTIME  (estimated time to download all the files in batch download queue)
  - FILETYPES  (allowed file types/extensions for current directory or "All")
  - DIRV       (virtual directory name for current directory)
  - DIRVPATH   (virtual path for current directory)
  - QWKNAME    (QWK conference name for current/open sub-board)
  - QWKTAG     (QWKnet tagline for current/open sub-board)
  - FIDOAREA   (FidoNet Area Tag for current/open sub-board)
  - FIDOORIGIN (FidoNet Origin Line for current/open sub-board)
  - NEWSGROUP  (Newsgroup Name for current/open sub-board)
  - PROTOCOL   (alias for PROTNAME)
  - ADDR2      (alias for FROM)
  - LASTCALL   (date/time of last logoff of this sbbs instance)
  - LASTCALL:t (custom strftime-formatted output of the above date/time)
  - OPTEXT     (current value of bbs.optext property, writable via JavaScript)

Text Strings
~~~~~~~~~~~~
o Newly added:
  - WideModeIsNow
  - NoMoreDownloads
  - ReadYourUnreadMailNowQ
  - UserDownloadsToday
  - NodeLoggedOnAtNbps added "via "
  - UserSentYouFile changed to include filename parameter
  - SeekingFile
  - SeekingFileDone
  - SeekPrompt
o UserDefaultsPassword changed to broaden scope (personal/credentials)
o UserDefaultsLanguage changed to reflect new command key (L)
o RawMsgInputModeIsNow changed to include RAWIO @-code
o Changed to accommodate 40 column terminals better (w/Cond-Linecont):
  - InternetMailReceived
  - DeletePostQ
  - NScanAllGrpsQ
  - SScanAllGrpsQ
  - CallingFromNorthAmericaQ
  - AutoTerminalQ
  - UeditReadUserMailWQ
  - UeditReadUserMailSQ
  - ForwardMailQ
  - NetMailCostContinueQ
  - DownloadBatchQ
  - AddSubToNewScanQ
  - IceColorTerminalQ
  - MouseTerminalQ
  - InternetMailSent
  - FidoNetMailSent
  - QWKNetMailSent
  - ReadYourUnreadMailNowQ
o Changed to refer to user's host name as such, not computer or client:
  - EnterYourComputer
  - UeditComputerModem
o Changed to accommodate bigger statistical values:
  - UserTimes
  - UserLogons
  - UserEmails
o Changed to use (new) Ctrl-AU and Ctrl-Au codes for user-defined (sysop
  defined)attributes instead of hard-coded high and low-intensity green:
  - too many to list
o Changed to accommodate bigger (60-char) group/lib/dir/sub descriptions:
  - SubLstHdr
  - SubLstFmt
  - GrpLstHdr
  - GrpLstFmt
  - DirLstHdr
  - DirLstFmt
  - LibLstHdr
  - LibLstFmt
  - SubInfoLongName
  - SubInfoShortName
  - SubInfoQWKName
  - SubInfoMaxMsgs
  - DirInfoLongName
  - DirInfoShortName
  - DirInfoAllowedExts
  - DirInfoMaxFiles

Security
~~~~~~~~
o Improved TLS and SSH error handling/logging
o New ARS keyword: DLT (Downloads Today)
o New option: SCFG->System->Security->Create Self-signed Certificate
  See issue #881
o Remove sorbes.net from ctrl/dns_blacklist.cfg as it is has ceased operation
o Rework part of the "good password" checking algorithm:
  Require that a good password contain a sequence of unique characters
  (not repeating, incrementing, or decrementing in ASCII code value) of at
  least half the configured minimum password length. By default, the minimum
  password length is 4 chars, so this means a sequence of at least 2 unique
  characters is required. If the minimum password length is increased by the
  sysop, so is the minimum required unique sequence length. The
  "PasswordInvalid" text.dat string is printed when passwords are rejected
  by this criteria.

  Previously, the following would be rejected by this portion of the algo,
  this logic has been replaced by the above:
  - all chars the same (would print the "PasswordInvalid" text.dat string)
  - first 4 chars are incrementing ("PasswordObvious" string printed)
  - first 4 chars are decrementing ("PasswordObvious" string printed)
  but now, a password that starts with "1234" or "abcd" is fine so long as
  it's longer than that and contains the minimum unique sequence length. This
  will prevent SBBS from rejecting high quality (e.g. randomly generated or
  crypto-hashed) passwords that just happen to begin with an incrementing
  sequence of 4 digits or alpha-characters.

  To enable high quality/entropy password checking, set SCFG->System->Security
  ->Demand High Quality Password to "Yes".
  This option defaults to false since the "quality" standard is higher than it
  used to be and that could be confusing for sysops or users.

SCFG
~~~~
o New menu: System->Extra Attribute Codes controls extra attribute
  support in display files (e.g. menus)
o New option: System->New User Prompts->Force Multi-word Real Name
  (default: Yes)
o New Option: System->New User Values->Toggles->Mouse-enabled Terminal
  (Defualt: No)
o New option: System->Security->Demand High Quality Password
  (default: No)
o New Option: System->Advanced->Statistics Interval (cache duration)
  (default: 5 seconds)
o New Option: System->Advanced->Cache Filter Files (file check interval)
  (default: 5 seconds)
o New Option: SCFG->Servers->Terminal Server->Max Dumb Login Inactivity
o New Option: System->Servers->[Web|FTP|Mail] Servers->Limit Rate of Requests
o New Option: Networks->QWK->Hubs... Include MIME-encoded Text (default: No)
  ... and Word-wrap Exported Messages (default: No)
o New option: External Editors ... Retain Ctrl-A Codes in Quotes
o New option: Message Options->MailBase Storage Method (default: Self-packing)
  allows sysop to choose "Fast Allocation" Storage Method if needed/preferred
  but requires periodic MailBase packing to keep manage disk usage/free space
o New System->Security Options->Security Level Values... "Downloads Per Day"
  (D/D): defaults to 0/Unlimited for each level
o System->Loadable Modules now allows multiple modules to be configured per
  "Loadable Module" type, restricting access based on Access Requirements (ARS)
o System->Short Date Format can be used to select a verbal or numeric date
  format (of many forms) for displaying short dates
o New option: SCFG->External Programs->Fixed Events->New User ...
o External Programs->Fixed Events now supports multiple events (i.e. commands)
  per event type
o Remove external editor option: "Expand LF to CRLF" - no longer needed
o Each configured sub-board can have each extra attribute type toggled on/off
o Access Requirements editing menu updated to include terminal and user types
o Creating new File Options->Viewable/Testable/Extractable/Compressible Files,
  Download Events, or Transfer Protocols now prompts for the required fields
  rather than copying values from an adjacent already configured item or (when
  the list is empty) pre-populating with default values
o Resolved issue of System menu detecting changes by the sysop
  (and prompting to Save Changes when exiting) when no changes were actually
  made, just that DST had been auto-enabled/disabled based on the date

SBBSecho
~~~~~~~~
o Extracts/imports inbound bundles starting from 6 days ago, not always Sunday
o Auto-enable "EchoList Only" areamgr mode when EchoList Keys are used
o If origin line missing form incoming echomail, attempt to parse origin
  address from the MSGID kludge, if it has one (issue #1066)
o When netmail is forwarded to an external (e.g. email) address, notify user
o UTF-8 encode Origin lines in exported messages when appropriate
o Strip Ctrl-A codes from exported *NetMail* messages
o Add the "Ignore Packed Foreign NetMail" option to echocfg
o Support robots that use .msg files directly
  Each configured robot now has a "Uses MSG File" option (defaults to false)
o Don't write empty PATH: control line to exported echomail message
  Points don't normally have any addresses to add to the PATH: line, so
  (as was pointed out in the FIDOTEST echo), an empty PATH: line would be
  included in exported echomail messages from points.
  Although this isn't a violation of FTS-4, it is a violation of its proposed
  successor: FSC-74: "Blank" path lines shall not be transmitted
o Don't list REQ (file request) files in flow files per FTS-5005
o Allow a "max message count" to be specified in AreaMgr "rescan" requests
  - The -R option (in the subject), can now include a message count (-R=count)
  - The %RESCAN function (in the body) can now include a message count
    i.e. %RESCAN [area-tag] [R=<count>]
o Add "maximum message age" in days option for AreaMgr %RESCAN use
  - Support for -D=<days> in message subject and D=<days> option in
    %RESCAN and %RESCAN <area-tag> commands
  - The -R subject option can be used in combination with the %RESCAN D=
    option (or vice versa) to both limit the number *and* the age of messages,
	if desired
  - Issue #929

Services
~~~~~~~~
o New configurable connect rate limiter (rate limited per client IP address)
o Support for LoginInfoSave option (ARS) to specify which users login info
  should be saved upon logon/off (default is *all* users)
o nntpservice.js
  - Fix -mail option
  - The -mail option now allows user (non-Guest) access to their email
  - Include sent mail messages in "mail" newsgroup too
  - Add support for -utf8 option - issue #917
o gopherservice.js
  - Send contents of text/gopher_welcome*.msg files in root of gopher map
    Issue #946

Modules
~~~~~~~
o automsg.js
  - Add meme formatter, make meme format the default (using meme_chooser.js)
    Set modopts/automsg.ini meme=false to disable this behavior
o chksetup.js improvements
  - Compares running version of Synchronet against latest release number
  - Reports users whose passwords don't meet current requirements
o default.js
  - New /M command to post a message in "meme format"
o delfiles.js
  - Speed up the -offline search by using the directory() output
o email_sec.js
  - Use the user's chosen sort order for all mail reading modes,
    including sent mail and unread mail
  - Now a configurable loadable module in SCFG->System->Loadable Modules->
    Email Section
o filelist.js
  - Allow the -utf8 option to work with the -json option
  - Better application of the -user=name argument
    Parse it before all other options (e.g. before -all)
o fileman.js
  - When editing a file description that doesn't exist, pass a blank string
o filescancfg.js
  - User's default download protocol is now configurable from this menu
  - Menu/prompt loops for non-expert users
o fonts.js
  - Add 'wantblink' setting (enabled by default) to root section of fonts.ini
o init-fidonet.js
  - Add prompt for packet password (optional)
o login.js
  - Don't send legacy prompts (NN:, PW:) unless legacy_prompts=true is set
    in ctrl/modopts/login.ini
o logon.js
  - Fixed node status upon aborting new user registration process
  - Moved terminal-related prompts for Guest here from C++ hard-coded logic
    (can prompt Guests for an alternate language during logon as well)
  - Moved missing user property checks/prompts here from C++ hard-coded logic
  - Supports Rlogin terminal="xtrn_sec=<code>" to take users directly
    to a specified external program section for Rlogins
  - modopts rlogin_xtrn_logon=false to skip the logon screens for Rlogins
  - modopts rlogin_xtrn_logoff=false/true/full to control log-off for Rlogins
o msglist.js
  - Fix going to a msg number from viewing/reading msgs mod
  - Set the current node action value appropriately
  - Add missing -preview option to help output, clean-up other option help
o newuser.js
  - Use new user's mailaddr as the reply-to addr for notification email msg
o newuser_prompts.js
  - Replaces most of the "hard-coded" new user registration prompts
  - Configured by default, in SCFG->System->Loadable Modules->New User Prompts
  - Issue #563
o newuser_info.js
  - Replaces most of the "hard-coded" new user info/help screen display logic
  - Configured by default, in SCFG->System->Loadable Modules->New User Info
o pcboard.js
  - New port of the old PCBoard Clone shell written in Baja
o postmeme.js
  - New meme-style message poster ("/M" command from default shell main menu)
o postmsg.js
  - New -D (date) and -T (time) options
o printfile.js
  - Small wrapper for console.printfile(), to replace use of type[asc].js
o purgefiles.js
  - Add support for -t (testing) and -v (verbose) options
o renegade.js
  - New port of the old Renegade Clone shell written in Baja
o rlogin.js
  - Fix default mode value (should *not* be 10, i.e TG_NODESYNC|TG_CRLF)
  - Add '-h[pepper]' option to send a salted and hashed password to the server
  - Add '-H <password>' option, to send specified hashed-password
o str_cmds.js
  - Allow string command parameters to line wrap the terminal and log them
  - Beautify the "help" output - issue #901
  - Allow ";help command" to work on partially-specified commands
o tempxfer.js
  - Major useability improvements
o text_sec.js
  - Support per-section and per-document print mode flag
    Sysop must hand-edit the data/text/*.ini file, for now, to use this feature
    Set "mode=P_* [| P_*]" in root or file-sections of text/*.ini file
    See load/sbbsdefs.js for possible values
  - Support per-section and per-document print columns
    Set "cols=<columns>" in root or file-sections of text/*.ini file
o tdfiglet.js
  - New FIGlet renderer for Synchronet using TheDraw fonts
  - Supports UTF-8 or CP437 encoded output
  - Supports ANSI or Ctrl-A encoded output
o type.js
  - Use P_CPM_EOF mode flag to stop printing at Ctrl-Z (CP/M and PC/MSDOS EOF)
o uselect.js
  - A new configurable loadable module for SCFG->System->Loadable Modules->
    Select Item
  - Similar to look feel of built-in C++ method, but very customizable
o uselect_tree.js
  - A new configurable loadable module for SCFG->System->Loadable Modules->
    Select Item
  - Lightbar user interface
o user_settings.js
  - Add ability to add/edit/delete SSH keys and edit personal information
    (see exec/user_personal.js)
  - Terminal settings moved to exec/user_terminal.js
  - Use default/new-user external editor when switching from internal editor
  - Look/feel configurable via modopts/user_settings, user_personal,
    and user_terminal
o userlist.js
  - Cosmetic fix: user totals displayed were wrong when not sorting the list
o viewimsgs.js
  - When displaying instant messages, auto-detect UTF-8 encoded messages
o xjs.js
  - Fix error "creating" log message details (filename and error value)
  - Throw Error exception rather than just logging errors, better traceability
o xtrn_sec.js
  - Allows the use of JS:xtrn_sec @-code in the 'which' prompt string
  - Support multicolumn xtrn program *section* listing
    (multicolumn_section_fmt option) - issue #915
  - Add 'align_prog_list' and 'align_section_list' options
    For use when multi/singlecolumn_fmt or section_fmt strings don't contain
	padded integer specifiers (e.g. %3u) - issue #911

JavaScript
~~~~~~~~~~
o js.exec() will now execute scripts from the configured mods and exec dir
o console.getstr() fix: off-by-one bug in use of maxlen argument
o New console.inkey() mode flag: K_EXTKEYS can be used instead of K_CTRLKEYS to
  get all control key input, but *with* extended key translations (e.g. arrows,
  home, end, page-up/down, etc.) and without messing with (modifying/restoring)
  console.ctrlkey_passthru
o console.mnemonics() method now accepts an optional p_mode parameter
o console output methods that accept p_mode parameters now support
  P_CENTER and (new) P_80COLS mode flags
o console.strlen() method now calculates display length more accurately when
  using advanced Ctrl-A codes, embedded CR or LF and extra attribute/color
  codes (e.g. PCBoard, Wildcat, etc.)
o Returned to SBBS v3.19 bug-compatible console.attributes behavior of
  silently ignoring Ctrl-A characters in assigned strings
o New 'console' properties:
  - optimize_gotoxy
  - uselect_count
  - uselect_title
  - uselect_items[].name and .num
  - color_list (technically there before, but not enumerable)
o msg_area.grp_list[] no longer includes groups with no sub-boards that the
  user can access - issue #905
o New 'bbs' methods:
  - logline(level=LOG_INFO, code, string)
  - matchuserdata()
o New 'bbs' properties:
  - batch_dnload_bytes
  - batch_dnload_cost
  - batch_dnload_time
  - optext (see OPTEXT @-code)
o bbs.ver()
  - now takes an optional 'p_mode' (print mode) argument
    (default: P_CENTER | P_80COLS)
  - now takes an optional 'verbose' argument (default: true)
o bbs.good_password() renamed to bbs.check_password(), with backward-alias
o bbs.read_mail() adds option to go directly to viewing messages (not listing)
o New 'system' property:
  - phonenumber_template
  - stats_interval
o New 'system' methods:
  - check_password()
  - check_realname()
  - check_netmail_addr()
  - check_birthdate()
  - minutestr()
  - undel_user()
o system.secondstr() now accepts an optional 'verbose' argument, default: true
o New User class properties:
  - is_guest
  - is_active
  - stats.bytes_downloaded_today
  - stats.files_downloaded_today
  - limits.file_downloads_per_day
o New User class methods:
  - can_access_sub()
  - can_access_dir()
o New TLS properties to the Socket class:
  - tls_nameverify (defaults to true)
  - tls_certverifiy (defaults to true)
  - tls_client_auth (defaults to false)
  - tls_enhanced_certcheck (defaults to false)
  - tls_remote_cert

JSexec
~~~~~~
o New -U (require successful config load) option, -R option is deprecated
  This new option (-U) is only really needed when invoking update.js to
  upgrade from Synchronet v3.19 or older to v3.20 or newer
o Only change the terminal/tty state if both the input AND output are TTY
  so when the output is redirected (e.g. to 'more' or 'less') we don't leave
  the terminal in a bad state when terminating - issue #999

SEXYZ
~~~~~
o Using poll() instead of select() on UNIX-like OSes now
  supporting socket descriptor values > 1024, issue #445
o Support for glob matching characters (e.g. "[]") in filenames on *nix
o ZMODEM interoperability with Tera Term
  https://github.com/TeraTermProject/teraterm/issues/889

SMBUTIL
~~~~~~~
o More resilient to concurrent opens (by other processes, even though locked)
  while maintaining/packing a msg base
o Fix index corruption resulting from packing an unmaintained msg base
  and filebase corruption

******************************************
* What's New in Synchronet Version 3.21e *
******************************************

General
~~~~~~~
o Fix !include'd .ini files getting merged (e.g. with modopts.ini), issue #1088
o Add configurable colors to uifc.ini (and related .ini files, e.g. scfg.ini)
o Fix non-blocking TCP connects (Mail Server SendMail and Telnet/Rlogin Gate)
o Fix crashes with cached filter files and using an older MSVC++ runtime
  (MSVCP140.dll)
o Fix linked-list mutual exclusion protection on Windows
  - all mutex-protected linked-lists shared the same critical section handle

Terminal Server
~~~~~~~~~~~~~~~
o Return to the 1-second ESC key delay of Synchronet v3.20 and earlier
o printfile(..., P_SEEK) now accounts for extended color codes in print columns
o Display changed attributes in change message attribute function
o When reading un-read mail, log msg "read un-read mail" instead of "read mail"
o Don't set the "read" message attribute flag if message display was aborted
o Fix the LINEDELAY @-code behavior (delaying between output lines)
o Do not apply the "Expire when out of time" feature to user not logged-in
  Resolve errors reported by plt via IRC when SCFG->System->Security->
  User Expires When Out-of-time is set to "Yes" and a client runs out of time
  before being able to successfully login. Example:
    term Node 1 !ERROR in data_ovl.cpp line 150 (sbbs_t::putuserdec32) writing
    "user.tab" access=-100
o When executing .bin modules, enable globally-supported
  (SCFG->System->Advanced) extra attribute codes in PRINT function calls
  Fix issue #1091

SCFG
~~~~
o Add help text for the "Parent Directory" prompt when importing a dir list
  This prompt could be confusing, so explain how/why it's being prompted for
o Add help text for the List File prompts when import/exporting directory list
o Re-word the "Min bytes Free Disk Space" option to be a little clearer
o Make the FTP server's minimum/maximum uploaded file sizes configurable here
o Add special help text for the "Moderated Posting User" requirements settings
o Update help text for fixed events, clarifying that some can be interactive

Synchronet Console (sbbs.exe for Windows)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Graceful detection and reporting of sbbs library version mismatch
o Accidentally named sbbscon.exe, back to the normal/expected name: sbbs.exe
o Add support for (re)starting stopped servers from prompt
o Make the prompt for which server to (T)erminate, (S)hutdown/Start, or
 (R)ecycle re-display when there new log messages appear

JSexec
~~~~~~
o Graceful detection and reporting of sbbs library version mismatch

Synchronet Control Panel (sbbsctrl.exe) for Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Fix uptime jump (forward or backward) upon Daylight Saving Time
  Fix issue #1093
o Close node.dab file between refreshes if first node is so-configured in SCFG
o Restore form "View states" - don't always restore all forms as visible

Web Server
~~~~~~~~~~
o Fix long standing heap corruption causing libmozjs crash triggered via POST
  Issue #1094

Mail Server
~~~~~~~~~~~
o Log the message relative number (and total msgs waiting) for POP3 retrievals
  giving some indication of progress towards the last message waiting for the
  user

FTP Server
~~~~~~~~~~
o Log better errors/warnings when upload directory doesn't exist
  or doesn't have enough free space
o Load file data from filebase when updating (uploading) an existing file
  Fix !DATA ERROR -101 updating file (filename) in database
o Log the restart offset both when the client sets it (with the "REST" command)
  and in the "uploading" log message, helpful in debugging unique upload issues
o More accurate log/response messages about maximum file size allowed
  The max file size allowed for upload can change based on available disk space
  and the sysop-configured minimum amount of free disk space. Report the
  correct numbers

Modules
~~~~~~~
o <several>
  - Fix wide-spread misuse of console.getkeys()
o automsg.js
  - More friendly to 40-column terminal users
o emailval.js
  - Usability improvements
  - Don't allow a blank valid_chars options to break this module:
    the default ctrl/modopts/emailval.ini has the key 'valid_chars' set to
    nothing, just as an example/documentation, but that had the effect of
	setting the valid chars to a blank string (no valid code chars). Now fixed
o email_sec.js
  - prompt is now configurable via modopts [email_sec] prompt
o avatars.js
  - install() no longer overwrites existing keys/values in modopts.ini
  - identicons are now supported
    Set modopts.ini [avatars] auto_identicon = false if you don't want them
  - Add 'enabled' option (default true) to modopts [avatars]
    The nuclear option to disable avatar display everywhere
o avatar_chooser.js
  - Add "Identicon as avatar" option
o meme_chooser.js
  - Usability improvements
o mqtt_spy.js
  - Output the MQTT spy banner earlier
o newuser.js
  - Add identicon avatar option, set modopts [newuser] avatar_identicon = true
o nodelist.js
  - Use console.putmsg() instead of write() where @-codes might be wanted
o update.js
  - '-noavatars' option now supported

chksmb/fixsmb/smbutil
~~~~~~~~~~~~~~~~~~~~~
o Gracefully terminate (e.g. unlock msgbase) when aborted with Ctrl-C/break

Text Strings
~~~~~~~~~~~~
o FileInfoEditPrompt - Shortened so it doesn't wrap (for 80col terminals)
  when spinning cursor is enabled
