imported 9.0.299 Beta.01
[ckermit.git] / ckuus2.c
index 1290763..b0dfb30 100644 (file)
--- a/ckuus2.c
+++ b/ckuus2.c
@@ -11,7 +11,7 @@
     Jeffrey E Altman <jaltman@secure-endpoints.com>
       Secure Endpoints Inc., New York City
 
-  Copyright (C) 1985, 2004,
+  Copyright (C) 1985, 2011,
     Trustees of Columbia University in the City of New York.
     All rights reserved.  See the C-Kermit COPYING.TXT file or the
     copyright text in the ckcmai.c module for disclaimer and permissions.
 
   IMPORTANT: Character string constants longer than about 250 are not portable.
   Longer strings should be broken up into arrays of strings and accessed with
-  hmsga() rather than hmsg().
+  hmsga() rather than hmsg().  (This statement was true in the 1980s and
+  probably is not a big concern in the 21st Century, but you never know;
+  there still might exist some 16-bit platforms and C compilers that have
+  restrictions like this.
 */
 #include "ckcsym.h"
 #include "ckcdeb.h"
@@ -47,6 +50,8 @@
 #include "ckokey.h"
 #endif /* OS2 */
 
+extern char * ck_cryear;               /* For copyright notice */
+
 extern xx_strp xxstring;
 extern char * ccntab[];
 /*
@@ -144,12 +149,11 @@ static char *tophlp[] = {
 #ifndef OS2
 #ifdef MAC
 "Documentation for Command Window: \"Using C-Kermit\" by Frank da Cruz and",
-"Christine M. Gianone, Digital Press, 1997, ISBN: 1-55558-164-1.  To order,",
-"call +1 212 854-3703 or +1 800 366-2665.",
+"Christine M. Gianone, Digital Press, 1997, ISBN: 1-55558-164-1",
 #else
 "DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,",
 "2nd Edition, Digital Press / Butterworth-Heinemann 1997, ISBN 1-55558-164-1,",
-"plus supplements at http://www.columbia.edu/kermit/ckermit.html.",
+"plus supplements at http://kermit.columbia.edu/ckermit.html#doc.",
 #endif /* MAC */
 #endif /* OS2 */
 #ifdef MAC
@@ -182,10 +186,8 @@ static char *tophlpi[] = {              /* Top-level help for IKSD */
 #endif /* NOHELP */
 " ",
 "DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,",
-"2nd Edition, Digital Press / Butterworth-Heinemann 1997, ISBN 1-55558-164-1.",
-"To order: +1 212 854-3703 or +1 800 366-2665.  More info at the Kermit",
-
-"Project website, http://www.columbia.edu/kermit/.",
+"2nd Edition, Digital Press (1997), ISBN 1-55558-164-1.  More info at the",
+"Kermit Project website, http://kermit.columbia.edu/.",
 ""
 };
 #endif /* NOIKSD */
@@ -193,52 +195,45 @@ static char *tophlpi[] = {              /* Top-level help for IKSD */
 #ifndef NOHELP
 char *newstxt[] = {
 #ifdef OS2
-"Welcome to Kermit 95 2.1.3.  Major new features include:",
+"Welcome to Kermit 95 3.x.x.  Major new features since 2.1.3 include:",
 #else
-"Welcome to C-Kermit 8.0.206.  Major new features include:",
-#endif /* OS2 */
-#ifdef NT
-#ifdef KUI
-" . Runs in GUI window",
-#else
-" . GUI version available",
-#endif /* KUI */
-#endif /* NT */
-#ifdef SSHBUILTIN
-" . New built-in SSH v1 and v2 clients",
-#endif /* SSHBUILTIN */
-#ifdef NEWFTP
-" . A new built-in FTP client",
-#endif /* NEWFTP */
-#ifndef NOHTTP
-" . A new HTTP 1.1 client",
-#endif /* NOHTTP */
-#ifdef TN_COMPORT
-" . Telnet Com Port Option for dialing from Telnet modem servers",
-#endif /* TN_COMPORT */
-" . File scanning for automatic text/binary determination",
-#ifdef CKLEARN
-#ifndef OS2
-" . Learned scripts",
+"Welcome to C-Kermit 9.0.299.  New features since 8.0.211 include:",
 #endif /* OS2 */
-#endif /* CKLEARN */
-#ifndef NOSPL
-#ifndef NOSEXP
-" . LISP-like S-Expressions and natural floating-point arithmetic",
-#endif /* NOSEXP */
-" . Lots of script programming improvements",
-#endif /* NOSPL */
-" . Performance improvements and bug fixes",
+" . Open Source Simplified 3-Clause BSD License",
+" . Full 64-bit memory model on platforms that support it",
+" . Large file support (64-bit file size) on most platforms",
+" . Long integer variables and constants in commands and scripts",
+" . Bigger maximum command and macro lengths",
+" . Bigger filename expansion space",
+" . New super-flexible RENAME command",
+" . New COPY and DIRECTORY command options",
+" . New TOUCH command",
+" . Raw SSL/TLS connections for connecting to POP3 and similar services",
+" . At prompt, Ctrl-K recalls most recent filename",
+" . Scripting and performance improvements and bug fixes",
 " ",
 "Documentation:",
-" 1. \"Using C-Kermit\", second edition (1997), current with C-Kermit 6.0.",
-" 2. http://www.columbia.edu/kermit/ckermit70.html",
+" 1. http://kermit.columbia.edu/usingckermit.html",
+"    \"Using C-Kermit\", second edition (1997), current with C-Kermit 6.0.",
+" ",
+" 2. http://kermit.columbia.edu/ckermit70.html",
 "    which documents the new features of C-Kermit 7.0.",
-" 3. http://www.columbia.edu/kermit/ckermit80.html",
+" ",
+" 3. http://kermit.columbia.edu/ckermit80.html",
 "    which documents the new features of C-Kermit 8.0.",
 " ",
+" 4. http://kermit.columbia.edu/ckermit90.html",
+"    which documents the new features of C-Kermit 9.0.",
+" ",
 "If the release date shown by the VERSION command is long past, be sure to",
-"check with the Kermit Project to see if there have been updates.",
+"check with the Kermit website to see if there have been updates:",
+" ",
+#ifdef OS2
+"  http://kermit.columbia.edu/k95.html     (Kermit 95 home page)",
+#else
+"  http://kermit.columbia.edu/ckermit.html (C-Kermit home page)",
+#endif /* OS2 */
+"  http://kermit.columbia.edu/             (Kermit Project home page)",
 ""
 };
 #endif /* NOHELP */
@@ -366,10 +361,13 @@ char *introtxt[] = {
 " . CTRL-B:      Command recall - same as Ctrl-P.",
 " . CTRL-N:      Command recall - go forward in command recall buffer.",
 #endif /* CK_RECALL */
+#ifndef NOLASTFILE
+" . CTRL-K:      Insert the most recently entered local file specifiction.",
+#endif /* NOLASTFILE */
 
 " . ?            (question mark) Display a menu for the current command field."
 ,
-" . ESC          (or TAB) Attempt to complete the current field.",
+" . ESC          (or TAB or Ctrl-I) Attempt to complete the current field.",
 " . \\            (backslash) include the following character literally",
 #ifndef NOSPL
 "                or introduce a backslash code, variable, or function.",
@@ -536,27 +534,31 @@ Press the key or key-combination shown after \"Command:\" in the status line",
 "  SHOW COMMUNICATIONS, SHOW FILE, SHOW PROTOCOL, etc.",
 #endif /* NOLOCAL */
 " ",
+"The manual for C-Kermit is the book \"Using C-Kermit\".  For information",
+"about the manual, visit:",
+"  http://kermit.columbia.edu/usingckermit.html",
+" ",
 #ifdef OS2
 "For a Kermit 95 tutorial, visit:",
-"  http://www.columbia.edu/kermit/k95tutor.html",
+"  http://kermit.columbia.edu/k95tutor.html",
 " ",
 #endif /* OS2 */
-"For a C-Kermit tutorial, visit:",
-"  http://www.columbia.edu/kermit/ckututor.html",
+"For an online C-Kermit tutorial, visit:",
+"  http://kermit.columbia.edu/ckututor.html",
 " ",
 "To learn about script programming and automation:",
-"  Read the manual, \"Using C-Kermit\".  For a brief tutorial, visit:",
-"  http://www.columbia.edu/kermit/ckscripts.html",
+"  http://kermit.columbia.edu/ckscripts.html",
 " ",
 "For further information about a particular command, type HELP xxx,",
 "where xxx is the name of the command.  For documentation, news of new",
-"releases, and information about other Kermit software, contact:",
+"releases, and information about other Kermit software, visit the",
+"Kermit Project website:",
 " ",
-"  The Kermit Project         E-mail: kermit@columbia.edu",
-"  Columbia University        Web:    http://www.columbia.edu/kermit/",
-"  612 West 115th Street      Voice:  +1 (212) 854-3703",
-"  New York NY  10025-7799    Fax:    +1 (212) 662-6442",
-"  USA",
+"  http://kermit.columbia.edu/",
+" ",
+"For information about technical support please visit this page:",
+" ",
+"  http://kermit.columbia.edu/support.html",
 ""
 };
 
@@ -568,9 +570,29 @@ static char * hmxymatch[] = {
 ""
 };
 
+#ifndef NOSEXP
+static char * hmxysexp[] = {
+"SET SEXPRESSION { DEPTH-LIMIT, ECHO-RESULT, TRUNCATE-ALL-RESULTS }",
+"  DEPTH-LIMIT sets a limit on the depth of nesting or recursion in",
+"  S-Expressions to prevent the program from crashing from memory exhaustion.",
+"  ECHO-RESULT tells whether S-Expression results should be displayed as",
+"  a result of evaluating an expression; the default is to display only at",
+"  top (interactive) level; OFF means never display; ON means always display.",
+"  TRUNCATE-ALL-RESULTS ON means the results of all arithmetic operations",
+"  should be forced to integers (whole numbers) by discarding any fractional",
+"  part.  The default is OFF.  SHOW SEXPRESSION displays the current settings."
+,""
+};
+#endif /* NOSEXP */
+
 #ifdef OS2
 #ifdef KUI
 static char * hmxygui[] = {
+"SET GUI CLOSE OFF",
+"  Disables the System Menu Close and File->Exit functions which could be",
+"  used to exit Kermit.  Once disabled these functions cannot be re-enabled",
+"  and the only way to exit Kermit is via the Kermit Script EXIT command.",
+" ",
 "SET GUI DIALOGS { ON, OFF }",
 "  ON means that popups, alerts, use GUI dialogs; OFF means to use",
 "  text-mode popups or prompts.  ON by default.",
@@ -580,11 +602,21 @@ static char * hmxygui[] = {
 "  choices.  The size can be a whole number or can contain a decimal point",
 "  and a fraction (which is rounded to the nearest half point).",
 " ",
+"SET GUI MENUBAR OFF",
+"  Disables menubar functions which could be used to modify the Kermit",
+"  session configuration.  Once disabled the menubar functions cannot be",
+"  re-enabled.", 
+" ",
 "SET GUI RGBCOLOR colorname redvalue greenvalue bluevalue",
 "  Specifies the red-green-blue mixture to be used to render the given",
 "  color name.  Type \"set gui rgbcolor\" to see a list of colornames.",
 "  the RGB values are whole numbers from 0 to 255.",
 " ",
+"SET GUI TOOLBAR OFF", 
+"  Disables toolbar functions which could be used to modify the Kermit",
+"  session configuration.  Once disabled the toolbar functions cannot be",
+"  re-enabled.", 
+" ",
 "SET GUI WINDOW POSITION x y",
 "  Moves the K95 window to the given X,Y coordinates, pixels from top left.",
 "  (Not yet implemented -- use command-line options to do this.)",
@@ -940,6 +972,31 @@ static char *hmxylocus[] = {
 };
 #endif /* LOCUS */
 
+#ifdef UNIX
+#ifndef NOPUTENV
+static char *hmxxputenv[] = {
+"Syntax: PUTENV name value",
+"  Creates or modifies the environment variable with the given name to have",
+"  the given value.  Purpose: to pass parameters to subprocesses without",
+"  having them appear on the command line.  If the value is blank (empty),",
+"  the variable is deleted.  The result is visible to this instantiation of",
+"  C-Kermit via \\$(name) and to any inferior processes by whatever method",
+"  they use to access environment variables.  The value may be enclosed in",
+"  doublequotes or braces, but it need not be; if it is the outermost",
+"  doublequotes or braces are removed.",
+" ",
+"  Note the syntax:",
+"    PUTENV name value",
+"  not:",
+"    PUTENV name=value",
+" ",
+"  There is no equal sign between name and value, and the name itself may",
+"  not include an equal sign.",
+"",
+};
+#endif /* NOPUTENV */
+#endif /* UNIX */
+
 static char *hmxxtak[] = {
 "Syntax: TAKE filename [ arguments ]",
 "  Tells Kermit to execute commands from the named file.  Optional argument",
@@ -1221,22 +1278,38 @@ static char *hmxxscrn[] = {
 
 #ifndef NOSPL
 static char *hmfword[] = {
-"\\fword(s1,n1,s2,s3,n2,n3) - Extract word from string.",
-"    s1 = source string",
-"    n1 = word number (1-based)",
+"Function \\fword(s1,n1,s2,s3,n2,n3) - Extracts a word from a string.",
+"    s1 = source string.",
+"    n1 = word number (1-based) counting from left; if negative, from right.",
 "    s2 = optional break set.",
-"    s3 = optional include set.",
+"    s3 = optional include set (or ALL, CSV, or TSV).",
 "    n2 = optional grouping mask.",
 "    n3 = optional separator flag:",
-"       0 = collapse adjacent separators",
+"       0 = collapse adjacent separators;",
 "       1 = don't collapse adjacent separators.",
 " ",
-"  Default break set is all characters except ASCII letters and digits.",
-"  ASCII (C0) control characters are always treated as break characters.",
-"  Default include set is null.",
+"  \\fword() returns the n1th \"word\" of the string s1, according to the",
+"  criteria specified by the other parameters.",
+" ",
+"  The BREAK SET is the set of all characters that separate words. The",
+"  default break set is all characters except ASCII letters and digits.",
+"  ASCII (C0) control characters are treated as break characters by default,",
+"  as are spacing and punctuation characters, brackets, and so on, and",
+"  all 8-bit characters.",
+" ",
+"  The INCLUDE SET is the set of characters that are to be treated as ",
+"  parts of words even though they normally would be separators.  The",
+"  default include set is empty.  Three special symbolic include sets are",
+"  also allowed:",
+"   ",
+"    ALL (meaning include all bytes that are not in the break set)",
+"    CSV (special treatment for Comma-Separated-Value records)",
+"    TSV (special treatment for Tab-Separated-Value records)",
 " ",
-"  If grouping mask given and nonzero, words can be grouped by quotes or",
-"  brackets selected by the sum of the following:",
+"  For operating on 8-bit character sets, the include set should be ALL.",
+" ",
+"  If the GROUPING MASK is given and is nonzero, words can be grouped by",
+"  quotes or brackets selected by the sum of the following:",
 " ",
 "     1 = doublequotes:    \"a b c\"",
 "     2 = braces:          {a b c}",
@@ -1248,7 +1321,10 @@ static char *hmfword[] = {
 "  Nesting is possible with {}()[]<> but not with quotes or apostrophes.",
 " ",
 "Returns string:",
-"  Word number n, if there is one, otherwise an empty string.",
+"  Word number n1, if there is one, otherwise an empty string.",
+" ",
+"Also see:",
+"  HELP FUNCTION SPLIT",
 ""
 };
 
@@ -1266,21 +1342,69 @@ static char *hmxxprompt[] = {
 };
 
 static char *hxxinp[] = {
-"Syntax:  INPUT [ /NOMATCH ] { number-of-seconds, time-of-day } [ text ]",
-"Example: INPUT 5 Login:  or  INPUT 23:59:59 RING",
+"Syntax:  INPUT [ /COUNT:n /CLEAR /NOMATCH /NOWRAP ] \
+{ number-of-seconds, time-of-day } [ text ]",
+" ",
+"Examples:",
+"  INPUT 5 Login:",
+"  INPUT 23:59:59 RING",
+"  INPUT /NOMATCH 10",
+"  INPUT /CLEAR 10 \\13\\10",
+"  INPUT /CLEAR 10 \\13\\10$\32",
+"  INPUT /COUNT:256 10",
+"  INPUT 10 \\fpattern(<*@*.*>)",
+" ",
 "  Waits up to the given number of seconds, or until the given time of day,",
-"  for the given text to arrive on the connection.  If no text is given,",
-"  INPUT waits for any character.  If the /NOMATCH switch is included, INPUT",
-"  does not attempt to match any characters, but continues reading from the",
-"  communication connection until the timeout interval expires.  If the",
-"  timeout interval is 0, the INPUT command does not wait; i.e. the given",
-"  text must already be available for reading for the INPUT command to",
-"  succeed.  If the interval is negative, the INPUT command waits forever.",
-"  For use in script programs with IF FAILURE and IF SUCCESS.  Also see",
-"  MINPUT, REINPUT, SET INPUT.  See HELP PAUSE for details on time-of-day",
-"  format.  The text, if given, can be a \\pattern() invocation, in which",
-"  case it is treated as a pattern rather than a literal string (HELP",
-"  PATTERNS for details).",
+"  for the given text to arrive on the connection. For use in script programs",
+"  with IF FAILURE or IF SUCCESS, which tell whether the desired text arrived",
+"  within the given amount of time.",
+" ",
+"  The text, if given, can be a regular text or it can be a \\pattern()",
+"  invocation, in which case it is treated as a pattern rather than a literal",
+"  string (HELP PATTERNS for details).",
+" ",
+"  If the /COUNT: switch is included, INPUT waits for the given number of",
+"  characters to arrive.",
+" ",
+"  If no text is specified, INPUT waits for the first character that arrives",
+"  and makes it available in the \\v(inchar) variable.  This is equivalent to",
+"  including a /COUNT: switch with an argument of 1.",
+" ",
+"  If the /NOMATCH switch is included, INPUT does not attempt to match any",
+"  characters, but continues reading from the communication connection until",
+"  the timeout interval expires.  If the timeout interval is 0, the INPUT",
+"  command does not wait; i.e. the given text must already be available for",
+"  reading for the INPUT command to succeed.  If the interval is negative,",
+"  the INPUT command waits forever.",
+" ",
+"  The INPUT buffer, \\v(input), is normally circular.  Incoming material is",
+"  appended to it until it reaches the end, and then it wraps around to the",
+"  beginning.  If the /CLEAR switch is given, INPUT clears its buffer before",
+"  reading from the connection.",
+" ",
+"  Typical example of use:",
+" ",
+"    INPUT 10 login:",
+"    IF FAIL EXIT 1 \"Timed out waiting for login prompt\"",
+"    LINEOUT myuserid",
+"    INPUT 10 Password:",
+"    IF FAIL EXIT 1 \"Timed out waiting for Password prompt\"",
+"    LINEOUT xxxxxxx",
+" ",
+"  The /NOWRAP switch means that INPUT should return with failure status",
+"  and with \\v(instatus) set to 6 if its internal buffer fills up before",
+"  any of the other completion criteria are met.  This allows for capture",
+"  of the complete incoming data stream (except NUL bytes, which are",
+"  discarded).  CAUTION: if the search target (if any) spans the INPUT buffer",
+"  boundary, INPUT will not succeed.",
+" ",
+"  \
+\\v(instatus) values are: 0 (success), 1 (timed out), 2 (keyboard interrupt),",
+"  3 (internal error), 4 (I/O error or connection lost), 5 (INPUT disabled),",
+"  and 6 (buffer filled and /NOWRAP set); these are shown by \\v(inmessage).",
+" ",
+"  Also see OUTPUT, MINPUT, REINPUT, SET INPUT and CLEAR.  See HELP PAUSE for",
+"  details on time-of-day format and HELP PATTERNS for pattern syntax.",
 ""};
 
 static char *hxxout[] = {
@@ -1427,7 +1551,7 @@ static char *hxyxyz[] = {
 "Syntax: SET PROTOCOL { KERMIT, XMODEM, YMODEM, ZMODEM } [ s1 s2 [ s3 ] ]",
 "  Selects protocol to use for transferring files.  String s1 is a command to",
 "  send to the remote host prior to SENDing files with this protocol in",
-"  binary mode; string s2 is the same thing but for text mode.  Use \"%\" in",
+"  binary mode; string s2 is the same thing but for text mode.  Use \"%s\" in",
 "  any of these strings to represent the filename(s).  If the protocol is",
 "  KERMIT, you may also specify a string s3, the command to start a Kermit",
 "  server on the remote host when you give a GET, REGET, REMOTE, or other",
@@ -1573,6 +1697,9 @@ static char *hmxxsexp[] = {
 "  nil       False (empty)",
 "  pi        The value of Pi (3.1415926...)",
 " ",
+"If SET SEXPRESSION TRUNCATE-ALL-RESULTS is ON, all results are trunctated",
+"to integer values by discarding any fractional part.  Otherwise results",
+"are floating-point if there fractional part and integer otherwise.",
 "If SET SEXPRESSION ECHO-RESULT is AUTO (the default), the value of the",
 "S-Expression is printed if the S-Expression is given at top level; if ON,",
 "it is printed at any level; if OFF it is not printed.  At all levels, the",
@@ -1627,6 +1754,8 @@ static char *hmxxgrep[] = {
 "    Ignores case of letters (ASCII only) when comparing.",
 "  /NOMATCH",
 "    Searches for lines that do NOT match the pattern.",
+"  /EXCEPT:pattern",
+"    Exclude lines that match the main pattern that also match this pattern.",
 " ",
 "Display options:",
 "  /COUNT:variable-name",
@@ -1675,17 +1804,20 @@ static char *hmxxdir[] = {
 "   /ARRAY:&a        Store file list in specified array (e.g. \\%a[]).",
 "   /PAGE            Pause after each screenful.",
 "   /NOPAGE          Don't pause after each screenful.",
+"   /TOP:n           Only show the top n lines of the directory listing.",
 #ifdef UNIXOROSK
 "   /DOTFILES        Include files whose names start with dot (period).",
 "   /NODOTFILES    + Don't include files whose names start with dot.",
 "   /FOLLOWLINKS     Follow symbolic links.",
 "   /NOFOLLOWLINKS + Don't follow symbolic links.",
+"   /NOLINKS         Don't list symbolic links at all.",
 "   /BACKUP        + Include backup files (names end with .~n~).",
 "   /NOBACKUPFILES   Don't include backup files.",
 #endif /* UNIXOROSK */
 "   /OUTPUT:file     Store directory listing in the given file.",
 "   /HEADING         Include heading and summary.",
 "   /NOHEADING     + Don't include heading or summary.",
+"   /COUNT:var       Put the number of matching files in the given variable.",
 "   /SUMMARY         Print only count and total size of matching files.",
 "   /XFERMODE        Show pattern-based transfer mode (T=Text, B=Binary).",
 "   /TYPE:           Show only files of the specified type (text or binary).",
@@ -1705,7 +1837,8 @@ static char *hmxxdir[] = {
 " ",
 "Factory defaults are marked with +.  Default for paging depends on SET",
 "COMMAND MORE-PROMPTING.  Use SET OPTIONS DIRECTORY [ switches ] to change",
-"defaults; use SHOW OPTIONS to display customized defaults.",
+"defaults; use SHOW OPTIONS to display customized defaults.  Also see",
+"WDIRECTORY.",
 #else
 "Syntax: DIRECTORY [ filespec ]",
 "  Lists the specified file or files.  If no filespec is given, all files",
@@ -1713,6 +1846,14 @@ static char *hmxxdir[] = {
 #endif /* DOMYDIR */
 ""};
 
+static char *hmxxtouc[] = {
+"Syntax: TOUCH [ switches ] filespec",
+"  Updates the modification time of the given file or files to the current",
+"  date and time.  If the filespec is the name of a single file that does not",
+"  exist, the file is created.  The optional switches are the same as for",
+"  the DIRECTORY command.  TOUCH operates silently unless the /VERBOSE",
+"  switch is given, in which case it lists each file it affects.",
+""};
 
 #ifndef NOSPL
 static char *hmxxkcd[] = {
@@ -2270,7 +2411,8 @@ static char *hmxxpat[] = {
 #else
 "  with \"t\".  When typing commands at the prompt, you must precede any",
 "  question mark to be used for matching by a backslash (\\) to override the",
-"  normal function of question mark, which is providing menus and file lists.",
+"  normal function of question mark in interactive commands, which is to",
+"  provide menus and file lists.",
 #endif /* VMS */
 " ",
 #ifdef OS2ORUNIX
@@ -2297,7 +2439,7 @@ static char *hmxxpat[] = {
 #ifndef NOSPL
 " ",
 "To force a special pattern character to be taken literally, precede it with",
-"a backslash, e.g. [a\\-z] matches a, hyphen, and z rather than a through z.",
+"a backslash, e.g. [a\\-z] matches a, hyphen, or z rather than a through z.",
 " ",
 "A floating  pattern can also include the following special characters:",
 " ",
@@ -2321,11 +2463,13 @@ static char *hmxxpat[] = {
 "  \\fsearch(abc,xxabcxxx) succeeds because xxabcxx contains abc.",
 "  \\fsearch(^abc,xxabcxx) fails because xxabcxx does not start with abc.",
 " ",
-"All other commands and functions that use patterns use anchored patterns,",
-"meaning that ^ and $ are not treated specially, and * is not assumed at the",
-"beginning or end of the pattern.  This is true mainly of filename patterns",
-"(wildcards), since you would not want a command like \"delete x\" to delete",
-"all files whose names contained \"x\"!",
+
+"All other commands and functions use anchored patterns, meaning that ^ and $",
+"are not treated specially, and * is not assumed at the beginning or end of",
+"the pattern.  This is true mainly of filename patterns (wildcards), since",
+"you would not want a command like \"delete x\" to delete all files whose", 
+"names contained \"x\"!",
+
 " ",
 "You can use anchored patterns not only in filenames, but also in SWITCH",
 "case labels, in the INPUT and MINPUT commands, and in file binary- and",
@@ -2356,7 +2500,9 @@ static char *hmxxwild[] = {
 #else
 "  with \".c\".  When typing commands at the prompt, you must precede any",
 "  question mark to be used for matching by a backslash (\\) to override the",
-"  normal function of question mark, which is providing menus and file lists.",
+"  normal function of question mark in interactive commands, which is to",
+"  provide menus and file lists.  You don't, however, need to quote filename",
+"  question marks in command files (script programs).",
 #endif /* VMS */
 " ",
 #ifdef OS2ORUNIX
@@ -2382,7 +2528,9 @@ static char *hmxxwild[] = {
 #endif /* OS2ORUNIX */
 " ",
 "To force a special pattern character to be taken literally, precede it with",
-"a backslash, e.g. [a\\-z] matches a, hyphen, and z rather than a through z.",
+"a backslash, e.g. [a\\-z] matches a, hyphen, or z rather than a through z.",
+"Or tell Kermit to SET WILDCARD-EXPANSION OFF before entering or referring",
+"to the filename.",
 " ",
 #ifndef NOSPL
 "Similar notation can be used in general-purpose string matching.  Type HELP",
@@ -2566,21 +2714,18 @@ static char * hmxxlearn[] = {
 
 #ifdef CK_MINPUT
 static char *hmxxminp[] = {
-"Syntax:  MINPUT n [ string1 [ string2 [ ... ] ] ]",
+"Syntax:  MINPUT [ switches ] n [ string1 [ string2 [ ... ] ] ]",
 "Example: MINPUT 5 Login: {Username: } {NO CARRIER} BUSY RING",
 "  For use in script programs.  Waits up to n seconds for any one of the",
 "  strings to arrive on the communication device.  If no strings are given,",
 "  the command waits for any character at all to arrive.  Strings are",
-"  separated by spaces; use { braces } for grouping.  If any of the strings",
-"  is encountered within the timeout interval, the command succeeds and the",
-"  \\v(minput) variable is set to the number of the string that was matched:",
-"  1, 2, 3, etc.  If none of the strings arrives, the command times out,",
-"  fails, and \\v(minput) is set to 0.  If the timeout interval is 0 the",
-"  MINPUT command does not wait; i.e. the given text must already be",
-"  available for reading for the MINPUT command to succeed.  If the interval",
-"  is negative, the MINPUT command waits forever.",
-" ",
-"Also see: INPUT, REINPUT, SET INPUT.",
+"  separated by spaces; use {braces} or \"doublequotes\" for grouping.  If",
+"  any of the strings is encountered within the timeout interval, the command",
+"  succeeds and the \\v(minput) variable is set to the number of the string",
+"  that was matched: 1, 2, 3, etc.  If none of the strings arrives, the",
+"  command times out, fails, and \\v(minput) is set to 0.  In all other",
+"  respects, MINPUT is like INPUT.  See HELP INPUT for the available switches",
+"  and other details of operation.",
 "" };
 #endif /* CK_MINPUT */
 
@@ -2940,6 +3085,9 @@ static char * hmxxdate[] = {
 " ",
 "  The following shortcuts can also be used in place of dates:",
 " ",
+"  NOW",
+"    Stands for the current date and time.",
+" ",
 "  TODAY",
 "    Today's date, optionally followed by a time; 00:00:00 if no time given.",
 " ",
@@ -2950,12 +3098,13 @@ static char * hmxxdate[] = {
 "    Tomorrows's date, optionally followed by a time (default 00:00:00).",
 " ",
 "  Timezone specifications are similar to those used in e-mail and HTTP",
-"    headers, either a USA timezone name, e.g. EST or a signed four-digit",
+"    headers, either a USA timezone name, e.g. EST, or a signed four-digit",
 "    timezone offset, {+,-}hhmm, e.g., -0500; it is used to convert date-time,"
 ,
 "    a local time in that timezone, to GMT which is then converted to the",
 "    local time at the host.  If no timezone is given, the date-time is local."
-,
+,"    To convert local time (or a time in a specified timezone) to UTC (GMT),",
+"    use the function \futcdate().",
 " ",
 "  Delta times are given as {+,-}[number date-units][hh[:mm[:ss]]]",
 "    A date in the future/past relative to the date-time; date-units may be",
@@ -3259,10 +3408,10 @@ static char *hmxxrc[] = {
 #ifndef NORESEND
 static char *hmxxrsen = "\
 Syntax: RESEND filespec [name]\n\n\
-  Resend the file or files, whose previous transfer was interrupted.\n\
-  Picks up from where previous transfer left off, IF the receiver was told\n\
-  to SET FILE INCOMPLETE KEEP.  Only works for binary-mode transfers.\n\
-  Requires the other Kermit to have RESEND capability.";
+  Resends the file or files, whose previous transfer was interrupted.\n\
+  Picks up from where previous transfer left off, IF the receiver kept the\n\
+  partially received file.  Works only for binary-mode transfers.\n\
+  Requires file-transfer partner to support recovery.  Synonym: REPUT.";
 
 static char *hmxxrget = "\
 Syntax: REGET filespec\n\n\
@@ -3354,17 +3503,38 @@ static char *hmhskey[] = {
 ""};
 #endif /* NOSETKEY */
 
-static char *hmxychkt[] = { "Syntax: SET BLOCK-CHECK type",
+static char *hmxychkt[] = { "Syntax: SET BLOCK-CHECK number",
+" ",
+"Type of block check to be used for error detection on file-transfer",
+"packets: 1, 2, 3, 4, or 5.  This command must be given to the file",
+"sender prior to the transfer.",
+" ",
+"Type 1 is standard and supported by all Kermit protocol implementations,",
+"  but it's only a 6-bit checksum, represented in a single printable ASCII",
+"  character.  It's fine for reliable connections (error-correcting modems,",
+"  TCP/IP, etc) but type 3 is recommended for connections where errors can",
+"  occur.",
+" ",
+"Type 2 is a 12-bit checksum represented in two printable characters.",
 " ",
-"  Type of packet block check to be used for error detection, 1, 2, 3, or",
-"  BLANK-FREE-2.  Type 1 is standard, and catches most errors.  Types 2 and 3",
-"  specify more rigorous checking at the cost of higher overhead.  The",
-"  BLANK-FREE-2 type is the same as Type 2, but is guaranteed to contain no",
-"  blanks.",
+"Type 3 is a 16-bit cyclic redundancy check, the strongest error",
+"  detection method supported by Kermit protocol, represented in three",
+"  printable characters.",
+" ",
+"Type 4 (alias \"BLANK-FREE-2\") is a 12-bit checksum guaranteed to",
+"  contain no blanks in its representation; this is needed for connections",
+"  where trailing blanks are stripped from incoming lines of text.",
+" ",
+"Type 5 (alias \"FORCE-3\") means to force a Type 3 block check on",
+"  every packet, including the first packet, which normally has a type 1",
+"  block check.  This is for use in critical applications on noisy",
+"  connections.  As with types 2, 3, and 4, if the Kermit file",
+"  transfer partner does not support this type, the transfer fails",
+"  immediately at the beginning of the transfer.",
 "" };
 
 static char * hmxydeb[] = {
-"Syntax: SET DEBUG { SESSION, ON, OFF, TIMESTAMP }",
+"Syntax: SET DEBUG { SESSION, ON, OFF, TIMESTAMP, MESSAGES }",
 " ",
 "SET DEBUG ON",
 #ifdef DEBUG
@@ -3387,6 +3557,12 @@ static char * hmxydeb[] = {
 " ",
 "SET DEBUG TIMESTAMP { ON, OFF }",
 "  Enables/Disables timestamps on debug log entries.",
+" ",
+"SET DEBUG MESSAGES { ON, OFF, STDERR } [C-Kermit 9.0]",
+"  Enables/Disables messages printed by the DEBUG command.",
+"  SET DEBUG OFF causes DEBUG messages not to be printed.",
+"  SET DEBUG ON sends DEBUG messages to standard output (stdout);",
+"  SET DEBUG STDERR sends DEBUG messages to standard error (stderr);",
 "" };
 
 #ifdef CK_SPEED
@@ -3660,7 +3836,7 @@ static char *hmxydial[] = {
 " ",
 "SET DIAL RETRIES <number>",
 "  How many times to redial each number if the dialing result is busy or no",
-"  no answer, until the call is succesfully answered.  The default is 0",
+"  no answer, until the call is successfully answered.  The default is 0",
 "  because automatic redialing is illegal in some countries.",
 " ",
 "SET DIAL INTERVAL <number>",
@@ -3896,7 +4072,7 @@ static char *hmxyf[] = {
 "     the incoming file under the name it was sent with.",
 "   OVERWRITE - Overwrite (replace) the existing file.",
 "   APPEND - Append the incoming file to the end of the existing file.",
-"   DISCARD - Refuse and/or discard the incoming file.",
+"   REJECT - Refuse and/or discard the incoming file (= DISCARD).",
 "   RENAME - Give the incoming file a unique name.",
 "   UPDATE - Accept the incoming file only if newer than the existing file.",
 " ",
@@ -4208,6 +4384,9 @@ static char *ifhlp[] = { "Syntax: IF [NOT] condition commandlist",
 #ifdef CK_TMPDIR
 "  DIRECTORY string                  - The string is the name of a directory",
 #endif /* CK_TMPDIR */
+#ifdef UNIX
+"  LINK string                       - The string is a symbolic link",
+#endif /* UNIX */
 "  READABLE filename                 - Succeeds if the file is readable",
 "  WRITEABLE filename                - Succeeds if the file is writeable",
 #ifdef ZFCDAT
@@ -4328,13 +4507,19 @@ static char *hxxask[] = {
 " ",
 "Syntax:  ASKQ [ switches ] variablename [ prompt ]",
 "Example: ASKQ \\%p { Password:}",
-"  Like ASK except the response does not echo on the screen.",
+"  Like ASK except the response does not echo on the screen or, if specified",
+"  it echoes as asterisks or other specified character.",
 " ",
 "Switches:",
 " /DEFAULT:text",
 "  Text to supply if the user enters a blank response or the /TIMEOUT",
 "  limit expired with no response.",
 " ",
+" /ECHO:char",
+"  (ASKQ only) Character to be echoed each time the user presses a key",
+"  corresponding to a printable character.  This lets users see what they are",
+"  doing when they are typing (e.g.) passwords, and makes editing easier.",
+" ",
 #ifdef OS2
 " /POPUP",
 "  The prompt and response dialog takes place in a text-mode popup.",
@@ -4915,7 +5100,7 @@ static char *hxytapi[] = {
 "  other applications and Kermit performs dialing functions using its",
 "  built-in dialing and modem databases.  If TAPI MODEM-DIALING is ON, TAPI",
 "  handles all dialing functions and the port may be shared with other",
-"  applications when a call in not active.  When TAPI MODEM-DIALING is OFF,",
+"  applications when a call is not active.  When TAPI MODEM-DIALING is OFF,",
 "  SET MODEM TYPE TAPI Kermit uses the TAPI modem commands imported from the",
 "  Windows Registry during the previous SET TAPI LINE call.",
 " ",
@@ -5143,7 +5328,7 @@ static char * hxxdcl[] = {
 "  elements are discarded; if it is larger, new empty elements are added.",
 " ",
 "ARRAY COPY array1 array2",
-"  Copys array1 to array2.  If array2 has not been declared, it is created",
+"  Copies array1 to array2.  If array2 has not been declared, it is created",
 "  automatically.  Range specifiers may be given on one or both arrays.",
 " ",
 "ARRAY LINK array1 arra2",
@@ -5193,13 +5378,28 @@ static char * hmxxcpy[] = {
 "  be copied to the given directory.  Switches:",
 " ",
 "  /LIST",
-"    Print the filenames and status while copying.  Synonyms: /LOG, /VERBOSE",
+"    Print the filenames and status while copying.  Synonyms: /LOG, /VERBOSE.",
 " ",
 "  /NOLIST",
-"    Copy silently (default). Synonyms: /NOLOG, /QUIET",
+"    Copy silently (default). Synonyms: /NOLOG, /QUIET.",
+" ",
+"  /PRESERVE",
+"    Copy timestamp and permissions from source file to destination file.",
+" ",
+"  /OVERWRITE:{ALWAYS,NEVER,NEWER,OLDER}",
+"    When copying from one directory to another, this tells what to do when",
+"    the destination file already exists: overwrite it always; never; only if",
+"    the source file is newer; or only if the source file is older.",
+" ",
+"  /APPEND",
+"    Append the source file to the destination file.  In this case the source",
+"    file specification can contain wildcards, and all the matching source",
+"    files are appended, one after the other in alphabetical order by name,",
+"    to the destination file.",
 " ",
 "  /SWAP-BYTES",
-"    Swap bytes while copying.",
+"    Swap bytes while copying (e.g. for converting between Big-Endian and",
+"    Little-Endian binary data formats).",
 #ifndef NOSPL
 " ",
 "  /FROMB64",
@@ -5219,19 +5419,70 @@ static char * hmxxren[] = {
 "  this command is equivalent to REMOTE RENAME (RREN).  Otherwise:",
 " ",
 #endif /* LOCUS */
-"Syntax: RENAME [ switches ] name1 name2",
+"Syntax: RENAME [ switches ] name1 [ name2 ]",
 "  Renames the source file (name1) to the target name2.  If name2 is a",
 "  directory, name1 is allowed to contain wildcards, and the file(s) matching",
 "  name1 are moved to directory name2, subject to rules of the underlying",
-"  operating system regarding renaming across disk boundaries, etc.  If name2",
-"  is not a directory, name1 may not include wildcards, and the file whose",
-"  name is name1 is renamed to name2.  Switches:",
+"  operating system regarding renaming across disk boundaries, etc. Switches:",
 " ",
 "  /LIST",
 "    Print the filenames and status while renaming.  Synonyms: /LOG, /VERBOSE",
 " ",
 "  /NOLIST",
 "    Rename silently (default). Synonyms: /NOLOG, /QUIET",
+" ",
+"  /COLLISION:{FAIL,SKIP,OVERWRITE}",
+"    Tells what to do if a file with the given (or derived) new name already",
+"    exists: fail (and stop without renaming any files); skip this file",
+"    without renaming it and go on to the next one, if any; or overwrite (the",
+"    existing file).  PROCEED is a synonym for SKIP.",
+" ",
+"  /SIMULATE",
+"    Show what the effects of the RENAME command would be without actually",
+"    renaming any files.",
+" ",
+"  When any of the following switches is given, name2 must either be the",
+"  the name of a directory, or else omitted, and name1 is allowed to contain",
+"  contain wildcards, allowing multiple files to be renamed at once. If name2",
+"  is given, then all files matching name1 are moved to the name2 directory",
+"  after being renamed.",
+" ",
+"  /LOWER:{ALL,UPPER}",
+"    Converts letters in the filename to lowercase.  ALL means to convert",
+"    all matching filenames, UPPER means to convert only those filenames",
+"    that contain no lowercase letters.  The switch argument can be omitted,",
+"    in which case ALL filenames are converted.",
+" ",
+"  /UPPER:{ALL,LOWER}",
+"    Converts letters in the filename to uppercase.  ALL means to convert",
+"    all matching filenames, LOWER means to convert only those filenames",
+"    that contain no uppercase letters.  As with /LOWER, ALL is the default",
+"    switch argument.",
+" ",
+"  /FIXSPACES:s",
+"    Replaces all spaces in each matching filename by the string s, which may",
+"    be empty, a single character, or a string of characters.  The default",
+"    replacement (if no argument is given) is underscore (_).",
+" ",
+"  /REPLACE:{{string1}{string2}{options}}",
+"    Replaces all or selected occurrences of string1 with string2 in the",
+"    matching filenames.  The braces are part of the command.  The options",
+"    string can contain the following characters:",
+"     A: String matching is case-sensitive.",
+"     a: String matching is case-insensitive.",
+"     ^: String matching is anchored to the beginning of the filename.",
+"     $: String matching is anchored to the end of the filename.",
+"     1: Only the first occurrence of the string (if any) will be changed.",
+"     2: Only the second occurrence, and so on for all digits up to 9.",
+"     -: (before a digit) Occurrences are counted from the right.",
+"     ~: (before occurrence) All occurences BUT the one given are changed.",
+" ",
+"  /CONVERT:cset1:cset1",
+"    Converts each matching filename from character-set 1 to character-set 2.",
+"    Character sets are the same as for SET FILE CHARACTER-SET.",
+" ",
+"  Global values for /LIST and COLLISION can be set with SET RENAME and",
+"  displayed with SHOW RENAME.",
 ""
 };
 #endif /* NOFRILLS */
@@ -5322,6 +5573,7 @@ An option that does not require an argument can be bundled with other options:"
 ""
 };
 
+
 #ifndef NOHELP
 #ifndef NOCMDL
 int
@@ -5558,7 +5810,7 @@ static char * hxxf_op[] = {
 " ",
 "/WRITE",
 "  Open the file for writing.  If /READ was not also specified, this creates",
-"  a new file.  If /READ was specifed, the existing file is preserved, but",
+"  a new file.  If /READ was specified, the existing file is preserved, but",
 "  writing is allowed.  In both cases, the read/write pointer is initially",
 "  at the beginning of the file.",
 " ",
@@ -5658,12 +5910,17 @@ static char * hxxf_rw[] = {
 
 static char * hxxf_se[] = {
 "Syntax: FILE SEEK [ switches ] <channel> { [{+,-}]<number>, EOF }",
-"  Switches are /BYTE, /LINE, /RELATIVE, ABSOLUTE.",
+"  Switches are /BYTE, /LINE, /RELATIVE, /ABSOLUTE, and /FIND:pattern.",
 "  Moves the file pointer for this file to the given position in the",
 "  file.  Subsequent FILE READs or WRITEs will take place at that position.",
 "  If neither the /RELATIVE nor /ABSOLUTE switch is given, an unsigned",
 "  <number> is absolute; a signed number is relative.  EOF means to move to",
-"  the end of the file.  Synonym: FSEEK.  Also available as \\F_seek().",
+"  the end of the file.  If a /FIND: switch is included, Kermit seeks to the",
+"  specified spot (e.g. 0 for the beginning) and then begins searching line",
+"  by line for the first line that matches the given pattern.  To start",
+"  searching from the current file position specify a line number of +0.",
+"  To start searching from the line after the current one, use +1 (etc).",
+"  Synonym: FSEEK.",
 ""
 };
 
@@ -5784,7 +6041,7 @@ dohlp(xx) int xx; {
 #ifdef NOHELP
     if ((x = cmcfm()) < 0)
       return(x);
-    printf("\n%s, Copyright (C) 1985, 2004,",versio);
+    printf("\n%s, Copyright (C) 1985, %s,",versio, ck_cryear);
 #ifndef NOIKSD
     if (inserver)
       return(hmsga(tophlpi));
@@ -5941,6 +6198,12 @@ case XXUNDEF:                           /* UNDEFINE */
   Undefines a macro or variable."));
 #endif /* NOSPL */
 
+case XXMSG:
+    return(hmsg("Syntax: MESSAGE text-to-print-if-debugging\n\
+  Prints the given text to stdout if SET DEBUG MESSAGE is ON; prints it\n\
+  to stderr if SET DEBUG MESSAGE is STDERR; doesn't print it at all if SET\n\
+  DEBUG MESSAGE is OFF.  Synonym: MSG."));
+
 #ifndef NOFRILLS
 case XXLDEL:
     return(hmsg(
@@ -5978,6 +6241,19 @@ case XXLDIR:                            /* LDIRECTORY */
 case XXDIR:                             /* DIRECTORY */
     return(hmsga(hmxxdir));
 
+case XXTOUC:                           /* TOUCH */
+    return(hmsga(hmxxtouc));
+
+case XXWDIR:                           /* WDIRECTORY */
+  return(hmsg("  WDIRECTORY is shorthand for DIRECTORY /SORT:DATE /REVERSE;\n\
+  it produces a listing in reverse chronological order.  See the DIRECTORY\n\
+  command for further information."));
+
+case XXHDIR:                           /* HDIRECTORY */
+  return(hmsg("  HDIRECTORY is shorthand for DIRECTORY /SORT:SIZE /REVERSE;\n\
+  it produces a listing showing the biggest files first.  See the DIRECTORY\n\
+  command for further information."));
+
 case XXLMKD:                            /* LMKDIR */
     return(hmsg(
 "  LMKDIR is an alias for the MKDIR command forcing it to execute\n\
@@ -6116,19 +6392,22 @@ Hang up the phone or network connection."));
       return(x);
 
     if (helpfile) {
-        printf("\n%s, Copyright (C) 1985, 2004,\n\
-Trustees of Columbia University in the City of New York.\n\n",versio);
+        printf("\n%s, Copyright (C) 1985, %s,\n\
+Trustees of Columbia University in the City of New York.\n\n",
+              versio,
+              ck_cryear
+              );
         return(dotype(helpfile,xaskmore,3,0,NULL,0,NULL,0,0,NULL,0));
     } else {
-        printf("\n%s, Copyright (C) 1985, 2004,",versio);
+        printf("\n%s, Copyright (C) 1985, %s,",versio,ck_cryear);
         return(hmsga(tophlp));
     }
 
 case XXINT:
 #ifdef OS2
-    return(hmsg("Give a brief introduction to C-Kermit."));
+    return(hmsg("The INTRO command gives a brief introduction to Kermit 95."));
 #else
-    return(hmsg("Give a brief introduction to Kermit 95."));
+    return(hmsg("The INTRO command gives a brief introduction to C-Kermit."));
 #endif /* OS2 */
 
 #ifndef NOSPL
@@ -6475,11 +6754,25 @@ case XXVIEW:
     return(hmsg(
 "View the terminal emulation screen even when there is no connection."));
 
+#ifdef NEWFTP
 case XXASC:
-    return(hmsg("Synonym for SET FILE TYPE TEXT."));
-
+    return(hmsg(
+"Inhibits automatic transfer-mode switching and forces TEXT (ASCII) transfer\n\
+mode for all files in both Kermit and FTP protocols."));
 case XXBIN:
-    return(hmsg("Synonym for SET FILE TYPE BINARY."));
+    return(hmsg(
+"Inhibits automatic transfer-mode switching and forces BINARY transfer mode\n\
+for all files in both Kermit and FTP protocols."));
+#else
+case XXASC:
+    return(hmsg(
+"Inhibits automatic transfer-mode switching and forces TEXT (ASCII) transfer\n\
+mode for all files."));
+case XXBIN:
+    return(hmsg(
+"Inhibits automatic transfer-mode switching and forces BINARY transfer mode\n\
+for all files."));
+#endif /* NEWFTP */
 
 case XXDATE:
     return(hmsga(hmxxdate));
@@ -6725,6 +7018,11 @@ case XXMAN:
 case XXWILD:
     return(hmsga(hmxxwild));
 
+#ifdef LOCUS
+case XXLOCU:
+    return(hmsga(hmxylocus));
+#endif /* LOCUS */
+
 case XXPAT:
     return(hmsga(hmxxpat));
 
@@ -6766,6 +7064,8 @@ case XXPURGE:
     return(hmsg("  RKERMIT is a short form of REMOTE KERMIT."));
   case XXRMKD:
     return(hmsg("  RMKDIR is a short form of REMOTE MKDIR."));
+  case XXRMSG:
+    return(hmsg("  RMESSAGE and RMSG are short forms of REMOTE MESSAGE."));
   case XXRPRI:
     return(hmsg("  RPRINT is a short form of REMOTE PRINT."));
   case XXRPWD:
@@ -6859,6 +7159,17 @@ case XXPURGE:
     return(hmsg(" In a FOR or WHILE loop: continue the loop.\n\
  At the prompt: continue a script that has \"shelled out\" to the prompt."));
 
+  case XXREDO:
+    return(hmsg(" Syntax: REDO xxx (or) ^xxx\n\
+ Re-executes the most recent command starting with xxx."));
+
+#ifdef UNIX
+#ifndef NOPUTENV
+  case XXPUTE:
+    return(hmsga(hmxxputenv));
+#endif /* NOPUTENV */
+#endif /* UNIX */
+
   case XXNOTAV:
     return(hmsg(" This command is not configured in this version of Kermit."));
 
@@ -6943,6 +7254,76 @@ hmsga(s) char *s[]; {                   /* pausing at end of each screen. */
     return(0);
 }
 
+#ifndef NOFRILLS
+static char * supporttext[] = {
+
+"Live technical support for Kermit software is no longer available",
+"from Columbia University, as it was from mid-1981 until mid-2011 when",
+
+#ifdef OS2
+
+"the Kermit Project was cancelled.  Beginning with version 3.0, Kermit 95",
+
+#else
+
+"the Kermit Project was cancelled.  Beginning with version 9.0, C-Kermit",
+
+#endif /* OS2 */
+
+"is Open Source software.  The Kermit website is supposed remain open",
+"indefinitely at:",
+" ",
+"  http://kermit.columbia.edu/",
+" ",
+
+#ifdef OS2
+
+"The Kermit 95 page is here:",
+" ",
+"  http://kermit.columbia.edu/k95.html",
+" ",
+"The Kermit 95 manual is here:",
+" ",
+"  http://kermit.columbia.edu/k95manual/",
+" ",
+"The Kermit 95 Frequently Asked Questions page is here:",
+" ",
+"  http://kermit.columbia.edu/k95faq.html",
+" ",
+"and many other resources are listed on the Kermit 95 home page.",
+" ",
+
+#else
+
+"The C-Kermit home page is here:",
+" ",
+"  http://kermit.columbia.edu/ckermit.html",
+" ",
+"The documentation for C-Kermit is listed here:",
+" ",
+"  http://kermit.columbia.edu/ckermit.html#doc",
+" ",
+"The C-Kermit Frequently Asked Questions page is here:",
+" ",
+"  http://kermit.columbia.edu/ckfaq.html",
+" ",
+"and many other resources are listed on the C-Kermit home page.",
+" ",
+
+#endif /* OS2 */
+
+"Time will tell what sort of development and support structures arise",
+"in the Open Source community.",
+""
+};
+
+/* Do the BUG command */
+int
+dobug() {
+    return(hmsga(supporttext));
+}
+#endif /* NOFRILLS */
+
 #ifndef NOXMIT
 static char *hsetxmit[] = {
 "Syntax: SET TRANSMIT parameter value",
@@ -7035,6 +7416,12 @@ static char *hsetcmd[] = {
 " ",
 #endif /* OS2 */
 
+"SET COMMAND ERROR { 0,1,2,3 }",
+"  Sets the verbosity level of command error messages; the higher the number,",
+"  the more verbose the message.  The default is 1.  Higher values are",
+"  useful only for debugging scripts.",
+" ",
+
 #ifdef OS2
 #ifdef NT
 "SET COMMAND HEIGHT <number>",
@@ -7461,11 +7848,6 @@ static char *hxyterm[] = {
 "  Selects the cursor style and visibility for the terminal screen.",
 #endif /* KUI */
 " ",
-"SET TERMINAL DG-UNIX-MODE { ON, OFF }",
-"  Specifies whether the Data General emulations should accept control",
-"  sequences in Unix compatible format or in native DG format.  The",
-"  default is OFF, DG format.",
-" ",
 #endif /* OS2 */
 
 "SET TERMINAL DEBUG { ON, OFF }",
@@ -7475,6 +7857,9 @@ static char *hxyterm[] = {
 " ",
 #ifdef OS2
 "SET TERMINAL DG-UNIX-MODE { ON, OFF }",
+"  Specifies whether the Data General emulations should accept control",
+"  sequences in Unix compatible format or in native DG format.  The",
+"  default is OFF, DG format.",
 " ",
 #endif /* OS2 */
 
@@ -7549,11 +7934,9 @@ static char *hxyterm[] = {
 "  CONNECT mode; if no text is given a NUL (0) character is sent.",
 #ifdef TNCODE
 " ",
-"And for Telnet connections:",
-" ",
 "SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }",
-"  Sends the indicated Telnet protocol message: No Operation (NOP) or",
-"  \"Are You There?\" (AYT).",
+"  For TELNET connections only: Sends the indicated Telnet protocol message:",
+"  No Operation (NOP) or \"Are You There?\" (AYT).",
 #endif /* TNCODE */
 " ",
 #endif /* CKTIDLE */
@@ -7603,6 +7986,16 @@ static char *hxyterm[] = {
 "  in a different mode than it's in, but did not send the escape sequence",
 "  to put it in the needed mode.",
 " ",
+
+#endif /* OS2 */
+
+"SET TERMINAL LF-DISPLAY { CRLF, NORMAL }",
+"  Specifies how incoming linefeed characters are to be displayed",
+"  on your screen.",
+" ",
+
+#ifdef OS2
+
 #ifdef KUI
 "SET TERMINAL LINE-SPACING <float>",
 "  Specifies the line spacing used when displaying text.  The default is 1.0.",
@@ -7766,7 +8159,7 @@ static char *hxyterm[] = {
 "  easily switch between the National Language character set and U.S. ASCII.",
 "  The default is ON which means to display characters as U.S. ASCII.  When",
 "  OFF the lanuage specified by SET TERMINAL SNI-LANUAGE is used to display",
-"  characters when 7-bit character sets are in use."
+"  characters when 7-bit character sets are in use.",
 " ",
 "SET TERMINAL SNI-FIRMWARE-VERSIONS <kbd-version> <terminal-version>",
 "  Specifies the Firmware Version number that should be reported to the host",
@@ -8781,15 +9174,34 @@ static char *hmxyprm[] = {
 
 #ifdef UNIX
 static char *hxywild[] = {
-"Syntax: SET WILDCARD-EXPANSION { KERMIT [ switch ], SHELL }",
+"Syntax: SET WILDCARD-EXPANSION { KERMIT [ switch ], SHELL, ON, OFF }",
 "  KERMIT (the default) means C-Kermit expands filename wildcards in SEND and",
 "  similar commands itself, and in incoming GET commands.  Optional switches",
-"  are /NO-MATCH-DOT-FILES (\"*\" and \"?\" should not match in initial",
+"  are /NO-MATCH-DOT-FILES (\"*\" and \"?\" should not match an initial",
 "  period in a filename; this is the default) and /MATCH-DOT-FILES if you",
 "  want files whose names begin with \".\" included.  SET WILDCARD SHELL",
 "  means that Kermit asks your preferred shell to expand wildcards (this",
 "  should not be necessary in C-Kermit 7.0 and later).  HELP WILDCARD for",
 "  further information.",
+" ",
+"  The ON and OFF choices allow you to disable and renable wildcard",
+"  processing independent of the KERMIT / SHELL choice.  Disabling wildcards",
+"  allows you to process an array or list of filenames without having to",
+"  consider whether the names might contain literal wildcard characters.",
+"  WARNING: SET WILD OFF also disables internal filename pattern-matching,",
+"  used (for example) in creating backup files.",
+"" };
+#else
+static char *hxywild[] = {
+"Syntax: SET WILDCARD-EXPANSION { ON, OFF }",
+"  ON (the default) means that filenames given to Kermit commands such as",
+"  SEND and DIRECTORY are automatically expanded into lists of filenames if",
+"  they contain special 'wildcard characters' such as '*'.  You can reference",
+"  files whose names contains such characters literally by preceding each",
+"  such character with a backslash '\\'.  When dealing programmatically with",
+"  a file list, however, you should SET WILDCARD-EXPANSION OFF to force",
+"  treat each name in the list as a literal name.  See HELP WILDCARDS for",
+"  details about wildcard syntax.",
 "" };
 #endif /* UNIX */
 
@@ -9000,6 +9412,7 @@ The template should include variables like \\v(filename) or \\v(filenumber).",
 "  throughout the transfer based on the packet rate.  Include the word FIXED",
 "  to use the \"number\" given throughout the transfer.  DYNAMIC is the",
 "  default.  After DYNAMIC you may include minimum and maximum values.",
+"  SET SEND TIMEOUT -1 FIXED means no timeouts.",
 #else
 "  retransmitting.",
 #endif /* CK_TIMERS */
@@ -9012,7 +9425,7 @@ The template should include variables like \\v(filename) or \\v(filenumber).",
 "" };
 
 static char *hxyxfer[] = {
-"Syntax: SET TRANSFER (or XFER) paramater value",
+"Syntax: SET TRANSFER (or XFER) parameter value",
 " ",
 "Choices:",
 " ",
@@ -9179,6 +9592,23 @@ static char *hmxybel[] = {
 #endif /* OS2 */
 ""};
 
+#ifdef OS2
+static char *hmxymsk[] = {
+"SET MSKERMIT FILE-RENAMING { ON, OFF }",
+"  ON enables the use of MS-DOS Kermit file renaming conventions instead of",
+"  C-Kermit conventions.  File renaming occurs during file transfers when",
+"  there is a file name collision and either BACKUP or RENAME collision",
+"  options are active.  C-Kermit conventions preserve the original file name",
+"  while appending .~num~ to the end.  MS-DOS Kermit conventions restrict",
+"  filenames to 8.3 notation and preserve the extension.  Unique numeric",
+"  values overwrite the right most portion of the file name's left hand side.",
+" ",
+"SET MSKERMIT KEYCODES { ON, OFF }",
+"  ON enables the use of MS-DOS Kermit compatible keycodes to provide script",
+"  portability.",
+""};
+#endif /* OS2 */
+
 static char *hmxycd[] = {
 "Syntax: SET CD { HOME <path>, PATH <path>, MESSAGE { ON, OFF, FILE <list> } }"
 ,
@@ -9461,6 +9891,13 @@ dohset(xx) int xx; {
         return(hmsga(hsetiks));
 #endif /* NOIKSD */
 
+case XY_REN:
+  return(hmsg("SET RENAME LIST { ON, OFF }\n\
+  Tells whether the RENAME command should list its results by default.\n\n\
+SET RENAME COLLISION { FAIL, PROCEED, OVERWRITE }\n\
+  Establishes the default action when renaming a file would destroy an\n\
+  existing file.  See HELP RENAME."));
+
 case XYATTR:
     return(hmsga(hsetat));
 
@@ -9475,6 +9912,9 @@ case XYPRTY:
     return(hmsg("SET PRIORITY { REGULAR, FOREGROUND-SERVER, TIME-CRITICAL }\n\
   Specifies at which priority level the communication and screen update\n\
   threads should operate.  The default value is FOREGROUND-SERVER."));
+
+case XYMSK:
+    return(hmsga(hmxymsk));
 #endif /* OS2 */
 
 #ifdef DYNAMIC
@@ -9740,7 +10180,8 @@ case XYRETR:
 case XYSESS:
 #ifdef UNIX
     return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
+"Syntax:\n\
+ SET SESSION-LOG { BINARY, DEBUG, NULL-PADDED, TEXT, TIMESTAMPED-TEXT }\n\
   If BINARY, record all CONNECT characters in session log.  If TEXT, strip\n\
   out CR, NUL, and XON/XOFF characters.  DEBUG is the same as BINARY but\n\
   also includes Telnet negotiations on TCP/IP connections."));
@@ -10052,6 +10493,20 @@ case XYTIMER:
   case XYMATCH:
     return(hmsga(hmxymatch));
 
+#ifndef NOSEXP
+  case XYSEXP:
+    return(hmsga(hmxysexp));
+#endif /* NOSEXP */
+
+#ifndef NOSPL
+  case XYVAREV:
+    return(hmsg("Syntax: SET VARIABLE-EVALUATION { RECURSIVE, SIMPLE }\n\
+  Tells Kermit weather to evaluate \\%x and \\&x[] variables recursively\n\
+  (which is the default for historical reasons) or by simple string\n\
+  replacement, which lets you use these variables safely to store strings\n\
+  (such as Windows pathnames) that might contain backslashes."));
+#endif /* NOSPL */
+
 default:
     printf("Not available - \"%s\"\n",cmdbuf);
     return(0);
@@ -10059,6 +10514,60 @@ default:
 }
 
 #ifndef NOSPL
+static char * hfsplit[] = {
+"Function \\fsplit(s1,&a,s2,s3,n2,n3) - Assigns string words to an array.",
+"  s1 = source string.",
+"  &a = array designator.",
+"  s2 = optional break set.",
+"  s3 = optional include set (or ALL, CSV, or TSV).",
+"  n2 = optional grouping mask.",
+"  n3 = optional separator flag:",
+"   0 = collapse adjacent separators;",
+"   1 = don't collapse adjacent separators.",
+" ",
+"  \\fsplit() breaks the string s1 into \"words\" as indicated by the other",
+"  parameters, assigning them to given array, if any.  If the specified",
+"  already exists, it is recycled; if no array is specified, the count is",
+"  returned but no array is created.  All arguments are optional",
+"  (\\fsplit() with no arguments returns 0).",
+" ",
+"  The BREAK SET is the set of all characters that separate words. The",
+"  default break set is all characters except ASCII letters and digits.",
+"  ASCII (C0) control characters are treated as break characters by default,",
+"  as are spacing and punctuation characters, brackets, and so on, and",
+"  all 8-bit characters.",
+" ",
+"  The INCLUDE SET is the set of characters that are to be treated as ",
+"  parts of words even though they normally would be separators.  The",
+"  default include set is empty.  Three special symbolic include sets are",
+"  also allowed:",
+" ",
+"    ALL (meaning include all bytes that are not in the break set)",
+"    CSV (special treatment for Comma-Separated-Value records)",
+"    TSV (special treatment for Tab-Separated-Value records)",
+" ",
+"  For operating on 8-bit character sets, the include set should be ALL.",
+" ",
+"  If the grouping mask is given and is nonzero, words can be grouped by",
+"  quotes or brackets selected by the sum of the following:",
+" ",
+"     1 = doublequotes:    \"a b c\"",
+"     2 = braces:          {a b c}",
+"     4 = apostrophes:     'a b c'",
+"     8 = parentheses:     (a b c)",
+"    16 = square brackets: [a b c]",
+"    32 = angle brackets:  <a b c>",
+" ",
+"  Nesting is possible with {}()[]<> but not with quotes or apostrophes.",
+" ",
+"Returns integer:",
+"  Number of words in source string.",
+" ",
+"Also see:",
+"  HELP FUNCTION WORD",
+""
+};
+
 /*  D O H F U N C  --  Give help for a function  */
 
 int
@@ -10080,10 +10589,11 @@ dohfunc(xx) int xx; {
     switch (xx) {
       case FN_IND:                      /* Index (of string 1 in string 2) */
       case FN_RIX:                      /* Rindex (index from right) */
-        printf("\\f%sindex(s1,s2,n1)\n\
+        printf("\\f%sindex(s1,s2,n1,n2)\n\
   s1 = string to look for.\n\
   s2 = string to look in.\n\
-  n1 = optional 1-based starting position, default = 1.\n",
+  n1 = optional 1-based starting position, default = 1.\n\
+  n2 = optional desired occurrence number, default = 1.\n",
                xx == FN_RIX ? "r" : ""
                );
         printf("Returns integer:\n\
@@ -10093,12 +10603,22 @@ dohfunc(xx) int xx; {
                xx == FN_IND ? "left" : "right"
         );
         break;
+      case FN_COUNT:                   /* Count occurrences of s1 in s2 */
+       printf("\\fcount(s1,s2,n1)\n\
+  s1 = string or character to look for.\n\
+  s2 = string to look in.\n\
+  n1 = optional 1-based starting position, default = 1.\n");
+       printf("Returns integer:\n\
+  Number of occurrences of s1 in s2, 0 or more.\n");
+        break;
+
       case FN_SEARCH:                   /* Search for pattern */
       case FN_RSEARCH:                  /* Search for pattern from right */
-        printf("\\f%ssearch(s1,s2,n1)\n\
+        printf("\\f%ssearch(s1,s2,n1,n2)\n\
   s1 = pattern to look for.\n\
   s2 = string to look in.\n\
-  n1 = optional 1-based offset, default = 1.\n",
+  n1 = optional 1-based offset, default = 1.\n\
+  n2 = optional desired occurrence of match, default = 1.\n",
                xx == FN_RSEARCH ? "r" : ""
                );
         printf("Returns integer:\n\
@@ -10400,11 +10920,22 @@ dohfunc(xx) int xx; {
         break;
 
       case FN_STL:                      /* Strip from left */
-        printf("\\flop(s1,c1)\n\
+        printf("\\flop(s1[,c1[,n1]])\n\
   s1 = string to look in.\n\
-  c1 = character to look for, default = \".\".\n");
+  c1 = character to look for, default = \".\".\n\
+  n1 = occurrence of c1, default = 1.\n");
         printf("Returns string:\n\
-  The part of s1 after the leftmost occurrence of character c1.\n"
+  The part of s1 after the n1th leftmost occurrence of character c1.\n"
+        );
+        break;
+
+      case FN_LOPX:                      /* Strip from right */
+        printf("\\flopx(s1,c1)\n\
+  s1 = string to look in.\n\
+  c1 = character to look for, default = \".\".\n\
+  n1 = occurrence of c1, default = 1.\n");
+        printf("Returns string:\n\
+  The part of s1 after the n1th rightmost occurrence of character c1.\n"
         );
         break;
 
@@ -10516,6 +11047,7 @@ dohfunc(xx) int xx; {
 #endif /* NORANDOM */
 
       case FN_SPLIT:                    /* Split */
+#ifdef COMMENT
         printf("\\fsplit(s1,&a,s2,s3,n2,n3) - \
 Assign string words to an array.\n\
   s1 = source string\n  &a = array designator\n  s2 = optional break set.\n");
@@ -10528,6 +11060,9 @@ Assign string words to an array.\n\
   if array not specified, the count is returned but no array is created.\n");
         printf("Returns integer:\n\
   Number of words in source string.\n");
+#else
+        hmsga(hfsplit);
+#endif /* COMMENT */
         break;
 
       case FN_DTIM:                     /* CVTDATE */
@@ -10541,7 +11076,9 @@ Assign string words to an array.\n\
         printf("  If n1 is given:\n\
   n1 = 1: yyyy-mmm-dd hh:mm:ss (mmm = English 3-letter month abbreviation)\n\
   n1 = 2: dd-mmm-yyyy hh:mm:ss (ditto)\n\
-  n1 = 3: yyyymmddhhmmss (all numeric)\n");
+  n1 = 3: yyyymmddhhmmss (all numeric)\n\
+  n1 = 4: Day Mon dd hh:mm:ss yyyy (asctime)\n\
+  Other:  yyyymmdd hh:mm:dd");
         break;
 
       case FN_JDATE:                    /* DOY */
@@ -11006,6 +11543,18 @@ Returns number:\n");
   Returns decimal equivalent.\n");
         break;
 
+      case FN_TOB64:
+        printf("\\b64encode(s)\n\
+  s = string containing no NUL bytes\n\
+  Returns Base-64 encoding of string.\n");
+        break;
+
+      case FN_FMB64:
+        printf("\\b64decode(s)\n\
+  s = string in Base-64 notation\n\
+  Returns the decoded string or an error code if s not valid.\n");
+        break;
+
       case FN_RADIX:
         printf("\\fradix(s,n1,n2)\n\
   s = number in radix n1\n\
@@ -11024,6 +11573,10 @@ Returns number:\n");
         printf("\
   Returns the (selected) elements of the array joined to together,\n\
   separated by the separator.\n");
+       printf("\n\
+  If s is CSV (literally), that means the array is to be transformed into a\n\
+  comma-separated list.  No other arguments are needed.  If s is TSV, then\n\
+  a tab-separated list is created.\n");
         break;
 
       case FN_SUBST:
@@ -11032,10 +11585,11 @@ Returns number:\n");
   s2 = List of characters to be translated.\n\
   s3 = List of characters to translate them to.\n");
         printf(
-"  Returns: s1, with each character that is in s2 translated to the\n\
+"  Returns: s1, with each character that is in s2 replaced by the\n\
   corresponding character in s3.  s2 and s3 can contain ASCII ranges,\n\
   like [a-z].  Any characters in s2 that don't have corresponding\n\
-  characters in s3 (after range expansion) are removed from the result.\n");
+  characters in s3 (after range expansion) are removed from the result.\n\
+  This function works only with single-byte character-sets\n");
         break;
 
 #ifndef NOSEXP
@@ -11134,16 +11688,18 @@ Returns number:\n");
 #endif /* FN_ERRMSG */
 
       case FN_KWVAL:
-        printf("\\fkeywordvalue(s1,c1)\n\
+        printf("\\fkeywordvalue(s1[,s2])\n\
   s1 = string of the form \"name=value\"\n\
-  c1 = separator character (default separator is \"=\")\n");
-        printf("    Assigns the value, if any, to the named macro.\n");
-        printf("    If s1 contains no separator, nothing happens.\n");
-        printf(
-"    If s1 contains a separator but no value, the macro is undefined.\n");
+  s2 = one more separator characters (default separator is \"=\")\n");
+        printf("    Assigns the value, if any, to the named macro and sets\n");
+        printf("    the \\v(lastkeywordvalue) to the macro name.\n");
+        printf("    If no value is given, the macro is undefined.\n");
         printf("Returns:\n");
-        printf("  0 on failure\n");
-        printf("  1 on success\n");
+        printf(" -1 on error\n");
+        printf("  0 if no keyword or value were found\n");
+        printf("  1 if a keyword was found but no value\n");
+        printf("  2 if a keyword and a value were found\n");
+        printf("Synonym: \\kwvalue(s1[,s2])\n");
         break;
 
 #ifdef COMMENT
@@ -11186,6 +11742,99 @@ Returns number:\n");
         break;
 #endif /* NT */
 
+      case FN_EMAIL:
+        printf("\\femailaddress(s)\n\
+  s = From: or Sender: header from an RFC2822-format email message\n");
+        printf("    Extracts and returns the email address.\n");
+        break;
+
+      case FN_PICTURE:
+        printf("\\fpictureinfo(s[,&a])\n\
+  s  = File specification of a JPG or GIF picture file.\n\
+  &a = Optional array name.\n\n");
+        printf("Returns integer:\n\
+  0 if file not found or not recognized;\n\
+  1 if orientation is landscape;\n\
+  2 if orientation is portrait.\n\n"); 
+       printf("  If an array name is included, element 1 is filled \
+in with the image width\n\
+  in pixels, and element 2 the image height.\n");
+       break;
+
+      case FN_PID:
+        printf("\\fgetpidinfo(n1)\n\
+ n1 = Numeric process ID\n");
+        printf("Returns integer:\n\
+ -1 on failure to get information;\n\
+  1 if n1 is the ID of an active process;\n\
+  0 if the process does not exist.\n"); 
+        break;
+
+      case FN_FUNC:
+       printf("\\ffunction(s1)\n\
+ s1 = name of function.\n");
+        printf("Returns integer:\n\
+  1 if s1 is the name of an available built-in function;\n\
+  0 otherwise.\n"); 
+        break;
+
+      case FN_RECURSE:
+       printf("\\frecurse(s1)\n\
+ s1 = name of \\&x or \\&x[] type variable\n");
+        printf("Returns the result of evaluating the variable recursively.\n");
+        break;
+
+      case FN_SQUEEZE:
+        printf("\\fsqueeze(s)\n\
+  s = string\n\
+    Returns string with leading and trailing whitespace removed, Tabs\n\
+    converted to Spaces, and multiple spaces converted to single spaces.\n");
+        break;
+
+#ifndef NOCSETS
+      case FN_XLATE:
+        printf("\\fcvtcset(s,cset1,cset2)\n\
+  s = string\n\
+    Returns string converted from character set cset1 to cset2, where cset1\n\
+    and cset2 are names of File Character-Sets \
+('set file char ?' for a list).\n");
+        break;
+#endif /* NOCSETS */
+
+      case FN_UNPCT:
+        printf("\\fdecodehex(s1[,s2])\n\
+  s1, s2 = strings\n\
+    Decodes a string s1 that contains prefixed hex bytes.  s2 is the prefix;\n\
+    the default is %%%%.  You can specify any other prefix one or two bytes\n\
+    long.  If the prefix contains letters (such as 0x), case is ingored.\n\
+    Returns string s1 with hex escapes replaced by the bytes they \
+represent.\n");
+        break;
+
+      case FN_STRINGT:
+        printf("\\fstringtype(s)\n\
+  s = string\n\
+    Returns a string representing the type of its string argument s1:\n\
+    7BIT, 8BIT, UTF8, TEXT, or BINARY.  TEXT means some kind of text\n\
+    other than 7BIT, 8BIT, or UTF8 (this probably will never appear).\n");
+        break;
+
+      case FN_STRCMP:
+        printf("\\fstrcmp(s1,s2[,case[,start[,length]]])\n\
+  s1, s2 = strings\n\
+  case, start, length = numbers or arithmetic expressions.\n\
+    case = 0 [default] means to do a case-independent comparison;\n\
+    nonzero case requests a case-sensitive comparison.\n\
+    The optional start and length arguments apply to both s1 and s2\n\
+    and allow specification of substrings if it is not desired to compare\n\
+    the whole strings.  Results for non-ASCII strings are implentation-\n\
+    and locale-dependent.\n\
+  Returns a number:\n\
+    -1: s1 is lexically less than s2;\n\
+     0: s1 and s2 are lexically equal;\n\
+     2: s1 is lexically greater than s2.\n");
+        break;
+
       default:
         printf("Sorry, help not available for \"%s\"\n",cmdbuf);
     }
@@ -13747,6 +14396,10 @@ case XZLGO:
   Logs out from a remote Kermit server to which you have previously logged in."
 ));
 
+case XZMSG:
+    return(hmsg("Syntax: REMOTE MESSAGE text\n\
+  Sends a short text message to the remote Kermit server."));
+
 case XZPRI:
     return(hmsg("Syntax: REMOTE PRINT filespec [ options ]\n\
   Sends the specified file(s) to the remote Kermit and ask it to have the\n\