C-KERMIT 6.1-7.0 CHANGE LOG (Changes since 6.0.192 of 6 September 1996)

Tue Feb  8 15:27:58 2000

SET TCP UCX-PORT-BUG command added, November 1996.

sdata() windowing loop to send packets could go too far if ACKs had
arrived out of order.  Fixed in nxtpkt().  9 Dec 96.

SET SEND DOUBLE-CHAR and SET RECEIVE IGNORE-CHAR added, for transferring
files with Honeywell DPS-6, and/or thru an Arpanet TAC.  10 Dec 96.

ADD SEND-LIST followed by MOVE did not delete original files.  Fixed in
ckuusr.c, 11 Dec 96.

When C-K is in local mode, and sending a file using Kermit protocol, and
sending an auto-upload string in advance, make it pause for 1.5 seconds to
give the remote Kermit time to start up; otherwise, since all the ioctls at
startup time result in clearing the input buffer, the first packet is lost and
we have to wait a long time for the timeout to kick off the transfer.  1.5 sec
vs 8 sec.  On the other hand, if the remote Kermit is already started, this
is a needless delay.  OK, so make it 400 msec.  This doesn't fix the problem
in the default case (unless the remote system is really fast), but at least
now there is a command-level workaround for the user: "set proto kermit
{kermit -YQqr} {kermit -YQqr}", to make the remote Kermit start up faster;
0.4 sec should be enough time to enter packet mode.  ckcpro.w, 15 Dec 96.

Added EDIT, SET EDITOR, SHOW EDITOR.  This required adding a new parsing
function, cmiofi(), to parse either the name of an existing file or the name
of a new file to be created.  SET EDITOR can not be executed by APC unless APC
is UNCHECKED, otherwise "edit foo" might become "delete foo".  If the EDIT
command is given without a filespec, then if a previous filespec had been
given to an EDIT command, it is used; if not, the editor is started without a
file.  If a filespec is given, the editor is started on that file, and the
filespec is remembered for subsequent EDIT commands.  ckuusr.h, ckuus[r235].c,
ckucmd.[ch], 15 Dec 96.

Changed \v(filespec) to contain fully qualified filenames rather than relative
ones.  This allows \v(filespec) to actually find the file just downloaded, in
case it went to a download directory, etc.  This makes NETEDIT easy to do.
ckuus[r6].c, 15 Dec 96.

New CKVKER.COM and CKVOLD.COM from Lucas Hart fixes errors with GCC builds.
25 Dec 96.

Added -DNONAWS to AT&T 3Bx entries.  16 Jan 97.

Added and modified SCO Xenix entries from Fred Smith. 26 Jan 97.

Added and modified HP-UX entries from Peter Eichhorn. 26 Jan 97.

Added -DNOINADDRX to all DG/UX 5.40 makefile entries.  1 Feb 97.

Added an entry for SINIX-Z (Intel) 5.42.  1 Feb 97.

Added "generic-high-speed" and Meghertz X-Jack modem types, 5 Feb 97.

Fix to VMS isdir() (free() being called prior to using the item that was
freed), causing CD not to work on Alphas with VMS 6.2.  ckvfio.c, 17 Feb 97.

Fixed \feval(m%n) not to dump core if n == 0, ckuus5.c, date unk.

References to S82 in newer-model Hayes modems causes ERROR.  Removed.
ckudia.c, date.unk.

Added STRATUS #ifdefs to ckusig.c, from Kernie Brashier.  7 Mar 97.

Added Greek file and terminal charset translation: ISO 8859-7, CP869, and
ELOT 927.  ck[cu]xla.[ch], ckuus[23457].c.  5 Apr 97.

Made Stratus getchar/putchar changes to ckcdeb.h, ckudia.c, ckuus[457].c
and uploaded to test area so Kernie B can make new builds.  6 Apr 97.

Added IF OPEN ...  ckuusr.h, ckuus[26].c.  6 Apr 97.

Added \v(pid), UNIX only for now.  ckcdeb.h, ckuusr.h, ckuus4.c.  6 Apr 97.

Jeff's changes to sdata() (after sending each packet) and input() (when we
get a timeout) to detect carrier loss.  ckcfn[s2].c, 7 Apr 97.

Added within #ifdef PIPESEND...  CSEND, CRECEIVE, and SET XFER PIPES governing
interpretation of incoming filenames that start with "!", and also
command-line -s "!command", for UNIX.  ckcdeb.h, ckcfn[s3].c, ckcpro.w,
ckucmd.c, ckuusr.h, ckuus[r2345y].c, 9-13 Apr 97.  Jeff also made them work
for Windows 95/NT and OS/2.

Removed spurious and redundant code from ckcmai.c to read the application
file a second time (which is never executed because the application file name
was zeroed out), and then removed the code to zero out the name, so the file
can be deleted later if "set startup-file discard".  17 Apr 97.

Added code to enforce that pipe transfers can be done only with Kermit
protocol.  ckcfns.c, ckuusr.c, ckuusy.c, 17 Apr 97.  NOTE: Actually, it is
perfectly possible to receive to a pipe using XYZMODEM in K95, but since it is
not possible to send from one (because these protocols use fseek to recover
from errors and you can't fseek into a pipe), we just say "use Kermit".

Added SET SEND FILTER and got it working -- needs a LOT of testing.
ckuusr.h, ckuus3.c, etc etc, 17 Apr 97.

Added \fcommand() and \frawcommand(); ckuusr.h, ckuus4.c, 18 Apr 97.

Added \v(filename) -- current filename while sending and receiving -- and
\v(filenumber) -- the current file number.  19 Apr 97.

Overhauled the as-name code to provide for filename templates using
\v(filename), \v(filenumber), etc, as well as \function()s...  19 Apr 97.

Added \v(pexitstat) -- exit status of most recent process started by zxcmd,
zshcmd, or ttruncmd().  ckuusr.h, ckuus4.c, ckufio.c, ckutio.c.  20 apr 97.

Overhauled process-oriented routines in ckufio.c to give a proper return code
and to set the pexitstat value.  In particular, zclosf() now fails if the
closed process did not return an exit code of 0.  20 apr 97.

In working on the previous item, discovered that I could use wait() rather
than waitpid() in ttruncmd(), and since wait() is totally portable, I enabled
REDIRECT for all UNIX implementations as well as OS/2 & Windows.  ckutio.c,
ckcdeb.h.  20 Apr 97.

Added tests to the protocol module to see whether closing the input file fails,
which is what happens if we are using a pipe and or filter, and the process's
return code indicates failure.  In this case we set the "cxseen" flag which
forces a failure condition on a per-file basis (in case of wildcard transfers
with send-filter), which is reflected in BOTH Kermits.  ckcpro.w, 20 Apr 97.

Added invisible CQ command for all but OS2 & Win32 as an abbreviation for
CONNECT /QUIETLY.  ckuusr.[ch], 20 Apr 97.

Changed SET { SEND, RECEIVE } FILTER to use the same syntax as as-names --
\v(filename), string functions, etc, permitted -- rather than "%s".
 ckuus7.c, ckcfns.c, 20 Apr 97.

Added \fstripx(), \fstripn(), \flop() string functions.  ckuusr.h, ckuus4.c,
21 Apr 97.

Added file-protection/permission attributes within #ifdef CK_PERM..#endif.
Enabled for UNIX only.  Sender puts system-dependent and system-independent
versions into the A packet.  The system-dependent permission string for UNIX
is a 3-digit octal string, the low-order 12 bits of the st_mode member of the
stat struct; we deliberately chop off the "file format" bits because they are
probably not portable, nor do we convey the setuid/setgid bits, lock bit,
sticky bit, etc; just the permissions.  The file receiver checks to see if the
sender has the same system ID; if so, it tries to decode the system-dependent
permissions, if any; if not, it uses the generic ones and applies them to the
owner field.  The main purpose is to not have to "chmod +x" an executable file
after transfer between two UNIXes.  ckcdeb.h, ckcmai.c, ckufio.c, ckcfn3.c,
and (for SET, REMOTE SET, and SHOW ATTRIBUTES) ckuus5.c, ckuus7.c.  22 Apr 97.

Added three more variables:
  \v(p_ctl)   Control prefix char
  \v(p_8bit)  8-bit prefix char (if parity not none)
  \v(p_rpt)   Repeat prefix char (if repeat compression enabled)
ckuusr.h, ckuus4.c.  22 Apr 97.

Merged Jeff's changes into ckuusr.h, 24 Apr 97.

Merged Jeff's changes into ckcker.h, ckcmai.c, 3 May 97.

Merged Jeff's changes into ckuusr.c; noticed that much of the PIPESEND code
was missing from Jeff's version.  3 May 97.

Merged Jeff's changes into ckuus*.[ch] and other modules, 3 May 97.

Merged Jeff's changes into ckudia.c, except the ones involving makestr(),
which should be entirely unnecessary -- or if they are, then makestr() should
be fixed.  3 May 97.

Made sure remaining modules were all in sync.  3 May 97.

Added CK_ENVIRONMENT for UNIX/Aegis/Plan9: ckcnet.h, ckutio.c, 4 May 97.

Added SET TELNET ENVIRONMENT { OFF, ON }.  This is needed so scripts can
behave predictably, etc.  Made OFF the default for UNIX, ON for OS/2 & friends
so as not to change existing default behavior.  Added this to SHOW NET.  Also
fixed a bug in Telnet NEW-ENVIRON negotiation.  ckuusr.h, ckuus[234].c,
ckcnet.c, 4 May 97.

Added TELNET SEND_LOCATION negotiation, since a potential customer needed it
desperately and asked about it just as I was working on the NEW-ENVIRON stuff.
Untested, though, since I can't find a host that uses it.  ckcnet.c, 4 May 97.

Added SOLARIS25 symbol and makefile entry for Solaris 2.5.  Added support for
134.5 and 1800 bps.  Enabled 134.5, 1800, 57600, 76800, 115200, 230400 for
Solaris 2.5.  makefile, ckcdeb.h, ckutio.c, 4 May 97.

Added casts to various function args (char vs uchar) to shut up picky
compilers.  ckcfn[s23].c, 4 May 97.

Added a fix for ATT 7300 UNIX PC to allow use by root when C-Kermit installed
setuid (e.g. to uucp), since System V R0 does not save original uid, from
Randolph J Herber <rjh@yclept.chi.il.us>.  ckutio.c, 4 May 97.

Added a new makefile entry for AT&T UNIX 3.51m, which added hardware flow
control for the AT&T 7300, resulting in a file-transfer performance boost of
about 30%.  Randolph J Herber, ckutio.c, 4 May 97.

Added regular POSIX-style high speeds for Linux 1.2 and later, from Ted Ts'o
<tytso@mit.edu>.  This involved reconciling several different and conflicting
patches from the PATCHES file.  Linux C-Kermit now supports serial speeds up
to 460800bps.  ckcdeb.h, ckuus3.c, ckutio.c, 4 May 97.  Also, added a new
makefile entry, "linux", for Linux 1.2 and later.  The old entry was kept
under the name "linux10", 4 May 97.

Added support, makefile entry, and designer herald for OpenBSD, from
Todd Miller <Todd.Mill@courtesan.com>, ckuver.h, makefile, 4 May 97.

All patches from the PATCHES file are now installed.

Fixes from Jeff to my fixes.  ckudia.c, ckcmai.c, ckcker.h, 6 May 97.

Redid Telnet Location after a closer reading of RFC779, added SET TELNET
LOCATION, added location to SHOW NET.  ckcnet.c, ckuus3.c, ckuus4.c, ckuusr.h,
6 May 97.  The "send location" business works like this:

 . All code related to this feature is in #ifdef CK_SNDLOC, which is defined
   by default for all platforms (in ckcnet.h).

 . When Kermit starts, sysinit() does makestr(tn_loc,getenv("LOCATION")),
   so this needs to be added to all the non-UNIX sysinit()'s, perhaps using
   other more appropriate environment variable names, if any exist.

 . If tn_loc is not NULL, then tn_ini() sends WILL SEND-LOCATION.  If the
   server says DO SEND-LOCATION, Kermit sends the string in an SB.

 . The C-Kermit user can change the location with SET TELNET LOCATION, and
   can defeat this feature by setting the location to the empty string.

 . If sysinit() does not fill in the initial value, the user can still use
   this feature by giving a SET TELNET LOCATION string prior to making the
   connection.

Added SHOW TELNET since I keep typing it all the time anyway, and updated help
text, ckuusr.h, ckuus[245].c, 6 May 97.

Also made numerous corrections to help text, some of which involved moving
feature-selection features (CK_ENVIRONMENT and CK_SNDLOC) from ckcnet.h to
ckcdeb.h.  6 May 97.

Fix typos in yesterday's changes.  ckcdeb.h, ckcnet.c, 7 May 97.

Removed date-dependent dial-number hacks for France and Finland, since the
dates are long past.  ckuus6.c, 7 May 97.

Finished SET DIAL { LC-PREFIX, LC-SUFFIX }.  Changed this from LOCAL-PREFIX,
LOCAL-SUFFIX because LOCAL is too long to type all the time and we already had
a SET DIAL LOCAL-AREA-CODE (albeit invisible).  The original names are still
there but invisible.  7 May 97.

Added SET DIAL LC-AREA-CODES [ <list> ] and display of it in SHOW DIAL.
ckuusr.h, ckuus[234].c, 8 May 97.

Filled in callisld() to return codes differentiating among (0) regular local
calls, (1) long-distance calls, and (2) local calls that still must dial the
area code, and changed dncvt() to use these codes for both well-formed
portable phone numbers and free-form portable numbers.  Also added code for
local prefix and suffix for free-form portable numbers.  ckuus6.c, 8 May 97.

Add SET DIAL FORCE-LONG-DISTANCE { ON, OFF }.  8 May 97.  ckuusr.h,
ckuus[246].c.

Automatically set the above to ON for SET DIAL COUNTRY-CODE 33 (France).
ckuus3.c, 8 May 97.

Fixed typo in #ifdef for "set speed 19200".  ckuus3.c, 11 May 97.

Added commands for modem speaker control, 11 May 97:

  Defined symbols in ckuusr.h.
  Variables defined in ckudia.c:
    int mdmspk       (speaker on off)
    int mdmvol       (modem volume)
    char * dialspon  (speaker on command)
    char * dialspoff (speaker off command)
    char * dialvol1  (volume low command)
    char * dialvol2  (volume medium command)
    char * dialvol3  (volume high command)
  Added keyword parsing to ckuus3.c:
    SET MODEM SPEAKER { ON, OFF }
    SET MODEM VOLUME { HIGH, MEDIUM, LOW }
  Added modem command parsing, ckuus3.c:
    SET MODEM COMMAND { SPEAKER-ON, SPEAKER-OFF } <string>
    SET MODEM COMMAND { VOLUME-HIGH, VOLUME-MEDIUM, VOLUME-LOW } <string>
  Added these fields to all MDMINF structs in ckcker.h and ckudia.c.
  Changed name of dial_str[] keyword table to mdmcmd[] because the original
  was in conflict with a MDMINF struct name, ckuus3.c.
  Filled in SHOW MODEM to show all these values, adjusted pagination, ckuus3.c.
  Filled in HELP SET MODEM, ckuus2.c.
  Added semantics to ckudia.c.

Fixed errors in yesterday's work.  ckuus3.c, ckudia.c, 12 May 97.

Added GENERIC-HIGH-SPEED to MINIDIAL selection.  Also, USER-DEFINED was
supposed to be there too, but that was only halfway done.  ckudia.c, 12 May 97.

Change SET MODEM CAPABILITIES to set or unset SPEED-MATCHING automatically
based on whether SB was included among the capabilities.  ckuus3.c, 12 May 97.

Added support for the following new built-in modem types:
 . QuickComm Spirit II
 . Motorola Montana
 . Compaq Data+Fax (e.g. in Presario)
 . Fujitsu Fax/Modem Adpater
 . Megahertz AT&T V.34
 . SupraSonic V288+
 . Best Data
ckudia.c, 12 May 1997.

Changed speaker and volume commands to use multiple keywords, not dashes,
like for EC and DC.  ckuusr.h, ckuus3.c, 13 May 97.

Added SET TERMINAL KEYBOARD-MODE { NORMAL, EMACS, HEBREW, RUSSIAN }.
ckuusr.h, ckuus[27].c.

Fixed HELP text for SET MODEM { SPEAKER, VOLUME }.  ckuus2.c, 13 May 97.

Added support for more new modem types:
 . AT&T Secure Data STU-III Model 1900 (untested)
 . AT&T Secure Data STU-III Model 1910 (untested)
These are scrambling modems used at high-security places, which only talk
to each other.  Also, rearranged SET MODEM TYPE keywords that were out of
alphabetical order.  ckudia.c, 13 May 97.

Added E1V1 to all Hayes-like modem init strings for OS/2 and Windows, to
make sure we parse word result codes -- this eliminates lots of confusion
caused by incompatible digit result codes.  I didn't do this for UNIX, VMS,
etc, because it is bad to reconfigure shared modems.  ckudia.c, 14 May 97.

Added DIA_TAPI (= 34), "TAPI reported failure - reason unknown", to DIAL
failure codes and messages, and changed TAPI dialing failure code to set this
reason.  ckcker.h, ckudia.c, 14 May 97.

Added missing cases 15, 16, 17, 19, 25, 45, 107 for USR digit result codes.
ckudia.c, 14 May 97.

Fix for SCRIPT command from Gerhard Rueckle <rueckle@dr.fbe.fh-darmstadt.de>
at FH Darmstadt, to filter out NULs from session log (otherwise whole lines
were getting lost due to use of str*() functions).  ckuscr.c, 15 May 97.

Discovered that S_I[RWX]OTH stat.h symbols for file permissions could not be
depended upon, and so added more #ifdefs to account for this in zsattr().
Also, realized it's silly to use the "world" permissions field for the
"generic" permission (even though that's what the book says); changed it to
use the "user" (self) field.  ckufio.c, 16 May 97.

After spending 2 hours on the phone with a user, revised the AT&T STU III
modem commands by trial and error until they worked.  The manuals and other
info from AT&T were wrong.  ckudia.c, 17 May 97.

Added \%* variable, used only in macros, replaced by all the args that the
current macro was called with (1..argc).  ckuus4.c, 18 May 97.

Added "IF <=" and "IF >=".  ckuusr.h, ckuus6.c, 18 May 97.

Changed DIRECTORY, general case (mostly UNIX), to use cmtxt() rather than
cmdir(), to allow free-form directory commands, inclusion of switches for
system directory command, redirectors, etc.  ckuus6.c, 18 May 97.

Added SET FILE EOF { CTRL-Z, LENGTH }.  Applies only to text-mode transfers.
When set to CTRL-Z, this makes the file sender treat the first Ctrl-Z in the
input file as the end of file (EOF) (NOTE: this never worked before), and it
makes the file receiver tack a Ctrl-Z onto the end of the output file if it
does not already end with Ctrl-Z.  This feature is included for any platform
for which CK_CTRLZ is defined during compilation; by default it is defined
only for OS2.  Added to SHOW FILE, reformatted SHOW FILE.  ckcdeb.h, ckcker.h,
ckuus[2347].c, ckcfns.c, ckufio.c, 18 May 97.

Changed CALL macro to not SET MODEM TYPE if given type is the same as the
current type, thus avoiding overwriting customizations.  Also, don't SET SPEED
or LINE if given values are the same as current ones.  ckermit.ini, 18 May 97.

Examined the problem in which we DIAL a modem, disconnect, then SET HOST or
TELNET, then HANGUP, and Kermit sends +++ATHO.  There is no good way to avoid
this, because this case can't reliably be distinguished from the case in which
the user does SET HOST <terminal-server>, SET MODEM TYPE <name>, DIAL.  In
both cases we have a valid modem type selected and we have a network
connection.  If the user wants to DIAL and then later make a regular network
connection, she will have to SET MODEM TYPE NONE or SET MODEM HANGUP RS232
to avoid this phenomenon.

Fixed IF EXIST and IF DIRECTORY to properly strip braces from around their
arguments, so "if directory {C:\Program Files}", etc, would work as expected.
However, this means that if the file or directory name is actually enclosed
in braces, the braces must be doubled.  ckuus6.c, 18 May 97.

Fixed problem that occurred if "set host nonexistent-host" followed by certain
commands like SEND; the original modem type was not restored and ttopen()
thought that it still had a network hostname.  ckuus7.c, 18 May 97.

Fixed HELP SET RECEIVE PATHNAMES to show default is OFF, not ON.  ckuus2.c,
18 May 97.

Fixed SET EDITOR and SET BROWSER to use PATH in UNIX.  ckuus3.c, 18 May 97.

Fixed cmifip() to make its own safe copy of the PATH string, so the caller
does not have do this every time, and simplified calls to cmifip(),
consolidating OS/2 and UNIX calls.  ckucmd.c, ckuus3.c, 18 May 97.

Got rid of the old cmdir() function, replaced it by a new one that is just a
wrapper for cmifi() that makes cmifi() parse only directory names and handle
completion and ?-file-lists.  This affects the CD, SET SERVER GET-PATH, SET
TEMP-DIRECTORY, SET FILE DOWNLOAD-DIR, and SPACE commands.  ckucmd.h,
ckucmd.c, 19 May 97.

Fix definition of TRMBUFL (termcap buffer length), and use it when allocating
the termcap buffer, trmbuf.  ckcdeb.h, ckuusx.c, 19 May 97.

Don't print "Warning: terminal type unknown, Fullscreen file transfer display
disabled" if C-Kermit is in remote mode.  ckuusx.c, 19 May 97.

Allow GET and RECEIVE as-names to override RECEIVE PATHNAMES setting.
rcvfil(), ckcfns.c, 19 May 97.

The READ command was being overly picky about "last line lacks terminator".
I changed it to allow the last or only line to lack a terminator.  This is a
sneaky way of allowing even binary files to be read into a variable (all at
once) if the READ buffer is set large enough (and the file does not contain
NUL characters).  doask(), ckuus6.c, 19 May 97.

The braces problem: Since braces are used in function calls to indicate
grouping, there is no way to pass literal braces to the function itself.
Solution: Define a variable containing the string that has braces.  Example:

  define \%a ab{cd
  echo \fsubstring(\%a)
  ab{cd

If the string is to start with a leading brace and end with a closing brace,
then double braces must appear around the string (which itself is enclosed in
braces):

  define \%a {{{foo}}}
  echo \fsubstring(\%a)
  {foo}

This also works for any other kind of string:

  define \%a {{ab{cd}}
  echo \fsubstring(\%a)
  ab{cd

No changes here -- this is how it has always worked, but was not documented
before.

Lots of users try to write scripts for Telnet logins, but use "telnet"
rather than "set host"... eventually they log out or close the connection,
and then when the INPUT command executes, it says "?Can't condition line
for INPUT", which is singularly uninformative.  I made INPUT issue a better
message when it knows the connection is not open (CK_TTYFD is defined and
ttyfd == -1).  doinput(), ckuus4.c, 19 May 97.

Added SET INPUT AUTODOWNLOAD { ON, OFF } (to control autodownload during INPUT
separately from during CONNECT) and SHOW INPUT.  ckuusr.h, ckuus[r2457].c,
19 May 97.

Changed CD to use CDPATH, like ksh.  If the CDPATH environment variable is
defined, then it is used: if a CD command is given for a relative directory,
then if it is not found in the current directory, the CD path is searched for
a directory that contains a directory of the given name.  ckucmd.c, ckuus5.c,
20 May 97.

Rearranged #ifdefs in ckcdeb.h so CK_ENVIRONMENT would take effect for UNIX.
20 May 97.

Added CGET command (GET to pipe).  ckuusr.h, ckuusr.c.  21 May 97.

Added SET EOF as invisible synonym for SET FILE EOF.  ckuusr.h, ckuus[37].c,
21 May 97.

Fixed UNIX version of CD, when following CDPATH, to treat an empty member as
the current directory, rather than root (by definition of CDPATH).  ckucmd.c,
22 May 97.

Changed netopen() to supply "23" as the default service, rather than "telnet",
to sidestep all the problems we have been having with getservbyname()
returning the service number with its bytes swapped.  ckcnet.c, 23 May 97.

Installed patches for CMUIP from Wolfgang Moeller <moeller@decus.decus.de>.
ckutio.c, 23 May 97.

Some fixes for Wollongong Pathway from Ray Hunter.  ckcnet.c, ckvtio.c,
23 May 97.

Some new #ifdefs for UCX / DECC from Martin Zinser.  ckcnet.c, 23 May 97.

Added CHECK NETWORK before trying to SET NETWORK DIRECTORY.  ckermit.ini,
23 May 97.

Added support for AT&T KeepinTouch modem card.  Moved modem-type definitions
to ckuusr.h.  ckuusr.h, ckudia.c, 27 May 97.

Fixed SET EDITOR and SET BROWSER to convert filename to a full pathname
in case it wasn't already.  Removed SET BROWSER from all implementations
except OS/2 and Windows.  ckuusr.c, ckuus3.c, 28 May 97.

SET EXIT WARNING didn't work properly when connection was opened with
-l, -j, or -J on command line.  Fixed in ckuusy.c, 29 May 97.

Fixed SET EDITOR to use EDITOR environment variable as default.

Fixed SET PROTOCOL not to parse external command fields if protocol is Kermit
(it never should have); Kermit isn't an external protocol.  ckuus3.c, 1 Jun 97.

Added "autoserver" command, 1 Jun 97:
 . It is not part of ptab[], since is specific to Kermit protocol.
 . Initialize char * srvstring to "kermit -x" in initproto(), ckcmai.c.
 . Added new 3rd field to SET PROTOCOL KERMIT for server string, ckuus3.c.
 . Updated SHOW PROTOCOL to display the server string, ckuus4.c.
 . Added code to send server string when GET or REMOTE are given, ckcpro.w.
 . Updated help message for SET PROTOCOL, ckuus2.c.

Added -O command-line option: "be a server, but execute Only One command".
ckuusy.c, 1 Jun 97.

Added a new keyword flag, CM_HLP, which (when combined with CM_INV), means
that the keyword, which is normally invisible, becomes visible in a HELP
command.  Adjusted calling conventions and prototypes for various command
parsing functions accordingly.  ckucmd.h, ckucmd.c, 2 Jun 97.

Added new keywords to top-level cmdtab[]: FUNCTIONS and KVERBS with CM_HLP
flag, visible only from HELP.  ckuusr.c, 2 Jun 97.

Filled in help text for each function (61 of them), and fixed some mistakes in
the function keyword table, fnctab[].  Adds about 8K. ckuus[24].c, 2 Jun 97.

Added reference to HELP FUNCTION to SHOW FUNCTION.  ckuus5.c, 2 Jun 97.

Added \v(regname), \v(regorg), \v(regnum), invisible variables for
registration info; they just call get_reg_blah() from ckoetc.c.  ckuusr.h,
ckuus4.c, 2 Jun 97.

Added \v(xprogram), the specific program name: "K-95", "K/2", or "C-Kermit".
ckuusr.h, ckuus4.c, 3 Jun 97.

From Jeff, 5 Jun 97:
 . \v(line) changed to return Kermit form of TAPI device name (no blanks etc).
 . Fix for internal coding error with IF EQUAL s1 s2.

Added IF TAPI.  ckuusr.h, ckuus6.c, 5 Jun 97.

Seemingly minor problems with cmdir() directory parsing fixed, 5 Jun 97:

 1. "cd /" would tend to fail because "too many directories match"; fixed in
    cmdir() by not calling zxpand if we are parsing a directory name and it
    does not contain any wildcard characters.

 2. "cd xxx<ESC>" would not supply the trailing directory separator when
    completion was successful.  Fixed in ckucmd.c.

 3. "cd xxx?" could produce unbalanced columns, etc.

 4. "cd xxx<ESC>" would fail even if only one directory started with "xxx",
    if a regular file also started with "xxx".

Problems 3 and 4 resulted from the fact that "x = zxpand(string);" returned
the number of *all* matching files, not just the number of directories that
matched.  But since it's far too late to change the API to add a new function
to return a list of directories, or to add an argument to zxpand(), I used a
horrible hack: cmdir() sets a global variable, dironly, if a list of only
directories is desired.  If dironly == 0, zxpand() behaves as before.  This
was implemented in the UNIX version of zxpand() in ckufio.c, but nowhere else,
although it is easy enough to add (but not to test!) in OS-9, etc.  If dironly
is to be set prior to calling to zxpand(), but MUST be restored immediately
after so as not to disrupt other legitimate callers throughout the code.
Thus, this usage is strictly confined to cmdir() (really cmifi2()) and not
documented in the API.

 5. "cd xxx<ESC>" left a space at the end when completion was successful.

It has to, in case there is a subsequent field.  Peter Eichhorn asked that it
stop at the "/" in case there are subdirectories, but how would we know (a)
that there *are* subdirectories without descending through the entire
directory tree, which could take hours, and (b) that even if there were
subdirectories, that this was not the directory the user wanted to CD to?
So no action here.  BTW, note that "if directory blah" does not use cmdir();
if it did, and "blah" was not a directory, we'd get a parse error.

Added SET BPRINTER (bidirectional printer port) for K95 only; Jeff will fill
in details; ckuusr.[ch], ckuus3.c, 6 Jun 97.  Full syntax is:
SET BPRINTER [ port speed [ parity [ flow ] ] ].

Fixed help text for PRINT and SET PRINTER.  Put BPRINTER code in #ifdef
BPRINT.  7 Jun 97.

Added options to SET EDITOR and SET BROWSER.  ckuus[r35].c, 8 Jun 97.

Added \v(editor), \v(editopts), \v(editfile), \v(browser), \v(browsopts),
\v(browsurl).  ckuusr.h, ckuus4.c, 8 Jun 97.

Added BROWSE command for UNIX & K95.  ckcdeb.h, ckuusr.h, ckuusr.c, 8 Jun 97.

Changed ^W to delete back to nonalphanum rather than back to space.
ckucmd.c, 8 Jun 97.

Updated help text for today's changes.  ckuus2.c, 8 Jun 97.

Fix GETOK -- it had garbage for the default prompt.  ckuus6.c, 17 Jun 97.

Added STATISTICS /BRIEF for Peter Eichhorn.  ckuusr.[ch], ckuus[24].c,
18 Jun 97.

Fixed Telnet SEND LOCATION negotiation to send WONT, rather than WILL,
if we don't have a location, in response to DO LOCATION.  ckcnet.c, 18 Jun 97.

Fixed EDIT and BROWSE to handle %1 (OS/2 & Windows only) and %s in the options
string as a filename placeholder.  ckuusr.c, 18 Jun 97.

Added array initializers, e.g. "declare \&a[3] {value1} {value2} {value3}".
Initializers are (a) optional, (b) start with element 1, (c) can only be given
up to the size of the array, (d) must be enclosed in braces if they contain
spaces, (e) are stored literally and not evaluated.  ckuusr.c, 18 Jun 97.

Added OS-9 support for incoming TCP/IP connections, from Steve Rance
<stever@ozemail.com.au>.  OS-9 has no select() call, so he made a dummy one.
ckcnet.c, 19 Jun 97.

Defined BIGBUFOK for AIX on RISC.  ckcdeb.h, 20 Jun 97.

---1.1.13---

Installed MINIX 2.0 changes from Terry McConnel, Math Dept, Syracuse U,
trmcconn@syr.edu, plus a new makefile target.  cku[tf]io.c, ckuus6.c,
ckucmd.c, makefile, 28 Jun 97.

Added zfnqfp() (the unspellable function) for AOS/VS.  Also zmkdir() and
isdir(), plus the changes for the new cmdir() support.  ckcdeb.h, ckuus3.c,
ckuus6.c, ckdfio.c, 29 Jun 97.

Removed spurious "extern int delay" from ckcfn2.c.  29 Jun 97.

Filled in MKDIR and RMDIR commands for AOS/VS.  But rmdir() doesn't work for
some unknown reason; "perror" always says "30 End of File".  The AOS/VS C
programming docs do not list any way to delete a directory.  So I changed it
to system("delete blah"), where blah is the directory name.  It works, but it
doesn't return a status code, and it also removes regular files.  Meanwhile,
AOS/VS stat() sometimes crashes.  There's nothing I can do about it, and no
pattern I can find as to what conditions make it happen.  ckuusr.c, 30 Jun 97.

Changed sfile() not to send filename as FILE001, etc, if an as-name is defined
as a variable that has no value.  This was a bug introduced in the template
code.  "send \%1 \%2" would cause this to happen (as in the BSEND macro).
ckcfns.c, ckermit2.upd, 30 Jun 97.

Fixed DG isdir() to not call stat(), to prevent crashing -- now it does the
appropriate VS syscall directly.  Also fixed DG iswild() not to return false
positives because of ^, which is like .. in UNIX.  ckdfio.c, 1 Jul 97.

Fixed cmdir() for DG to not append : to directory name during completion,
because chdir() does not work if you do that.  ckucmd.c, 1 Jul 97.

END from inside SWITCH did not work right -- SWITCH, although implemented
as a macro internally, should not count as a macro level to END.  This was
already handled correctly for FOR, WHILE, and XIF.  Added SWITCH to the list.
ckuusr.c, 3 Jul 97.

Added cmswi(), which is just like cmkey(), but for switches (optional keywords
that begin with "/").  If the CM_ARG bit is set in the keyword table, then the
switch takes an argument, separated by ":" or "=", e.g. /PROTOCOL:KERMIT.
Otherwise, it doesn't, e.g. /BINARY.  ckucmd.[ch], with some testing material
(under the TYPE command) in ckuusr.[ch], 4 Jul 97.

Added chained parse fields.  New function cmfdb(), takes the address of an FDB
struct (containing parse function code plus inputs for the function -- help
message text, default, etc), as an arg, which may contain a pointer to another
one, and so on, until the "next-FDB" pointer is null.  If user's input is not
parsed successfully by the first, then the second is tried, and so on to the
end of the chain, at which point a parse error is returned.  ESC and ? work.
ckucmd.[ch], 4 Jul 97.  (What does FDB stand for?  I don't remember; that's
what they were called in TOPS-20... Function Descriptor Block?)

Removed testing material from the TYPE command.  Added experimental XSEND
command, which is like SEND, but takes all sorts of switches: /BINARY,
/AS-NAME:xxx, etc.  It replaces the old SEND, plus CSEND and PSEND, as well as
MOVE and the BSEND and TSEND macros.  Filled in the actions for all switches.
XSEND is implemented entirely in doxsend().  ckuusr.[ch], 5 Jul 97.

Finished testing & debugging XSEND command.  Verified that when given no
switches, it behaves exactly like the SEND command, and so repaced the SEND
command with doxsend(), leaving the old code still there for CSEND, PSEND,
etc, so they can still be used.  The new arrangement allows more and more
variations on SEND to be accomplished without adding top-level commands.  It
also allows combinations that were not possible before, such as /PRINT or
/MAIL with a SEND-LIST, SEND /PRINT /DELETE or SEND /COMMAND /MAIL:address.
Changed MOVE, CSEND, MAIL, and RESEND to use doxsend(), since they have the
same format as SEND.  Left MSEND, MMOVE separate.  Added description of
switches to ckermit2.upd, section 1.5, and new section 4.7 on SEND command.
Changed HELP SEND text.  6 Jul 97.

Same treatment for RECEIVE / CRECEIVE; GET / REGET / CGET / RETRIEVE.
ckuus[r6].c, ckermit2.upd, 7 Jul 97.

Updated help text for RECEIVE and GET.  ckuus2.c, 8 Jul 97.

Updated section 4.2 of ckermit2.upd to show new forms.  8 Jul 97.

Added switches to MSEND and MMOVE, combined code into doxsend().
Made many of the stupider command names (CGET, RETRIEVE, etc) invisible;
now top-level ?-help looks a lot better.  ckuusr.c, 8 Jul 97.

Corrections and refinements to switch code.  Fix MSEND/MMOVE when used with
ZMODEM, when used with /MAIL, etc.  Eliminate ambiguity about what happens
when a switch that must take an arg is followed by a space.  The rule is:
if a switch name ends in : or =, then if the next character is a space, that
means an empty value has been given, and the next field is parsed.  ckuusr.c,
ckucmd.c, 9 Jul 97.

#ifdef adjustments for HP-UX 10.x and Digital UNIX 3.2/4.0 from Jonathan
Kamens <jik@cam.ov.com>.  ckcdeb.h, ckufio.c, ckutio.c, 12 Jul 97.

Fixes (or stabs in the dark at fixes) for recently reported VMS problems; see
notes in ckvtio.c for edit 091.  12 Jul 97.

Added some missing #ifdefs for protocol switching and pipesend to the recent
switch-parsing code.  ckuus[r6].c, 12 Jul 97.

Added some missing prototypes for recently added command-parsing functions.
ckuusr.h, ckucmd.h, 12 Jul 97.

--Alpha.01--

Added APC check to MOVE/MMOVE -- we don't want APC strings stealing files
from people...  ckuusr.c, 13 Jul 97.

Now that we have all the pipesend / receive filter stuff in place, it turned
out to be easy to rearrange the mail-receiving code to pipe the incoming
material directly into the mail program (in UNIX).  This has the advantages of
(a) not requiring a temp file, and (b) allowing a normal subject in place of
the filename.  Temp files were bad not only because they required (a) space,
and (b) writeability of the current directory, but also because using them
could result in wiping out an existing file.  So now:

  send /mail:whoever@xyz.com /as:{Hi there} oofa.txt

when sent to C-K results in whoever@xyz.com receiving oofa.txt as email
with subject "Hi there".  ckcpro.w, ckcfns.c, 13 Jul 97.

Added /SUBJECT: as a synonym for /AS-NAME:, and fixed a couple minor glitches
related to mail.  ckuusr.c, 13 Jul 97.

Changed reception of print files (from REMOTE PRINT or SEND /PRINT) to use
pipes also.  UNIX only.  ckcpro.w, ckcfns.c, 13 Jul 97.

In response to people *still* complaining about exit warning when they swear
the modem is not asserting CD...  In hupok(), ttgmdm() returns an error.  This
can happen if we used to have carrier but now we don't and the device driver
won't let us look at the device any more (e.g. Solaris 2.5).  Previously, we
always set needwarn to 1 here to be safe, but really, if CARRIER-WATCH is OFF,
we already decided not to warn, so CARRIER-WATCH must be ON or AUTO, which
*probably* means that we had CD on this connection before, and so if ttgmdm()
fails now, it means we don't have it any more.  So now let's try NOT warning
when ttgmdm() returns an error.  ckuus3.c, 13 Jul 97.

Speaking of modems, in response to increasing requests for an option to ignore
dialtone, added SET DIAL IGNORE-DIALTONE { ON, OFF } and SET MODEM COMMAND
IGNORE-DIALTONE <command>, and a new ignoredt member to struct MDMINF, etc
etc.  Untested, except that SET, SHOW, and HELP work OK.  ckcker.h, ckuusr.h,
ckuus[234].c, ckudia.c, 13 Jul 97.

Back to VMS...  Noticed that zxpand() would malloc() its array of filenames
every time it was called, but nobody would ever free them.  Fixed in ckvfio.c,
14 Jul 97.

An off-by-one error in the switch parser caused the placeholder for highest-
numbered switch value (SND_LBL) to go uninitialized, thereby making VMS
C-Kermit send in labeled mode (depending what was in the uninitialized
memory).  Fixed in doxsend(), ckuusr.c, 14 Jul 97.

Lots of changes to isdir() and cmdir() for VMS.  The idea is to make directory
parsing work as in UNIX, Windows, AOS/VS, etc, but it's much harder in VMS
because a directory can be represented in many ways: a logical or device name,
or [FOO.BAR], or DEV:[FOO.BAR], or [FOO]BAR.DIR;1, etc.  This was about two
days' work, with some help on isdir() from Mark Berryman.  ckucmd.c, ckvfio.c,
15 Jul 97.

Removed gratuitous message showing new directory from docd().  ckuus5.c,
15 Jul 97.

Fixed UNIX "cd ~name" to work again -- I must have broken it recently.
ckucmd.c, 15 Jul 97.

Changed ckindex() to accept -1 as a "starting position" argument, meaning
"length of string 2".  ckcmai.c, 15 Jul 97.  (NOTE: fix \frindex() to take
advantage of this...)

Amplifed, reorganized, and numbered ckuins.doc.  16 Jul 97.

Attempted to add support for 57600, 76899, and 115200 bps for IRIX 6.2 (the
first release of IRIX that supports these speeds).  A previous attempt at
doing this by adding -DPOSIX to the make was a disaster.  This time I tried
defining POSIX for IRIX62 within ckutio.c only around ttsspd() and ttgspd(),
and also defined the BPS_xxx symbols for IRIX62 in ckcdeb.h.  16 Jul 97.

Mike Freeman reported that login scripts didn't work in VMS.  Evidently this
was because a new check was added for ttyfd == -1, but VMS doesn't use file
descriptors, and so ttyfd is always -1 there.  Fixed doinput() in ckuus4.c to
skip this test for VMS.  16 Jul 97.

Found a few places where the protocol module was not setting the exit status
code; hopefully caught them all.  ckcfn2.c, 16 Jul 97.  Nope, that wasn't it.
The real problem was that the "what" variable was set to W_NOTHING until a
protocol transfer actually had begun.  So if we timed out on the first packet,
ORing "what" into the exit status had no effect.  Fixed in ckcpro.w by
initializing what to 1 rather than W_NOTHING.  16 Jul 97.

Changed "CD" (by itself) in VMS to simply chdir("SYS$LOGIN:").  ckvfio.c,
16 Jul 97.

Fixed IF ALARM to make sure both time comparands are left-padded with "0"s
so they compare correctly with strcmp().  ckuus6.c, 18 Jul 97.

Previously MGET and GET were synonyms.  But now the new GET syntax prevents
the (little-known) feature in which you could GET a list of files, like "get
oofa.txt *.ps /etc/motd".  So now MGET has become a separate command that does
allow this syntax (but no as-names).  This also fixes a problem with "get xxx
yyy" (i.e. as-name is yyy), resulting in "?Write permission denied - yyy".
It also fixes a bug with "get {xxx yyy zzz}", in which the first "{" was not
removed prior to sending the R packet.  ckuusr.[ch], ckuus[26].c, 19 Jul 97.

Added a note to top-level help about macro names.  Changed built-in predefined
names _forx, _whilex, etc, to be invisible so they don't show up in "do ?".
ckuus5.c, 19 Jul 97.

Corrections & updates to ckermit2.upd, 19 Jul 97.

Fixed ANOTHER off-by-one error in the declarations of switch tables for SEND
and GET (this was a bad one, causing core dumps).  ckuus[r6], 19 Jul 97.

---Alpha.02---

James Cameron verifies the VMS problem with closing DECwindow on C-K is fixed.
20 Jul 97.

Added cmdate() to parse a date and/or time.  ckucmd.[ch], 20 Jul 97.

Dale Dellutri says problem with hanging after "Communications disconnect" is
fixed, but NO CARRIER message never shows up (as it always did in 5A(190)).
Asked him for a debug log.  21 Jul 97.

Added /BEFORE: and /AFTER: switches to SEND, using cmdate().  Also added
/LARGER-THAN: and /SMALLER-THAN:.  ckcfns.c now has a nice fileselect()
routine that decides whether to send the file based on these switches.
ckuusr.c, ckcfns.c, ckuus2.c, ckermit2.upd, 21 Jul 97.

Added a crude pattern matcher, ckmatch(pattern,string), supporting only * and
? as metacharacters.  ckcmai.c, 21 Jul 97.

To test it, added IF MATCH <string> <pattern>.  ckuusr.h, ckuus6.c, 21 Jul 97.

Added /EXCEPT:<pattern> to SEND.  ckuus[r2].c, ckermit2.upd, 21 Jul 97.

Fix #ifdefs so that CK_ENVIRONMENT is not defined unless TCPSOCKET is defined,
to prevent unresolved externals at link time in non-TCP/IP UNIX builds.
ckcdeb.h, 21 Jul 97.

Add new updates for wait() argument (is it "int" or is it "union wait"?).
ckutio.c, 21 Jul 97.

Rearrange some lines in ckcnet.c so ucx_port_bug does not turn up undefined
if we are using DECC, 21 Jul 97.

Built on Digital UNIX 4.0 (where there is a warning about wait() that I can't
seem to shut up) and 3.2 (no problem there).  21 Jul 97.

Fixed numerous #ifdef errors regarding feature selection, many modules.
21 Jul 97.

Shuffled some more #ifdefs and variable declarations to allow for NOICP build.
Minor help text cleanups.  Don't allow SEND /STARTING-AT:n for file groups.
Many modules, 22 Jul 97.

Fixed another (off-by-one) bug with transfer mode in VMS (it always insisted
on receiving in labeled mode).  ckuus6.c, 22 Jul 97.

VMS C-Kermit would crash if given invalid command-line args detected in
prescan() because fatal(), called to print the error message, could not print
it because sysinit() had not yet been called to obtain the console channel.
This mess really needs cleaning up.  Meanwhile, I worked around it by having
all the console i/o routines in VMS check first to make sure they have an open
channel, and also to have main set a global flag "initflg" after return from
sysinit() to indicate that sysinit has been done.  If it hasn't, then fatal
calls sysinit() first before trying to print any messages or exit.  This is
also important elsewhere in case (e.g.) we try to restore some systemish
things that we haven't saved yet, e.g. tty modes or somesuch.  ckcmai.c,
ckuusx.c, ckvtio.c, 22 Jul 97.

Fixed cmini() to not assume that buffers had already been malloc'd.
ckucmd.c, 22 Jul 97.

Got tired of having to remember to update version numbers, dates, etc, in so
many places, so broke all these strings up into their component parts so that
each one only has to be changed in one place, pretty much, and then added a
routine, makever(), to put the various strings and numbers in the places where
all the other routines expect to find them.  ckcmai.c, 24 Jul 97.

Added \v(test) == "0" if this is not a test version of Kermit, or else the
test version, e.g. "Alpha.03".  ckuusr.h, ckuus4.c, 24 Jul 97.

Added optional pattern for SHOW VARIABLES, e.g. "show var *ver*".  Also, "show
var x" shows all variables whose names start with x, etc.  ckuus5.c, 24 Jul 97.

Fixed a bug in the parsing of the LOCAL command.  ckuus5.c, 24 Jul 97.

The test for DELETE success/failure was wrong in the non-K95 case.
Fixed in dodel(), ckuus6.c, 25 Jul 97.

Added \fn2hex() and \fn2oct() to convert numbers to hex and octal.  \fhexify()
converts *strings* to hex, which is quite different.  E.g. \fhex(16) = 3130,
whereas \fn2hex(16) = 10.  ckuusr.h, ckuus[24].c, 26 Jul 97.

Changed default maximum packet buffer size to 290K if BIGBUFOK and DYNAMIC are
both defined at compile time.  This doesn't change the size of the executable,
and the memory is allocated only if requested.  ckcker.h, 26 Jul 97.

Missing file display on RESEND after SEND, and SEND after RESEND behaved like
RESEND.  Fixed misplaced #ifdefs in doxsend.  ckuusr.c, 26 Jul 97.

Scenario: my current directory has a file that I can delete, but the directory
itself lacks write permission.  I try to receive a file into this directory
that has the same name as an existing file, with FILE COLLISION set to BACKUP.
The transfer fails, not because I can't overwrite the original file, but
because I can't create the backup file.  But when in local mode, the
appropriate message does not make it to the file-transfer display.  This took
quite a bit of reworking how E packets work and where their messages are
saved, but it seems OK now.  If the user sees the new message ("Can't create
backup file"), she can switch to SET FILE COLLISION OVERWRITE or APPEND,
which work.  ckcpro.w, ckcfn*.c, ckermit.bwr, 26 Jul 97.

Things I should have thought of long ago dept, cont'd...  Added a new internal
variable, xferstat, that remembers the status of the most recent file
transfer: -1 = no transfer yet, 1 = failure, 0 = success.  Added this info,
plus the text of the error packet that terminated an unsuccessful transfer,
to the STATISTICS display.  Also added variables for these: \v(xferstat)
and \v(xfermsg).  ckuusr.h, ckuus4.c, ckermit2.upd, 26 Jul 97.

Cleaned up a bunch of internal messiness involving file-transfer failures.
For example, clsof and clsif should not do all of their usual stuff if the
file they are trying to close was never opened.  In particular, they should
not call fstats(), which writes messages to the transaction log and
accumulates statistics.  ckcpro.w, ckcfn[s23].c, ckuusx.c, 26 Jul 97.

Simplified & corrected parsing of RETURN and added brace-stripping for the
return value.  ckuusr.c, 26 Jul 97.

Added a BACK command, which means to "CD to my previous current directory".
Very simple, not a stack -- so successive BACK commands just switch between
two directories.  ckuusr.[ch], ckuus[52].c, ckermit2.upd, 26 Jul 97.

Added an optional switch, /RAW-SOCKET, to end of SET HOST / TELNET command.
It can be given only if you first give a host and a port.  When this switch is
given, ttnproto is set to the new value, NP_TCPRAW.  See ckermit2.upd 2.3.5.
ckuus7.c, ckcnet.[ch], 26 Jul 97.

Fixes to /raw-socket code from yesterday to make it actually work, and add
display of this to SHOW NET.  ckcnet.[ch], ckutio.c, ckuus4.c, 27 Jul 97.

Fixes to epktmsg-related code from yesterday -- in some cases the pointer was
not initialized, causing core dumps, etc.  Many modules, 27 Jul 97.

Added zgperm() to ckufio.c, UNIX only for now (protected by CK_PERMS), to get
file modes/permissions.  ckufio.c, ckcplm.doc, 27 Jul 97.

Used zgperm() in rcvfil() in the file collision section.  If the incoming file
has the same name as an existing file, and we are going to create a new copy
or overwrite the existing file, we get its permissions first and stuff them
into the attribute structure when initializing it (in initattr()).  If the
sender puts its own (local-format) permissions in the A-packet, these will
override.  But if it doesn't, then the new file inherits the permissions of
the old one.  If there is no A-packet, the new file inherits the old file's
permissions, but the new file gets the current date and time.  If there is
no file collision, there is no inheritance.  ckcfn[s3].c, 27 Jul 97.

Adjustments to ckcnet.h for DECC 5.5-002 (remove bzero/bcopy prototypes).
27 Jul 97.

---Alpha.03---

Fixed some bad buffer & pointer declarations in ckcmai.c when DYNAMIC not
defined.  28 Jul 97.

Changed SEND /EXCEPT: to allow a list of patterns, rather than just one.
ckuus[r5].c, ckcfns.c, 29 Jul 97.

Added SEND /NOT-AFTER: and /NOT-BEFORE: to get the {greater,less}-than-or-equal
effect.  ckuusr.[ch], ckuus2.c, 31 Jul 97.

Added SET FLAG { ON, OFF } and IF FLAG.  It's just a user-settable flag that's
easy to test in scripts.  ckuusr.[ch], ckuus[23].c, 1 Aug 97.

Added { SEND, RECEIVE, GET, etc } /FILTER.  ckuus[r26].c, 1 Aug 97.

Fix from Jeff for reconnecting to a raw TCP socket without having the protocol
switch to Telnet.  ckcnet.c, 2 Aug 97.

Changed dial module to echo commands if DIAL DISPLAY is ON but modem is not
echoing them.  ckudia.c, 2 Aug 97.

Added a new member to struct MDMINF -- ini2, the last-minute init string, to
be sent just prior to dialing.  For compatibility with TAPI.  ckcker.h,
ckudia.c, 2 Aug 97.

Added SET MODEM COMMAND PREDIAL-INIT <string> to set the last-minute init
string.  ckuusr.h, ckuus[23].c, 2 Aug 97.

Reported problem with PPI seems to be lost chars on output -- commands are OK.

Added \v(sendlist) = number of entries in send-list.  ckuusr.h, ckuus4.c,
2 Aug 97.

Updated the TAP script to be more robust, etc.  ckepage.ksc, 2 Aug 97.

Added /PATHNAMES:{ON,OFF} and /FILENAMES:{CONVERTED,LITERAL} to SEND commands.
SEND /PATHNAMES:ON also temporarily SETs FILE NAMES LITERAL.

Noticed that more-prompting in the STATISTICS command was messed up.  It
turned out that the cmd_rows variable got set to 0 after a failed file
transfer (and who knows what else!).  Why?  When an E packet is received, we
have some new code to copy the error message to a "failure reason" buffer
using strncpy.  Well, the target buffer was being accessed thru a string
pointer that was mistakenly declared as an array (it originally was an array,
but later was changed to a pointer, and evidently the change didn't propogate
thru all the modules).  This one was great fun to track down.  ckcfn[s23].c,
ckuus4.c, 2 Aug 97.

Some testers of Alpha.03 noticed that REMOTE DIRECTORY didn't work.  It was
actually worse than that.  I had broken this when adding the code to avoid
closing a file when it wasn't open.  First, the o_isopen flag was not always
being set, and second reof() did not give a proper return code.  Now fixed.
ckcfn[s3].c, 2 Aug 97.

But sending of remote commands to pipes was also broken in Alpha.03.  This
required adding a system-independent front-end to zxcmd(), openc(), that sets
the o_isopen flag.  ckcfn3.c, ckcpro.w, 3 Aug 97.

Integrated Jeff's changes from the past week.  Many modules, 10 Aug 97.

Replaced all HP-UX makefile entries with new ones from Peter Eichhorn.
makefile, 10 Aug 97.

Added high serial speeds for SCO OSR5.0.2, along with a new symbol,
POSIX_SPEEDS, used to select POSIX speed setting/getting separately from POSIX
for everything else, and predefined this for OSR5.0.2 and IRIX 6.2, along with
POSIX itself and BSD44.  Added new makefile entries for SCO OSR5.0.2.
ckcdeb.h, ckutio.c, ckuver.h, makefile, 10 Aug 97.  But this doesn't work at
all -- REVISIT THIS MONDAY...

Fixed spurious error message issued by VMS C-K when doing a GET command.
ckuus6.c, 10 Aug 97.

More futzing with SCO OpenServer R5.0.2.  To get the new high speeds, I have
to convert completely to POSIX, but this proves to be an adventure because of
the situation with hardware flow control, which is outside the scope of POSIX.
Got it, after much header-file shuffling.  This also involved some minor but
perhaps significant changes to the general POSIX code.  ckcdeb.h, 11 Aug 97.

Fixed a truly horrible bug, in which the modem types above 55, namely
SupraSonic, Best Data, ATT 19x0, and ATT KeepInTouch, were indexed
incorrectly, off by one, because the pointer to SupraSonic was left out of the
modemp[] array.  This goes back to May, and nobody ever noticed.  ckudia.c,
12 Aug 97.

NOTE: THERE IS STILL MORE CONFUSION LURKING because of 1-based modem numbers
versus 0-based modemp indexes!

More fixes for POSIX serial i/o in SCO OSR5.0.2, and presumably elsewhere too.
ckutio.c, 12 Aug 97.

Spent the morning determining there was no way to read modem signals in SCO
OSR5.0.4 (in termio.h, TIOCMGET is defined only if _SVID3 is defined *and*
_POSIX_SOURCE is *not* defined, but we need _POSIX_SOURCE defined so we can
get the high serial speeds).  Anyway the underlying ioctl() probably is a just
no-op.  13 Aug 97.

Noticed and fixed a typo in the Telebit init string: S61=1 should be S61=0
(BREAK action should be "do what S63 says" rather than "return to command
mode").  ckudia.c, 13 Aug 97.

Fixed hardware flow control in SCO OSR5.0.4 -- more #ifdef juggling.
makefile, ckcdeb.h, ckutio.c, 13 Aug 97.

Changed references to modemp[n_TAPI] to modemp[n_TAPI - 1] because the
modemp[] array is 0 based even though the modem type numbers are 1-based.
Confusing but true.  ckudia.c, 13 Aug 97.

Another day spent with SCO 5.0.4.  Evidently the new stuff (high serial speeds
etc) only works in 5.0.4, even though it might be in the header files for
5.0.2, so I changed the symbols, makefile entry names, etc, accordingly.
Experimentation with flow control revealed:

 . The <sys/termiox.h> material (RTSXOFF/CTSXON) compiles OK but doesn't work
   (the ioctls return -1).
 . The RTSFLOW/CTSFLOW material does not show up in a POSIX compilation.
 . Forcing RTSFLOW/CTSFLOW definitions (yuk) seems to do the trick.

But forcing TIOCMGET does not get us working modem signals -- the ioctls just
say "invalid argument".  But I left it in anyway, because some third-party
drivers, like Digiboard, might implement it.  ckcdeb.h, ckutio.c, ckuus5.c,
makefile, ckuins.doc, 14 Aug 97.

Straightened out the aforementioned mess with the modemp[] array.  Now that
wasn't so hard, was it?  ckudia.c, ckuus[34].c, ckuusr.h, 14 Aug 97.

Changed mainline binary variable when switching automatically from text to
binary mode in VMS C-Kermit -- cosmetic only; should only affect the
file-transfer display.  ckvfio.c, 14 Aug 97.

Changed SET EDITOR and SET BROWSER in VMS to parse text strings rather than
filenames.  It turns out that zshcmd() (in VMS, a front end for LIB$SPAWN())
can not run programs when given a filespec; it runs DCL commands, period --
always has -- did I know that?  ckuus3.c, ckermit2.upd, 14 Aug 97.

Added support for USR XJ1560 X2 56K modem.  ckuusr.h, ckudia.c, 14 Aug 97.

Changed keyword parser to skip over CM_INV keywords when completing an
abbreviation.  ckucmd.c, 14 Aug 97.

Fixed some typos from yesterday's SCO work.  ckutio.c, 15 Aug 97.

Discovered that "remote host xxx" followed by "get" did not work.  This was
yet another case of the i_isopen flag not being set (this time in syscmd()).
I'm wondering now what the original idea was behind these stupid flags -- oh
yeah, I remember -- calling fstats() would have the side effect of writing a
misleading transaction log entry if the file had never been opened.  Anyway,
all fixed now.  ckcfn[s3].c, 16 Aug 97.

Fix from Jeff for tn_ini() -- make sure *all* Telnet protocol flags are
reset.  ckcnet.c, 17 Aug 97.

Miscellaneous minor corrections from compiling on many platforms.
ckuusr.c, ..., 17 Aug 97.

---Alpha.04---

Changed USR X2 max speed to 115200.  ckudia.c, 18 Aug 97.

Some tentative changes for Apollo SR10.  ckuusx.c, ckuver.h, 18 Aug 97.

Some of the cmfld()-parsing SEND (etc) switches were not stripping braces.
ckuusr.c, ckuus6.c, 19 Aug 97.

Console modes were not being twiddled in the EDIT and BROWSE commands, which
affected VMS (some editors would not echo when started).  ckuusr.c, 19 aug 97.

Fixed a problem in which REMOTE HELP failed, caused by a rearrangement of the
code in opent() which, if it succeeded, it did not set a return value, so its
return value was random (i.e. system-dependent).  Now why didn't all those
strict ANSI compilers notice?  ckcfn3.c, 19 Aug 97.

The client end of REMOTE RENAME and REMOTE COPY have been broken since 6.0
came out -- nobody noticed till just now.  The code that was added to parse
redirectors wiped out the second field.  ckuus7.c, 20 Aug 97.

Fixed broken RECEIVE XXX for XMODEM transfers and assorted other parsing
problems in doxget().  ckuus6.c, 23 Aug 97.

Added CONNECT command switches:

 /QUIETLY              All but K95    (n/a)
 /IDLE-LIMIT:int       K95 only       int    tt_idlesnd_tmo;
 /IDLE-STRING:string   K95 only       char * tt_idlesnd_str;
 /TIME-LIMIT:int       K95 only       int    tt_timelimit;
 /TRIGGER:string       K95 only       char * tt_trigger_str;

Like file-transfer switches, these are local to the specific CONNECT command,
overriding, but saving and restoring, the global session-limit and other
corresponding settings.  /QUIETLY was already there, and it's still the only
one that non-K95 users will see; session limits, etc, are implemented only
in K95.  ckuusr.[ch], 23 Aug 97.

Added partial completion of keywords.  ckuusr.h, ckucmd.c, ckcmai.c,
23 Aug 97.

Corrected a couple minor problems with partial completion and CONNECT
switch parsing.  ckuusr.c, ckucmd.c, 24 Aug 97.

Discovered that if you typed Esc when entering a field parsed by chained
fdb's, nothing happened if the field had no default value -- in fact it should
have beeped.  Fixed in ckucmd.c, 24 Aug 97.

Changed VMS zhome() to use SYS$LOGIN rather than HOME.  This is to avoid the
problem that occurred when using getenv(HOME) as a default for CD, and that
directory was defined as a search path -- e.g. SYS$SYSROOT:[SYSMGR] on a
cluster, where SYS$SYSROOT: was a list of disks, namely that you can't SET
DEFAULT to a search list.  Reportedly using SYS$LOGIN: avoids this problem
and seems to work OK otherwise.  ckuus5.c, 24 Aug 97.

Spent a few hours trying to get the IRIX 6.2 version to compile with POSIX
defined (same deal as for SCO 5.0.4), but could not find a way to make it
execute the definitions & declarations for struct timeval and the select()
related ones.  I finally gave up when I discovered that the IRIX 6.2 system
I was using for this didn't have the high serial speeds defined in any of its
header files anyway.  25 Aug 97.

Added /TRIGGER:string to UNIX CONNECT module.  ckucon.c, 26 Aug 97.

Added SET TERMINAL TRIGGER to set global trigger, which can be overridden by
local switch.  ckuus[s7].c, ckuusr.h, 26 Aug 97.

Expanded trigger feature to allow up to 8 triggers, using the same notation as
SEND /EXCEPT.  Changed makexcept() into makelist(), so it can be used to parse
any {{s1}{s2}...{sn}} string into a list of pointers to s1, s2, ..., sn.
Moved autoexitchk() to ckuusx.c, since it is portable and can be shared by all
CONNECT modules.  Added \v(trigger) to give the value of the trigger that was
selected.  Added SHOW TRIGGER to display current SET TERM TRIGGER values.
ckcdeb.h, ckuusr.[ch], ckuus[2457x].c, ckucon.c, ckermit2.upd, 27 Aug 97.

Changed CONNECT to always reset triggerval (i.e. \v(trigger)) before going
online, so that \v(trigger) refers only to the most recent CONNECT command.
ckuusr.c, ckermit2.upd, 28 Aug 97.

Added trigger support to VMS version.  Plus one last attempt at making VMS
version not lose "NO CARRIER" message.  ckvcon.c, 1 Sep 97.

Added trigger support to AOS/VS version.  ckdcon.c, 1 Sep 97.

Renamed warn variable to ckwarn to avoid conflict in BSDI 3.0.  Also added
support for high serial speeds in BSDI 2.0 and later (including a new makefile
entry).  Many modules, 1 Sep 97.

---Alpha.05---

Changed VMS zhome() (again), this time from getenv("SYS$LOGIN") to
simply "SYS$LOGIN:".  ckvfio.c, 2 Sep 97.

Still doesn't work -- now we try it without the colon (but only as the default
for "cd", since we need the colon in other contexts).  ckuus5.c, 4 Sep 97.

Previous, cont'd...  Turns out Alpha VMS 6.2 chdir() doesn't work.  Got code
from William Bader to use sys$setddir() instead.  Works OK, but (OF COURSE
there's a BUT) it applies to the whole job and not to just the Kermit process,
so when Kermit exits, the user's default directory has changed to whatever
Kermit last CD'd to.

Rework sending of A-packets so that multiple A-packets can be sent in case all
the attributes won't fit into a single packet:
 . Added an initialize flag parameter to sattr().
 . Changed sattr() to return a positive number if it sent an A packet,
   0 if it didn't have anything to send, or -1 on error.
 . Added a new util routine, maxdata(), to return size of data field, shared
   by sattr() and getpkt().
 . Recoded sattr() to fill data field with as many attributes as will
   fit, marking each one as done, and returning when it can't fit any more,
   or there are no more left, or no more that can fit even by themselves, and
   to send the "end of attributes" attribute only after all attributes that
   could possibly have been sent, were sent, provided at least one was sent.
 . Changed the protocol engine to keep calling sattr() until it says it has
   nothing left to send.
ckcker.h, ckcpro.w, ckcfn3.c, 6 Sep 97.

Changed rpar() to not send I or S packets (or their ACKs) that are longer than
what the other Kermit asked for, again calling the new maxdata() function to
find out the length.  The parts that are chopped off from the end have their
corresponding settings defaulted automatically, overriding whatever the user
might have asked for.  ckcfns.c, 6 Sep 97.

What about F packets in this context? -- if a filename is too long, it is
simply truncated (in both the F/X packet and its ACK); there is no way in the
protocol to have continued file headers.  We could conceivably strip any
path info, but that would not always solve the problem, and anyway the user
can control this with a command.

Added a new system-dependent routine to ckutio.c: ttspdlist().  It returns a
list of speeds (as long ints) that are supported on the platform where
C-Kermit is being compiled.  Then in cmdini() we call this routine and build
our "set speed" keyword table on the fly when the program starts.  This
eliminates (just for UNIX at first) the prebuilt speed keyword table with all
the #ifdefs, and problems keeping the BPS_xxxx symbol definitions in sync with
the tt[sg]speed() routines in all the ck?tio.c modules.  ckcdeb.h, ckutio.c,
ckuus3.c, ckuus5.c, ckcplm.doc, ckccfg.doc, 7 Sep 97.

Added ttspdlist() for VMS.  ckvtio.c, ckcdeb.h, 7 Sep 97.

Added modem table entries for Rolm 244PC and 600 series.  ckuusr.h, ckudia.c,
10 Sep 97.

Added SET PRINTER PRINT command switches: /BIDIRECTIONAL, /DOS-DEVICE,
/FLOW-CONTROL, /OUTPUT-ONLY, /PARITY, /SEPARATOR, /SPEED, /TERMINATOR,
/TIMEOUT, /WINDOWS-QUEUE.  Only for K95 for now.
ckuusr.h, ckuus3.c, 10 Sep 97.

Made SHOW PRINTER show all these things.  ckuus5.c, 10 Sep 97.

Added SET PRINTER /PIPE:xxx.  ckuusr.h, ckuus3.c, 11 Sep 97.

Updated HELP SET PRINTER, ckuus2.c, 11 Sep 97.

Made another attempt at straightening out the CD mess in VMS.
ckv[ft]io.c, 12 Sep 97.

Added \v(startup) to UNIX and VMS, ckuus4.c, ckufio.c, 12 Sep 97.

Debugged VMS changes from 12 Sep.  ckvfio.c, 16 Sep 97.

Added a reference to SET EXIT to HELP EXIT.  ckuus2.c, 16 Sep 97.

Corrected various #ifdefs for building with various features deselected.
ckcpro.w, ckuus6.c, etc, 16 Sep 97.

---Alpha.06---

Put SET TERM { AUTOSCROLL, AUTOPAGE } in #ifdef OS2.  ckuus7.c, 17 Sep 97.

Put checks for and against modem signals, especially versus hardware flow
control, into the DIAL command, and also turned off hwfc during dialing
automatically for AT&T 19x0 modems.  ckuus6.c, 18 Sep 97.

IF condition keyword was completely out of alphabetical order.  ckuus6.c,
18 Sep 97.

"set host" to numeric IP address should not call gethostbyname() on any
platform; previously it did this except in Windows.  ckcnet.c, 20 Sep 97.

Fixes from Jeff to my fixes for RTS/CTS vs dialing from 2 days ago, ckcdeb.h,
ckudia.c, ckuus6.c, 20 Sep 97.  NOTE: The right way to do this is to add a new
sys-dependent ttdial() routine, to condition the device for dialing, which
does not overload the flow parameter; we'll do that later since it must
involve changing all the ck?tio.c modules.

Fixes from Jeff to NEW SET PRINTER code for when they give a Windows printer
name as the final word of the command, rather than as a switch value.
ckuus3.c, 20 Sep 97.

Save and restore default or user-requested block check around protocol.
ckcmai.c, ckcpro.w, 20 Sep 97.

Change SET WINDOW parsing to give error message for X and Ymodem[-g], and
changed for ZMODEM to require that window size be a maximum of 64K, and not
a multiple of 64.  ckuus3.c, 20 Sep 97.

Changed SET RECEIVE PACKET-LENGTH to be usable only for Kermit protocol.
In XYZMODEM, if you can change them at all, you have to do it to the sender.
ckuus7.c, 20 Sep 97.

Supplied missing error message for junk typed after "CONNECT" and then
completion was attempted (e.g. "connect xxx<ESC>").  Chained FDB parsing can
be a bit tricky...  ckuusr.c, 20 Sep 97.

Make SET SPEED 134.5 and SHOW SPEED for 134.5 work right.  ckuus[34].c,
20 Sep 97.

Fixed UNIX ttspdlist[] not to return two copies of "57600" if _B115200 was
defined, oops (HPUX only).  ckutio.c, 20 Sep 97.

Updated UNIX, VMS, etc, BWR and UPD files about lots of stuff.  20 Sep 97.

VMS CMU/IP fixes from John Santos.  ckvtio.c, ckvker.com, 20 Sep 97.

New makefile entries for all HP-UX versions from Peter Eichhorn.  20 Sep 97.

Lots of #ifdef adjusting for building on many platforms with & without various
features, assorted modules.  Builds OK on SunOS with various feature sets,
HP-UX 10.20, AIX 4.1, SINIX 5.42, Linux, VMS 5.5, and passes basic runtime
tests.  20 Sep 97.

A couple corrections to yesterday's work from Jeff.  ckuus[37].c, 21 Sep 97.

Changed minor version number from 0 to 1: 6.1.193.  ckcmai.c, 21 Sep 97.

SET TERM AUTODOWNLOAD wasn't working right in UNIX -- the first packet is
missed, so we had to wait forever for a timeout before it kicked in.  Not sure
why it stopped working, but to fix it I changed the hokey mechanism that was
being used (i.e. throw the packet away and send a NAK) to what I should have
done in the first place -- put the packet in a global buffer, caching it for
rpack(), and then actually using the one that kstart() recognized.  Of course
this wasn't easy in UNIX with the forks and all (no matter wht you want to do,
the *other* fork is always only place to do it)...  But now it works again,
and it's much faster.  ckuus4.c, ckucon.c, ckcfn2.c, 21 Sep 97.

Also removed NAK-sending code from autodown() (the INPUT command autodownload
handler), ckcfn2.c, 21 Sep 97.

Fixed VMS version to work with this too (just remove code to send NAK).
ckvtio.c, 21 Sep 97.

At the end of a protocol transaction, after we ring the bell, flush stdout --
otherwise the bell can get queued up for quite a while (e.g. if a file was
autodownloaded, the bell never rings until the next time you escape back).
This might also address reports we've had about the file transfer display not
fully updating itself before returning to the prompt.  UNIX only.  ckuusx.c,
21 Sep 97.

Ctrl-C during autodownload killed the UNIX version of C-Kermit.  This has been
true since 6.0 was first released.  Fixed in ckuus4.c, 21 Sep 97.

Added /PROTOCOL: for RECEIVE, still requiring an as-name for XMODEM.
ckuus6.c, 21 Sep 97.

Made sure that /PROTOCOL was available for both SEND and RECEIVE even if
CK_XYZ not defined (in which case it is accepted but does nothing -- i.e.
protocol remains Kermit), ckuus[r6].c,  21 Sep

The DG is dead (can't load OS from disk, hard error 0000001), RIP.  21 Sep 97.

Added addtl msgs for when UNIX C-K can't access dialout device or lockfile.
ckuus7.c, 22 Sep 97.

Filled in new speed-setting code for Plan 9.  ckutio.c, 22 Sep 97.

Now that Ctrl-C out of autodownload doesn't blow C-K away any more, I
discovered that it does prevent subsequent autodownloads.  After a lot of
heavy staring, I realized it was because the _apc_command macro is still
defined.  So I changed the Ctrl-C trap() routine to undefine it, and while
I was at it, I also had it reset a whole bunch of other protocol-related
settings by calling a new routine, ftreset(), which can also be called from
anywhere else when protocol settings need to be restored to their defaults
(e.g. after dynamic local changes that occurred during file transfer, or
because of an interrupted file-transfer command that was given with switches).
ckuusr.h, ckuus[5x].c, 22 Sep 97.

All the above stuff relative to autodownload broke APC execution in the UNIX
version of C-Kermit.  Ensured that the upper fork reads stuff from the pipe
in the same order and number that the lower fork puts the stuff there.  What
a mess, yuk -- it's so much easier without forks...  ckucon.c, 22 Sep 97.

Put back hpux500wintcp makefile entry (there's still at least one of them
out there...)  22 Sep 97.

Discovered that UNIX C-Kermit would crash upon startup if the current
directory was not readable.  Fixed in zgtdir(), ckufio.c, 23 Sep 97.

---Alpha.07---

(Actually that last item was done after the Alpha.07 binaries were built,
a few minutes after the announcement went out...)

Add /-stripping for URLs in netopen() (K95 only -- we should expand this to
work for all C-Kermits...)  ckcnet.c, 23 Sep 97.

The new autodownload code was calling parchk incorrectly, the result being
that parity was set whenever an autodownload took place, thus (at best)
slowing down the transfer by as much as 50%, or (at worst) making it fail.
Fixed in ckcfn2.c, 24 Sep 97.

---1.1.14---
---1.1.15---

Broke out separate getpkt() and decode() routines, bgetpkt() and bdecode(),
for the binary-mode no-parity case, to speed up this very common type of
transfer.  But the local net is so awful there is no way to tell if it does
any good.  ckcfns.c, 26 Sep 97.

Added fflush() to UNIX zsout() if file is ZWFILE (i.e. OPEN WRITE file) to
make it work better with pipes and FIFO files.  ckufio.c, 4 Oct 97.

Added SHOW LOGS (broke this out from SHOW FILE, which was getting too long).
ckuus[r45].c, ckuusr.h, 7 Oct 97.

Changed SET TRANSFER CRC-ACCUMULATION default from ON to OFF to speed up
transfers, added display of this setting to SHOW PROTOCOL.  ckcfns.c,
ckuus4.c, 7 Oct 97.

Tightened up decode() and getpkt() a bit more, as well as the checksum
routines.  Still no good way to test given heavy loads on systems and network.
ckcfn[s2].c, 7 Oct 97.

Changed exit-warning code to not warn under UNIX if running in background.
ckuus3.c, 8 Oct 97.

Adapted Jeff's URL-parsing code in netopen() to work for all versions, not
just K95, so now SET HOST, TELNET, -J, etc, can accept most forms of URL,
including the nutty ones from Netscape 4.0.  This is #ifdef'd in CK_URL, which
is now defined for all by default; -DNOURL overrides.  ckcnet.c, 8 Oct 97.

Generalized SET { SEND, RECEIVE } PATHNAMES at Peter Eichhorn's suggestion.
Instead of just ON and OFF, now we also allow ABSOLUTE and RELATIVE.  PATH_xxx
symbols defined in ckcker.h, new keyword table in ckuus7.c, SHOW FILE shows
new values.  I also undid the crazy "on means off", "1 - x", etc, and now just
compare against the symbol values.  ON is still accepted as an invisible
synonym for ABSOLUTE.  When receiving, if we get a (recognizably) absolute
pathname, we convert it to relative.  ckcmai.c, ckcfns.c, ckuus[r24567x].c,
8 Oct 97.

Fixed previously unused UNIXOROSK definition.  ckcdeb.h, 8 Oct 97.

Made a new symbol to enable all the new tuning code, CKTUNING, and defined it
for all but pdp11, where every byte counts.  So when CKTUNING is defined, it's
OK to duplicate chunks of code, put it inline, etc, to make file-transfer go
faster.  Added more tuning code to eliminate function calls & loops in various
spots -- calculate header checksum inline, call b{decode,getpkt} directly
rather than from inside decode and getpkt, tighten up b{decode,getpkt}
themselves.  Define NOTUNING to undo all of this and restore earlier well-
tested code.  Some of these improvements could also be filtered back into the
original general-purpose routines...  ckcfns.c, 9 Oct 97.

Microtuning, cont'd -- more of the same, in spack() and rpack().  Also in
zinfill() and zoutdump().  Guard potential function calls like debug() and
logpkt() with if-statements in critical sections, etc.  ckufio.c, ckcfns.c,
9 Oct 97.

There's no good way to test this stuff locally since the effect will be
noticed only on connections that are so fast that CPU is the bottleneck --
but the local net here is always saturated, so that never happens.  Still,
in many trials on an average busy day the new code seems about 50% faster
than the old.  (We also improve by a factor of 2 if we bypass the Telnet
server...)

Filled in COPY (alias CP) command for UNIX.  ckcdeb.h, ckuus6.c, ckufio.c,
9 Oct 97.

Added recursive directory traversal.  For the first cut, this works only
when a filename of "." is given, as in "send ." or "echo \ffiles(.)".  When
sending files, this works in conjunction with the various new SET SEND
PATHNAMES options, and so allows replication of directory trees between like
file systems.

 . test unix-to-unix because MSK rejects names unnecessarily (ok)
 . expand to be more flexible, e.g. "SEND /RECURSIVE *.txt". (ok)
 . What about VMS?  I think this already works: "SEND [...]*.*".

Also the relative/absolute pathnames need a lot more work -- what about
VMS, etc?  Need to:

 . Make /RECURSIVE imply /PATHNAMES:RELATIVE (ok)
 . Handle pathnames even when FILE NAMES CONVERTED.  In this case, convert
   to and from UNIX format.
 . Handle them when LITERAL - send native VMS (etc) *relative* paths.
 . Ditto for AOS/VS, etc.  Need to add a new zblah() function for this?
 . Check #ifdefs (CK_MKDIR, NORECURSE, etc.).

Added directory-creation entry to transaction log.  NOTE: this required a
(nonlethal) change to zmkdir().  ckcfns.c, 14 Oct 97.

SET PRINTER /FILE:xxx parsing improved by Jeff to parse an output filename
and check accessibility.  ckuus3.c, 14 Oct 97.

SET NET FILE parsing improved to use cmifi, from Jeff.  Also literal string
key definitions now handled when saving key definitions.  ckuus7.c, 14 Oct 97.

Removed "." as an alias for "current directory tree" except in UNIX, where it
can't possibly mean anything else.  Removed "..." altogether, since it has
opposite meanings in Windows and VMS.  ckufio.c, 15 Oct 97.

Added /MATCH-DOT-FILES and /NO-MATCH-DOT-FILES to SET WILD KERMIT.
ckuus[23].c, ckufio.c, ckcmai.c, 15 Oct 97.

Added \frfiles, \fdir(), \frdir() to list regular files and directory files,
flatly or recursively.  Changed \ffiles() to only list regular files.  Each of
these functions sets up \fnextfile() in the same way, but with a different
list of files.  In UNIX, these functions match or don't match dot-files
according to the SET WILD KERMIT /xxx setting.  The recursive functions don't
recurse when WILD is set to SHELL.  ckuusr.h, ckuus4.c, ckufio.c, 15 Oct 97.

 * Add another \f?files() function to match both files and dirs ??? (no)
 * Add help text to ckuus2 (ok).

Changed UNIX zxpand() to treat a directory name as if it ended in "/*" so now
"send foo" sends all the files in "foo" if "foo" is a directory, and "send
/recursive foo" does the same, but recursively.  ckufio.c, 15 Oct 97.

Added a new top-level token that lets us assign values to variables in a
somewhat more natural way: "." (shades of Bliss-10).

 .name = value    is equivalent to   DEFINE name value
 .name := value   is equivalent to   ASSIGN name value
 .name ::= value  is equivalent to   EVALUATE value then assign result to name

There can also be space(s) between "." and the name, and the name can be a
macro name, a \%{digit,letter} variable, or an array element.  ckucmd.[ch],
ckuus[r56].c, 16 Oct 97.

New code from Jeff for recursion in K95.  ckufio.c, 21 Oct 97.

Increased MAXWLD, SSPACE values in ckufio.c by a lot if BIGBUFOK and DYNAMIC
are defined.  ckufio.c, 21 Oct 97.

From Jeff: changed chkvar() not to actually evaluate a potential \f...()
function, since this can have side effects.  The check for a function is now
simply if the string matches \f*(*), which is less rigorous than checking if
it is really a function (e.g. parse the name and look it in the table, etc),
so this can be beefed up later if necessary.  But it probably won't be, since
we aren't likely to find files or directories with () in their names.
ckuus6.c, 21 Oct 97.

Changed \ffiles() and friends to make a copy of the array created by zxpand(),
except in K95, where Jeff did this in zxpand/znext themselves (to save space,
since K95 doesn't have to build lists).  Each call to \ffiles() (or \fdir(),
etc) frees the previous list (if any) and then allocates a new one dynamically
of the appropriate size.  With this change it is no longer necessary to copy
the \ffiles() list to an array before use (as on p.398 of the book).
ckuus4.c, 21 Oct 97.

Fixed parsing of SEND /PATHNAMES:xx<DEL> to work right.  ckuusr.c, 21 Oct 97.

Ditto for { RECEIVE, GET } /PATHNAMES, plus fixed the semantics -- it had
ON/OFF backward.  ckuus6.c, 21 Oct 97.

Made max(), min(), and mod() return their argument when given only one.
ckuus4.c, 21 Oct 97.

Fixes to K95 DIR command from Jeff.  ckuus6.c, 22 Oct 97.

Binary-mode file-transfer was sending short files sometimes due to a problem
trying to hand-optimize repeat-count code in bgetpkt() .  Fixed in ckcfns.c,
22 Oct 97.

Added WHERE command to show where most recent file transfer went.  ckuusr.h,
ckuus[r2].c, ckcfn[s3].c, ckcpro.w, 22 Oct 97.

Removed OS2 material from ckufio.c.  23 Oct 97.

Changed REMOTE QUERY KERMIT to evaluate its operand.  Thus:

  assign \%c xx
  remote query kermit files(\%c*)

asks for the number of files whose names match "xx*".  That is, \%c is
evaluated locally before the function call is passed to the server.  If you
want an argument to be evaluated remotely, double the leading backslash:

  remote assign \%c yy
  remote query kermit files(\\%c*)

ckuus7.c, 23 Oct 97.

Added REDO <command>, synonyms RR and token ^.  Required moving a lot of code
around in ckucmd.c -- in particular, the code that adds a command to history
buffer from gtword() to cmcfm() (which makes sense).  Added a new keyword flag
CM_NOR, meaning that this command should not be added to the history buffer.
This is used for the REDO command, of course, because otherwise REDO by itself
(which we would want to re-do the most recent command) would REDO itself
instead in an infinite loop.  ckucmd.[ch], ckuusr.[ch], ckuus5.c, 25 Oct 97.

Added /MOVE:xxx and /RENAME:xxx switches to SEND (etc).  These are similar to
/DELETE, specifying what happens to the source file after it is successfully
sent, except instead of deleting it, they move it to another place, or give it
a new name, respectively.  ckuusr.[ch], ckcmai.c, ckcpro.w, 25 Oct 97.

Added { RECEIVE, GET } /CALIBRATE.  This simply avoids opening incoming files
or writing anything to them, but still does all the rest -- decoding, etc.
ckuusr.[ch], ckuus6.c, ckcpro.w, 26 Oct 97.

Added SEND /CALIBRATE[:n], where n is the number of K to send, default = 1024.
This makes C-K internally generate its own pseudorandom file data, which is
about 77% uncompressible by gzip; no function calls, no file accesses.  The
data is processed normally, however, according text/binary settings, etc, so
the packets are the same as if the same data was read from a file.
ckuusr.[ch], ckuusx.c, ckcfn[s3].c, ckcpro.w, 26 Oct 97.

For now /CALIBRATE is an invisible switch.  It does not fool with packet or
window sizes, etc.  Maybe later.  All calibration code is in #ifdef CALIBRATE,
which is defined for all but CK_SMALL builds in ckcdeb.h.

Discovered that if a switch that does not take an argument is given an
argument anyway, e.g. /BINARY:foo, that the ":" or "=" would be treated as a
space and the argument would be treated as the first non-switch field.  Fixed
in ckuus[r6].c, 26 Oct 97.

Discovered that SEND switch table had some entries out of order, which
interfered with completion.  Fixed in ckuusr.c, 26 Oct 97.

If BIGBUFOK is defined, then also define IFDEBUG automatically.  If memory
is not scarce, then compile in all those if-tests to save thousands of
function calls when the debug log is not open.  ckcdeb.h, 26 Oct 97.

Added SEND /LIST:filename.  The named file contains a list of filenames to
be sent.  ckuusr.[ch], ckcfns.c, 26 Oct 97.

Whenever the /AS-NAME switch was used, the SEND parsing code could assign a
variable to point at a malloc'd buffer, which is later freed, but the variable
would still refer to it, potentially causing all sorts of problems later.
And some other problems like that.  Fixed in ckuusr.c, 26 Oct 97.

Looked into adding support for filenames (or other fields) enclosed in
doublequotes, but it didn't work after a few stabs so I gave up.

Added peak transfer rate to the STATISTICS display.  ckuus[x4].c, 26 Oct 97.
It only works when in local mode and FILE DISPLAY is FULL or CRT, otherwise
the per-packet CPS calculation code is not called.

A new variable, reliable, is set when (a) we make a connection on a reliable
network, such as TCP/IP, or (b) we start C-Kermit with the new -I (uppercase)
switch (mnemonic: I = Internet).  When this variable is set, we add a fudge
factor to the ttinl() timeout, since it normally should not need to time out.
ckuusy.c, ckcmai.c, ckcfn2.c, ckuus7.c, 26 Oct 97.

Made local-mode transfer display completion message a little more standoutish:
SUCCESS or FAILURE in big letters.  ckuusx.c, 26 Oct 97.

Fix from Jeff for changes to command recall.  ckucmd.c, 27 Oct 97.

Various fixes to calibration mode.  Missing thermometer in some cases,
improvements in random-file-generating code, various stats were not being
updated, etc, because it wasn't a real file, GET /CAL would say it failed when
it didn't, { GET, RECEIVE } /CAL filename was lost, SEND /CAL bytecount was
off, etc.  ckcpro.w, ckcfn3.c, 27 Oct 97.

Don't accumulate peak transfer rate until after the initial excitement has
settled down.  When sending, this is after the first windowful of packets has
gone out.  When receiving, just wait till after the 10th packet to get past
the slow-start effect.  ckuusx.c, 27 Oct 97.

Changed default statistics display to /BRIEF, and added a /VERBOSE switch
for greater detail.  ckuus[r4].c, 27 Oct 97.

Tightened up bdecode() even further by eliminating additional cases it will
never see.  ckcfns.c, 27 Oct 97.

Discovered that screenc() could skip updating the percent done, etc, in some
(rare) cases at the end of a file, so the file transfer would be complete, but
the display would show less than 100%.  Fixed in ckuusx.c, ckcfn3.c, 27 Oct 97.

Increased uncompressibility of /CAL data stream to over 90% and also gave it a
random seed so it will generate different data streams, but with the same
uncompressibility.  ckcfns.c, 28 Oct 97.

Fix from Jeff for SET LINE, which under some circumstances might get clobbered
when user types CR.  Not sure if this problem appeared in any released
version or was caused by recent edits.  ckuus7.c, 28 Oct 97.

Changed zopeno() to set the output file (when receiving a file during file
transfer) to O_NONBLOCK.  On some systems, including the one we mostly use
here, disk writes can be very slow -- there is no cache.  The same would be
true if writing to a slow disk, floppy, etc.  It's not clear to me yet how
errors are reported back if they occur -- presumably on the next write() call?
Preliminary measurements seem to show some improvement.

New command-line option, G, which is like g (GET), but sends result to stdout.
Use, for example, to suck files up for printing to the remote from the local
via autoupload:

  kermit -G oofa.txt | lpr

ckuusy.c, 29 Oct 97.

A couple micro-optimizations to ttinl, but it's already just about as
tight as it can be.  ckutio.c, 29 Oct 97.

Poked at zoutdump() some more.  Took out the fflush, and made it allow for
the possibility that write() might write less than asked.  ckufio.c, 29 Oct 97.

Added CRC to STATISTICS display.  ckuus4.c, 29 Oct 97.

Changed name of openx() to ckopenx() to avoid conflict in AIX.
ckcpro.w, ckcfn3.c, ckcker.h, 29 Oct 97.

More fallout from REDO -- a failing command was no longer entered into the
scrollback buffer, which is a major pain, because that's one of its major uses.
Fixed in ckucmd.c, ckuus5.c, 29 Oct 97.

Fixed the "def \%a 12:00:00, pause \%a" problem.  ckuus6.c, 29 Oct 97.

Added \v(printer).  ckuusr.h, ckuus4.c, 29 Oct 97.

Fixed parsing error in SET PRINTER <esc> (non-OS2).  ckuus3.c, 29 Oct 97.

Added invisible SET FILE OUTPUT { [UN]BUFFERED [ size ], [NON]BLOCKING } and
filled it in for UNIX.  It's only for experimentation, and users shouldn't be
told about it unless it can get them out of a jam, and there's no way to
display the settings, but they do show up in the debug log.  The optional size
parameter can be given after BUFFERED or UNBUFFERED to control the size of
C-K's internal file output buffer, zoutbuffer.  This can be any number at all,
even 1.  ckuusr.h, ckuus7.c, ckufio.c.  29 Oct 97.

Went public with SET FILE OUTPUT -- made it visible, added HELP and SHOW, made
it UNIX-only.  ckuus[247].c.  30 Oct 97.

Some initial work on automatic arrays, not done yet.  Must fill in pusharray(),
then add poparray().  ckuu5.c, 30 Oct 97.

Fixes to command parser from Jeff: partial filename completion, and case
insensitivity of filenames in OS/2.  ckucmd.c, 1 Nov 97.

Added automatic arrays.  ckuus5.c, 1 Nov 97.

Added "reliable" display to SHOW COMM.  ckuus4.c, 1 Nov 97.

Added \v(escape), \frandom(max), \fdirname(filespec).
ckuusr.h, ckuus4.c, 1 Nov 97.

Discovered that the UNIX code to make output file unbuffered wasn't working at
all because fcntl() was being called with a file pointer instead of a file
descriptor.  Fixed in ckufio.c, 2 Nov 97.

Moved outbound pathname handling into a new function nzltor(), which is like
zltor(), but has two more arguments: filename conversion flag (fncnv) and
send-pathnames value (fnspath).  This is done within #ifdef NZLTOR..#endif.
NZLTOR is defined for UNIX and VMS.  In the mainline code, we now call this
routine always, rather than only under certain conditions (if NZLTOR is
defined; otherwise we keep the old code).  ckcdeb.h, ckcfns.c, ckcplm.doc,
2 Nov 97.

The nzltor() function must handle six cases:

  SEND PATHNAMES {OFF,RELATIVE,ABSOLUTE} times FILE NAMES {CONVERTED,LITERAL}

The new prototype is:

  nzltor(char * name, char * outbuf, int fncnv, int fnspath, int max);

zltor() was converted to a stub which calls nzltor() with the appropriate
arguments in case anybody calls it by mistake.

VMS zltor() calls (static) parse_fname(), which luckily already gets the
various pieces of the filespec separately (node, device, directory, name,
extension, and version), and so handles its job by shuffling the new args
internally and adding a lot of creative string toodling.  A VMS expert could
no doubt do the same with system calls.  ckvfio.c, 2 Nov 97.

UNIX zltor was also made into a stub; nzltor simply adds the appropriate calls
to zstrip, zfnfqp, etc, to handle the pathnames, and then goes on to do what
it used to do.  ckufio.c, 2 Nov 97.

This was tested in UNIX by cd'ing to ~/tmp and giving "send blah/oofa.txt"
commands with all combinations of SET FILENAMES and SET SEND PATHNAMES, and
similarly in VMS with "set default [fdc], send [.blah]oofa.txt].  Results:

FILENAMES   SEND PATHNAMES  UNIX Result               VMS Result
 CONVERTED   OFF             OOFA.TXT                  OOFA.TXT
 CONVERTED   RELATIVE        BLAH/OOFA.TXT             BLAH/OOFA.TXT
 CONVERTED   ABSOLUTE        /W/FDC/TMP/BLAH/OOFA.TXT  /FDC/BLAH/OOFA.TXT
 LITERAL     OFF             oofa.txt                  OOFA.TXT
 LITERAL     RELATIVE        blah/oofa.txt             [.BLAH]OOFA.TXT
 LITERAL     ABSOLUTE        /w/fdc/tmp/blah/oofa.txt  [FDC.BLAH]OOFA.TXT

All of this works very nicely with existing features like "who am i"
(automatic switching to literal filenames between like systems, etc).

NOTES: In VMS, we always strip the node::, device:, and ;version, even when
file names are literal.

STILL TO DO: The other direction, nzrtol().  Its calling conventions will be
extended by the same kind of integer args: name conversion on/off, receive
pathname setting, and max length for result.

From Jeff: clear network buffers before starting an Rlogin session.  ckcnet.c,
3 Nov 97.

Lots of changes relating to detection of connection loss before or
during file transfer.  Many modules, 3 Nov 97.

K95 prompt now shows forward slashes in directory name, from Jeff, ckuus5.c,
4 Nov 97.

Save and restore many more variables around file transfer -- packet length,
etc, from Jeff, and then fixes to same.  ckuus[r6x].c, 4 Nov 97.

Change name of BeBox terminal from BeOS-ANSI to BeTerm, but leave old name
there invisibly.  ckuus7.c, 4 Nov 97.

Fix autodownload Kermit packet detector to ignore parity.  ckcfn2.c, 4 Nov 97.

Added SET OUTPUT SPECIAL-ESCAPES { ON, OFF } to turn on/off special processing
of \N, \B, and \L.  Added this to HELP and SHOW SCRIPTS, plus a new SHOW
OUTPUT command.  ckuusr.h, ckuus[r235].c, 4 Nov 97.

Jeff found a place in the protocol module where the input file is not closed
(if sdata() returns an error indicating the connection dropped).  ckcpro.w,
4 Nov 97.

Fixes to OS/2 from Jeff for previously unhandled socket errors.  ckcnet.c,
4 Nov 97.

Added SET { SEND, RECEIVE } NEGOTIATION-STRING-MAX-LENGTH <number> as a last
resort for making C-K talk with buggy Kermit implementations on the other
side that don't expect the init string to be longer than a certain length, or
that don't handle parameters after a certain length correctly.  It's invisible
and undocumented, for use only by help desk when confronted with desparate
callers who absolutely have to exchange files with a buggy BBS, etc.
ckuus7.c, ckcfns.c, 4 Nov 97.

Changed ttinl(), when in local mode, to check for console interruptions and
return -1 if there is something waiting in the console buffer (Jeff's idea),
to make for snappier response to file-transfer interruption characters.
ckutio.c, 4 Nov 97.  But then commented this out, since it's at least an extra
function call and system call per packet, and the response to keyboard
interruptions on fast connections is pretty fast anyway.  Can revisit this
later after further experimentation.

Changed ttchk() to always check first if we have an open connection and if
not, to return -2.  ckutio.c, 4 Nov 97.

Changed doconect() to use ttchk() to check if the connection is open.
ckuus4.c, 4 Nov 97.

Changed ttinl() and ttol() to return -3 when they detect a broken connection.

Went through all of the ckcfn*.c and ckcpro.w modules and made sure that every
call to rpack() and spack() had its return code checked and then did the
appropriate thing when it was < 0 (and, in particular, when < -1).  Tested by
making a Telnet connection, starting uploads and downloads, and then killing
the job on the far end during the transfer.  Now, for the first time, this
makes the file transfer either quit right away, or else within one timeout
interval, and the appropriate message is printed on the display, and the
transfer fails.  Once the failure was propogated up to the protocol state
machine, two more actions were needed to distinguish the cases where the
connection dropped when a file was open, versus when no file was open.
ckcfn[s23.c], ckcpro.w, 4 Nov 97.

Evidently there are places where we call command parsing routines with
constant strings as defaults, and then later attempt to write into those
strings (e.g. to strip braces, trim blanks, etc).  This was addressed by
making an internal copy of the default string and using that instead.
ckucmd.c, 4 Nov 97.

Fixed command-file reader to be tolerant of lines that end with bizarre
strings of control characters like ^M^M^J.  ckuus5.c, 4 Nov 97.

Added nrztol() for UNIX, moving lots of inappropriate code from rcvfil() to
it (with #ifdef NZLTOR..#endif).  ckcfns.c, ckufio.c, 5 Nov 97.

Added nrztol() for VMS.  ckvfio.c, 5 Nov 97.

Results for VMS receiving files, current directory is [FDC.TMP]:

Receive     File
Pathnames   Names      Incoming Name       Saved as
 OFF         CONVERTED  OOFA.TXT            [FDC.TMP]OOFA.TXT
 OFF         CONVERTED  oofa.txt            [FDC.TMP]OOFA.TXT
 OFF         CONVERTED  /foo/bar/oofa.txt   [FDC.TMP]OOFA.TXT
 OFF         CONVERTED  [foo.bar]oofa.txt   [FDC.TMP]OOFA.TXT
 RELATIVE    CONVERTED  OOFA.TXT            [FDC.TMP]OOFA.TXT
 RELATIVE    CONVERTED  bar/oofa.txt        [FDC.TMP.BAR]OOFA.TXT     (*)
 RELATIVE    CONVERTED  [.bar]oofa.txt      [FDC.TMP.BAR]OOFA.TXT     (*)
 RELATIVE    CONVERTED  /foo/bar/oofa.txt   [FDC.TMP.FOO.BAR]OOFA.TXT (*)
 ABSOLUTE    CONVERTED  /foo/bar/oofa.txt   [FOO.BAR]OOFA.TXT         (*)
 ABSOLUTE    CONVERTED  [foo.bar]oofa.txt   [FOO.BAR]OOFA.TXT         (*)

(*) The indicated directory or subdirectory, one or more levels,
    is automatically created if allowed, otherwise the transfer fails.

Note: It turns out to be easy to recognize the directory format in incoming
packets, and so the FILE NAMES { CONVERTED, LITERAL } setting is not actually
so important, except if we care about case conversion.  We only need to detect
the native and UNIX pathname formats -- see VMS nzrtol() in ckvfio.c.

  This must still be done for OS/2.  After OS/2 part is done, a chunk
  of #ifdef OS/2 can be removed from the "not NZLTOR" part of rcvfil.

Fixed isabsolute() for VMS.  ckcmai.c, 5 Nov 97.

Added IF ABSOLUTE to test if a filename is absolute or relative.  The file
need not exist.  ckuusr.h, ckuus6.c, 5 Nov 97.

After all this:

 . I can transfer a directory tree UNIX-to-UNIX by telling the sender to
   "send /pathnames:relative /recursive *" and the receiver to
   "receive /pathnames:relative".  The entire directory tree is transferred
   quickly and quietly, and replicated on the other side.

 . Ditto from UNIX to VMS!

 . VMS to UNIX works too, but it's still a bit flaky.  In VMS you have to say:
   send /pathnames:rel /filenames:converted [...]*.*".

So hurray, transferring directory trees between unlike platforms.

From Jeff: peakcps should only be reset once per transaction; cps/peakcps
should be calculated and saved when File Display is None or CRT; thermometer
pct should not be set to 100% if we are discarding the file.  ckuusx.c,
6 Nov 97.

Made /RECURSIVE un-invisible for VMS and AOS/VS, since their native
recursive wildcards work fine.  In these cases, /RECURSIVE is only informative
and really translates to /PATHNAMES:RELATIVE.  (But I didn't actually migrate
any of the pathnames-handling code to AOS/VS yet, did I?)  ckuusr.c, 6 Nov 97.

Figured out why VMS-to-UNIX recursive transfers didn't seem to be working
right: SEND (and RECEIVE) /PATHNAMES:<not-OFF> was setting FILE NAMES to
LITERAL, which as needed before we made the new nz[rl]to[lr]() routines; fixed
by #ifdefing.  ckuus[r6].c, 6 Nov 97.

Various fixes to VMS nz[rl]to[lr](), including some long-standing problems
such as the inability to accept files whose names contain multiple periods.
Now it all works pretty well.  nrztol() now changes spaces and tildes into
underscore, other nonprintables into dollar signs -- much more readable in VMS
than changing everything to X, and as for dots:

 a.b.c.1 becomes a_b.c;1 (when only digits follow the last dot)
 a.b.c.d becomes a_b_c.d (otherwise)

and VMS is happy.  ckvfio.c, 6 Nov 97.

Added /SINCE as an invisible synonym for /AFTER since I type it all the time.
ckuusr.c, 6 Nov 97.

Changed -L switch to also SET SEND PATHNAMES RELATIVE.  ckuusy.c, 6 Nov 97.

Filled in MKDIR for VMS, and made MDKDIR and RMDIR for other platforms
print appropriate error messages when they fail.  ckuusr.c, 6 Nov 97.

Made blind stabs at implementing RMDIR in VMS.  Finally I gave up on doing
it using any APIs, since I haven't a clue, and just used system() commands.
Crude but effective.  Note: in VMS, we have to change the directory name
[a.b.c] into a filename [a.b]c.dir;1, change its protection to allow deletion,
and then delete it, which only works if it's empty.  If it can't be deleted,
all sorts of error messages spew out.  Needs to be replaced by somebody who
knows the actual VMS API for deleting a directory.  ckvfio.c, 6 Nov 97.

Added zrmdir() for UNIX.  #defined ZRMDIR symbol in ckcdeb.h for all platforms
that have a zrmdir() function (UNIX and VMS so far).  Changed RMDIR command
to use it.  ckufio.c, ckcdeb.h, ckuusr.c, 6 Nov 97.

zmkdir() was already there for UNIX, VMS, etc.  I fixed it so it could be
called to create directories, as you might expect.  Its previous use expected
a complete filespec, including a filename.  But this was not required for VMS,
and in UNIX the way to not require it is to make sure the string that is
passed to it ends with a directory separator.  Changed the MKDIR command to
do this.  ckuusr.c, 6 Nov 97.  Slightly reworded the zmkdir description in
ckcplm.doc.

  (This is all groundwork for adding REMOTE MKDIR and REMOTE RMDIR, but
  that's not done yet.)

"msend <nonexistent-file><SP>" caused a parsing foulup.  Fixed in ckucmd.c,
7 Nov 97.

Added all the new switches to the MSEND table.  ckuusr.c, 7 Nov 97.

Changed ?-help to add a directory separator at the end of a filename (except
in VMS) if the file is a directory, so you can tell by looking at the list
what's what.  ckucmd.c, 7 Nov 97.

Fix from Jeff to catch disk-write errors during file reception, bdecode()
(I left out an automatic variable declaration so a global variable of the same
name, but different type, was being used).  ckcfns.c, 7 Nov 97.

Added a 3rd arg to ckmatch() to say whether to ignore case in string
comparisons, and then in places where we are using it to match filenames, to
be case-sensitive or not depending on the underlying file system (like in SEND
/EXCEPT in UNIX vs DOS), and to ignore case in other pattern-matching
applications (e.g. REDO, SHOW VARIABLES *FOO*), regardless of the file system.
ckcker.h, ckcmai.c, ckucmd.c, ckcfns.c, ckuus[56].c, 7 Nov 97.

Added automatic per-file text/binary mode switching based on filename
pattern recognition, all within #ifdef PATTERNS..#endif.  7 Nov 97.

Commands:
 . SET FILE PATTERNS { ON, OFF }
 . SET FILE { BINARY-PATTERN, TEXT-PATTERN } [ <pattern>  [ <pattern> ... ] ]

Files:
 . ckcker.h - symbol defs & max number of patterns (64)
 . ckuusr.h - change name of shoparf to shofil (it was annoying me)
 . setfil, ckuus7.c - parse the command, set up the pattern lists
 . shofil, ckuus4.c - show the lists
 . gnfile, ckcfns.c - declare use the lists (via calls to ckmatch())
 . ckuus2.c - "help set file" text
 . ckermit2.upd - docs, mainly section 4.3, others updated too.

NOTE: Needed for VMS: permissions.

A couple fixes to yesterday's stuff from Jeff: ckuus2.c, ckucmd.c, 8 Nov 97.

Added { ADD, REMOVE } { BINARY-PATTERNS, TEXT-PATTERNS }.  Redid the lists to
be more dynamic and free()-safe.  Added SHOW PATTERNS, with a nice display,
and redid SHOW FILE to refer to SHOW PATTERNS.  (I also added { ADD, REMOVE }
SEND-LIST, but didn't fill it in.)  Added lots more patterns to default lists.
Made SET FILE TYPE LABELED override filename pattern-matching.  ckcmai.c,
ckcfns.c, ckuus[457].c, ckermit2.upd, 8 Nov 97.

"delete dir/file" didn't work for some reason in UNIX.  Changed dodel() to be
a little less confusing with its use of line[] and tmpbuf[].  Then I changed
the UNIX version to use Jeff's loop.  But all the messages were annoying so I
added /VERBOSE and /QUIET switches, making the latter the default for UNIX,
and cleaned up the output when /VERBOSE is set.  ckuus6.c, 8 Nov 97.

Started to add code to prevent client from sending a BYE or FINISH when it
had already done so on the same connection, but the risk outweighs the
benefit.  Maybe some other time.  8 Nov 97.

Fixed a bug I introduced in VMS zrtol() at the last minute on Nov 6, which had
extra filename dots being converted to underscores even after we had scanned
backwards into the directory name.  ckvfio.c, 8 Nov 97.

Added a second arg to gfmode() (get file mode) to tell it to return its result
in upper or lower case, adjusted the prototype and all references, removed
various chunks of redundant code.  ckuusr.h, ckuus[r56].c, 8 Nov 97.

Added client end of REMOTE MKDIR and REMOTE RMDIR.  ckuusr.[ch], ckuus7.c,
8 Nov 97.

Increased number of patterns to 256 if BIGBUFOK.  ckcker.h, 9 Nov 97.

Made "remo" an acceptable abbreviation for "remote".  ckuusrc., 9 Nov 97.

Fixes from Jeff to yesterday's code: ckucmd.c, ckuus5.c, 9 Nov 97.

From Jeff: don't check text patterns if already in text mode; ditto for binary,
ckcfns.c, 9 Nov 97.

Don't bother trying to send FINISH or BYE command when in local mode and
there is no connection.  ckcpro.w, 9 Nov 97.

Made sure that RESUME and SERVER macros in protocol module set all counters,
packet numbers, etc, back to 0.  ckcpro.w, 9 Nov 97.

Disabled automatic file type switching during RESEND.  ckcfns.c, 9 Nov 97.

Updated ckuker.bwr and ckermit.bwr.  9 Nov 97.

Discovered that when the C-Kermit server got a REMOTE DELETE command for
a directory (rather than a file), it did terrible things.  Added a check
against this in ckcpro.w, 9 Nov 97.

Moved some prototype declarations around in ckcpro.w to alleviate possible
problems with "declarations out of scope" noticed by some picky ANSI compilers.
ckcpro.w, 9 Nov 97.

Moved code out of MKDIR command in ckuusr.c to a new function, ckmkdir(), that
can be called from the command parser or during protocol, and similarly for
RMDIR.  ckcker.h (prototypes), ckuusr.c, ckcfn3.c, 9 Nov 97.

Added EN_MKD and EN_RMD symbols in ckuusr.h, and corresponding en_mkd and
en_rmd variables.  ckuusr.h, ckcmai.c, 9 Nov 97.

Added server end of REMOTE MKDIR & RMDIR.  ckcpro.w, ckcfn3.c, 9 Nov 97.
Added ENABLE/DISABLE MKDIR/RMDIR commands.  ckuus[56].c, 9 Nov 97.
Added help for above.  ckuus2.c, 9 Nov 97.
Added info for above to SHOW SERVER.  ckuus5.c, 9 Nov 97.

Should make server-side CD accept UNIX-style pathnames too (at least in
VMS).

There are still a few problems with REMOTE DIRECTORY, etc.  For example,
if pathnames are off, "remote directory foo/*" strips the "foo/".  But
that's what it should do.  But it seems to do it also when pathnames are on.

VMS difficulty with SEND /MAIL using:
system("$ mail %s %s/subj=\"Enclosed file %s\"")

Juggled things a bit in the got-E-packet section of the protocol module to try
(again) to ensure that file-transfer display does not say "100%" if a transfer
is canceled by an E-packet.  ckcpro.w, ckuusx.c, 10 Nov 97.

Added yet another level of file-type saving and restoring to allow gnfile() to
use prevailing transfer mode (as set by user, or as overridden by "whoami"
negotiation) for files it fails to identify by name pattern.  So now we have
three levels to save and restore: what the user said ("set file type"), the
"whoami" type (which persists throughout a transaction), and a per-file type
based on automatic file type recognition.  gnf_binary, ckcfns.c, 10 Nov 97.

Added /SUBDIRECTORIES as an invisible synonym for /RECURSIVE.  ckuus[r6].c,
10 Nov 97.

I just sent an E-packet.  I'm in local mode, I was receiving a file, I'm not a
server, and sliding windows are in use.  Therefore, there are likely to be a
bunch of packets already "in the pipe" on their way to me by the time the
remote sender gets the E-packet.  So the next time I CONNECT or try to start
another protocol operation, I am likely to become terribly confused by
torrents of incoming material.  To prevent this, a loop was added to errpkt()
to soak up packets from the connection until there is an error or timeout.
ckcfn2.c, 10 Nov 97.

Another try at getting better error screens when an E-packet is received.
ckcfn[s23].c, 10 Nov 97.

Make { ADD, REMOVE } patterns be case independent/sensitive according to
the underlying file system.  ckuusr.c, ckermit2.upd, 10 Nov 97.

Made K95 default patterns lowercase rather than upper.  ckcmai.c, 10 Nov 97.

---Alpha.08---

Streaming prototype & proof of concept, 12 Nov 97 (to be described later)
(if you stumble on it, don't try to use it).

Fixed VMS ttchk() to detect connection loss the same way the UNIX and OS/2
versions do.  ckvtio.c, 13 Nov 97.

Added missing prototype for cmaddnext().  ckucmd.h, 13 Nov 97.

Protected a couple unguarded references to no_recall by #ifdef CK_RECALL.
ckucmd.c, 13 Nov 97.

Removed unguarded references to binpatterns[] and txtpatterns[] from
doadd().  ckuusr.c, 13 Nov 97.

Added missing VOID to VMS declaration of nzrtol().  ckvfio.c, 13 Nov 97.

Removed spurious "(-1)" from VMS nzltor() return.  ckvfio.c, 13 Nov 97.

Supplied missing printf() argument in ADD command.  ckuusr.c, 13 Nov 97.

Added instructions for defining new network types to ckcplm.doc.  13 Nov 97.

Support for IRIX 6.2 from Ric Anderson.  Many modules, 13 Nov 97.

Got rid of call to time(0) in ckcmai.c as a random number seed, to avoid
yet another avalanche of #ifdefs, and called gtimer() instead, which is
already well-defined in ck?tio.c.  ckcmai.c, 13 Nov 97.

Changed UNIX version to strip off leading "./" or "../" from outbound
pathnames, no matter what the SEND PATHNAMES setting is.  ckufio.c, 13 Nov 97.

Fixed SHOW VERSIONS to state version numbers and dates consistently.
Many modules, 13 Nov 97.

Corrected some typos in ckermit2.upd, 13 Nov 97.

---Alpha.09---

Revived my DG mini.  Of course its compiler found several glitches that none
of the others revealed: extern declarations for variables that were never
defined anywhere, prototypes for static functions in header files, a reference
to zzstring in a cmtxt call instead of xxstring, and a backwards #ifdef NZLTOR
construction.  After fixing these, I successfully built the AOS/VS version.
ckuus[r35].c, ckcfn3.c, 14 Nov 97.

Based on logs from Carl Friedburg and Mike Freeman, found the spot where
file transfers on outbound VMS LAT connections were being inhibited and fixed
it (always remember: ttyfd is valid in VMS only on TCP/IP connections).
cncfn2.c, 17 Nov 97.

From Jeff over the weekend, installed 17 Nov 97:
 . Fixes to parens in peakcps calculation, ckuusx.c.
 . Changed communications input buffer from 4K to 32K if BIGBUFOK
   defined, so that TCP reads will have a chance of being big enough to open
   the TCP receive window.  ckutio.c.
 . Rearranged file input buffer size definitions.  ckcker.h.
 . Make -j/J command-line options set the reliable flag.  ckuusy.c.
 . Beginnings of Telnet client authorization and encryption code.  ckcnet.[ch].

Added missing AIX defines for TCP_NODELAY, TCP_KEEPALIVE, and TCP_MAXSEG.
ckcnet.h, 17 Nov 97.

Built for 16-bit QNX for the first time since before 6.0 was released, no
problems. 17 Nov 97.

Rec'd verification that VMS LAT calls now work again.  18 Nov 97.

Numerous tiny syntactic changes for the benefit of gcc -Wall, a couple of
which might actually make a difference (e.g. 2 or 3 spots where variables
could possibly be used before set).  Many modules, 18 Nov 97.

Fixed a problem with SEND /MAIL:<address> <filename> on VMS.  While working on
this, also improved some VMS error messages.  Tested to make sure that VMS
C-Kermit can SEND /MAIL and also receive files as mail and deliver them.
ckuusr.c, ckvfio.c, 18 Nov 97.

Using bgcc, William Bader found two places where an out-of-bounds array
reference might occur.  One was just a debug() call, so I commented it out.
The other was in the loop that strips junk from the end of a modem call-result
message; the tests were reversed.  Fixed in ckutio.c, ckudia.c, 18 Nov 97.

Added -V command-line option = SET FILE PATTERNS OFF / SET XFER MODE MANUAL.
ckuusy.c, 18 Nov 97.

Fixed SHOW MACRO <name>.  Not sure when it broke...  ckuus5.c, 18 Nov 97.

Added GET /RECURSIVE.  This is like telling the server to SEND /RECURSIVE.
Also GET /RECURSIVE /DELETE.  Client and server ends of both.
ckuus6.c, ckcpro.w, ckcfn2.c, 18 Nov 97.

Note: GET /DELETE /RECURSIVE deletes files but not directories.

Still have to add help text for this, etc.

See ~/new/Wall.txt again.

Cleaned up server end of new GET forms.  Got rid of en_ret, merged with
en_del.  Save & restore recursive & fnspath around each server transaction.
ckcpro.w, ckuus6.c, 19 Nov 97.

ttflui() should not be called by input() when streaming.  ckcfn2.c, 19 Nov 97.

Added SET STREAMING AUTO and SHOW STREAMING.  All of this is still invisible.
ckuusr.[ch], ckuus[356].c, 19 Nov 97.

Fixed input() in the streaming case to actually send an Error packet if it
received a bad packet, rather than just pretend that it got an Error packet.
ckcfn2.c, 20 Nov 97.

Simplified the syntax of shotab[], ckuusr.c, 20 Nov 97.

SET LINE / SET HOST / SET PORT commands were not getting into the recall
buffer.  Fixed in ckuus7.c, 20 Nov 97.

Ditto for SET DIAL DIRECTORY, SET MODEM CAPABILITIES, SET CONTROL PREFIX,
WAIT, and many other commands.  These are commands that accept a variable
number of args, and terminate when the command parsing routine returns -3.
The solution is, when this happens, to make sure that cmcfm() is called
anyway; otherwise lots of stuff doesn't happen that should happen.  Note: when
cmcfm() is called *after* the user typed CR, it knows this and does not make
them type another one.  ckuus*.c, 20 Nov 97.

Fixed REMOTE LOGIN not to succeed when it was not given enough parameters.
ckuus7.c, 20 Nov 97.

From Jeff: Make SET TITLE take effect immediately.  ckuus7.c, 20 Nov 97.

Added SET TRANSFER DISPLAY BRIEF.  Thus just writes a one-line report on
each file, similar to FTP:

  filename (transfer-mode) (size-if-known): status (and cps if status OK)

ckcker.h, ckuus[7x].c, 20 Nov 97.

Discovered that filename pattern matching was happening too early, and could
be undone by things that happened later.  Moved the matching code out of
gnfile() and into sfile() to make sure it was executed AFTER the S/I-packet
exchange rather than before, so it would not be undone by the WHO/WHATAMI
mechanism.  ckcfns.c, 20 Nov 97.

Allowed UNIX C-Kermit to accept /dev/null as an incoming filename and use
it literally.  ckufio.c, 20 Nov 97.

Changed \v(cps) to treat 0 elapsed seconds as 1 in calculating the transfer
rate (previously it just returned "0 cps", so now it returns the filesize).
ckuus4.c, 21 Nov 97.

Eliminated unnecessary screen() procedure calls in rpack() and spack()
when XFER DISPLAY is BRIEF.  ckcfn2.c, 22 Nov 97.

From Jeff: corrections to Telnet initializations when telnetting to non-23
ports more than once, plus unhiding some debugging routines.  ckcnet.c,
22 Nov 97.

Corrections to WHATAMI negotiation; some of the bits were wrong.  ckcfn2.c,
22 Nov 97.

More fixes to command history -- macro invocations were being skipped, and
commands that were canceled by the parser for syntax errors before entry were
being entered when they shouldn't have been.  ckuus[r5].c, 22 Nov 97.

Added SET FILE DESTINATION NOWHERE (alias CALIBRATE), invisible, a sticky
version of /CALIBRATE for receiving files, but it doesn't work -- come back
and fix it...

Changed all calls to screen() to go through a new macro, xxscreen(), which
does not make the call if Kermit is in remote mode.  This can eliminate a lot
of function-call overhead during file transfer, on one end anyway.  ckcpro.w,
ckcfn*.c, ckuusx.c, 24 Nov 97.

Changed sdata() to skip "sbufnum" countdown when streaming, and nxtpkt()
to skip out-of-window check.  ckcfn[s2].c, 24 Nov 97.

Changed brief file transfer display to use the same cps calculation that the
other displays use, and added elapsed seconds to the display.  ckuusx.c,
24 Nov 97.

Looked into making communication-device writes be nonblocking, so Kermit can
be forming its next packet while the write() is actually occurring.  But as
far as I can tell, at least in the UNIX version, ttyfd is already opened in
nonblocking mode, since that's how myread() works, and we use the same fd for
both reading and writing.  Still, I added a test for EWOULDBLOCK after the
write, so make sure it is not treated as an error.  ckutio.c, 25 Nov 97.

Fixed up the changes to sdata() from yesterday.  ckcfns.c, 25 Nov 97.

Added CLOSE [ CONNECTION ] command, since the current method for closing a
connection is quite mysterious ("set line" and/or "set host" without a device
or hostname), and added a new function, clsconnx(), to do it, consolidating a
bunch of confusing code that was in setlin().  ckuus[r7].c, 25 Nov 97.

Fixed STREAMING message on fullscreen file-transfer display.  ckuusx.c,
25 Nov 97.

Fixed STATISTICS to show the packet length that was actually used when sending
the last file, rather than the default that would be used in absence of
instructions from the receiver.  ckcfns.c, ckuus4.c, 25 Nov 97.

Turned slow-start off for transfers in which streaming is negotiated.
ckcpro.w, ckuusx.c, 25 Nov 97.

Fixed a bug in which bgetpkt() was repeat-counting a run of two characters,
when the minimum should be three, thus turning 2 into 3 and adding needless
overhead to the packet.  ckcfns.c, 26 Nov 97.

Made NUL (0) unprefixable:
 . Changed SET CONTROL UNPREFIX commmand to allow it.
 . Changed logpkt() to log packets correctly when they contain NULs.
 . Now C-Kermit sends packets containing NULs correctly.
 . Make [b]gecode() be length-driven, rather than stopping at NUL.
 . Make [b]getpkt() handling of leftovers be length-driven.
 . Make all chk[123]() routines be length driven rather than stopping at NUL.
 . Make all calls to chk[123]() routines pass length.
 . Update prototypes for chk[123]() routines.
ckcfn2.c, ckuus3.c, ckuus4.c, 26 Nov 97.

Not done:
 . Anything about recording packets the debug log.
 . Including zero in "set control unprefix all" or "set prefixing none".
 . Docs, help, etc.
 . Enough testing.

After these changes (reducing the unneeded repeat count for doublets and
allowing NUL to be unprefixed), the packet overhead went down by about 10%
when transferring the SunOS C-Kermit binary:

  size:         1026152
  packet chars: 1166088 (before)
  packet chars: 1062181 (after)

As a quick check, I built it on AIX and sent some files to it.  I was able to
consistently get 766Kcps sending the same 4MB binary file that never went
faster than about 600Kcps before.

Changed SET PREFIXING command to account for unprefixing 0, and also made
SET PREFIXING MINIMAL take flow-control setting into account when deciding
whether to prefix 17,19,145,147.  ckcmai.c, 26 Nov 97.

Fixed length in chk1() call from chkspkt(), which affected autodownloads,
from Jeff.  ckcfn2.c, 27 Nov 97.

Why on earth did chk3() take parity as an arg?  The CRC is applied to outbound
packets before adding parity, and is checked on arriving packets after
stripping parity.  Removed this in hopes of tightening up one more critical
loop.  ckcfn2.c, ckuus4.c, 27 Nov 97.

Added new low-level routines to the UNIX version: rftimer() and gftimer().
These time things using floating point seconds.  Within #ifdef GFTIMER, which
is, at present, defined only for UNIX.  ckcdeb.h, ckutio.c, ckcplm.doc,
27 Nov 97.

Added #ifdef GFTIMER sections throughout ckcpro.w, ckcfn*.c, ckuus4.c, and
ckuusx.c to take advantage of [rg]ftimer() when calculating elapsed time, time
left, and cps.  Now we no longer have the 1-second granularity in
file-transfer speed measurements, and therefore get accurate elapsed time and
CPS figures at the end of a transfer regardless of the file size (within
reason).  10BaseT socket-to-socket transfers from SunOS to AIX now routinely
register over 800Kcps.  27 Nov 97.

To add these routines to non-UNIX platforms:

 (VOID) rftimer() gets and saves the current time in whatever subsecond
   precision (millisecond, microsecond) is available.
 (float) gftimer() returns the number of seconds that have passed since
   rftimer() was last called as a fractional floating-point number.
 In ckcdeb.h, #define GFTIMER for your platform.

Converted getmsec() to gftimer(), so now we can get packet-read/write
millisecond times in the debug log for any platform where GFTIMER is defined
("grep msec debug.log").  ckcfn2.c, ckutio.c, 27 Nov 97.

Checked GFTIMER on SunoOS, HP-UX 10.20, AIX 4.1, Solaris 2.5,

Defined and added new WM_CLEAR flag to WHATAMI negotiation field.  This gives
the opposite Kermit permission to send any and all control characters
unprefixed in data packets.  ckcker.h, ckcfns.c, ckcmai.c, 27 Nov 97.

Added SET CLEARCHANNEL { ON, OFF, AUTO }, AUTO is the default, and lets
C-Kermit tell the other Kermit whether it has a clear channel based on whether
it has opened a TCP socket connection.  ON and OFF have the expected meanings.
The CLEARCHANNEL setting, for now, is shown by SHOW STREAMING.  Now if (and
only if) I SET HOST directly to a Kermit server that is waiting on a TCP
socket, I get minimal prefixing automatically.  For example, from SunOS to
AIX, with W=30, P=9000, I get > 800Kcps just about every time.  ckuusr.[ch],
ckuus3.c, etc, 27 Nov 97.

Added SET TRANSACTION-LOG { VERBOSE, BRIEF [ separator ] }.  If BRIEF is
chosen, one line is written per file, with a timestamp, action (SEND or RECV),
filename, size, mode (text or binary), status (OK or FAILED), and additional
info depending on the status.  The default separator is comma, but any other
nonalphanumeric character can be specified.  This format is suitable for
direct importation into Informix, Oracle, Sybase, etc.  ckcdeb.h, ckuusr.h,
ckuusx.c, ckcfn[s3].c, ckcpro.w, 27 Nov 97.

Built on SunOS, Solaris, HP-UX, AIX, and Unixware as a last-minute check.  No
complaints.

Fixed CPS display in brief display to be file chars / elapsed time, rather
than most recent CPS calculation.  ckuusx.c, 28 Nov 97.

Various other minor corrections to yesterday's work, mainly correcting
backwards #idefs for GFTIMER.  28 Nov 97.

Refinement of brief transaction log: always write 8 fields, enclose any
field in quotes if it contains the separator.  ckuusx.c, 28 Nov 97.

Added docs for new transaction log format to ckermit2.upd.  28 Nov 97.

Assorted minor corrections from Jeff to the last few days' work, ckcnet.c,
ckcdeb.h, ckutio.c, ckuus[4x].c, ckcfn2.c, 1 Dec 97.

Addition of hex dump debug tool, from Jeff, ckuusx.c, 1 Dec 97.

Fixed IF NUMERIC to work correctly for variables whose definitions contain
multiple words.  ckuus6.c, 1 Dec 97.

Made a lot of fixes that should improve the situation with command recall.
Until now, the command functions module, ckucmd.c, was ignorant about where
command were coming from.  Which is silly.  So now there is a function in the
command parser, cmdsrc(), that can be called from ckucmd.c (or anywhere else)
to determine the command source (keyboard, macro, TAKE file, etc), which makes
decisions about the command recall buffer, and many other things, perfectly
straightforward.  Also, throughout the ckuus*.c modules, I replaced all the
#ifdef'd tests of cmdlvl vs tlevel with calls to the new cmdsrc() function.
So now we have the command recall buffer working pretty much as it did before
I added the REDO command -- commands issued from macros don't go in; the SEND
command doesn't always go in; macro invocations do go in, etc.  Many modules,
1 Dec 97.

Replaced hardwired server-mode help text (sent in response to REMOTE HELP)
with dynamic version that actually tells which commands are available,
enabled, etc.  Will pretty it up later.  ckcmai.c, ckcfns.c, ckcpro.w,
1 Dec 97.

Replaced all checks for ttyfd < 0 to see if connection broken with calls to
ttchk(), which must be coded to fill this role.  This removes the risk of
checking ttyfd on systems where it's not supported or, worse, on systems where
it is used for one kind of connection but not others.  Examples: in VMS, where
it is used for TCP/IP but not serial; in AIX, where it is used for serial and
TCP/IP, but not X.25, etc.  ckcmai.c, ckcfn2.c, ckuus[434].c, 2 Dec 97.

Added some extra checks to ttgmdm() and ttchk() for local vs remote mode to
make sure they behave as advertised.  ckutio.c, 2 Dec 97.

SET DESTINATION NOWHERE (aka CALIBRATE) seems to have fixed itself.  Added
help and show text for it.  ckuus[24].c, 2 Dec 97.

Fixed READY TO SERVE... message for socket-based server.  ckcpro.w, 2 Dec 97.

Defined BIGBUFOK for Linux.  ckcdeb.h, 2 Dec 97.

Ripped out tons of stupid, confusing, and contradictory code for calculating
the elapsed time and CPS of file transfer.  Now this is done automatically in
the protocol module at the end of each file transfer, and again at the end of
a transaction, and the results are stored in global variables available for
use by the various display routines (file transfer display, STATISTICS
command, \v(cps) variable, etc).  Furthermore, the contradiction between file
time/cps and transaction time/cps when only one file was transferred was
eliminated simply by defining the latter to be the former in the 1-file case.

Routines:
  fcps(), called when an input or output file is closed, sets:
    xfsecs   = elapsed time this file, whole number of seconds.
    fpxfsecs = elapsed time this file, floating-point seconds.
    ffc      = number of characters, this file.
  tstats(), called when a B packet is sent or received, sets:
    tfsecs   = elapsed time whole transaction, whole number of seconds.
    fptsecs  = elapsed time whole transaction, floating-point seconds.
    tfc      = number of characters, all files.

Many modules, 2 Dec 97.

Fixed a bug in which a server could be given a REMOTE SET WINDOW and
REMOTE SET RECEIVE PACKET-LENGTH combination larger than its buffer size,
and it would accept them and try to use them.  Reported by David Fiander.
ckcfns.c, 2 Dec 97.

Fixed SET MODEM COMMAND VOLUME HIGH; previously it was assigning the given
command to VOLUME LOW.  Reported by Dragan Milicic.  ckuus3.c, 2 Dec 97.

Changed SHOW MACRO to use chained FDBs, so "show mac ?" works, and yet
"show mac x" also works when x is ambiguous, etc.  ckuus5.c, 2 Dec 97.

Changed askmore() to not ask when the batch or background flags are set.
ckuus5.c, 2 Dec 97.

Removed "kludge to fix redefinitions in <linux/wait.h>" since (a) this
interferes with the new glibc and headers, and (b) it isn't needed any more
anyway since we simplified how REDIRECT works.  ckutio.c, 2 Dec 97.

Another attempt at preventing "Transfer OK" messages when transfer wasn't
OK.  ckcpro.w, 3 Dec 97.

Started adding a "filestatus" variable to protocol modules, to clean up the
mess and confusion of all the separate flags: cxseen, czseen, discard,
epktrcvd, etc etc.  Not set or tested yet, to be continued later, maybe...
ckcker.h, ckc*.c, 3 Dec 97.

Removed the kludge by which we forced macro invocations into the command
recall buffer, since Monday's fixes removed the need for it.  ckuusr.c,
3 Dec 97.

Changed SHOW COMM to always show SET CARRIER-WATCH setting.  Updated the
HELP SET CARRIER-WATCH text.  ckuus[42].c, 3 Dec 97.

New HP-UX makefile entries from Peter Eichhorn.  3 Dec 97.

Enabled RLOGIN code for HP-UX 10.00 (it was already enabled for HP-UX 9.00)
and Digital UNIX 4.0.  ckcnet.h, 3 Dec 97.

Added a hint message for RLOGIN failures.  ckuusr.c, 3 Dec 97.

Changed STATISTICS to omit the transmission speed if it's a network connection
or if C-Kermit is not in local mode.  ckuus4.c, 3 Dec 97.

Fixed "cd .<ESC>" and "cd ..<ESC>" to behave as expected in UNIX and OS-9.
(Fixing this for "?" would be much harder, since "." and ".." do not get into
the directory list).  ckucmd.c, 3 Dec 97.

The following for VMS from Lucas Hart:

(1)  Add a NOVMSSHARE "feature", since that condition is contrary to
     default VMS linking,  and a __CRTL_VER (that is what DEC C calls
     it, though DECC_RTL would be more precise for their usage) to CKUUS5.C
(2)  Update OLD_VMS conditionals for VMS 4.7 (before they were only to
     V4.4), in CKVOLD.C, CKVFIO.C, CKVTIO.C
(3)  Change the CKVKER.COM link logic slightly to always define either
     NOVMSSHARE, or VMSSHARE, and to make the VAX NOVMSSHARE also define
     (and link) /NOSYSSHARE, as initially intended.
(4)  Comment out more of the debugging output in CKVKER.COM
(5)  Similar changes to CKVOLD.COM (and incorporate CKVKER 1.17 edits)

Contributed 5 Oct 97; I finally got around to them on 3 Dec 97.

Removed perror() calls from keepalive(), and replaced with debug() calls.
No point scaring people to death...  ckcnet.c, 3 Dec 97.

Assorted #ifdef adjustments for building on many systems.  Various modules,
3 Dec 97.

Fixed Data General AOS/VS version to allow recently defined file numbers,
chkfn(); ditto for OS-9.  ck[d9]fio.c, 4 Dec 97.

RETURN from inside SWITCH did not work right; same problem as END (fixed on
July 3).  doreturn(), ckuus6.c, 4 Dec 97.

DIAL and ANSWER should not automatically CONNECT, no matter what the DIAL
CONNECT setting is, if C-Kermit is running in batch or in the background.
ckuusr.c, 4 Dec 97.

Documented CLOSE command.  ckermit2.upd, 4 Dec 97.

Added lots of code to VMS ttopen() to see what I could find out about modem
signals, in an effort to get SET CARRIER-WATCH working in VMS, where it never
has been implemented.  Need more info before I can make further progress.
However, it looks like the VMS SET TERM /MODEM vs /NOMODEM setting might be
critical here, and this has never been examined or set in VMS C-K before.
ckvtio.c, 4 Dec 97.

Changed CKVKER.COM to not give /NOSYSSHARE to linker when NOSHARE chosen,
since some of the nonsharable libraries are unusable (UCX, some versions of
SMG, etc).  Now I no longer get LIB$FIND_IMAGE_SYMBOL when building.
ckvker.com, 4 Dec 97.

From Lucas Hart, a fix for the annoying warning from DECC in Digital UNIX 4.0
about "union wait".  ttruncmd(), ckutio.c, 4 Dec 97.

Fixed some problems with parsing the DELETE command when it was given the
name of a file that doesn't exist.  ckuus6.c, 4 Dec 97.

Finally tracked down the reason why sometimes the file-transfer bar zooms
out to 100% when a file transfer is interrupted; the screen() routines were
resetting percent done when the Z packet comes, at the end of the transfer,
rather than when the F or X packet comes, at the beginning of the transfer.
This was OK except when a second copy of the Z packet came -- then suddenly
the percent done was 100 instead of whatever it was the first time.  No more.
screenc(), ckuusx.c, 5 Dec 97.

Still, it seems rather common for the file sender to send two Z packets when
streaming.  Why?  Because once interrupted, the receiver sends an ACK(X) for
every packet from now on.  The sender gets the first one and sends Z(D).  But
more arrive, so it sends another Z(D).  Cure: the receiver should only send
ONE ACK(X) or ACK(Z) when streaming.  Cure applied in ckcpro.w, 5 Dec 97.

When draining incoming packets after sending an E-packet and using the
fullscreen file-transfer display, put up a message that we are draining -- it
can take a while -- then another when finished.  errpkt(), ckcfn2.c, 5 Dec 97.

Eliminated another per-packet function call, getrtt(), in the streaming case.
ckcfn2.c, 5 Dec 97.

Ditto for calling gtimer() every time we send or receive a packet if we are
not timing out (as when streaming).  ckcfn2.c, 5 Dec 97.

Tightened up "drain loop" in error-packet sender by calculating timeouts on
the fly rather than using an overconservative value, even when streaming and
the timeout was 0.  errpkt(), ckcfn2.c, 5 Dec 97.

Cleaned up much errpkt()/ermsg()/screen()/clsif()/clsof() redundancy.  Made
errpkt() close files, call screen(), make debug and transaction log entries,
etc, which was previously done piecemeal all over the place.  Also made
errpkt() set czseen, since of course an E packet cancels the current batch of
files.  This prevents still more spurious "100%"'s, completion messages
stomping over each other, etc.  Now it all seems pretty tight.  ckcpro.w,
ckcfn2.c, 5 Dec 97.

Added some debugging code to netopen() to catch possible problems when
non-Telnet port is requested.  Plus merged in Jeff's recent changes.  ckcnet.c,
6 Dec 97.

UNIX C-Kermit beware file updated with various items.  ckuker.bwr, 6 Dec 97.

Elapsed time was always showing up as zero when receiving files.  Fixed in
fstats(), ckcfn2.c, 6 Dec 97.

Lots of changes to ckcnet.c from both me and Jeff regarding set socket options;
mine removed perrors (again) and replaced them with a consistent format of
debug log entry; Jeff's were substantive.  6 Dec 97.

Discovered it was too easy to introduce interoperability between non-zero-
prefixing and zero-prefixing Kermits by including 0 in SET PREFIXING MINIMAL.
Changed this to not unprefix zero after all, and changed SET PREFIXING NONE
to unprefix everything but CR, IAC, and SOP, and had the clear-channel code
do SET PREFIXING NONE, rather than MINIMAL.  ckcmai.c, ckcfns.c, ckuus5.c,
6 Dec 97.

Joe D persistently complained that streaming could not be interrupted in
Unixware.  Reason: ttchk() was not doing its job; it has to be relied on to
tell us how many characters are waiting unread.  But this was not happening in
UNIX versions that support select() or rdchk(), etc, but that do not support
FIONREAD.  select() would tell us *that* characters were waiting, but not how
many.  So the test in sdata() for (ttchk() > some-number) would never succeed,
and so the reverse channel would never be sampled.

Well, it seems FIONREAD is being picked up on most systems from ioctl.h,
term.h, etc, but not on Solaris or Unixware, so we need to include it from
<filio.h> or wherever else it might be found.  ckutio.c, 6 Dec 97.

It turns out the non-FIONREAD-yet-MYREAD versions were just not working very
well at all transferring files with window sizes > 1 (or streaming).  In this
case I made ttchk() return the number of bytes in the myread buffer, if
nonzero; we'll get the next bunch of characters next time around.  When the
internal buffer is empty, then we go to select() and friends, and if select()
tells us data is ready to read, we call the myfillbuff() function to get as
many as are there, rather than returning 1 as before; this allows the
ACK-checking logic in the sdata() loop to detect an ACK much more quickly, in
theory at least.  ttchk(), ckutio.c, 6 Dec 97.

Meanwhile, I cleared up the old problem -- at least in MYREAD versions of UNIX
C-Kermit -- in which we read a packet by its length field and then leave any
trailing junk (like EOP) to still be read, which makes ttchk() always find at
least one character waiting, which can slow us down when we go to read a
packet but there isn't one there.  ttinl(), ckutio.c, 6 Dec 97.

Fixed SHOW STREAMING to show the actual cps of the last transfer.  ckuus5.c,
6 Dec 97.

Isolated SCO as a platform where there is no OS-assisted buffer peeking, and
so our new ttchk() select-then-read method must be used.  Tested streaming
there, including interruption of the SCO version from a receiver on the other
end -- it works fine.  The connection from here to there is Internet, but it
goes through a V.34 modem.  Streaming is anywhere from 50% to 1000% faster on
this connection.  Sometimes nonstreaming fails badly due to unpredictable
timing, whereas streaming has no timeout worries.  7 Dec 97.

Made sure streaming is turned on only during data phase, to prevent
"Transmission error on reliable link" from stopping the transmission before
it started, in case the user didn't escape back fast enough.  ckcpro.w,
ckcmai.c, ckcfn2.c, 7 Dec 97.

Joe D's persistent report about C-K in Unixware starting out at the slow-start
packet size and never going up turned out to be true.  The reason I couldn't
reproduce it is that all the versions I tested on had BIGBUFOK, but Unixware
didn't, aha.  Fixed in spar(), ckcfns.c, 7 Dec 97.

Discovered (after hours of trial and error) that you can't send the following
characters unprefixed to VMS: 1 3 13 14 15 17 19 24 25 141 145 147.  Several
of these (14,15,24,25) are a surprise.  Once I made sure these were prefixed,
streaming worked fine, as well as non-streaming with W=30, P=8000.  I added
the missing ones to the SET PREFIXING CAUTIOUS list, and also set them when
the WHOAREYOU mechanism lets us know we have VMS on the other end.

               FIONREAD                          SO_ERROR
SunOS          <sys/filio.h>      Works OK       <sys/socket.h>
Solaris        <sys/filio.h>      Works OK       <sys/socket.h>
Unixware       <sys/filio.h>      Works OK       <sys/socket.h>
AIX 4.1        <sys/ioctl.h>      Works OK       <sys/socket.h>
HP-UX 10.20    <sys/ioctl.h>      Works OK       <sys/socket.h>
SCO 5.0.4      <sys/socket.h>     Doesn't work   <sys/socket.h>
NeXT           <bsd/sys/ioctl.h>  Works OK       <bsd/sys/socket.h>
IRIX 6.2       <sys/socket.h>(*)  Works OK       <sys/socket.h>

(*) also in <sys/filio.h>

On a Telnet connection to an IRIX 6.2 system at the U of Oregon, discovered
that the IRIX version could not send a packet longer than 4096 bytes.  Its
logs show it constructing the packet right, but logs on the other side show
the packet being truncated at 4096 and then concatenated with other pieces of
itself.  Why?

 . Does it happen without streaming?                        Yes
 . Does it happen wit streaming?                            Yes
 . Does it happen with older Kermit on IRIX?                Yes
 . Does it happen with older Kermit on SunOS?               Yes
 . Does "set receive packet-length 4000" make it go away?   Yes
 . Does it happen if local is not SunOS?                    Yes
 . Does it happen with "set host *"?                        No <--
 . Does it happen with SET HOST connections?                No <--

So the IRIX 6.2 Telnet server is the culprit.  Streaming / 9K packets works
fine as long as the IRIX Telnet server is not in the picture.

The IRIX incident revealed that there were still some places where
transmission errors (crunched packets, timeouts, NAKs, out-of-sequence
packets, etc) were not treated as fatal during streaming.  Fixed in input(),
ckcfn2.c, 8 Dec 97.

I realized that streaming should be turned on the instant it is negotiated,
and turned off only at the end of the transaction.  There is absolutely no
need to switch it off within a transaction.  This simplifies matters greatly
and avoids errors when we get retransmissions of between-file packets (for
which there is absolutely no need).  ckcpro.w, ckcfn2.c, 8 Dec 97.

Tightened up UNIX ttinl() just a wee bit by checking the packet length field
only when (!havelen) (Jeff noticed this).  ckutio.c, 8 Dec 97.

Changed debug format F011 (never before used) to write counted strings
possibly containing NULs into the debug log:

  debug(F011,label-string,counted-string,count);

Used for entering a packet, or the beginning of one, into the debug log in a
relatively legible way, even if it contains NULs, LFs, etc.  ckuusx.c,
ckcfn2.c, ckutio.c, 8 Dec 97.

Back to VMS unprefixing -- it seems that SO/SI and ^C/^X/^Y don't need
prefixing when sending into an Alpha with Multinet.  But that doesn't prove
anything -- I've had transfers freeze with many VMS's, not just KERVAX, so
for now I'm leaving the extra prefixing in.

Changed "clear-channel" unprefixing to be sticky instead of saving and
restoring the user's prefixing selection around protocol actions.  Otherwise
the user would never be able to find out what happened (e.g. why a transfer
failed).  ckcfn2.c, 8 Dec 97.

Made "te" be a sufficient abbreviation for TELNET (conflicted with TELOPT),
and "ta" sufficient for TAKE (conflicted with TAPI).  ckuusr.c, 8 Dec 97.

Added BIGBUFOK for Unixware 2.0 and higher.  makefile, 9 Dec 97.

Change chktimo() to return(0) if streaming.  ckcfn2.c, 9 Dec 97.

The old bug of the server sending responses to REMOTE commands back in binary
mode came back again, so I fixed it again.  ckcpro.w, ckcfn2.c, 9 Dec 97.

Verified that IRIX 4K bug also exists on IRIX 5.3.  ckuker.bwr, 9 Dec 97.

Resync'd sources with Jeff's, ckuusr.h, ckuus[57x].c, ckcnet.c, 9 Dec 97.

Changed VMS version to not test controller type in ttgmdm() if it is running
on an Alpha.  I have no way of testing this.  ckvtio.c, 9 Dec 97.

Changed SET CARRIER and HELP SET CARRIER in VMS to print appropriate messages
about why it can't be done.  ckuus[23].c, 9 Dec 97.

Reorganized and augmented CKVKER.BWR.  9 Dec 97.

Started adding a section on how to invoke C-Kermit from Web browsers.
I couldn't find any way to do this in Lynx...  ckermit2.upd, 9 Dec 97.

Built quickly on SunOS, Solaris, HPUX, Unixware.  9 Dec 97.

In VMS C-K, incoming filetype attribute was overriding SET FILE TYPE IMAGE.
Fixed in ckcfn3.c, 10 Dec 97.

Peter Eichhorn says that in HP-UX, when C-Kermit is in CONNECT mode and pops
back to the prompt automatically, that the lower CONNECT fork is not killed,
so subsequent CONNECTs make more and more forks, which compete for i/o on
the device.  I can't reproduce it:

Popping back because connection dropped:
 . Does it happen in SunOS with a Telnet connection?   No
 . Does it happen in HP-UX with a Telnet connection?   No
 . Does it happen in HP-UX with a serial connection?   ???

Popping back because of an APC:
 . Does it happen in HP-UX with a Telnet connection?   No
 . Does it happen in HP-UX with a serial connection?   No

But there's another problem: HP-UX C-Kermit doesn't pop back to the prompt
anyway when carrier is lost.  As far as I can tell, it never did.

Streaming on serial connection:
 . V.34 ZIP-file Uploads: about 3400cps.
 . V.34 ZIP-file Downloads: about 2800cps.
 . C-X interrupt when uploading seems to hang, but works OK downloading.
   (Or else the modem just cut out -- it does that a lot).

Added addt'l debug stmts to UNIX CONNECT module to help catch a situation
reported in HP-UX in which "garbage" on the connection results in C-Kermit
popping back to command mode without killing the lower CONNECT fork, so that
subsequent CONNECTs make extra new forks that compete with each other for
input.  I also made sure that the pid variable was initialized to -1, and
reset to 0 whenever the fork was killed, so we can check it upon reentry to
the CONNECT module.  And then I decided, since the pid is kept in a static
variable anyway, to check it upon (re)entry to the CONNECT module, and if it's
not 0, to print a big message and then try to kill it -- a failsafe mechanism.
Also changed all debug() entries from the CONNECT module to start with
"CONNECT" to make them easily greppable.  ckucon.c, 11 Dec 97.

The new fullscreen cps-display procedure was taking up way too much time on
fast (e.g. local-net) connections, and tended to be too busy to read, so I
changed it to operate no more frequently than once per second.  The estimated
time left field received the same treatment.  ckuusx.c, 11 Dec 97.

Rearranged the code in VMS buffered-read routine, txbufr(), to recognize the
purported fact that some new data can be returned by sys$qiouw() even when it
also returns a status of SS$_HANGUP, in an effort to prevent loss of dying
gasps like NO CARRIER.  ckvtio.c, 11 Dec 97.

Changed SET TRANSFER MODE MANUAL to also SET FILE PATTERNS OFF, since those
who read about TRANSFER MODE MANUAL in the book expect it to do what the book
says.  ckuus3.c, 11 Dec 97.

The VMS version was not returning directory names when in server mode and
given the REMOTE DIRECTORY command.  Fixed in ckcfns.c, ckvfio.c, 12 Dec 97.

Changed fullscreen display to put the STREAMING message in the Window Slots
field, since window slots are irrelevant when streaming, and also not to put
false numbers in the RTT/Timeout field, and fixed various other fields to not
update unnecessarily, and consolidated various other code in the fullscreen
display routines.  ckuusx.c, 12 Dec 97.

Discovered I had broken sliding windows a few days ago by commenting out a
section of code I thought was redundant.  It wasn't.  ckcpro.w, 12 Dec 97.

Added comments to gattr() regarding the possibility of retaining the current
FILE COLLISION option when receiving a file with the Recover attribute that
does not need to be recovered.  The upshot is that it could be done, but it
would not be easy (so I didn't).  ckcfn3.c, 12 Dec 97.

Results back from VMS testers on CKVTIO.C changes:
 . Mike Freeman: It doesn't break LAT dialouts.

Changed SET CLEAR-CHANNEL AUTO to also announce a clear channel if RELIABLE
is ON.  ckcfns.c, 17 Dec 97.

External protocols were not propogating the exit status to the success variable
(which is the basis of IF SUCCESS / FAILURE as well as \v(status)).  Fixed in
ckcpro.w, 18 Dec 97.

More work on VMS txbufr() to allow for more and more possibilities regarding
how or whether VMS reports hangup of serial connection.  ckvtio.c, 19 Dec 97.

Minor change in Microlink modem description text.  ckudia.c, 19 Dec 97.

Checked on HP-UX automatically popping back when carrier was dropped -- it
never did.  Aside from that, serial dialouts are good; RTS/CTS works
perfectly, streaming works (since it's an error-corrected connection and the
connection between the modem and the HP is solid).  A non-compressed binary
file uploads at about 5400cps (on a 31200bps connection), whereas SEND /CAL
(the dynamically generated 90+ uncompressible data) uploads at about 3600cps.

Last-minute checks of streaming transfers between SunOS and AIX over local
10BaseT are fine -- they go at 600-730Kcps streaming, 540-660Kcps
nonstreaming.

Numerous #ifdef, prototype, declaration, and other syntactic adjustments to
allow compilation everywhere.  Many modules, 19 Dec 97.

Restored TELOPT_SGA handling to the way it was in Alpha.09 to prevent double
echoing when telnetting to AOS/VS.  ckcnet.c, 20 Dec 97.

More syntactic adjustments for VMS & DEC C, plus a fix for the new VMS handing
of SET [ MODEM ] CARRIER-WATCH.  ckuus3.c, various header files, 20 Dec 97.

"make du32"...  while compiling ckuusx.c, the compiler dumps core.  I did the
trick with compiling this module separately without the optimizer.  makefile,
20 Dec 97.

ckuus2.c (the help-text module) grew too big for the QNX 16-bit build, so
NOHELP added to makefile.  Also clearok() seems to be missing from its curses
library, so the reference to it in screenc() was #ifdef'd out.  makefile,
ckuver.h, ckuusx.c, 21 Dec 97.

---Alpha.10---

Changes from Jeff to ckcnet.c, 21 Dec 97.

The VMS version was warning that connection was still open after it closed.
That's because ttclos() was setting network to 0, so then a subsequent call to
ttchk() was taking the serial path.  Fixed in ckvtio.c, 22 Dec 97.

Added GFTIMER to VMS version using sys$gettim() and lib$sub_times(), with help
from James Puzzo <jamesp@dgii.com>.  Compiles and runs without complaint on
VMS 5.5, so should be OK on 5.0 and above, but maybe #ifndef OLD_VMS might be
needed.  ckcdeb.h, ckvtio.c, 22 Dec 97.

Added "*.exe" to UNIX list of binary filename patterns.  ckcmai.c, 22 Dec 97.

Changed \frand(n) to return a random integer between 0 and n, as advertised,
even if n <= 0.  ckuus4.c, 22 Dec 97.

Changed "Default file-transfer mode" message to say AUTOMATIC in the more
modern cases.  ckuus5.c, 22 Dec 97.

Changed a recently-added memcpy() in tn_sb() to strncpy(); memcpy is not
portable.  ckcnet.c, 22 Dec 97.

Changed #ifndef to #ifdef to avoid making a debug log entry for every single
character than comes in, in netinc(), ckcnet.c, 22 Dec 97.

Updated bgcc (bounds-checking gcc) makefile entry from William Bader,
23 Dec 97.

Fix from Jeff to netflui() for TCPLIB case.  ckcnet.c, 23 Dec 97.

Replaced the strncpy() that replaced the memcpy() with a loop so as not to
terminate at NUL.  tn_sb() in ckcnet.c, 23 Dec 97.

Changes from Jeff to SHOW TELNET.  ckuus4.c, 23 Dec 97.

Fixed clsconnx() in the remote-mode VMS case to call ttclos(), otherwise it's
not possible to SET LINE TTA0:, then SET LINE, the SET LINE TTA0: again (we
should check this in K95, etc, too).  ckuus7.c, 23 Dec 97.

Changed "float" to CKFLOAT everywhere, and defined CKFLOAT to be double in
ckcdeb.h (a little reading shows that double is more portable than float).
This was needed (at least) because in SCO, conversion from float to long dumps
core (on purpose!) if the real number is too long for a long (clearly, then,
this is not the right fix).  The default CKFLOAT definition can be overridden
by -DCKFLOAT=float (or whatever) on the command line.  Many modules, 24 Dec
97.

Fixed SHOW PATTERNS to not make some lines too long; it was miscounting the
length.  shopat(), ckuus5.c, 24 Dec 97.

Fix from Jeff for handling receive filters: evaluate \v(filename) after
converting the incoming name, rather than before.  rcvfil(), ckcfns.c,
29 Dec 97.

Disabled filename pattern-match based transfer mode switching when sending
from pipe or filter (Jeff's suggestion).  sfile(), ckcfns.c, 29 Dec 97.

Change from Jeff to not log incoming NUL after CR when executing INPUT
commands on Telnet connections.  ckuus4.c, 29 Dec 97.

Fixed a "== should be =" typo in the SET HOST code and supplied some missing
TCPSOCKET ifdefs (from David Lane).  ckuus7.c, 29 Dec 97.

Added entry for zrmdir() to ckcplm.doc.  29 Dec 97.

Updated IRIX makefile entries from Ric Anderson.  29 Dec 97.

Fixed an unguarded reference to zfnqfp().  ckcfn3.c, 30 Dec 97.

Fixed UNIX ttinl() to terminate on turn argument, if given, rather than
eol argument.  ckutio.c, 30 Dec 97.

Improvements on the new F011 debug.log format (so far used only by the UNIX
version of ttinl()).  ckuusx.c, 30 Dec 97.

Various changes to debug logging.  cku[tf]io.c, 30 Dec 97.

Found the problem that William Bader was reporting in the SCO version.  The
new code that I added to ttchk() in Alpha.10 for the non-FIONREAD case, that
would force a nonblocking read when all else failed, set the initial myread
buffer index to 0 when it should have been -1 (since, unlike mygetbuf(), it
was not returning a character).  ckutio.c, 30 Dec 97.

Made kermit -X and -Z (X.25 connections) set the reliable flag.  ckuusy.c,
30 Dec 97.

Added switches to SET LINE / SET HOST.

 /CONNECT means CONNECT automatically if connection is successful.
 /SERVER means go into server mode automatically if connection is successful.
 /SHARE (VMS SET LINE only) means allow SET LINE device to be shared.

/SHARE is to get around a problem in DECIntact, where the only way to use the
controlling terminal is if you have SHARE privilege.  When /CONNECT or /SERVER
is given on a serial connection, we wait up to 1 sec for CD to appear if
CARRIER-WATCH is not OFF, since instantaneous connecting tends to work because
it can take some time for CD to react to DTR.  Also, made the trailing /TELNET
and /RLOGIN switches invisible, since it doesn't make a lot of sense to say
"telnet blah /rlogin" or v.v.; left the "/raw-socket" switch visible.  Tested
on SunOS with TCP/IP, SunOS with serial ports, and Solaris X.25 connections.
The switch parsing code was not added for network types other than TCP/IP and
X.25.  ckuusr.h, ckuus[27].c, ckvtio.c, ckermit2.upd, 30 Dec 97.

The SET LINE (SET PORT) switch parsing for OS/2 is in place but not tested.
setlin(), ckuus7.c, 30 Dec 97.

C-Kermit's SWITCH command would erroneously execute the first case if the
switch variable did not have a matching label and there was no ":default"
label.  Fixed by adding a :default label to the SWITCH macro definition, which
is ignored if the user provides a :default label in the SWITCH statement.
ckuus5.c, 30 Dec 97.

Changed copyright dates to 1998.  All ck[cuv]*.[ch] modules.  30 Dec 1997.

Some fixes from Jeff to yesterday's changes.  ckuus[27].c, 31 Dec 97.

Allow remote filename to be shown in serial and/or CRT display, from Jeff.
ckcpro.w, ckuusx.c, 31 Dec 97.

Fixed protocol module to propogate failure into exit-status variable.
proto(), ckcpro.w, 31 Dec 97.

Changed SET LINE /SHARE (VMS) to not only not drop SHARE privilege but also
to try to enable it.  ckermit2.upd, ckvtio.c, 31 Dec 97.

Added SET LINE /NOSHARE (VMS), the opposite of /SHARE, since VMS people like
their switches in pairs.  ckuusr.h, ckuus[27].c, 31 Dec 97.

Changed all the VMS code that tests for SS$_HANGUP to do so only when
CARRIER-WATCH is not OFF.  txbufr(), contti(), ckvtio.c, 31 Dec 97.

Removed text from HELP SET CARRIER-WATCH saying that it didn't work in VMS.
ckuus2.c, 31 Dec 97.

Removed VMS warning text from SET CARRIER-WATCH.  ckuus3.c, 31 Dec 97.

Changed /CONNECT to undo any previous /SERVER and vice versa; the two are
contradictory and mutually exclusive, so if more than one are given, the last
one sticks.  ckuus7.c, 31 Dec 97.

Added carrier check at VMS CONNECT entry, just like in UNIX, to enforce
CARRIER-WATCH setting.  ckvcon.c, 31 Dec 97.

Improved the "Carrier required but not detected" message in the UNIX CONNECT
module (making it the same as the VMS one).  ckucon.c, 31 Dec 97.

Removed scary message from VMS CONNECT module if CD drops but CARRIER-WATCH
is OFF.  ckvcon.c, 31 Dec 97.

Commented out three gratuitous "blah connected on port blah" messages from
ckcnet.c which started popping up yesterday.  With only very few exceptions,
the upper-level code should take care of printing information messages.
ckcnet.c, 31 Dec 97.

Discovered that elapsed-time (and therefore also CPS) calculations were
complete nonsense in VMS on the Alpha, even though they were OK on the VAX.
Changed definition of CKFLOAT from "double" to "float" on the Alpha only.
which seems to have fixed it.  ckcdeb.h, 31 Dec 97.

This bodes ill for other operating systems on the Alpha (like Digital UNIX),
especially if they use DEC C, but I tried it on DU4.0 as "double".  It did
the calculations correctly, but eventually died with a "floating point
exception", so I made CKFLOAT "float" here too.  ckcdeb.h, 31 Dec 97.

More fooling with Digital UNIX 4.0.  Regular file transfer works OK, but
streaming halts (hangs) almost immediately.  Debug log shows FIONREAD is
returning ridiculous numbers, like 4393751543808...  And so then we get
awfully confused trying to read that many bytes.  "man 7 tty" in DU4.0 says
the FIONREAD ioctl arg is int *, but I was using long *.  Changed it to int *,
and now get reasonable results from it -- numbers like 252 or less.  But it
still hangs when trying to stream.  Aha, it's only the stupid Xon/Xoff
business.  I wonder why it doesn't happen when not streaming?  Probably
because streaming is so much faster...  Anyway, the change to ckutio.c was a
good one, and long overdue -- I wonder how the code ever worked before...
31 Dec 97.

(I wonder what happens with Linux on the Alpha...)

Back to VMS...  If I Telnet from VMS C-K to somewhere else, then close the
connection (to return to remote mode), then type "receive", it goes back the
prompt immediately.  This is fallout from the December 22 change regarding
ttclos() setting network to 0.  Well now nobody was.  Fixed by making ttopen()
set network to 0 when it opens a serial connection.  ckvtio.c, 31 Dec 97.

Updated ckuker.bwr.  31 Dec 97 (sic transit anno 1997).

In the UNIX version, initialize all 12 file pointers to NULL, not just the
first 8.  ckufio.c, 1 Jan 98.

Documented modem signal treatment in VMS.  ckvker.bwr, section 3.1.4,
1 Jan 98.

Don't print hangup error message in VMS C-Kermit during CONNECT if
CARRIER-WATCH is OFF.  ckvtio.c, 1 Jan 98.

When doing a labeled-mode transfer, if an as-name was given in the RECEIVE or
GET command, it should override the file's internal name, but until now it
didn't, which was very confusing.  This is now done by doing an implicit "set
file label name off" in rcvfil(), and then restoring the "set file label name"
setting to its previous value after the transfer.  Tested, works.  ckcfns.c,
ckuus[6x].c, 1 Jan 98.

Added cross-references to other relevant SHOW commands from SHOW FILE.
ckuus4.c, 1 Jan 98.

Minor cosmetic improvements to SHOW SCRIPTS.  ckuus5.c, 1 Jan 98.

Added Streaming and CKFLOAT type (float or double) to SHOW FEATURES.
ckuus5.c, 1 Jan 98.

Defined CK_PERMS for VMS to see what would happen.  Nothing.  ckcdeb.h,
1 Jan 98.

There's already code from Terry in ckvfio.c to fill in this stuff, but it has
never been exercised.  Does it send generic protection?  No, because the code
was putting binary data into the A packet.  Fixed it to convert to strings
(hex for 16-bit system-dependent, tochar() for generic).  VMS sys-dependent
protection is hex representation of WGOS fields (World,Group,Owner,System)
in that order; in each field Bit 0 = Read, 1 = Write, 2 = Execute, 3 = Delete.
A bit value of 0 means permission is granted, 1 means permission is denied.
ckvfio.c, 1 Jan 98.

VMS generic protection was being sent for "world" (by the book), but we're
doing it for "owner" instead these days, which makes more sense, so I made
this change.  So now VMS C-Kermit sends both permission fields correctly:

  r-01-00-^A/!FWERMIT.EXE'"
  s-01-00-^AE!Y/amd/watsun/w/fdc/new/wermit.exe.DV
  r-02-01-^A]"A."D7""B8#119980101 18:14:05!#8531&872960,$A20B-!7(#512@ #.Y
  s-02-01-^A%"Y.5!                                     ^^^^^^^^^

The system-dependent protection "A20B" corresponds to (E,RWED,RED,RE) (but
note the order of fields is reversed and the bit sense is reversed).  The
generic protection "7" = 23 + 32; 23 = 16+4+2+1 = Read, Write, Execute,
Delete, which is indeed the owner permission.  ckvfio.c, 1 Jan 98.

This was somewhat difficult and time-consuming without manuals, man pages, or
header files, requiring much trial and error...  Then came the even more
mysterious task of setting received-file protection from the incoming
Attribute packet.  Two cases:

 1. Local protection (for VMS-VMS transfers; needs "set transfer mode manual"
    or else we get labeled transfer, which bypasses all of this).  I've got
    this working to the point of converting the incoming bit (like ",$E20B")
    to internal format.  (Once this works, we can easily extend it to cover
    RSX, etc, provided PDP-11 Kermit uses the same format, which it probably
    doesn't.)

 2. Generic protection.  I've got this working to the point of converting
    the generic format to VMS internal format, but only for the one field.
    What do I set the other fields to?

And then, in both cases, I wind up at the bottom of zstime() with
xabpro_ofile.xab$w_pro filled in with a plausible value, but then nobody ever
uses it for anything so the incoming file's protection is never actually set.
That last part needs a VMS expert:

 1. How do I get the default protection for the file we're creating so I
    can set the non-owner fields to reasonable values?  For example, if it's
    a new version of an existing file, it should (and normally does) inherit
    its protection, but that happens transparently to Kermit.  But now we want
    to get the protection that *would* be set and change the owner field
    according to the attribute.

 2. What do I do with xabpro_ofile.xab$w_pro once it's filled in?  zstime()
    sets the file date simply by copying it to xabdat_ofile.xab$q_cdt, and
    then this is picked up later by zopeno(), so why isn't the protection
    also picked up?  I couldn't quite follow all the RABs and FABs...

The upshot is, protection/permissions work when sending from VMS to UNIX, but
not in the other direction.  So, for example, if you send an EXE file from VMS
to UNIX, it keeps its execute permission.  If we can get this working in the
other direction, then when you send it back from UNIX to VMS, it will still
have its execute permission.

Changed UNIX C-Kermit to set Delete bit in Generic permissions if file has
Owner Write permission (since UNIX has no separate Delete permission), and to
treat Delete bit in incoming Generic permission equivalent to Write bit.
ckutio.c, 1 Jan 98.

Tried not defining NOLISTEN for VMS to see what would happen.  It worked OK on
UCX 2.0.  It failed horribly on MultiNet; I twiddled some stuff here and there
and seem to have got it working.  Went back to UCX to make sure I didn't break
it there...  Hmmm, still seems to work.  ckcnet.[ch], ckermit2.upd, 1 Jan 98.

VMS: turn off broadcasts on the *console* channel as well as on the
communications channel.  conbin(), ckvtio.c, 2 Jan 98.

Changed the UNIX version when it is about to set a received file's owner
permissions from the incoming generic protection attribute, to use the umask
for the group and world permissions.  zstime(), ckufio.c, 2 Jan 98.

Updated File Permissions section of ckermit2.upd, 2 Jan 98.

Updated ckermit.bwr, and added a new section on "echoplex" scripts.  2 Jan 98.

Moved usage() routine and hlp1[] strings from ckuus2.c to ckuusy.c.  2 Jan 98.

Added little help blurbs for each command-line argument.  ckuusy.c, 2 Jan 98.

Added HELP OPTIONS [ { <opt>, ALL } ].  If <opt> given, it prints the short
HELP text for the option.  If ALL given, it prints them for all options, with
more-prompting, etc.  HELP OPTIONS by itself explains command-line options.
ckuusr.h, ckuus[2y].c, 2 Jan 98.

VMS protections, cont'd...  John Santos showed me how to link the protection
field into that rat's nest of FABs, RABs, and XABs, so now we are actually
setting the VMS file protection from the incoming A packet.  And it works for
both system-dependent (VMS 16-bit) and generic Kermit protections, hurray.
Except when using the generic protection, the non-Owner fields are set to 0,
e.g. (,RWED,,); I'll do something about that tomorrow.  ckvfio.c, 2 Jan 98.

Added \v(pid) for VMS.  ckcdeb.h, ckvfio.c, 3 Jan 98.

Added code to VMS version to set its process name to "C-Kermit_6.1".
If that's a duplicate name, then "C-Kermit_6.1_1", C-Kermit_6.1_2", etc.
sysinit(), ckvtio.c, 3 Jan 98.

Added code to VMS zstime() to get the user's default file protection with
sys$setdfprot(), and then used it to set the S, G, and W fields when setting O
field from generic protection (but using the O field as a mask for the other
fields).  ckvfio.c, ckcplm.doc, ckermit2.upd, 3 Jan 98.

Merged some changes from Jeff.  ckcmai.c, ckcnet.c, ckuus[xy].c, ckuusr.h,
3 Jan 98.

Minor cosmetic cleanups to HELP OPTIONS.  ckuus[2y].c, 3 Jan 98.

Increased Olimit for SINIX to 2100.  makefile, 3 Jan 98.  (But now ckcpro.c
takes a loooooong time to compile...)

Numerous last-minute #ifdef & declaration adjustements.  Many modules.
3 Jan 98.

At the last moment, found that what should have been "xitsta |= what;" had
been typed as "xitsta != what;" (watcom caught it - "meaningless expression").
So it's corrected in the code, but wrong in all the Alpha.11 binaries.
ckcpro.w, 3 Jan 98.

---Alpha.11---

(See last entry for Alpha.11.)

Some fixes to usage() message.  ckuus[2y].c, 4 Jan 98.

Minor fixes from David Lane to a debug() statement in ckcnet.c and to
VOS-related #ifdefs in ckcdeb.h, 4 Jan 98.

Added display of sizeof(xxx) to SHOW FEATURES, for xxx == int, char, long, etc.
ckuus5.c, 6 Jan 98.

Merged Jeff's recent changes, many modules.  13 Jan 98.

Merged David Lane's changes for Stratus VOS, adding support for recursive
directory traversal, fully-qualified filenames, etc.  ckcdeb.h, ckuusx.c,
plus all-new ckl*.* modules, 13 Jan 98.

We were still getting floating-point exceptions and related difficulties (up
to and including system halts) in Alpha.11 apparently due to constructions
like the following:

    if (fpxfsecs <= 0.0)
      fptsecs = (CKFLOAT) 0.000001;
    filcps = (long)((CKFLOAT) ffc / fpxfsecs);

The division by a tiny number created a quotient that might not fit in a long.
I replaced all references to "0.000001" by GFMINTIME, which is now defined in
ckcdeb.h to be 0.005.  This doesn't totally fix the problem, but makes it a
lot less likely.  E.g. suppose we have network so fast that we can transfer a
1MB file in less time than can be measured, so fpxfsecs is 0.0.  When we set
the time to 0.00001:

  1,000,000 / 0.00001 = 1,000,000,000,000

but 2^32 (the longest long) is 4,294,967,296, too small for this number,
hence the trap.  But if we set the time to 0.005:

  1,000,000 / 0.005 = 200,000,000

which fits.  The new symbol GFMINTIME is defined to this value, and we use
the symbol everywhere rather than the hardwired value.

But this still doesn't fix the problem; if the file were (say) 3MB, it would
still happen.  So we also have to check whether the result of a division would
exceed the capacity of a long (or int) to hold it, and in that case take
special action to avoid the trap.  ckcdeb.h, ckcfn2.c, ckutio.c, 13 Jan 98.

Recoded the memcpy() replacement loop in ckcnet.c to not use an unitialized
variable.  Then replaced the loop altogether with a call to a new routine,
ckmemcpy(), which is a system-independent version of memcpy() that can be
called safely from anywhere in C-Kermit.  Presently it's defined in ckcmai.c,
but eventually all of these utility routines should be moved out to a new
ckcuti.c module.  13 Jan 98.

Fixed an out-of-bounds array reference in the new debug(F011,...) handler.
From William Bader.  ckuusx.c, 13 Jan 98.

Raised MAXWLD for VMS from 4K to 1024K and made mtchs[] array dynamic.
ckvfio.c, 14 Jan 98.

Raised MAXWLD for UNIX in the non-BIGBUFOK case from 1K to 4K.  ckufio.c,
14 Jan 98.

Moved MAXWLD definition from ck[uvdl]fio.c to ckcdeb.h, so we can access
it from other modules.  Added MAXWLD display to SHOW FEATURES.  ckuus5.c,
14 Jan 98.

Defined BIGBUFOK for HP-UX 9.x.  ckcdeb.h, 14 Jan 98.

Added makefile entries and banner for HP-UX 11.00: "make hpux1100", etc.
makefile, ckuver.h, 14 Jan 98.

UNIX C-Kermit CONNECT command was not checking the return code of ttchk() for
a negative value, and so was not popping back to the prompt automatically.
Seems to do so now, at least on HP-UX, as long as CARRIER-WATCH is not OFF.
ckucon.c, 14 Jan 98.

By chance, I noticed something very strange in UNIX:

  C-Kermit> send /b foo

Sent the "foo" file over and over again.  Diagnosis: "/b" is not treated as a
switch because it does not uniquely match any switch (it is ambiguous between
/binary and /before).  So since it does not match a switch, we look to see if
it matches a file.  It so happens, there was a "b" directory under root.  Now
with the new recursive file sending feature, the SEND command, when given a
directory name, sends the files from the directory.  In other words, "/b"
is treated as "/b/*".  But the b directory contained no files, so zxpand()
came up with 0.  In that case, UNIX zxpand would call zltor() on the filespec
and try again.  Bad idea!  This caused the pathname to be stripped, leaving
only "*".  So "send /b foo" sent all the files from the current directory
with an as-name of "foo".  Cure: (1) remove the fallback -- if the filespec
doesn't match anything, that's that.  And (2) Make "/b" an acceptable
(nonunique) abbreviation for "/binary".  ckufio.c, ckuusr.c, 14 Jan 98.

Added missing return(0) to dohopts().  ckuus2.c, 14 Jan 98.

In SGI IRIX and in NeXTSTEP, there is no API for hardware flow control, but it
can still be used by selecting a device with a particular name, like /dev/cufa
instead of /dev/cua.  But in this case SET FLOW AUTO would wind up setting the
flow control to Xon/Xoff instead of leaving it alone.  Added #ifdefs for IRIX
and NeXT to prevent this.  Also defined a new IRIX symbol for all IRIX
versions 4.0 and later.  ckcdeb.h, ckuus3.c, 14 Jan 98.

How does VMS C-Kermit know if it's running under batch.  Currently:

 . When run interactively, batch == 0.
 . If started from a COM file, batch == 1.
 . If started in batch, batch == 1 and congm sys$qiow = SYSTEM-F-ILLIOFUNC
 . In batch, SHOW LOG SYS$INPUT says "_NLA0:".

Tried adding a sys$getjpiw() call, once I figured out how to set it up.
If asked for JPI$_MODE, it returns the mode of the job: batch, interactive,
etc: perfect.  Builds and runs fine on VMS 5.5-2, so should be OK elsewhere.
ckvtio.c, 14 Jan 98.

Fixed the new xxscreen() macro to not call screen() if batch (VMS) or backgrd
(elsewhere) was set.  ckcker.h.  This also required adding extern declarations
for batch & backgrd to ckcfn[s23].c, ckcpro.w, and ckuusx.c.  14 Jan 98.

 . Fullscreen display in interactive sessions: Yes
 . Fullscreen display in @blah.com sessions:   ??
 . Fullscreen display in submit blah sessions: No <-- so this is fixed now.

Not sure what the deal is with when running C-Kermit with @blah.com, where
blah.com contains image data...  But batch jobs now work nicely, don't put any
junk in the batch log.

Added SET BATCH { ON, OFF } in VMS to let user have the final word.  ckuusr.c,
14 Jan 98.

Minor fixes to "help options" text.  ckuus2.c, 14 Jan 98.

VMS C-Kermit reported a "fatal error" when executing an INPUT command on a
modem when it hung up, even though CARRIER-WATCH was OFF.  Tracked this down
with help of a debug log from Dale Dellutri.  Fixed in txbufr(), ckvtio.c,
15 Jan 98.

Dale D. also reported that an extraneous character could show up on the
CONNECT screen when the remote hung up.  No explanation jumps out from the
code, but I changed VMS ttinc() to not deduct 1 from the buffer count until
first checking that it's > 0.  ckvtio.c, 15 Jan 98.

Checked the VMS version on a system where I can dial out -- I don't seem to
have broken anything, and I don't see any of the symptoms any more that I
tried to fix, so maybe that's progress.

Built on the NeXT, dialed out, logged in somewhere, logged out, and for the
first time ever, C-Kermit popped back to its prompt automatically.  And if
CARRIER-WATCH is OFF it doesn't, and you can see the NO CARRIER message and
type more AT commands.

Evidently the HP workstation Reset key sends some kind of ueber-SIGINT that
can not be SIG_IGNored.  When the user hits it (usually because it's where PC
users expect Esc to be), suddenly we're in the Ctrl-C handler, longjmping back
to the prompt, which leaves the lower CONNECT spinning away merrily.  What's
odd about this is that it is the *previous* SIGINT handler, not the current
one, which is SIG_IGN.  I sent off a query to HP about how to handle this, but
in the meantime, in addition to the stale-fork-killing code I added to
ckucon.c a while back, I made the Ctrl-C trap simply return
"if (what == W_CONNECT)".  ckuusx.c, 15 Jan 98.

Peter Eichhorn verifies this fixes leftover fork problem on HP-UX; Reset is
now properly ignored during CONNECT and causes SIGINT at the command prompt,
which is handled properly.  16 Jan 98.

To subtract from, or maybe add to, the confusion about text and binary mode,
I made sure that if the user says SEND (MSEND, etc) /BINARY, that binary mode
is really used, i.e. not superseded by filename pattern-matching, or by
TRANSFER MODE AUTO.  Ditto for SEND /TEXT of course.  ckuus[r6x].c, 16 Jan 98.

Unfortunately, matters are not quite so simple with GET because WHOAMI takes
precedence over WHATAMI, as the manual states.  WHOAMI is controlled by SET
TRANSFER MODE, so if I tell the client to SET TRANSFER MODE MANUAL, then "get
/text x.zip", it should work.  But it doesn't because the server still has
FILE PATTERNS ON and ".zip" is a binary pattern.

While looking into this, I also discovered that REMOTE SET FILE TYPE was
broken.  Why?  Because as soon as we changed the mode, it was restored to its
previous value because it didn't also change g_binary (the global, prevailing
mode).

OK, fine, that's fixed.  But now if TRANSFER MODE is MANUAL, WHATAMI still
doesn't work.  Why?  Again because of the patterns.  gnfile() was resetting
its file type to whatever it was when protocol started between each file, so
as to get the global file mode right when pattern-switching.  So this undid
WHATAMI.  Fixed in gnfile(), ckcfns.c, 16 Jan 98.

So now if I tell the server to SET TRANSFER MODE MANUAL before putting it in
server mode, everything works right.  But there is no way for the client to do
this after the server is started.  So I added REMOTE SET TRANSFER MODE.  The
new code is 410, the values are 0 for AUTO, 1 for MANUAL.  Client side in
ckuus3.c, server sever side in remset() in ckcfns.c, documentation in
ckermit2.upd, 16 Jan 97.  Also sent a note to JRD so he can add it to MSK.

Added REMOTE SET XFER as a synomym for REMOTE SET TRANSFER and fixed both of
these to have a private keyword list rather than using the non-REMOTE one.
ckuus7.c, 17 Jan 98.

Additions/corrections to text and binary patterns lists.  ckcmai.c, 17 Jan 98.

Added \v(intime) to tell the number of milliseconds it took for INPUT to
find its match.  ckuusr.h, ckuus4.c, ckermit2.upd, 17 Jan 98.

Added display of modem's dial result message to "Call complete" if DIAL
DISPLAY not ON (and not quiet, etc).  ckudia.c, ckermit2.upd, 17 Jan 98.

Added \fword(s1,n1,s2) to return word number n1 from string s1, with optional
break set s2.  ckuusr.h, ckuus[24].c, ckermit2.upd, 17 Jan 98.

Fixed cmfdb() to print an error message if it gets through all the chained
fdb's without finding anything and the return code from the last parsing
function is -9.  Previously it just moved the cursor backwards silently
over the offending field.  ckucmd.c, 18 Jan 98.

If a command has a switch that takes an argument followed by a switch that
does not, e.g.:

  send /as:oofa.txt /text foo.bar

and then this command is recalled, there is a parse error.  Fixed in gtword(),
ckucmd.c, 18 Jan 98.

Added help text for KERMIT command.  ckuus2.c, 18 Jan 98.

Added optional message to EXIT/QUIT, like END and STOP.  ckuusr.c, 18 Jan 98.

Merged Jeff's recent changes, ckcdeb.h, ckuus7.c, ckcnet.c.  19 Jan 98.

Adjusted the constants for float->long overflow detection in fstats() and
tstats() (thanks to gcc -Wall).  ckcfn2.c, 19 Jan 98.

Ran a bunch of feature-test builds on SunOS; each one involved some --
sometimes lots of -- #ifdef adjustments and declaration juggling, especially
the ones marked with (*).  ckuus5.c, in particular, has been massively
rearranged:

 . (full)           ok (1097K)
 . -UDYNAMIC        ok (1081K)
 . CK_SMALL         ok (1073K)
 . MINIDIAL         ok (1064K) (*)
 . NOBIGBUF         ok (1081K)
 . NOBROWSER        ok (1081K)
 . NOCAL            ok (1089K)
 . NOCKSPEED        ok (1089K)
 . NOCKTIMERS       ok (1089K) (*)
 . NOCMDL           ok (1073K)
 . NOCKXYZ          ok (1089K)
 . NOCSETS          ok (1024K)
 . NODEBUG          ok ( 991K)
 . NODIAL           ok ( 958K)
 . NOFRILLS         ok (1056K)
 . NOGFTIMER        ok (1089K)
 . HOHELP           ok ( 974K)
 . NOICP            ok ( 393K) (*)
 . NOJC             ok (1089K)
 . NOKERBEROS       ok (1089K)
 . NOLOCAL          ok ( 770K) (*)
 . NOMKDIR          ok (1089K) (*)
 . NONET            ok (1015K)
 . NOPARSEN         ok (1089K)
 . NOPATTERNS       ok (1081K)
 . NOPERMS          ok (1089K)
 . NOPIPESEND       ok (1089K)
 . NOPUSH           ok (1073K) (*)
 . NORECURSIVE      ok (1097K)
 . NOREDIRECT       ok (1089K)
 . NORENAME         ok (1089K)
 . NORESEND         ok (1089K)
 . NOSETKEY         ok (1089K)
 . NOSERVER         ok (1064K)
 . NOSHOW           ok (1040K) (*)
 . NOSPL            ok ( 925K) (*)
 . NOTRIGGER        ok (1089K)
 . NOTUNING         ok (1089K)
 . NOUNPREFIXZERO   ok (1097K)
 . NOSPL+NOLOCAL    ok ( 614K)
 . sunos42mi        ok ( 294K) ("minimum interactive")
 . sunos41m         ok ( 180K) ("minimum" - cmd line only)

After getting all these to build, I went through the list a second time to
make sure that the accumulated fixes didn't break earlier builds.  Then I
spot-checked various builds to make sure they transferred files OK, etc.
19 Jan 98.

Fixed "kermit -Q" to work no matter what the compile-time buffer lengths are.
ckuusy.c, 20 Jan 98.

Still more #ifdef adjustments for feature selection.  20 Jan 98.

Added an "include list" for \fword() (an exception list to the break set).
ckuus4.c, ckermit2.upd, 20 Jan 98.

Fixed cmdate() to not accept times that were so large they would wrap around
and become negative.  ckuus4.c, 20 Jan 98.

Discovered that filename completion was broken on VMS.  Fixed in ckucmd.c,
20 Jan 98.

Updated some of the UNIX makefile production rules to include ckcnet.h.
makefile, 20 Jan 98.

Discovered that TELOPT_AUTHENTICATION is erroneously defined as 45 on Ultrix,
OSF/1, Digital Unix, and IRIX (all versions of each).  It should be 37.  This
introduces conflicting definitions in the preprocessor, which I #ifdef'd out.
ckcnet.h, 20 Jan 98.

---Alpha.12---

Merged Jeff's changes since last week.  ckuus7.c, ckcnet.c, ckucmd.c,
26 Jan 98.

Added \fsplit(string,&array,break,include).  ckuusr.h, ckuus4.c, ckuus2.c,
ckermit2.upd, 26 Jan 98.

Made SHOW NETWORK available in all versions; if no network support is
included, it says so.  ckuus[r5].c, 26 Jan 98.

Integrated Jeff's changes since yesterday.  ckuus7.c, ckcnet.[ch], ckuusr.h,
27 Jan 98.

Added SET TCP REVERSE-DNS-LOOKUP { ON, OFF }.  Sets tcp_rdns; code needs to
be added to use it.  ckuusr.[ch], ckuus[234].c, ckcnet.c, 27 Jan 98.

Added -DNOGFTIMER to HP-UX 5.00 makefile entry, since the high precision
timers give off-the-wall results there.  makefile, 27 Jan 98.

Changed predefined FAST macro to "set prefixing cautious" instead of "minimal".
ckuus5.c, 27 Jan 98.

Discovered that command-line syntax error messages were never printed.
Fixed in fatal(), ckuusx.c, 27 Jan 98.

Merged Jeff's changes.  ckuus[r37].c, ckcnet.[ch], 28 Jan 98.

Moved +DA1.0 from the hpux100o entries to the basic one, since it applies to
both compilers.  makefile, 28 Jan 98.

Added -pipe to linux entry so it won't make temp files, allowing builds on
systems where /tmp is too full.  makefile, 28 Jan 98.

In VMS, make zshcmd() (RUN command) return proper status, ditto for zxcmd(),
and make both set pexitstat.  ckcdeb.h, ckuus4.c, ckvfio.c, 29 Jan 98.

Enabled ck_errstr() for VMS, but errno is always 0.  Tried it again based on
vaxc$errno, same result.  So then I went thru ckvfio.c and ckvtio.c and
assigned the return of every sys$blah() and lib$blah() call to a global
variable, vms_lasterr.  Works.  ckv[ft]io.c, ckuusx.c, 29 Jan 98.

Added \ferrstring(n), returns error message for code n.  In <sys/errno.h>
environments (like UNIX), this requires knowing the maximum index of the
sys_errlist[] array, normally sys_nerr.  We'll soon find out how portable
that is...  UNIX and VMS only for now.  ckuusr.h, ckuus4.c, 29 Jan 98.

Added SET FUNCTION DIAGNOSTICS { ON, OFF }.  When ON, this makes variables
and functions return an error-message string as their values.  ckuusr.h,
ckuus[34].c.  30 Jan 98.

Discovered that array initializers were off by one (i.e. not skipping over
the "=" sign); numerous other problems with array bounds, malloc'ing and
freeing, etc, when processing initializers.  ckuusr.c, 30 Jan 98.

Added makefile entrys aix41, aix42, aix43.  These are all the same, but
set a different program herald.  ckuver.h, makefile, 31 Jan 98.

Kerberos V authentication added to Linux version, using Cygnus libs.
Encryption does not work yet due to fork structure of ckucon.c.  makefile,
ckcmai.c, ckuus5.c, ckutio.c, ckcnet.[ch] + new non-public krbtel.[ch] module,
documented in kerberos.txt.  1 Feb 98.

Fixed the size of the command buffer to be at least as big as the function
result buffer.  This means, for BIGBUFOK builds, 10K rather than 4K.
ckucmd.h, 1 Feb 98.

Added SET FUNCTION ERROR { ON, OFF }.  When ON, this makes any command that
contains a bad function call or built-in variable reference fail.
ckermit2.upd, ckuus[2345].c.  1 Feb 98.

Uncoupled display of dialing-directory related info during dialing from
SET DIAL DISPLAY ON, which should only affect whether dialog with modem is
shown.  ckuus6.c, 1 Feb 98.

Fixed some prompt-stomping in VMS DIAL command when DIAL DISPLAY is ON.
ckudia.c, 1 Feb 98.

Added "k95" as a command to K95, an alias to "kermit".  ckuusr.c, 1 Feb 98.

Fixed minor problem with completion of "intro" command.  ckuusr.c, 1 Feb 98.

Discovered that isabsolute() for UNIX, OSK, Amiga, and K95 returned 1 instead
of 0 if the filename started with ".", which is completely wrong.  One symptom
was that an incoming file whose name started with "." when RECEIVE PATHNAMES
were RELATIVE would have a second dot added to the front of its name.  I can't
imagine why this was done in the first place, and hope I haven't broken
anything that depended on this -- but if I did, it shouldn't have...
ckcmai.c, 1 Feb 96.

When a file group is being transferred, CPS rates were not being calculated
after the first file.  Must have happened during the GFTIMER work...  Fixed
in ckuusx.c, 1 Feb 96.

In VMS, on a serial connection with CARRIER-WATCH off, and the remote hangs up
while C-Kermit is in CONNECT mode, contti() gets a completion from sys$qiow()
indicating SS$_HANGUP, but no character; however, Kermit was returning a
character anyway, whatever happened to be left in the variable from last time.
Fixed by having contti() set the read up to be queued again next time and then
returning a special status, -2.  ckcgetc(), looks for the -2 and then calls
contti() again, up to 10 times.  Experimentation shows that the second call
always succeeds -- SS$_HANGUP is returned only once; after that, reads work
normally again.  ckvtio.c, ckvcon.c, 1 Feb 98.

Quick check-builds on SunOS, Linux, HP-UX, VMS, and Unixware all compile OK...

Added test & message for no-such-macro to \fexec().  Added tests for bad array
references to \fwords().  Added tests for numeric arguments that were not
there yet, supplied defaults where they were not previously being supplied in
cases where it made sense, etc.  ckuus4.c, 2 Feb 98.

Added RTS/CTS for IRIX 6.2 and higher, since an API for it seems to have
appeared in termios.h; the "POSIX" style is used (tcsettar()), but the field
name is unique (CNEW_RTSCTC).  ckcdeb.h, 2 Feb 98.

Upon receipt of newer information, fixed RTS/CTS support for SGI to go back
to IRIX 5.2.  ckcdeb.h, ckuver.h, makefile, 3 Feb 98.

Added "set send packet 4000" to definition of FAST macro for IRIX.  ckuus5.c,
3 Feb 98.

Removed a lot of junk from ckermit.ini that isn't needed any more -- EDIT
macro, BSEND and friends, etc.  3 Feb 98.

Numerous declaration and #ifdef fixups, many modules, 4 Feb 98.

---Alpha.13---

Merged Jeff's changes: Telnet X-display-location, logout options, etc.
ckcnet.[ch], ckuus[27].c, ckcdeb.h, 5 Feb 98.

Changed \%* to hold the entire argument line for the macro, so now it can
be used to reference arguments past \%9.  ckuus[45].c, 5 Feb 98.

Changed SET LOGIN { USER, PASSWORD, PROMPT } <text> to allow braces around
<text> so text can end with "{" without swallowing the rest of the script.
ckuus3.c, 6 Feb 98.

After several false starts, figured out how to let the \&_[] array, which
contains pointers to the argument of the current macro, have more than 10
elements.  So now, for the first time, users can pass as many arguments as
they like to a macro in a straightforward way, and have a straightforward way
to reference them.  This works with nesting, FOR-loops, and everything else.
\v(argc) now includes any extra arguments.  ckuusr.h, ckuus[56].c, 9 Feb 98.

Added a new function, \fdimension(&a), which tells the declared size of the
given array.  ckuusr.h, ckuus4.c, 9 Feb 98.

Filled in \&_[0] element with name of macro.  ckuus5.c, 10 Feb 98.

New HP-UX 7.x entries from Peter Eichhorn.  makefile, 10 Feb 98.

Shuffled CK_AUTODL and CK_APC #ifdefs a bit to allow successful compilation
on OS-9.  ckcfn2.c, ckcker.h, ckucon.c, 10 Feb 98.

Removed -DNETCONN from Plan 9 makefile.  ckpker.mk, 10 Feb 98.

Guarded reference to EWOULDBLOCK error code by #ifdef EWOULDBLOCK, for Plan 9
and possibly also ISC 4.1.  ckutio.c, 10 Feb 98.

Removed redundant definition of OUT_PAC from ckuusr.h, 10 Feb 98.

Added CLOSE TRANSACTIONS as a synonym for CLOSE TRANSACTION-LOG, because the
book mentions CLOSE TRANSACTIONS.  ckuusr.c, 10 Feb 98.

Changed command-line option '#' to require a numeric argument, startflags.
ckuus[4y].c, 10 Feb 98.

Changed SET PRINTER #ifdefs to allow pipes for OS-9.  ckuus3.c, 10 Feb 98.

Commented out the "?Retry limit must be greater than window size" check
in SET RETRY, a relic from bygone days.  ckuus3.c, 10 Feb 98.

Fixed the DIAL command not to send modem commands if they were empty
strings (in this case, the behavior is different for null pointers and
empty strings).  ckudia.c, 10 Feb 98.

Fixed compilation of main program to not crash gcc on SCO OSR5.04.
ckcmai.c, 10 Feb 98.

Ditto for ckwart.c, 10 Feb 98.

rmdir() is not available in OS-9; guarded reference to it in ckmkdir()
by appropriate #ifdefs.  ckcfn3.c, 11 Feb 98.

rand() and srand() not available in OS-9, added NORANDOM to OS-9 makefile.
ck9ker.mak, 11 Feb 98.

Added another check to clsif() to make sure it does not put up a "Transfer
OK" screen when sending is incomplete (in this case because there was an i/o
error when sending), the check being for the number of file characters sent
less than the number of characters in the file, taking resends into account.
ckcfn3.c, 11 Feb 98.

Lots of fooling with ckutio.c (ttvt(), ttinc(), mygetbuf(), etc) and ckcgetc()
in ckucon.c to try to catch the case where C-Kermit is in CONNECT mode, stuck
in a blocking single-byte read(), and the modem is switched off, e.g. on HP-UX.
Even though CLOCAL is explicitly unset, the read() does not return when this
happens.  There doesn't seem to be anything I can do about it.  ckuker.bwr,
11 Feb 98.

In "get /as-name:foo bar", the as-name was ignored; I wonder why nobody
noticed this before.  Fixed in doxget().  ckuus6.c, 11 Feb 98.

Added SET INPUT CANCELLATION { ON, OFF } to enable / disable keyboard
cancellation of INPUT command in progress.  ckuusr.h ckuus[r2457].c, 12 Feb 98.

Added SET TRANSMIT TIMEOUT <sec>.  ckuus[r2457].c, 12 Feb 98.

Toned down disconnection error messages in doinput() (Jeff).  ckuus4.c,
14 Feb 98.

Changed [M]SEND /MOVE: to /MOVE-TO:.  Ditto for /RENAME:.  ckuusr.c, 14 Feb 98.

Fixed GET /COMMAND -- it was totally broken by my change on 11 Feb 98.
ckuus6.c, 15 Feb 98.

Added perfunctory help text for Kerberos-related commands; detailed help would
just be way too much.  Referred them to the kerberos.txt file instead.
ckuus2.c, 15 Feb 98.

Fix from Jeff for a memory leak in ckuus4.c, 20 Feb 98.

Reverse DNS lookup ON/OFF/AUTO + send DO LOGOUT, Jeff.  ckcnet.c, 20 Feb 98.

Fix for problem with ECHO and SET FUNCTION ERROR, Jeff.  ckuusr.c, 20 Feb 98.

Merged other changes from Jeff, ckuus[35x].c, ckucmd.c, ckcpro.w, 20 Feb 98.

Fixed another memory leak in initmac().  ckuus5.c, 20 Feb 98.

Fix from Jeff for SET { BROWSER, EDITOR }.  ckuus3.c, 21 Feb 98.

Added SET FTP-CLIENT / SHOW FTP.  ckuusr.[hc], ckuus[235].c, 21 Feb 98.

Added SET SLEEP (or PAUSE) CANCELLATION { ON, OFF }.  ckuusr.h, ckuus[r236].c,
21 Feb 98.

Added SET COMMAND INTERRUPTION { ON, OFF } to enable/disable the Ctrl-C trap.
ckuusr.h, ckuus[35].c, 21 Feb 98.

Fixed WAIT to work as advertised with SET WAIT (SLEEP) CANCELLATION OFF, and
Updated HELP WAIT and HELP SLEEP.  ckuus[r2].c, 22 Feb 98.

DISABLE CD prevented GET from working when a GET-PATH was set.  Fixed in
gnfile() and openi(), ckcfn3.c, 22 Feb 98.

The error message from C-Kermit when it could not open a file to be sent was
always "Can't open file", which was singularly uninformative.  Now it sends
"Access denied" if sending was prevented by DISABLE CD or other restriction,
otherwise it is the system error message from the open() failure, such as
"Read access denied".  ckcfn3.c, ckcpro.w, 22 Feb 98.

Similarly for sending files to C-Kermit.  opena(), ckcfn3.c, 22 Feb 98.

Discovered that UNIX C-Kermit server was no longer handling tilde notation
in GET command filespecs.  Fixed in sgetinit(), ckcpro.w, 22 Feb 98.

Ditto for MGET.  Fixed in gnfile(), ckcfns.c, 22 Feb 98.

Added SET DIAL PACING <msec>.  ckuusr.h, ckuus[34].c, ckudia.c, 22 Feb 98.

Added S14=0 to USR init string so +++ will not hang up the call.  ckudia.c,
22 Feb 98.

SHOW DIAL was too long; askmore()'d it.  ckuus4.c, 22 Feb 98.

Assorted last-minute fixes for declarations & ifdefs.  ckcnet.c, ckuus4.c,
22 Feb 98.

---Beta.01---

Fix for repeat counts when sending in text mode on CRLF-based systems, from
Jeff.  ckcfns.c, 22 Feb 98.

Added a definition for CK_UTSNAME for SunOS, HP-UX, POSIX (per POSIX.1), AIX,
and SVR4 (per SVID).  Will check on others later.  When this symbol is
defined, we #include <sys/utsname.h>, and then we can get the machine type, OS
name, OS version, etc, at runtime by calling uname() in sysinit().
ckcdeb.h, ckutio.c, 25 Feb 98.

In ckutio.c, CK_UTSNAME means it's OK to include <sys/utsname.h> and to call
uname(), but outside ckutio.c, it simply means that the strings listed below
may be referenced (which implies that they are defined in the corresponding
ck?tio.c module, and filled in by any appropriate means).

Added string variables to ckutio.c to hold these items:

  unm_mch[]  Machine name (e.g. "9000/715")
  unm_nam[]  OS name (e.g. "HP-UX")
  unm_ver[]  Name of major OS release (e.g. "A")
  unm_rel[]  Name of specific OS release (e.g. "A.10.20")

And logged them in the debug log.  Just type "log debug", "close debug" and
look at the top of debug.log to see them.  ckuus4.c, 25 Feb 96.

Changed \v(cpu) to evaluate to unm_mch[] in preference to "unknown" if
CK_UTSNAME is defined.  ckuus4.c, 25 Feb 96.

Added \v(osname) and \v(osversion).  For systems where CK_UTSNAME is defined,
these are the sysname and release members of the utsname struct, respectively.
Thus, these describe the system where C-Kermit is actually running.  We never
had this information before.  ckuusr.h, ckuus4.c, 25 Feb 96.

From now on \v(platform) should be thought of as describing the system for
which C-Kermit was built, which is not necessarily the same as the one it's
running on.

In HP-UX 9.0 and later, sysinit() sets the variable hpis800 if the machine is
an 800-series, otherwise unsets it, using the HP-blessed method of looking at
utsname.machine[5].  ckutio.c, 25 Feb 98.

Defined a new symbol HPUX9PLUS meaning "HP-UX 9.00 or higher".  Changed
ttlock() and ttunlock() to use this symbol instead of HPUX10.  But since the
format of device names in HP-UX 9.x is different from 10.00 on Series 700
hardware than on Series 800, I used the hpis800 variable to construct the
appropriate format for the lockfile name in ttlock().  At this point, the
lockfile behavior of HP-UX 9.xx and 10.xx and 11.xx should be identical.
ckutio.c, 25 Feb 98.

Changes to make 6.1 build under Sunsoft Interactive UNIX 4.1 from Kenneth
Cochran (#include <sys/time.h>, link with libinet).  ckutio.c, makefile,
26 Feb 98.

Added code to let server handle a GET command for a filename that contains
spaces.  This works if the client sends the name enclosed in either braces
or doublequotes.  ckcpro.w, ckermit2.upd, 26 Feb 98.

Fixed compilation errors HP-UX 9.xx lockfile code.  In HP-UX 10.00 and above
we also do SVR4 advisory locks, but these are not available in 9.xx, so more
#ifdefs were needed.  ckutio.c, 27 Feb 98.

Another change for HP-UX 9.xx lockfiles (it was using the HP-UX 10.00 lockfile
directory, /var/spool/locks, rather than /usr/spool/uucp).  ckutio.c, 2 Mar 98.

Adapted recent HP-UX lockfile code to all HP-UX versions.  Added additional
names to the list of names to check for lockfiles: "cuad" and "culd".  Built
and tested on HP-UX 10.20, 9.05, 8.00, 5.21.  ckutio.c, ckuker.bwr, 3 Mar 98.

Fixed \v(cpu) to return uname() hardware type if known, in preference to
"unknown".  I thought I did this before, but I missed an #ifdef in ckuver.h.
Now we can see all those exotic cpu types (tested on an HP-9000/550, where
\v(cpu) now says "9050X" rather than "unknown").  ckuver.h, 3 Mar 98.

Discovered that UNIX \v(xxx) variables that returned directory names did so
inconsistently -- some ended with /, some didn't, some ended with two /'s.
Fixed all of them to send with one and only one /.  ckuus4.c, ckutio.c,
3 Mar 98.

Merged Jeff's recent changes.  ckuus[r347x].c, ckcdeb.h, cknet.h, 3 Mar 98.

Discovered that \v(inidir) returned a filename rather than a directory name
if the initialization file didn't exist.  It should have returned an empty
string in this case.  Fixed in doinit(), ckuus5.c, 3 Mar 98.

Added designer banner for BSDI 3.0.  ckuver.h, makefile, 3 Mar 98.

Added uname() info, if we have it, to SHOW VERSION.  ckuus5.c, 3 Mar 98.

VMS #ifdefs for getsockname() to suppress compilation warnings in
getlocalipaddr(), from Lucas Hart.  ckcnet.c, 3 Mar 98.

Changes from Lucas Hart to VMS file module, ckvfio.c, 3 Mar 98:
 a. Issue an informative message upon failure to SPAWN.
 b. Support transfer of odd-record-length files.
 c. Improvements to isdir().

In more detail:

(a) add a diagnostic message when SPAWN fails because the default directory is
a remote node.  (4263)

(b) when sending a file in C-Kermit BINARY mode, change from RMS BLOCK to RMS
RECORD mode if the file format is fixed record length and the record length is
odd.  Implementing that turned out to be simple (after the fact.)  Maybe that
will do the job for whoever wants to retain the Kermit-32 behaviour.  I've
done some minimal testing - transfer to a du40 system of a short odd record
length file; in that case IMAGE vs BINARY had the intended effect of
including/excluding the pad byte.  (918)

(c) an extension of Mark Berryman's isdir(), to use $SEARCH rather than
depending on $PARSE to return the directory status.  By trial-and-error, I
concluded that PARSE only tests a directory specification for the existence of
a corresponding file with ".DIR;1"; it does not test if that file is a
directory file.  Also, PARSE is documented to not test for the existence of
the directory on a remote node.  As far as I can tell, isdir now correctly
reports whether a file is recognized by RMS as a directory and whether the
name was a passed as a directory specification or a directory name.  (715)

Disabled GFTIMER for VMS versions prior to 5.0 (William Bader & Lucas Hart --
actually Lucas sent in code to enable this, but it involves changing the
mechanism used on later versions also, a risk that would seem to outweigh the
benefit).  ckcdeb.h, 3 Mar 98.

Discovered that REMOTE SET <various things> didn't work any more because
the things that were SET were then restored to their saved values upon exit
from protocol mode.  Affected things were BLOCK-CHECK, RECEIVE TIMEOUT, and
FILE NAMES.  ckcpro.w, ckcfns.c, 4 Mar 98.

A user reported bizarre problems when using the MKDIR command in a macro.
Problem: incorrect assumption that msgflg was 0 when in protocol mode, nonzero
otherwise (found by Jeff).  Solution: add another agument to ckmkdir().
ckcker.h, ckcpro.w, ckuusr.c, 4 Mar 98.

Merged Jeff's changes.  ckuus7.c, ckuusy.c, ckucmd.c, 4 Mar 98.

VMS zrmdir() is a horrible hack, calling system() to set the permission of the
directory file and calling system() again to delete it -- if anyone knows a
better way, be my guest.  Improved this slightly by setting the owner
permission to RWED rather than just D, so if the delete command fails, at
least the directory can still be accessed (e.g. to delete its files, so the
directory can be deleted after all).  ckvfio.c, 4 Mar 98.

Discovered that VMS C-Kermit could not receive a file whose name contained
a segment that was more than 39 characters long.  The file-creation API does
not truncate extra characters from name segments, so I added code to VMS
nzltor() to do this.  ckvfio.c, 4 Mar 98.

Discovered that whenever an .OBJ file is sent from VMS C-Kermit, it says
"transfer interrupted", even though the file is sent OK.  This is because of a
check I added to clsif() recently to see if the number of file bytes sent was
not less than the size of the file.  Turns out this is not a reliable test for
VMS, so I dummied out the test for VMS.  Ditto for VOS.  ckcfn3.c, 4 Mar 98.

The same thing would happen if K95 was sending a text file with EOF CTRLZ,
so I added another test to allow for that too.  ckcfn3.c, 4 Mar 98.

Discovered that VMS C-Kermit on my local VAX with UCX doesn't know the name of
the TCP host it's connected to.  Evidently the new reverse DNS lookup doesn't
work in UCX (or at least not in UCX 2.0).  Changed the default for this in UCX.
ckcnet.c, 4 Mar 98.

Discovered that VMS C-Kermit under TGV Multinet doesn't have a SET TCP
command.  This is because all the tables are #ifdef SOL_SOCKET, which is
evidently not defined in Multinet.  But TCP ADDRESS, TCP REVERSE-DNS-LOOKUP,
etc, don't depend on this, so I removed the #ifdefs.  ckuus[3c].c, 4 Mar 98.

A bug was reported in VMS C-Kermit's fullscreen file transfer display that
happens during GET commands, but not SEND commands -- the left and right sides
of the display are skewed by one line.  I can't reproduce on VAX or Alpha.

Parsing of SET MODEM command was pretty awful if the user tried to edit, etc,
because of the horrible hack used to accept SET MODEM <modem-type> for
backwards compatibility.  Removed the hack and replaced with chained FDBs for
the two keyword tables.  ckuus3.c, 4 Mar 98.

More changes to HP-UX lockfile recognition -- now we recognize any string of 1
or more digits, or any string of one or more digits followed by a "p" followed
by one or more digits, as a unit number for purposes of identifying a standard
HP-UX serial device, regardless of the HP-UX version or the hardware model.
ckutio.c, 4 Mar 98.

Fixes to the yesterday's HP-UX lockfile work.  ckutio.c, 5 Mar 98.

Added more text and binary filename patterns for UNIX.  ckcmai.c, 5 Mar 98.

Added an error message if ttvt() call in OUTPUT command fails.  Made INPUT
messages consistent with OUTPUT.  ckuus[45].c, 5 Mar 98.

Conversion of UNIX CONNECT module to select()...  Previous copy of ckucon.c is
safe with Beta.01.  I butchered my working copy to:

 . Remove all hints of forks, pipes, pids, and signals.
 . Remove all X.25 support.
 . Use select() to wait for next event.

This cuts it down from 2400 lines to 1400 lines.

All the existing i/o and buffering mechanisms were kept.  Works fine on SunOS:

 . As a Telnet client (negotiations all ok).
 . As an Rlogin client (as root, of course).
 . On a serial port too.

Very fast too.  Ditto on HP-UX 10.20 and Solaris 2.5.  And Linux, yay.
But details need fixing:

 . Autodownload doesn't work.
 . The key-macro code was stripped out -- must put it back in.
 . Prompt-stomping & missing messages upon return from CONNECT mode.
 . #ifdefs for syntax of FD_blah, select(), etc, on many systems.
 . Test transferring files through this Kermit in the middle.

To do:

 . Fix above details.
 . Test test test, find and fix other details.
 . Add Kerberos support for Linux.
 . Find out which UNIXes can use select() for both serial & net connections.
 . Figure out a way to make a single source support both fork() and select().

The last one is probably too much.  But we can have separate modules easily
enough, since there are separate production rules in the makefile for regular
and Kerberized builds; this allows CONNECT modules with different names.
All the above: ckocon.c, 5 Mar 98.

Added back key mapping to new ckucon.c.  7 Mar 98.

Discovered SET KEY, when given in its multiline format, did not allow the
definition to be edited.  Fixed in ckuus3.c, 7 Mar 98.

Fixed APC, autodownload, prompt-stomping and missing messages.  Tested
triggers, character-set translation, Telnet to NeXT, all OK.  ckucon.c,
7 Mar 98.

Now try to get Kerberos encryption going on Linux.  Short story: it works but
it's slow.  Longer story: The normal ckucon.c strategy of using a blocking
ttinc() followed by n = ttchk() and then ttxin(n,buf) won't work with Kerberos
because ttxin() decrypts or does not decrypt the entire buffer that it reads
based on the current encryption state.  But the encryption state can change
midstream based on Telnet negotations that might be in the middle of the
buffer.  Since Telnet negotations are handled only at the highest level (by
the client of the client of the ttblah() functions), we must do
single-character reads only, using ttinc(), if there is a possibility of
encryption.  So far so good...

BUT... ttinc() also buffers stuff up internally, and this conflicts with the
our new select()-driven strucure; a deadlock can occur when select() waits on
the net, but the net has already sent everything it intends to and all this
material is already sitting in ttinc()'s internal buffer.  ttchk() to the
rescue?  No, because ttchk() looks not only at the internal buffer, but also
at the TCP buffers.

So... since it's all in the family (UNIX), I added a new UNIX-only function,
ttpeek(), which tells how many bytes are waiting in ttinc()'s internal buffer
(i.e. the MYREAD buffer).  This tells us whether to tell select() to block on
the net.  The result works fine, but slowly, since we have several layers of
function calls for each character we read: ckcgetc() -> ttinc() -> read().
And of course, now also the Kerberos decryption function.  There is no other
way to do this given the current layering.

I'll see if I can find any way to speed up the code, but in any case, it needs
variables it can test to see if encryption is a possibility.  For example, if
we know at runtime this is not a kerberized connection, we don't need the
byte loop.  I used "me_auth" for now.

File transfer works, but slooooowly, and streaming doesn't work at all because
there is always a CRC error on the first packet.  After a streaming transfer
failure and re-CONNECT, it just hangs -- nothing on the far end, can't escape
back either -- encryption sync is evidently lost.

After analyzing logs, I realized: if a packet is ever resent, then we are
encrypting a packet that was already encrypted, since ck_krb_encrypt() works
in place.  So I made ttol() copy the clear-text packet to its own private
buffer, then encrypt the buffer, then write it.  This cures the problems in
one direction (encrypting local Kermit is receiving -- autodownload works ok),
but not in the other -- it hangs for a while at the beginning, and then again
(forever) at the end of the transfer.

Made it safe to use memcpy() by defining a memcpy() macro to use ckmemcpy()
if USE_MEMCPY not defined, and then defining USE_MEMCPY for systems where I
know it's available (K95 + most modern UNIXes).  ckcdeb.h, 8 Mar 98.

Added a "SECURE" indication to SHOW COMM, the CONNECT message, and the Network
Type field of the fullscreen file-transfer display.  ckucon.c, ckuusx.c,
8 Mar 98.

Ran encrypted transfers again via K5 localhost connection, client/server:

 . SEND worked fine, no errors.  But later another SEND took a long time
   to start and hung at the end.

 . GET worked fine, no errors, but was excrutiatingly slow (83 cps).
   Both sides reported zero errors.  But after "fin" and connecting back,
   I saw a fragment of garbage on the screen, indicating some kind of
   encryption screwup.

 . Streaming transfers still fail immediately.

Speculation: mode-changing by ttpkt(), ttvt(), ttres(), etc, result in data
loss and therefore in loss of encryption sync.  No, they don't actually do
anything except turn Nagle on and off.

Added Nagle restoration code to ttres().  ckutio.c, 8 Mar 98.  (This made
no difference.)

Looking at the (huge) debug logs, now I see that there were lots of NAKs
after all, but they did not show up in the file-transfer display or statistics
(why?)  Sometimes the delay between packets was as much as 70 seconds.

OK, now I see the problem.  ttinl() reads the first data packet.  It is
decrypted correctly.  ttinl() recognizes the beginning, the length field, and
the end.  Then it gets to its CR-removal stage and says: "ttinl removed=13"
(good), "ttinl removed=0" (good), "ttinl removed=1" <-- uh oh, the SOH of the
next packet.  And then proceeds to discard the entire next packet.  Problem:
the lookahead test for the packet-start character was performed by peeking
into the encrypted buffer.  Solution: decrypt each character first, then test
it.  But oops, now we've already read it.  So resurrect the old myunrd()
function to push it back.  But oops, that doesn't work either, because when
we go to read it again, we decrypt it again.  So instead we add a special
variable for saving and restoring a pushed-back ttinl() character, to know
not to decrypt it again when fetching it.  ttinl(), ckutio.c, 8 Mar 98.

So now we have my favorite situation: file transfers work perfectly in both
directions when the debug log is on, and fail miserably when it's off.  So
let's turn on streaming, which always fails, to catch an error in the log.
Nope, streaming works now too.  But when debugging is off sending to a server
still takes a long time to start and then hangs forever after sending the B
packet.

So I checked all calls to ck_krb_encrypt() in ckutio.c.  It is only called in
two places, ttol() and ttoc().  In neither place can it possibly encrypt
something that was already encrypted.  So the culprit must be ck_krb_decrypt().
But all calls to that look right too.

Since the problems occur most frequently at the beginning or end of a file
transfer, ttflui() is the next suspect.  And dummying out ttflui() does,
indeed, make the problems completely disappear.  OK, but why?  Aha, an
off-by-one error in the clever reference to the mybuf address (the buffer
index is pre-, not post-incremented).  Fixed in ttflux(), ckutio.c, 8 Mar 98.

So now it all works.  Some tests:

 . Client/server works fine -- send/get, etc.
 . Streaming works fine.
 . Ditto for both when transferring a gzip'd file no prefixing, provided
   we SET FLOW NONE on the far end (!) (I need to address this in any case...)
 . Autodownload, APC work fine.
 . Scripts work, including the CLEAR command.
 . Encrypted transfers go at about 55Kcps on localhost connection,
   versus unencrypted transfers at about 106Kcps.
 . CONNECT mode is noticeably slower on long scrolling displays:
   ripple test is 24 seconds encrypted vs about 9 sec unencrypted.
   This is due to the combination of decryption overhead and character-
   at-a-time i/o.

However, attempts to make a new connection occasionally fail -- authentication
works, CONNECT works, etc, but encryption is evidently starting out wrong
because we just get a blank screen and frozen keyboard -- can't even escape
back.  Speculation: the encryption state is carried across sessions?  So if
something winds up not being encrypted or decrypted at the end of session <n>,
then session <n>+1 will never get off the ground.  I tried calling ttflui()
from ttclos() -- and not sending Telnet DO LOGOUT -- if it's an encrypted
connection.  This seems to alleviate the problem in most cases; now I can
reproduce only it by starting a server on the remote end and sending it a BYE.
All seems normal -- the client gets the ACK to the BYE, the server side logs
out, but the next encrypted connection attempt always fails.  I tried putting
an msleep(500) in the server code after sending the ACK() to the BYE and
before calling ttres() or zkself(), but it didn't change anything.  There
probably needs to be some kind of Kerberos call when C-Kermit exits or when
it logs itself out, to reset Kerberos to some known state.

Hmmm -- here's another way to make it always happen: use "set host" and
"connect" instead of "telnet".  The debug log shows that everything is working
correctly -- all the Telnet negotiations are correct -- authentication,
encryption, etc.  Then the host sends us its banner and greeting and we sit in
myfillbuf() stuck in a read() waiting for the prompt, but it never comes...

Ha, got it.  Yesterday I decided to use "me_auth" as the variable to decide
whether encryption was possible.  If me_auth was set, then the CONNECT module
did all reads by calling ttinc(), otherwise it was free to call ttxin().  But
this was not a good choice -- the log shows we called ttxin() before me_auth
was set, but ttxin() read too much.  So backing off that choice (a) makes
everything work, but (b) means that there is no way to use the faster code on
non-Kerberized connections.  I also backed off the changes to netclos();
everything works fine now without them.  ckcget(), ckucon.c, 8 Mar 98.

Removed some verbose debugging statements from file-transfer buffer management
code, since this code has been stable for six years.  ckcfn3.c, 8 Mar 98.

Improved F000 debug format to allow omission of s2.  ckuusx.c, 8 Mar 98.

Renamed the new ckucon.c to ckucns.c (UNIX CONNECT with select()) and changed
the makefile to reference it only for Kerberos builds.  Restored the original
ckucon.c for non-Kerberos builds.  It would have been better to combine them,
but the structures are radically different.  So this task is tabled until and
unless it becomes an issue with real users.  ckucon.c, ckucns.c, makefile,
8 Mar 98.

Noticed the maximum number of macros was only 256.  Increased this to 4K for
BIGBUFOK builds.  ckuusr.h, 8 Mar 98.

A user reported that "remote who > file" did not work.  The actual problem was
that redirection was never implemented for short-form REMOTE command replies.
Note: this was a bit tricky because a line terminator needed to be added to
the end -- it's too hard to explain, but it required adding a new character
output function zputfil(), that does exactly what putfil() does, but that has
a different name.  To see why, look for references to "putfil" in decode().
Fixed in ckcpro.w, ckcker.h, ckcfns.c, 10 Mar 98.

Merged Jeff's changes for "set net type { command, dll, ssh }" - K95 only for
now.  Note: I had to make a change to krbtel.c to indicate that Kerberos 4 was
*not* available in UNIX.  11 Mar 98.

Fixed up status messages in netopen().  ckcnet.c, 12 Mar 98.

Added code to allow the Kerberized version of C-Kermit to use block i/o on a
non-authenticated connection, so that the 99% of people who are not using
authentication or encryption won't be penalized because it is supported in the
binary.  ckutio.c, ckucns.c, 12 Mar 98.

Started to try to separate input and output communications file descriptors.
Eventually I gave up -- I don't think there's a prayer of doing this, at least
not in UNIX, when you look at all the manipulations we do on them -- hundreds
and hundreds of ioctl's (fcntl's, tcsattr's, etc) to change modes, duplicate
them, close/open them, etc etc.  Doing all this to *two* file descriptors in
lockstep without having to worry about which operations are legal on input vs
output descriptors in which releases of which OS's, not to mention opening up
timing windows or tickling peculariarities in underlying drivers or kernels,
is too much to expect.  12 Mar 98.

Added support for net i/o from lower fork thru pipes within #ifdef NETCMD:

 . ttopen() starts the command & opens the pipes, sets ttpipe flag.
 . ttclos() kills fork if active, closes pipes if open, unsets flag.
 . tthang() calls ttclos() if flag set.

 . ttvt/ttpkt/ttres: does nothing if flag is set.
 . ttsetflow(), tthflow() - ditto
 . ttsspd(), ttgspd() - ditto.
 . ttsnd[l]b() -- send a NUL if flag set.
 . ttgmdm() -- returns -1 if flag set.

 . myfillbuf(), ttxin(), ttinl(), ttinc() -- read from pipe if flag set.
 . ttol(), ttoc() -- write to pipe if flag set.
 . ttchk() - checks pipe if flag set.

 . ttlock() & friends are never called.
 . ttpeek, ttpushback, ttflux... - unaffected.

ckutio.c, ckucon.c, ckucns.c, ckuus5.c, 13 Mar 98.

Builds and works OK with NETCMD not defined.
Compiles OK (on SunOS) with NETCMD defined.
Works OK on normal connections.
Works OK on pipe connections:
 . Makes the connection.
 . CONNECT mode works right, no buffering delays, and it's fast.
 . File transfer works too, but rather slowly in the sending direction.
 . ttchk() always returns 0 on SunOS -- evidently FIONREAD doesn't work
   on pipes.  Slows down sliding-window sends.  I'll need to do something
   about this later.

Disabled if NOPUSH defined or nopush set.  ckcdeb.h, ckuus3.c, 13 Mar 98.

Added a brief preliminary section (2.7) on this to ckermit2.upd, but it needs
a lot of fleshing out with examples of ssh, ssl, etc.

Still need to make the command structure nicer.  SET NETWORK TYPE COMMAND
followed by SET HOST <command> is OK, but afterwards the network type is still
set to COMMAND, and so subsequent SET HOST commands probably won't work as
most people expect them to.  So I think it might be better to collapse this
into a PIPE command that combines the two, but does not affect the global
network type.  PIPE would be the general case, SSH could be a specific case
(with accompanying SET SSH command for configuration, etc).  None of this
is done yet.

Also, note that this feature has nothing to do with networks, yet it's only
available #ifdef NETCONN.  So this should be changed too.  Next week...

Got tired of wraparound during "make sunos.." so moved the common symbol
definitions from the makefile to ckcdeb.h.  13 Mar 98.

Got rid of the duplicate SET NETWORK keyword tables so now we only need to
add new network-type keywords in one place rather than two.  ckuus[r3].c,
13 Mar 98.

Jeff discovered that binary-mode transfers with space parity didn't work any
more.  Fixed by making receipt of a request to do 8th bit prefixing when
parity is none *and* no parity has been detected cause the parity to be
switched to space.  ckcfn[s2].c, 16 Mar 98.

Various changes for BeBox, SRP, etc, and other updates from Jeff, including
a fix for "wait 0 <signal>" not bothering to test for signal.  Many modules,
18 Mar 98.

Discovered that SET HOST did not parse switches for certain network types,
e.g. COMMAND.  Rearranged setlin() again so switches would be always be parsed
for SET HOST and SET PORT (LINE), removing about 200 lines of code in the
process.  Needs lots of testing.  ckuus7.c, 18 Mar 98.

Added SET HOST /COMMAND.  This takes the place of SET NETWORK TYPE COMMAND
followed by SET HOST <name-of-command>, but in this case the network type is
not sticky (normal behavior for switches).  Thus, for example, you can:

  set host /command rlogin hosta

and then later "set host hostb", and it will work, using the previous global
network type (usually TCP/IP).  ckuusr.h, ckuus7.c, 18 Mar 98.

Added the PIPE command, equivalent to SET HOST /COMMAND /CONNECT.  ckuusr.h,
ckuusr.c, 18 Mar 98.

Changed cmfdb() to return -9 and print a message if it was about to return -6,
which should be internal to cmfdb().  ckucmd.c, 19 Mar 98.

Changed cmkey() to return -3 as it should if the user types CR and no other
characters were given and there was no default.  ckucmd.c, 19 Mar 98.

Fix from Jeff to SET TERM KEY <type> <CR>.  ckuus7.c, 19 Mar 98.

Added REMOTE SET FILE INCOMPLETE.  Previously this was available only as
REMOTE SET INCOMPLETE, now demoted to invisibility.  ckuus[37].c, 19 Mar 98.

Added -DNOCOTFMC to Linux makefile entries at the suggestion of Paul Kimoto.
Details in the Linux section of ckuker.bwr.  makefile, 19 Mar 98.

Added NOCOTFMC display to SHOW FEATURES.  ckuus5.c, 19 Mar 98.

Big revisions/updates to ckuker.bwr for Linux & elsewhere.  19 Mar 98.

Fixes from Jeff to parsing of Telnet authentication/etc negotiations.
ckcnet.c, 19 Mar 98.

In UNIX, "send /recursive foo" (foo not wild) did not work; it only sent the
foo file from the current directory, but then did not recurse.  Furthermore,
if no foo file was in the current directory, nothing was transferred, even if
one or more foo's were in subdirectories,   Fixed in traverse(), ckufio.c,
19 Mar 98.  (Needs more testing, though...)

Minor changes from Jeff to ckcnet.c.  20 Mar 98.

Added missing mention of /RECURSIVE in HELP GET.  ckuus2.c, 21 Mar 98.

Discovered that not defining USE_MEMCPY on platforms where we pick up
prototypes for memcpy() from the header files (like string.h on the NeXT)
causes ANSI compilations to bomb.  Added USE_MEMCPY for NeXT, OSF/1, VMS,
AOS/VS.  ckcdeb.h, 21-22 Mar 98.

Moved the -Dblah CFLAGS that were common to all the Solaris makefile entries
to ckcdeb.h, similar to what was done for SunOS a few days ago.  ckcdeb.h,
21 Mar 98.

Added new "xermit" target to UNIX makefile.  It's just like "wermit", but
uses ckucns (select() version of CONNECT module) rather than ckucon (fork()
version).  Changed sunos41 entry to use xermit target, tested it on serial,
TCP/IP, and pipe connections, works fine.  Tried it in several other places:

 Entry      Telnet   Serial    Pipe
  sunos41     OK       OK       OK
  hpux100     OK       OK       OK
  linux       OK       ??       OK
  solaris25   OK       ??       OK (but rlogin prints scary messages)

Left xermit in for SunOS, left the others as is.  makefile, 21 Mar 98.

Fixed a problem in ttinc(), timed MYREAD case, when it gets a NUL character
(as it would during rlogin initial connection) -- test for error was off by 1.
Diagnosed by Jeff.  21 Mar 98.

Discovered that \v(errstring) evaluation in nvlook() was returning a pointer
to an automatic array, oops.  Made it static.  ckuus4.c, 22 Mar 98.

Added \v(osrelease).  ckuusr.h, ckuus4.c, 22 Mar 98.

Changed \v(osname) to return the same as \v(platform) if CK_UTSNAME not
defined.  ckuus4.c, 22 Mar 98.

Changed sinix542 makefile target to not optimize ckcpro.c, since this was
taking several hours before I interrupted it...  makefile, 22 Mar 98.

--- Beta.02 ---

successful "xermit" tests:

  sunos 4.1
  unixware 1.1.2
  hpux 10.20

Minor changes to prototypes, etc.  ckuus[7x].c, ckcnet.h, ckcdeb.h,
24 Mar 98.

Added SET HOST /PASSWORD:.  ckuusr.h, ckuus[r37x].c, 24 Mar 98.

Authentication material from Jeff. ckuus[347].c, ckutio.c, ckcnet.c, 25 Mar 98.

Added better ?-help message for SET TELNET ENCRYPTION.  ckuus3.c, 25 Mar 98.

Folded lines > 79 and removed trailing blanks from ckuath.c.  25 Mar 98.

Changed definitions of CX_xxx encryption types to use the ENCTYPE_xxx_xxx
ones if they are defined.  However, there is no ENCTYPE_blah for NONE, and we
can't use negative numbers for keyword values, so I chose 999.  ckcnet.h,
25 Mar 98.

Removed various unportable constructions from ck_crp.c.  25 Mar 98.

Changed SET TELNET ENCRYPTION TYPE to get its keyword table dynamically.
ckuus3.c, 25 Mar 98.

....

Added checking of LINES and COLUMNS to ttgwsiz() if ioctl() fails.  ckutio.c,
25 Mar 98.

Added dgux54411i entry to makefile.  3 Apr 98.

Merged Jeff's changes, mostly a&e, plus: some updated help text, crypto
material in SHOW TELNET; moved "Server done" message until after all files are
closed to prevent overwriting of messages.  Also, fix one more "Transfer OK"
test in clsif() that could result in spurious OK result when not OK.  Many
modules, 3 Apr 98.

Removed the hidden TEST command so people can define macros called TEST as
shown in various docs.  ckuusr.c, 3 Apr 98.

Changed SET TELNET ENVIRONMENT DISP to DISPLAY (spelled out) to agree with
docs.  ckuus3.c, 3 Apr 98.

SHOW NET display was too long.  Gave it the askmore() treatment.  This was a
big job, since it calls a lot of subfunctions.  This askmore() business really
needs to be reworked.  We need a *portable* printf() replacement that takes
screen dimenensions into account.  Either that, or one that pipes its output
into an external program (like "more") (but that would not be portable) (but
UNIX users would still like it -- plus then you could redirect output of any
command to a file, etc).  ckuus[45].c, 4 Apr 98.

Changed ttopen() to not print "DNS lookup..." if it is not doing a DNS lookup.
ckcnet.c, 4 Apr 98.  But it almost always does, so this makes little
difference.

Added TERMINAL as a synonym for SET TERMINAL TYPE.  Familiar to UNIX users,
etc.  ckuusr.[ch], ckuus7.c, 4 Apr 98.

Added STATUS as a synonym for SHOW STATUS.  ckuusr.[ch], 4 Apr 98.

Added a second "personality" to the C-Kermit command line.  If C-Kermit is
stored as telnet (or telnet.exe), it parses a Telnet command line:

  telnet [ host [ port ] ]

I didn't bother with rlogin.  This works with the C-Kermit networks directory.
ckcmai.c, ckuus[4y].c, ckermit.ini, 4 Apr 98.

Added \v(name), the name with which the program was invoked.  Used this to
bypass non-Telnet material in the initialization file for faster startup
(since we don't have options on the Telnet command line, e.g. to bypass the
initialization file).  ckuusr.h, ckuus4.c, ckermit.ini, 4 Apr 98.

Noticed that "telnet watsun 13" (i.e. to the "daytime" socket) has started to
misbehave again.  First, ttopen() is called two or three times for some
reason.  Second, ttvt() fails because the other side has already closed itself
before we can get around to reading the daytime string.  I thought I fixed
this a long time ago.  It needed more fixing.  In ckucon.c, the section that
handles ttvt() failures by hanging, closing, and reopening the connection
makes no sense at all for network connections, so now it is used only if
(!network).  Second, a loop-exit test was missing in the new CONNECT module.
ckucon.c, ckucns.c, 4 Apr 98.  NOTE: K95 has the same problem, needs checking.

Added ON and OFF as invisible synonyms for DISABLED and ENABLED in nabltab[],
since the book has some examples like this that wouldn't work otherwise.
ckuus7.c, 4 Apr 98.

Added command-line switch -0, meaning "be 100% transparent in CONNECT mode".
This is equivalant to a bunch of other commands, like eightbit, set flow none,
set term escape disabled, set term char transparent, set term autodownload
off, set term apc off, etc.  It probably could use some work.  Setting the
flow control to none might be a bit extreme, but currently there is no way to
say "don't allow software flow control, but do allow any kind of hardware
flow control."  ckuusy.c, 4 Apr 98.  Note: I did not add an interactive
command to do the same thing since that would beg the question of how to undo
it, which would not necessarily be easy.

Noticed that a quoted hyphen or opening brace at the end of a line was still
taken as a continuation character, which shouldn't happen; \- should mean
to take the dash literally.  Fixed in getnct() and in gtword().  Ran all the
demo & hostmode scripts to make sure this didn't break anything.  ckcuus5.c,
ckucmd.c, 4 Apr 98.

Noticed that "echo foo - ; comment", when given at the prompt, did not treat
the "-" as a continuation character.  Fixed in gtword(), ckucmd.c, 4 Apr 98.

Got rid of SET HOST /PASSWORD: since it can't work.  ckuus7.c, 4 Apr 98.

PIPE connections worked only once; subsequent ones would not work.  Nor
would (say) CONNECT to a closed pipe connection.  Fixed in ttclos(), ckutio.c,
4 Apr 98 (Don't set ttpipe to 0 -- leave it alone).

Added utsname info for VMS, obtained by assorted $GETSYI() calls.  Also added
a new variable, \v(model), which returns the CPU model.  Works only for VMS,
returns null string elsewhere.  Note: K95 will need to define a unm_mod[]
buffer for this, and either fill it in or set it to the null string.
ckuusr.h, ckuus4.c, ck[uv]tio.c, 5 Apr 98.

Added utsname info to SHOW FEATURES.  ckuus5.c, 5 Apr 98.

Added Stanford copyright to main copyright notice shown by VERSION command
if SRP included.  ckcmai.c, 5 Apr 98.

In Beta.02, routine tn_sb() broke the HP-UX 7.0 optimizer.  Changed all HP-UX
7.0 entries to not optimize ckcnet.c.  makefile, 5 Apr 98.

I had a report that \v(filename) did not work when sending, but I don't see
a problem, in either remote or local mode.

C-Kermit or K95 server failed to send any files when sent "GET *" -- oops.  It
looks like something I broke when adding /CALIBRATE back in October; I wonder
why nobody noticed until Jeff did a couple days ago.  Good thing we actually
use this software ourselves...  Fixed in fnlist(), ckcfns.c, 5 Apr 98.

If C-Kermit was sending a file and the transfer was interrupted with Ctrl-C,
then a subsequent SEND or RESEND would fail to update the Estimated Time Left
and Transfer Rate fields of the fullscreen file transfer display because the
time variables were not reset by the Ctrl-C handler.  Fixed in ftreset(),
ckuusx.c, 5 Apr 98.

Changed -I switch to also "set flow none" (except on VMS), since not doing so
makes for Xoff deadlocks.  This is a bit risky, but I think it's less risky
than not doing it.  ckuusy.c, 5 Apr 98.

Added 877 and 866 to list of toll-free area codes for the NANP.  877 goes live
today; 866 is next, probably within a year or two.  ckuus3.c, 5 Apr 98.

If the connection is lost during file transfer, the file-transfer display
message "FAILED: Connection lost" is properly displayed, but then immediately
overwritten by "Transfer interrupted", a less specific reason.  This was
because we never sent an Error packet, since there was no longer a connection
to send it on.  Fixed by pretending to send an E packet by setting epktsent=1
in spack() when it prints the "FAILED: Connection lost" message, to prevent
clsif() from printing any subsequent messages, and copying the "Connection
lost" message to the file-transfer error message buffer so it could be
accessed afterwards by \v(xfermsg).  ckcfn[23].c, 5 Apr 98.

Remove OLD_VMS #includes for GFTIMER; they didn't work, and we're not using
GFTIMER in OLD_VMS anyway.  From Lucas Hart.  ckvtio.c, 5 Apr 98.

Various last-minute adjustments to copyright notices, etc.  ckcmai.c,
ckuus5.c, 6 Apr 98.

Addition of SRP-related makefile entries for Linux.  makefile, 6 Apr 98.

Add ".hex" and ".hqx" as text file types.  ckcmai.c, 6 Apr 98.

---1.1.16--- (8 Apr 98)

Add -DKANJI for Linux ifndef NOCSETS.  ckcdeb.h, 10 Apr 98.

Fixed "Closing..." message (and call to ttclos()) in doexit() to make the
ttyfd != -1 test only #ifdef OS2 (not OS2ORUNIX).  Otherwise this path is
always taken in UNIX.  ckuusx.c, 10 Apr 98.

Suppose C-Kermit is sitting at its prompt and receives the command "kermit -x".
This almost certainly is the "autoserver" string from K95, or another copy of
C-Kermit.  The user has given a GET or REMOTE command without first putting
C-Kermit in server mode.  So far so good; the "kermit -x" command does the
trick.  But then after the transaction is finished, C-Kermit stays in server
mode, so when the user CONNECTs back, s/he gets "a blue screen".  Solution:
any protocol actions resulting from "kermit" commands at the prompt set the
justone flag, which tells the protocol to exit after just one transaction.
This way they get the command prompt back, as expected.  ckuusr.c, 10 Apr 98.

Put doftp() and doping() in #ifndef NOPUSH..#endif.  ckuusr.c, 10 Apr 98.

Allow for longer debug messages for tracking authentication problems.
ckuusx.c, 11 Apr 98.

Updated sv68r3v6 and sv88r40 makefile entries from Gerry Belanger at
Cognitronics, since GFTIMER broke both of them, and REDIRECT broke the
former.  makefile, 11 Apr 98.

Merged in Jeff's recent changes, mainly (1) addition of XMODEM-CRC as a
protocol type, and (2) make sure INPUT sets \v(instatus) correctly upon
failure due to lost connection.  Also, remove auto-upload strings for XMODEM
and YMODEM because their echoes cause confusion about the checksum type, etc,
e.g. if the filename contains an uppercase C.  Many modules, 17 Apr 98.

Merged IBM AIX X.25 support from Stephen Riehm, pc-plus, in Germany.  Most
modules.  18 Apr 98.  This still needs to be tested to ensure it didn't break
anything, especially Sun X.25, and to document it.

Added support for ttylock()/ttylocked()/ttyunlock() via #ifdef USETTYLOCK,
which is defined in ckcdeb.h for IBM AIX 3.1 and later.  This is supposed to
prevent confusion about the name, location, contents, and format of the UUCP
lockfile.  ckcdeb.h, ckutio.c, ckuus5.c, 19 Apr 98.

Built on an AIX 4.1 system; it compiles and links without complaint, but I
can't test it because that system has no serial devices.  20 Apr 98.

SET HOST commands weren't making it into the command recall buffer.  Fixed
(I think -- at least I can't make it happen any more) in setlin(), ckuus7.c,
20 Apr 98.

Changed ttopen() to always call perror() to print error message when open()
fails.  Also added perror() calls to ttunlck() to give informative messages
upon failure to delete lockfiles.  ckutio.c, 21 Apr 98.

"help ?" incorrectly said "Or the name of a macro..." at the end of the
keyword list.  Fixed in ckucmd.c, 21 Apr 98.

Changed ttrpid() to not depend on hardwired definition for format of lockfile,
but rather to check its size and then treat it as binary if 4 bytes or less,
and as a string if longer than 4 bytes.  Tested successfully with string pids.
ckutio.c, 21 Apr 98.

Changed ttunlck() to not try to remove the lockfile if the pid it contains is
not ours, e.g. in case some other process has seized control of the device.
ckutio.c, 21 Apr 98.

Added a couple checks against dereferencing NULL data pointer, which can
evidently happen if C-Kermit is started with the -J command-line option and
then Ctrl-C'd at a certain critical point.  ckcfns.c, 21 Apr 98.

Added code to make INPUT 0 xxx behave as advertised: it should check the
only the characters that have arrived but have not yet been read for the
search string, and succeed or fail immediately depending on whether a match
was found.  ckuus4.c, 21 Apr 98.

Added 877 and 866 to default list of toll-free area codes for country code 1
(again -- I did this before, but in the wrong place).  ckudia.c, 22 Apr 98.

Discovered that an optimization I added to ckucns.c to avoid unnecessary calls
to chkaes() was bad -- symptom: as soon as the first escape sequence was
received, C-Kermit would send an ESC to the terminal before each character
from then on.  Removed the optimizations, went back to calling chkaes() for
every incoming character.  ckucns.c, 23 Apr 98.

Got rid of some confusing and dangerous ifdefs in VMS sysinit(); now we get
the hardware & OS version consistently on VAX and Alpha.  ckvtio.c, 23 Apr 98.

Fixed various bad declarations.  ckuus5.c, ...

Added OSF/1 and SCO 3.2v5.04 to the systems where CK_UTSNAME can be safely
defined.  ckcdeb.h, 23 Apr 98.  (Also tried NeXT, but it's not allowed.)

---Beta.03---

Removed an unreachable return() statement from the end of tn_doop().
Jeff, ckcnet.c,1 May 98.

Fixed \fsplit() return value -- it was counting too many words.
Jeff, ckuus4.c, 1 May 98.

Fixed broken SET TERMINAL ESCAPE option synonyms.  Jeff, ckuus7.c, 1 May 98.

Added -DNOGFTIMER to hpux90mot (HP-UX 9.0 on Motorola 680x0), since this
evidently doesn't work.  If somebody wants to try fixing it, be my guest.
makefile, 2 May 98.

Changed Elapsed Time display in STATISTICS command to show hh:mm:ss as well
as the total number of seconds.  ckuus4.c, 2 May 98.

Added \v(model) for HP-UX, works by running the HP-UX "model" command and
capturing its output into a cache (there is no API for this); subsequent
references read from the cache.  ckuus4.c, 2 May 98.

Moved the NEEDSELECTDEFS section from ckcnet.h to ckcdeb.h to allow non-TCP
builds to get these definitions, e.g. when needed for the new select()-based
CONNECT module.  This was necessary at least for HP-UX 6.5.  Added hpux65x
target for HP-UX 6.5 that specifies the xermit target and includes
-DNEEDSELECTDEFS.  ckcnet.h, ckcdeb.h, makefile, 2 May 98.

Peter E reported that Beta.03 no longer removed its lockfiles in HP-UX.  Since
my HP workstation drowned in the recent flood, I could not check this myself;
it doesn't happen on non-HP platforms, but they use different code.  I went
through the code, consolidated the HP and non-HP parts as much as possible,
added debugging statements, corrected some errors, and satisfied myself that
it works fine on non-HP platforms:

 . If the device is not in use, the appropriate lockfile is created and
   then destroyed when it is closed.

 . If the device is in use by an active process (Kermit or cu), Kermit refuses
   to open it, and displays the pid of the owning process.

 . If there is a lockfile for the device, but it contains a pid that does
   not correspond to an active process, C-Kermit removes the stale lockfile
   (printing a message) and opens the device.

Later I found an HP-UX 10.20 workstation that had an unprotected serial port
and lockfile directory -- all the above tests worked fine, except that cu was
not installed so I could only verify that Kermit interlocked with itself, and
that 4-byte integer pids were written and read OK.  ckutio.c, 2 May 98.

Made "x" a legal abbreviation for "xmodem" in "set protocol" (because of
"xmodem-crc".  ckuus3.c, 2 May 98.

Discovered that the code to check that RECEIVE was given an as-name for
XMODEM protocol was not in the right place.  Moved it.  ckuus6.c, 2 May 98.

The following sequence did not work with XMODEM:

  define \%a foo
  set protocol xmodem
  receive \%a

Fixed in doxget(), ckuus6.c, 2 May 98.

I broke SunLink X.25 compilation in Beta.03.  Fixed in ckuus4.c, 2 May 98.

PIPE command didn't allow its argument to be braced.  Fixed in setlin(),
ckuus7.c, 3 May 98.

Plugged a couple of out-of-bounds array references noticed by DEC C 5.7 and
reported by John Santos.  ckv[tf]io.c, 3 May 98.

Added #ifdefs to [rg]ftimer() for System V/88 on Motorola 88000 from Gerry
Belanger at Cognitronics.  ckutio.c, 3 May 98.

---Beta.04---

Ric Anderson reported a place where ttchkpid() could exit without returning
a value.  Fixed in ckutio.c, 4 May 98.

Finally discovered the cause of persistent reports that uucp lockfiles were
not being removed: a test of ttchk()'s return value in doclean() would fail if
the line had never been used, and so ttclos() would not be called, which was
just plain wrong: "set line /dev/xxx, exit" would leave the lockfile behind.
(Thanks to Peter Eichhorn for narrowing down how to reproduce it.)
ckuusx.c, 4 May 98.

In tracking down the previous problem, I discovered the following: in HP-UX,
if the "set line" device name starts with "cu", we also create a lockfile for
the corresponding "ttyd" device, even if that device does not exist.  This is
normally OK, since both lockiles are removed by ttunlck().  However, when a
stale "cu"... lockfile is found (and removed), C-Kermit did not remove the
corresponding "ttyd"... lockfile if the ttyd device did not exist.  So I
changed ttlock() to create the ttyd lockfile only if the ttyd device exists.
ckutio.c, 4 May 98.

Fixed a reference to an uninitialized variable in ttopen(), detected by DECC
5.8.  ckutio.c, 4 May 98.

Filled in \v(model) for Digital UNIX on advice from DEC, and added a symbol,
OSF50, and a designer banner for Digital UNIX 5.0, which will be released
soon.  ckcdeb.h, ckuver.h, ckuus4.c, makefile, 4 May 98.

Fixed \v(model) to return value of unm_mch[] in preference to nothing at all.
ckuus4.c, 4 May 98.

Removed -DNOGFTIMER from hpux90mot entry, since reportedly Beta.04 works fine
there.  makefile, 4 May 98.

Omitted listing of unm_mod at beginning of debug log if not filled in, which
it won't be except in VMS or if \v(model) has previously been referenced.
ckuus4.c, 4 May 98.

Updated AOS/VS text & binary filetype list.  ckcmai.c, 4 May 98.

Put an unguarded reference to "nopush" within #ifdef NOPUSH..#endif.
setlin(), ckuus7.c, 4 May 98.

Moved zxcmd() and zclosf() inside of #ifdef NOPUSH..#endif

syscmd() was not properly #ifdef'd for NOPUSH.  Fixed in ckcfns.c, 4 May 98.

Ditto for zshcmd().  ckufio.c, 4 May 98.

References to doftp() and doping() were not ifdef'd for NOPUSH.  Fixed in
ckuusr.c, 4 May 98.

Added a new compile-time option, NOTIMESTAMP, to disable all code related
to file timestamps, and employed it accordingly in ckufio.c.  4 May 98.

Added a banner for the AS/400 to ckuver.h.  You never know...  4 May 98.

Fix for hpux90mot makefile entry from Peter E.  makefile, 5 May 98.

Commented out "Alias => xxx" display.  ttopen(), ckcnet.c, 5 May 98.

Various #ifdef fiddling for AT&T 3Bx's.  cku[tf]io.c, ckcdeb.h, 5 May 98.

Final corrected makefile entries for AT&T 7300 that work, with help from
Peter Mauzey at Bell Labs.  makefile, 6 May 98.

Added banners for Ultrix 4.3, 4.4, 4.5.  ckuver.h, 6 May 98.

Made new SET MODEM TYPE keywords for USR and Megahertz that more obviously
correspond with the actual models, via synonyms, invisible abbreviations, etc,
without invalidating previous names.  ckudia.c, 7 May 98.

Made SET / SHOW { STREAMING, RELIABLE, CLEARCHANNEL } visible keywords.
ckuusr.c, 7 May 98.

Improved HELP SET [ TERMINAL ] ESCAPE messages.  ckuus2.c, 7 May 98.

VMS fixes from Lucas Hart, 7 May 98:

 . More allowances for <xxx> directory-name format: ckcfn3.c.
 . Improvements in hardware-name getting: ckvtio.c.
 . Enabling reverse DNS lookup for UCX (but not old UCX): ckcnet.c.
 . Improved isdir(), relative directories for labeled transfers,
   Fortran CC handling fixed to handle 0-length records and overprinting,
   etc: ckvfio.c.

Made MKDIR print a message (but still succeed) if it is told to create a
directory that already exists.  ckuusr.c, 7 May 98.

Added cross-references to SHOW PROTOCOL.  ckuus4.c, 7 May 98.

Added missing switches to HELP SEND text, plus cross-refs, and fixed text
for SEND /PATHNAMES:xxx.  ckuus2.c, 7 May 98.

UNIX nzltor() was correctly stripping ./ or ../ from the beginning of a local
filename before sending it to the remote, but only the first occurrence.
Fixed it to strip all occurrences from the beginning of the pathname.
ckufio.c, 7 May 98.

---Beta.05---

Added some minor source-code corrections to ckucon.c and ckcnet.c affecting
only IBM AIXLink/X.25 builds, from Stephen Riehm.  15 May 98.

From Jeff:

 . Don't always set success for REMOTE commands that get a short form reply.
 . Increase atom buffer length.
 . Minor correction to UNIX ttol() when encrypting.
 . Prevent spurious parse errors from cmnum() within cmfdb().
 . Added zgetfs() to get a file's size (regardless of accessibility).
 . Make \v(return) show END <n> value.
 . Fix \fsplit() not to skip final word.
 . Fix mixup with RESEND/REGET versus filename patterns.
 . Corrections to (REMOTE) DIRECTORY command using zgetfs().
 . Fixes to LOOKUP, DIAL, and PDIAL.
 . Various networking fixes regarding blocking/select/etc vs streaming.
 . New SHOW TERM command for K95.

Added \fcvtdate(date) to convert free-format date and/or time to standard
format.  This required pulling conversion code out of cmdate() into a separate
routine.  ckuusr.h, ckuus4.c, ckucmd.c, 11 Jun 98.

Added zjdate() for UNIX, returns julian date yyyyddd.  ckufio.c, 11 Jun 98.
Needs to be added for K95, VMS, AOS/VS, ...  In UNIX we get it simply by
calling localtime().  ZJDATE is defined in ckcdeb.h for each platform that
has this feature (so far just UNIX).  (Note: we could also do this in a system
independent way, algorithmically -- maybe later.)

Added \fjdate(date), prints Julian date from given free-format date, or for
today if no arg.  Within #ifdef ZJDATE.  ckuusr.h, ckuus4.c, ckucmd.c,
11 Jun 98.

Added ckdate() to return the current date/time in standard yyyymmdd_hh:mm:ss
format.  This now supplies the defaults for the new date functions (when
called with no arg) and for the DATE command (next item).  ckuus4.c, 12 Jun 98.

Changed DATE command to take an optional free-format date/time argument, and
then convert it to standard format and print it.  This provides a quick
pre-check on date formats.  ckuusr.c, ckucmd.c, 12 Jun 98.

Added help text for the new functions and DATE command.  ckuus2.c, 12 Jun 98.

Removed extraneous \n from end of all hmsg() calls, which were causing
unnecessary double blank lines.  ckuus2.c, 12 Jun 98.

Fixed att3bxc makefile entry to spell NONAWS right.  makefile, 12 Jun 98.

Added brace-stripping to SET TERM IDLE-SEND.  ckuus7.c, 12 Jun 98.

Changed STATISTICS to round hh:mm:ss to nearest second when floating point
is used.  ckuus4.c, 12 Jun 98.

Same deal for Elapsed time in the file transfer display.  ckuusx.c, 12 Jun 98.

Added "*.doc" to binary patterns -- Microsoft wins.  It's better to transfer
a plain-text doc file in binary mode than to transfer a Word document in text
mode (except with IBM mainframes!).  Users can, of course, always change this.
ckcmai.c, 12 Jun 98.

Suppose "oof*" matches one filename, which happens to be a directory (say,
"oofa").  Then "cd oof*" would fail, but would print "oofa - not a directory",
even though "oofa" is a directory.  Fixed in cmifi2() by making a last-minute
check for directoryness after calling zxpand.  ckucmd.c, 12 Jun 98.

A subtle problem, reported by Morten Knudsen in Norway:

  set count 4
  :back
  echo Jo!     ; (Norsk for Yo)
  input 1 OK
  xif fail { xif count { goto back } }

would keep going forever because COUNT was not being decremented.  Diagnosis:
since XIF is really a macro, it has its own COUNT variable on the stack.  When
the XIF was finished, the stack would be restored and the old COUNT would come
back -- thus it would never change.  Cure: Although XIF, FOR, WHILE, and SWITCH
are implemented as macros, this is supposed to be invisible to the user.  The
_GETARGS and _PUTARGS routines are used to fix up the stack before and after
use.  _PUTARGS, however, failed to restore the "stackable" variables: COUNT,
INPUT TIMEOUT, INPUT CASE, TAKE ERROR, and MACRO ERROR.  Fixed in dogta(),
ckuus6.c, 12 Jun 98.

So this fix takes care of:

  set count 6
  for \%i 1 3 1 { if count echo \v(count) }
  echo count = \v(count)

Previously it would say "count = 6" after exiting the loop; now it says
"count = 3".  However, it still does not fix Morten's script.  A further fault
was in GOTO, which takes an abnormal exit from XIF (and FOR, WHILE, and
SWITCH), thus bypassing their normal exit sequence (including the call to the
now-fixed dogta()).  So I added code to dogoto() to do the right thing when
called from within XIF, FOR, WHILE, or SWITCH.  ckuus6.c, 12 Jun 98.

Added three trivial commands useful in debugging scripts:

  ASSERT <condition> - Sets SUCCESS / FAILURE according to <condition>.
  FAIL               - Always fails (same as "assert false").
  SUCCEED            - Always succeeds (same as "assert true").

ckuusr.h, ckuusr.c, ckuus2.c, 12 Jun 98.

By popular demand, put a SIGHUP handler into the UNIX version, which simply
sets backgrd = 1, makes a debug log entry (if the debug log was open) and then
calls doexit(), which in turn flushes and closes all logs and other files
(shouldn't be necessary) and resets terminal modes, etc, and _exits.  Tested
by sending kill -1, works, seems harmless enough.  ckutio.c, 12 Jun 98.

When \f(r)index() was given a non-numeric start position, it printed the wrong
error message.  Fixed in ckuus4.c, 14 Jun 98.

Changed the LOOKUP command to accept phone numbers as well as directory entry
names.  If given a literal-format phone number, it gives it right back.  If
given a portable-format phone number, it converts it for dialing from the
current location and prints the result.  ckuus6.c, 14 Jun 98.

Added \fdialvalue(xxx) which returns the dial string that would actually be
used when given the phone number xxx.  ckuusr.h, ckuus4.c, 14 Jun 98.

Added \v(pdialsuffix) and \v(dialtype).  Didn't have time to test very much.
ckuusr.h, ckuus[46].c, 14 Jun 98.

Changed \v(pdialsuffix) to \v(dialsuffix) -- might as well set it for every
phone call.  Makes testing easier too.  ckuus4.c, 15 Jun 98.

Changed \fdialvalue() to \fdialconvert().  ckuus4.c, 15 Jun 98.

Cleaned up HELP FUNC messages for recent functions.  ckuus2.c, 15 Jun 98.

Renamed all text files to *.txt to fit Microsoft associations:

  ckermit2.upd => ckermit2.txt
  ckaaaa.hlp   => ckaaaa.txt
  ckc193.upd   => ckc193.txt
  ckuins.doc   => ckuins.txt
  ckvins.doc   => ckvins.txt
  ckermit.bwr  => ckcbwr.txt
  ckuker.bwr   => ckubwr.txt
  ckvker.bwr   => ckvbwr.txt
  ckcplm.doc   => ckcplm.txt
  ckccfg.doc   => ckccfg.txt

etc.  15 Jun 98.

There is no protocol for REGET /DELETE or REGET /RECURSIVE, yet these commands
can be given to the client.  Since no protocol is defined, the result is not
what the user expects.  For now, code has been added to prevent the client
from accepting these combinations.  Before allowing these combinations, I need
to do for the protocol what switches did for the command parser -- allow many
combinations of options, rather than inventing new top-level command words for
every conceivable combination.  The result will be an XGET (Extended GET)
packet that has distinct Options and Filespec fields.  doxget(), ckuus6.c,
15 Jun 98.

SEND /RECOVER (RESEND) refused to work if SET FILE TYPE was not BINARY.  But
this was unreasonable when FILE PATTERNS were ON, since the file to be sent
might well be recognized as binary when Kermit gets to it later.  So the
offending check was removed from doxsend().  ckuusr.c, 15 Jun 98.

REGET (GET /RECOVER) did the same thing.  Normally, the client's transfer mode
controls the server's.  But if the server is doing per-file text/binary mode
switching because of filename patterns or record formats, this takes
precedence, and in that case the command-time check prevents an operation that
would have worked otherwise.  BUT WE HAVE NO WAY OF KNOWING whether the server
will do automatic mode switching, do we?  So if our current transfer mode is
text, we can (a) automatically change it to binary, or (b) leave as text and
hope that the transfer will switch to binary when the partially transferred
file is encountered.  (a) is bad since it might allow a broken text-mode
transfer to be resumed in binary mode, thus corrupting the file.  (b) would be
bad if no other checks were made, but checks have been added in the protocol
to prevent recovery in text mode on a per-file basis (Jeff's changes from
above).  So the parse-time check is now omitted.  doxget(), ckuus6.c,
15 Jun 98.

Tested by having the server download part of a zip file, then telling it to:

  SET FILE PATTERNS OFF
  SET XFER MODE MANUAL
  SET FILE TYPE TEXT
  SERVER

and then telling the client to REGET the zip file.  The server says FAILURE:
Recovery attempted in TEXT mode: xxx, where xxx is the filename.

Somehow the recursive flag was getting stuck on in K95 when receiving files.
Changed ftreset() to always set recursive to 0, since this can never be a
global mode.  By the way, this had *all* sorts of odd effects, affecting the
DIRECTORY, DELETE, and many other file-oriented commands.  ckuusx.c, 15 Jun 98.

Changed ckdate() to return the same format as \fdate(), etc -- space between
date and time, rather than underscore.  ckuus4.c, 16 Jun 98.

Added .vxd to binary patterns.  ckcmai.c, 16 Jun 98.

Changed edit number from 193 to 194.  ckcmai.c, 18 Jun 98.

DIAL would no longer dial if given a phone number rather than a dialing
directory entry name, due to LOOKUP changes made on 14 June.  Fixed in
ckuus6.c, 20 Jun 98.

---1.1.17---

Changes from Jeff:
 . Fix for DATE bug
 . Various K95-specific bits
 . Upped edit numbers
 . IKS changes
 . ttinc() non-MYREAD Telnet case was returning the wrong character

Added \v(lockpid), UNIX only.  Contains the PID from the UUCP lockfile from
the most recent SET LINE command, if (a) the command failed because the line
was in use by another process, and (b) the PID was obtainable.  Otherwise
\v(lockpid) has an empty value.  ckuusr.h, ckuus4.c, ckutio.c, 27 Jun 98.

Also \v(blockcheck), and also make "set block 4" an invisible synonym for
"set block B" so the \v(block) value could be used in SET BLOCK commands.
ckuusr.h, ckuus[34].c, 27 Jun 98.

More changes from Jeff for IKS.  Fixed some confusion in ckcnet.c.  28 Jun 98.

The VMS RESEND problem...

 . RESEND X.ZIP complains and fails if SET FILE TYPE not BINARY, even
   though it will be binary when it opens the file.  Fixed in doxsend(),
   ckuusr.c, 28 Jun 98.

 . RESEND /BINARY X.ZIP temporarily sets xfermode to BINARY (rather than AUTO)
   and this prevents rpar() from including the System ID in the S packet.
   There is no reason why the System ID should not always be sent.  Fixed in
   rpar(), ckcfns.c, 28 Jun 98.

 . VMS server fails to execute REGET unless it's already in binary mode.
   That's because the last-minute check for binary in sfile() was before
   the call to openi() rather than after, and in VMS, openi() (zopeni()
   really) has the final word on the transfer mode.  Fixed in ckcfn2.c,
   28 Jun 98.

 . When VMS C-K resends, it always sends the whole file again, except for
   the first byte.  This was the real problem...

I checked this with C-Kermit 6.0 to see if the same thing happened before all
the recent changes for odd-record-length files, etc.  Nope, it didn't.
Detailed comparison of the 6.0 and 6.1 code only turned up a lot of
SYS$RAB/FAB stuff I didn't understand.  Added lots of debugging statements to
see where we go wrong.  Hours later...  I found an "|" that should have been
an "&" in the code that was added to handled odd-record-length fixed-block
files.  So now RESEND in VMS is fixed, at least for even-record length files.
REGET too.  ckvfio.c, 28 Jun 98.

Added zgetfs() for VMS.  ckvfio.c, 28 Jun 98.

When (UNIX) C-Kermit got an autodownload and then returned to CONNECT mode
automatically, the terminal modes were messed up the first time we escape back
manually.  Fixed in doconect(), ckuus4.c, 28 Jun 98.

Added some debugging to try to track down a very strange problem in the OS-9
version, in which the pointer to the outbound packet buffer is NULL by the
time it reaches bgetpkt().  ckcfn[s3].c, 29 Jun 98.

Discovered that calling the system to get the Julian date is a LOT more
trouble than it's worth in most OS's except UNIX, so I moved zjdate() to
ckuus4.c and had it calculate the Julian date using old-fashioned arithmetic.
Now all C-Kermits have it.  ZJDATE symbol removed.  ckcdeb.h, ckuusr.h,
ckuus4.c, ckufio.c, 29 Jun 98.

Discovered that "blah" would be accepted as a valid date.  Bulletproofing
added to cmcvtdate().  ckucmd.c, 29 Jun 98.

Having written an algorithmic date-to-julian-date converter, it wasn't hard to
add a conversion in the other direction, so \fj2date() converts a Julian date
to a regular date.  ckuusr.h, ckuus4.c, 30 Jun 98.  (I was tempted to also add
date/time arithmetic functions, but resisted -- they are on the list for
later.)

Got rid of bell sound after successful DIAL if SET QUIET ON.  ckuus6.c,
30 Jun 98.

Supplied missing Microcom-AT "error-correction off" command.  ckudia.c,
1 Jul 98.

Fix from Jeff for partial dialing.  ckuus6.c, 2 Jul 98.

One call to cmcvtdate() was overlooked in converting to 2-arg format, as
well as one of the prototypes.  ckucmd.[ch], 2 Jul 98, from Jeff.

Added information about new dialing rules in Italy and Spain to Section 2.1
of ckermit2.txt, 3 Jul 98.

Fixed HANGUP to include an implicit CLEAR DIAL-STATUS.  ckuusr.c, 3 Jul 98.

Added bulletproofing to encstr() and getpkt() similar to that added to
bgetpkt(), to catch null "data" pointer.  ckcfns.c, 3 Jul 98.

Added Telnet negotiation to ttinl() in the UNIX version.  I did not add it to
ttxin(), since, in the UNIX version, ttxin() is used only by the CONNECT
module, which handles Telnet negotiations itself (except there is also one
call to ttxin() from ckudia.c, which is called only for modem type "unknown",
and then only when dialing failed, an unlikely combination on a Telnet
connection).  ckutio.c, 3 Jul 98.  Here's the first Internet Kermit Service
dialog between a C-Kermit client and a C-Kermit server:

  TELNET SENT WILL TERMINAL-TYPE=24
  TELNET SENT WILL NEGOTIATE-ABOUT-WINDOW-SIZE=31
  TELNET SENT WILL NEGOTIATE-ABOUT-KERMIT-SERVER=45
  TELNET SENT DO NEGOTIATE-ABOUT-KERMIT-SERVER=45
  TELNET SENT DO SUPPRESS-GO-AHEAD=3
  TELNET RCVD DONT TERMINAL-TYPE=24
  TELNET SENT WONT TERMINAL-TYPE=24
  TELNET RCVD DONT NEGOTIATE-ABOUT-WINDOW-SIZE=31
  TELNET SENT WONT NEGOTIATE-ABOUT-WINDOW-SIZE=31
  TELNET RCVD DO NEGOTIATE-ABOUT-KERMIT-SERVER=45
  TELNET SENT SB NEGOTIATE-ABOUT-KERMIT-SERVER START-SERVER IAC SE=0
  TELNET RCVD WILL NEGOTIATE-ABOUT-KERMIT-SERVER=45
  TELNET RCVD WILL SUPPRESS-GO-AHEAD=3
  TELNET SENT DO SUPPRESS-GO-AHEAD=3
  TELNET SENT DO LOGOUT=18

After some research, discovered that yyyyddd is *not* a Julian date, but
rather a "day of year".  Changed \fjdate() to \fdayofyear() (but left
\fjdate() as an invisible synonym, since we released K95 1.1.17 with it),
and \fdoy() as another invisible synonym.  Changed \fj2date() to
\fdoy2date() (day of year to date).  ckuus4.c, 3 Jul 98.

Now, a *true* Julian date is the number of days since a fixed date in the
past, and this is more useful anyway, since normal arithmetic works on it.  By
definition, the fixed date is 1 Jan 4713 BCE, but that makes for big numbers,
so the more common form is the Modified Julian Date (MJD), which is the number
days since 17 November 1858 -- which, coincidentally, is also Day Zero in VMS.
I added system independent functions to convert from a free-format date to MJD
(\fmjd()) and vice versa (\fmjd2date()).  So now we have date arithmetic,
e.g.:

  .\%x := \fmjd()                  ; Today's MJD
  .\%x ::= \%x - 7                 ; MJD one week ago
  send /after:\fmjd2date(\%x) *.*  ; Send all files created in the last week

or more compactly:

  send /after:\fmjd2date(\fmjd() - 7) *.*

ckuusr.h, ckuus4.c, 3 Jul 98.

Added \fday(date) (day of week) and \fnday(date) (numeric day of week).
ckuusr.h, ckuus4.c, 4 Jul 98.

Added help text and docs for new date functions, ckuus2.c, ckermit2.txt,
4 Jul 98.

Added evalx(), which is a silent version of evala() -- does the same thing,
but does not print any error messages.  ckuus5.c, 5 Jul 98.

Fixed rdigits() not to succeed when given the null string or an empty string.
ckucmd.c, 5 Jul 98.

\fdate() and \fsize() did not fail or print error messages if given bad
arguments.  Fixed in ckuus4.c, 5 Jul 98.

Added \ftime(), \fntime(), and \fn2time().  ckuusr.h, ckuus[24].c,
ckermit2.txt, 5 Jul 98.

Added \v(tftime) - elapsed time in seconds of most recent file transfer.
ckuusr.h, ckuus4.c, 5 Jul 98.

From Kevin Handy: Although it is legal to take the address of a constant in
VAXC, it is not legal in GCC (and not a good idea either!).  This was done in
the VMS version of gftimer().  Fixed by assigning the constant to a variable
and taking the address of the variable.  He can now build C-K 6.1 B.05
successfully with GCC 2.8.1 on VMS 5.5-2 without network support.  ckvtio.c,
5 Jul 98.

IKS changes from Jeff, many modules, 6 Jul 98.

Removed the restriction from tod2sec() that hours must be 24 or less.  There
is no reason why lots of hours can't be specified -- after all, we can still
convert them to seconds.  ckuus6.c, 6 Jul 98.

Changed cm/ckcvtdate() to allow hours to be > 24 if given a special argument.
ckucmd.c, 6 Jul 98.

Merged tod2sec() and \fntime() -- they have the same purpose, but the latter
is much more tolerant (see ckermit2.txt).  ckuus4.c, 6 Jul 98.

Removed 75 lines of crufty code from doalarm() and replaced them by calls to
the new date/time-handling functions, to fix problems with alarms that span
midnight.  ckuus3.c, 6 Jul 98.

Corrections to yesterday's changes -- missing args to ckcvtdate(), etc.
ckuus3.c, ckuus6.c, 7 Jul 98.

Added HADDRLIST definition for major Unixes to ckcnet.h, and removed them from
the makefile.  7 Jul 98.

Added CLEAR ALARM -- more intuitive than SET ALARM 0 (which still works).
ckuusr.[ch], ckuus3.c, 7 Jul 98.

Added CLEAR TEXT-PATTERNS and CLEAR BINARY-PATTERNS; everything that has an
ADD or REMOVE command should also have a CLEAR command.  ckuusr[ch], 7 Jul 98.

Updated HELP CLEAR -- it was way out of date.  ckuus2.c, 7 Jul 98.

Added a section, 7.15, on alarms to ckermit2.txt.  7 Jul 98.

Changes from Jeff to support server-side Telnet negotiations and remote/local
echo.  ckuusr.h, ckuus[23457].c, ckcfn2.c, ckucon.c, ckucns.c, ckcnet.c,
11 Jul 98.

Added hooks for SET NETWORK TYPE PTY, but they don't do anything yet.  Symbol
NETPTY governs inclusion of PTY code, defined for now only for SunOS.
ckcnet.h, ckuus[r3].c, ckutio.c, 11 Jul 98.

Added REMOTE EXIT, 12 Jul 98.:
 . Server side: ckcpro.w, ckcfns.c, ckcmai.c.
 . Client side: ckuusr.h, ckuus[r7].c.
 . { ENABLE, DISABLE } EXIT: ckuusr.[ch].
 . SHOW SERVER.  ckuus[56].c.
 . HELP REMOTE EXIT.  ckuus2.c.
 . Documentation.  ckermit2.txt.

Defined Option and Mode bits for Extended GET.  ckcker.h, 12 Jul 98.

Added client side of Extended GET, single-packet, single-filespec version
only, supporting only /DELETE /RECOVER /RECURSIVE options and /BINARY /TEXT
/LABELED modes:

 . Defined Option and Mode bits for Extended GET.  ckcker.h,
 . Set opkt flag in GET cases where needed & get options.  doxget(), ckuus6.c.
 . Added new start state "o" for Extended GET.  ckuus6.c, ckcpro.w.
 . Added opkt parameter to srinit(): ckcker.h, ckcpro.w, ckcfn2.c.
 . Reset O-Packet options after transaction complete. ftreset(), ckuusx.c,
 . Added code to srinit() to send O-packet.  ckcfn2.c.

Added server side of Extended GET.  New state for incoming O packet, new
second arg to sgetinit() indicating O packet, sgetinit() parses the O packet,
extracts the flags, mode, and filename.  Allows for multiple incoming O
packets, even though the client doesn't send them yet.  Does not yet allow for
multiple filespecs.  Does not yet support selectors of any kind (date, size,
exception list).  Cleaned up various other bits in sgetinit().  ckcpro.w,
12 Jul 98.

Tested all combinations of GET switches on regular files as well as commands;
it all seems to work nicely, including GET /DELETE /RECOVER /RECURSIVE when
recursion and recovery actually are involved.  If a new client sends an O
packet to an old server, the server complains about unknown packet type.  If
an OLD client sends GET, REGET, RETRIEVE, etc, to a new server it works as
expected.

No particular documentation or help messages were needed since it's all under
the surface -- it makes some GET switch combinations work that didn't work
before.

Will add selectors and multiple filenames (mget) later.  Ditto for quoting
and generic wildcards (but since wildcards already work nobody will notice
that this part isn't done).

Changes from Jeff to ckcfn2.c and ckcnet.c, 13 Jul 98.

Fixed a bug in O-Packet encoding (it neglected to terminate the string).
ckcfn2.c, 13 Jul 98.

Added comments to O-packet decoder.  ckcpro.w, 13 Jul 98.

Changed O-Packet encoder to build a linked list of fields, and O-Packet sender
to fill one or more packets with one or more fields on a first-fit basis.
Various errors are now possible (malloc failure, filename too long, missing
filename, etc), so an appropriate message is set for the E-Packet.  ckcfn2.c,
14 Jul 98.

Changed protocol engine to include a new state for sending and getting ACKs
to O-Packets, and another new state for sending a sequence of O-Packets.
ckcpro.w, 14 Jul 98.

Tested OK with GET /RECURSIVE /RECOVER /DELETE /BIN short-filename (so it
assembles the O-Packet fields from the linked list OK).  Tested with a very
long filename and verified that it triggers a second O-Packet.  Tested
with a null filename and verified it sends the proper error message (which
should never occur in real life).

Then came a test where the filename exactly reached the end of the packet,
leaving no space for the 2-byte EOP tag ("@ ").  This failed for a subtle
reason in the getpkt() routine, namely that it did not distinguish between
real data and memory-string data.  Real data (such as file data) could leave
behind leftovers that would be picked up next time.  But getpkt() is called
only once on string data -- the encoded argument string is supposed to fit
into one packet.  But getpkt() was (a) making leftovers, and (b) returning
success, rather than failing in this case, thus truncating the data.  This bug
must have other consequences too, but none that have ever been reported.

Once this was fixed it was possible to test the other cases.  So now the
protocol part is working -- the client will send as many O-Packets as it takes
to handle all the O-Packet fields, and the server will read and process
incoming O-Packets until the final one is received, and then will switch into
send state, and the client will switch into receive state.

There is a still one remaining area to handle -- packet loss:
 . What if the final O-Packet is lost?  No problem, the server NAKs it.
 . What if the server's S-packet is lost?  Here we have a problem if
   the client times out and resends its final O-Packet *and* this O-Packet
   has a nonzero sequence number: the server's transport layer
   rejects the packet.  I'll handle this tomorrow...

Still to do (easy now):
 . Handle multiple filenames
 . Handle selectors
 . Redo MGET to use O with multiple filenames (?)

Merged LOGIN and LOGOUT commands from Jeff.  Made lots of portability changes,
plus some corrections (cklogin/out routines already existed; various malloc'd
buffers were not being freed on error return from routines, etc).
ckcdeb.h, ckuusr.[ch], ckuus7.c, 15 Jul 98.

With the changes above, C-Kermit would not run properly when chroot'd because
it could not find "/dev/tty", which it normally opens when entering protocol
mode.  This could be worked around with "-l 0" on the command line, except
then Kermit thought it was in local mode.  Fixed by making ttopen(), when
given a device name of "0", set remote mode rather local.  ckutio.c,
16 Jul 98.

Added "-A" command-line option.  Starts K95 as an Internet server on device
"0".  ckuusy.c, 16 Jul 98.

Problem with both the above, at least on SunOS: After return from protocol
mode, CRs are no longer supplied by the terminal driver after LFs (CRMOD
function is lost).  Explicitly setting it in concb() doesn't help.  Turns out
the problem was that UNIX concb() would just return if Kermit was started with
device "0".  Commented out that code and it works OK, but I wonder why it was
there to begin with (i.e. I wonder what I just broke).  ckutio.c, 16 Jul 98.

Changed main program to call ckxlogin(NULL,NULL,NULL) if C-Kermit invoked with
-A option, so the first thing the user sees is a login prompt.  This happens
before the initialization file, script, or any command-line action option is
executed, but after Kerberos initialization, and it works OK,  ckcmai.c,
16 Jul 98.   (Presumably ckxlogin() will return 1 if user has already
authenticated via Kerberos...)

But when running C-Kermit in this manner, for some reason it gets a SIGHUP
when receiving a file.  Experimentation shows this happens whenever we use
"-l 0" and the receive packet length (or the product of packet length and
window size) is greater than 897, which looks suspiciously close to the TCP
MSS.  So all the changes made to accommodate file descriptor 0, though perhaps
useful in other contexts, don't help here.  The real trick is to go back to
opening /dev/tty, but doing it before the chroot(), while we can still see it.
Fixed in ckcmai.c, ckuus4.c, ckuusy.c.  16 Jul 98.

Cleanups from Jeff for login code.  ckuus7.c, 18 Jul 98.

Tried building a version with:
"LIBS= -L/usr/local/lib -lpwent -lcurses -ltermcap"
to see if it would use the local authentication methods, found lots of bugs
in the code that logs in a real user.  Fixed them, now it works.  ckuus7.c,
18 Jul 98.

Moved user ID and password-checking code to new system-dependent routines,
zvuser() and zvpass().  ckufio.c, 18 Jul 98.

Changed ckxlogin() to behave consistently in call cases, always prompting for
both a user ID and password, and not giving a failure message until after the
user has given both, and always giving the same message in case of failure:
"Access denied".  ckuus7.c, 18 Jul 98.

Verified that when logged in via ckxlogin() that "set line /dev/blah" fails
properly when lockfile directory is protected against the logged-in user,
even though the real user is root.

Built a copy with CK_LOGIN, local libs, and NOLOCAL, since this is the
configuration that will probably be used in the real world -- allowing an
Internet Kermit server to dial out or make Telnet connections would make about
as much sense as allowing an FTP server to do this.  (But with Kermit, it
would actually work -- but it would also open up enormous security holes...)
Got this working OK after adjusting some #ifdefs, and the resulting executable
is about 200K smaller.  NOTE: We can't enclose all of ckcnet.c in #ifndef
NOLOCAL because now we support server-side Telnet negotiation.  However, I was
able to #ifdef out a rather large portion of it.  This involved making sure
that TNCODE was not disabled if NETCONNN or TCPSOCKET were not defined, or
if NOLOCAL was defined.  So another 25K cut away.  Many modules, 18 Jul 98.

Rather massive rearrangement of ckcnet.c to allow TELNET routines and
variables to exist even when NETCONN & TCPSOCKET are not defined and/or
NOLOCAL is defined.  18 Jul 98.

Enabled SET/SHOW TELNET when TNCODE defined, even if NETCONN & TCPSOCKET
not defined or NOLOCAL defined.  ckuus3.c, 18 Jul 98.

All of the above will obviously need a lot more work, testing, and thought
(not necessarily in that order).  For example, how does Kermit, when in remote
mode, know if it should be doing server-side Telnet negotiation?  If it's
already under a telnetd, then the only time it will see an IAC is if a quoted
IAC has been unquoted and passed down, but how do we tell the difference?
There's no way, unless we are told, e.g. by a command-line argument.

For example, constructions like:

    if (netconn && (ttnproto == NP_TELNET) && (n == IAC))

when used to decide whether to call tn_doop(), tn_siks(), etc, are completely
wrong.  They should be more like:

    if (n == IAC &&
	((local && network && (ttnproto == NP_TELNET)) ||
	(!local && sstelnet)))

where sstelnet is nonzero when we should be doing server-side Telnet
negotiation.  Such changes need be made only in code that can be executed in
remote mode, e.g. in ttinl(). doinput(), etc.  For now, we set the sstelnet
flag when the -A command-line option is given (but we might want to make
separate cases in the future for Telnet and non-Telnet servers that must be
logged in to -- e.g. Kermit replacing login for incoming serial connections).

Anyway, I think I caught most of these cases.  Many modules, 18 Jul 98.

Made a new makefile entry for testing all this: sunos41gccx.  It adds NOLOCAL,
TNCODE, and IKS_OPTION.  18 Jul 98.

A debug log from Ron Heiby showed that we are accepting 0x81 as Start of
Packet (SOP) even though we know parity is none.  This is an artifact of the
automatic parity detection code -- since we don't know in advance if the first
packet has parity, we check for SOP using a mask of 0x7f.  But after we know
there is no parity, we should change the mask to 0xff.  Fixed in ttinl().
Also, improved the way ttinl() decides whether a parity check is needed by
(re)setting the flag in ttpkt(), which is always called at the beginning of
packet operations.  I also rearranged the code a bit to test for interruption,
SOP, and length in a more sensible (and efficient) order.  ckutio.c, 19 Jul 98.

Made "set prefixing none" invisible.  ckuus3.c, 19 Jul 98.

From Jeff, 19 Jul 98:

 . Moved cmdini() call to higher up in main() just in case anything that
   happens in prescan() needs the command parser or buffers.  ckcmai.c.
 . Moved some code from prescan() to main().  ckuus4.c, ckcmai.c.
 . Change end_login() to zvlogout().  ckufio.c, ckuus7.c.

Added protytpes for zv{user,pass,logout}() to ckcdeb.h, 19 Jul 98.

Updated some comments in input().  ckcfn2.c, 19 Jul 98.

Removed NONE from HELP SET PREFIXING message (Jeff), ckuus2.c, 21 Jul 98.

Added SET SERVER CD-MESSAGE { ON, OFF }.  When ON, and the user successfully
CDs to a directory that contains a READ.ME file (name configurable), its
contents are sent to the client's screen, similar to what wu-ftpd does.  If
such a file does not exist, or is not readable, the directory name is sent
back in the ACK, as before.  The default CD Message filename is defined in
ckcker.h as DFCDMSG.  This can be overridden by defining DDFCDMSG on the CC
command line to be the quoted filename, e.g.:

  make xxx "KFLAGS=-DDFCDMSG=\\\"newname\\\""

(the number of \'s depends on the shell, how deeply nested the makefile entry
is, etc).  The default for UNIX and OS-9 is "./.readme"; for others it's
"READ.ME".  The default for SET SERVER CD-MESSAGE is OFF, except when user
logs in anonymously, in which case it's ON.  ckcmai.c, ckcker.h, ckuusr.h,
ckuus[23].c, ckcfns.c, ckcpro.w, 21 Jul 98.

Added SET SERVER CD-MESSAGE FILE <name> to allow the message-file name to be
specified at runtime.  ckuus3.c, 21 Jul 98.

Added REMOTE SET SERVER CD-MESSAGE { ON, OFF }, client side and server side,
Code 420, ckuus3.c, ckcfns.c, 21 Jul 98.

Added CD Message material to SHOW SERVER.  ckuus5.c, 21 Jul 98.

Considered adding ENABLE/DISABLE CD-MESSAGE, but I don't see a need for it.
If you can CD to a directory, you can GET or REMOTE TYPE any file in it that
you have read access to, so there is no reason to disable the CD message
feature; the user can turn it on or off as desired, and whoever sets up the
server can set the initial state.

Don't set the sstelnet flag if in local mode.  ckuus4.c, 21 Jul 98.

Made -A imply -z (force foreground), for when we are running under inetd.
ckcmai.c, 22 Jul 98.

Changed default CD-message file for non-UNIX to README.TXT.  ckcker.h,
22 Jul 98.

Problem with filename patterns, first noted by Peter Eichhorn:

 1. Person sending files is running C-Kermit 6.1 on UNIX with SET FILE
    PATTERNS ON (which is the default) and SET FILE TYPE BINARY.

 2. The Kermit program on the receiving end does not support Attribute packets.

 3. The sender switches between text and binary mode per file, but since the
    receiver does not support A-packets, the sender has no way to tell the
    receiver about the mode switching.

 4. Text files are sent with CRLFs.

Consequences:

 1. If the receiver is UNIX, this ruins the text files (at least for certain
    applications).  This is an incompatible change from past behavior, and
    it is bad.

 2. If the receiver is on a DOS-like file system, the text files arrive in
    the proper format.  This, too, is a change from previous behavior in
    which the text files would have been sent in UNIX format.

Possible solutions:

 1. Leave matters as they are.  Not good, since this breaks something that
    used to work.

 2. As soon as the transfer starts, C-Kermit knows whether the other Kermit
    supports A-packets.  If it does not, disable per-file mode switching.
    This eliminates Bad Consequence 1 above, restoring the earlier (and
    expected) behavior.  It also eliminates Good Consequence 2 above, but
    that's OK since it is not a change from previous behavior.

 3. Solution 2 is satisfactory but less than optimal, since one would expect
    that in SET FILE PATTERNS ON, "ON" means ON.  It also rules out Good
    Consequence 2 even in cases where we might want it.  A better solution
    might be to add SET FILE PATTERNS AUTO and make it the default.  Then
    ON would mean ON, OFF would mean OFF, and AUTO would mean "ON but only
    if the other Kermit accepts Attribute packets".

Option 3 restores the original behavior when the receiver does not support
A-packets, but allows for mode switching when A-packets can be used, and it
also allows for Good Consequence 2 when A-packets can't be used if you SET
FILE PATTERNS ON.  So...

 . Added AUTO to SET FILE PATTERNS keywords, value 2.  ckuus7.c.
 . Changed default to AUTO.  ckcmai.c.
 . Changed SHOW FILE and SHOW PATTERNS to display "auto".  ckuus5.c.
 . Updated HELP SET FILE message.  ckuus2.c.
 . Changed spar() to set patterns = 0 if AUTO && A-packets not negotiated.
   The prevailing setting is restored automatically at the end of protocol.
   ckcfns.c, ckuusr.c.  22 Jul 98.

Corrected some filename patterns that were missing "*".  ckcmai.c, 22 Jul 98.

Server-side telnet changes from Jeff, including recognition of Telnet
negotiations when at prompt.  23 Jul 98.

Some minor server-side Telnet corrections:
 . When packet mode interrupted by ^C^C^C, echo "^C..." to stdout not stderr.
 . Flush typeahead before username and password prompts.

Changed UNIX packet reader to print ^X... when interrupted, where ^X is the
actual transfer cancellation character, rather than always printing "^C...".
ttinl(), ckutio.c, 23 Jul 98.

If TCPSOCKET is defined but TNCODE is not, define TNCODE for the benefit of
any modules that might need it for server-side Telnet protocol, but that don't
need to include all of ckcnet.h.  ckcdeb.h, 23 Jul 98.

The previous change still wasn't good enough for ckucmd.c, so I made it
include ckcnet.h.  23 Jul 98.

Added SET COMMAND AUTODOWNLOAD { ON, OFF }, independent of SET TERMINAL
AUTODOWNLOAD { ON, OFF }.  When ON, which is the default, the command parser
recognizes Kermit packets.  An S packet makes it go into receive mode, an I
packet makes it go into server mode.  ckuusr.h, ckuus[235].c, 23 Jul 98.

Implemented SET COMMAND AUTODOWNLOAD in gtword(), ckucmd.c, and
kstart(), ckcfn2.c, 23 Jul 98.  For now, works only for Kermit protocol.
Add Zmodem later.

Changed server end of REMOTE LOGIN as follows:

 1. If a login attempt fails, send back an Error packet rather than an ACK
    with an error message, so the client can tell that it failed.

 2. If started with -A, authenticate the user via ckxlogin() rather than
    the SET SERVER LOGIN strings.

 3. If the client tries to log in when already logged in, send an E packet,
    but leave them logged in.

The next step is to allow a REMOTE LOGIN packet to be received and processed
at the Username: prompt.  This almost works -- kstart() recognizes the packet
OK, but since the command parser has not entered its keyword parsing loop yet,
the mechanism that is used under normal circumstances (stuff "server" or
"receive" into the command buffer) is inappropriate here -- it just looks like
a username.  I'll fix this tomorrow.

Add server idle-timeout into to SHOW SERVER, from Jeff.  ckuus5.c, 24 Jul 98.

printf(), putchar(), perror() replacements from Jeff for UNIX, to translate
"\n" to CRLF when C-Kermit is an Internet server, in which case there is no
terminal driver to do this.  When run as an Internet server, C-Kermit now
prints normal-looking output rather than giving the stairstep effect.
ckutio.c, ckcdeb.h, 24 Jul 98.

Changed '-A' to include '-Q' (fast protocol settings) and (from Jeff) to
set "nopush".  Previously, nopush was set only for guest logins; now it is
set for regular ones too, not for security reasons, but because output from
inferior processes has bare LFs, since there is no terminal driver to convert
them to CRLF.  ckcmai.c, ckuusy.c, 24 Jul 98.

Changed ckwart to not use the printf(), putchar(), perror() replacements,
since it does not have access to them.  ckwart.c, 24 Jul 98.

Added numerous casts to shut up picky Sun ANSI cc.  ckcfn[2s].c, ckcpro.w,
ckuus[r7].c, 24 Jul 98.

Yesterday's code broke regular logins at the Username: prompt by failing to
set the "logged in" variable checked by the server whenever a command is given
that requires the user to be logged in.  Fixed in ckcmai.c, 24 Jul 98.

Adjusted the method for the command parser to let the upper level code know
that a Kermit packet had been received, so now it doesn't depend on the
top-level keyword table.  Instead, it just sets the start-state appropriately.
This method could be used by the CONNECT command too, since it's a lot simpler
and does not rely on APC or the script language being configured in, but it
would also require changing every CONNECT module plus the mainline code that
calls the CONNECT module.  ckucmd.c, 24 Jul 98.

Adjusted the main program to call ckxlogin() in a loop in a way that allows
direct login at the prompt, or via Kermit REMOTE LOGIN packet.  But this fails
because of the autoupload string "kermit -x" has already been read at the
Username prompt and taken as the user name.  But then if the password reader
also checks for autoupload, we undo this and it works quite nicely.  Made sure
that "kermit -A" exits after three successive unsuccessful attempts to log in,
no matter whether this is at the prompt or by REMOTE LOGIN.  But this does not
close the connection to the client, since it is the superior program (such as
inetd) that has it open, so that program has to be relied upon to close the
connection when the server program exits.  ckcmai.c, ckuus7.c, 24 Jul 98.

Added a pause after each unsuccessful login attempt.  ckcmai.c, 24 Jul 98.

Even assuming the connection is closed by the remote after 3 bad login
attempts, if the client is sitting at its prompt sending REMOTE LOGIN
requests, there is no indication to the user that the connection has been
closed.  Changed the client so if REMOTE LOGIN or any other REMOTE command is
given when in local mode but ttchk() returns < 0, it prints "?No connection"
and fails.  ckcpro.w, 24 Jul 98.  (I probably should do this for SEND and
RECEIVE too...)

Changed DIRECTORY command, general case, to call domydir() (built-in
directory-listing generator) if NOPUSH is defined or if nopush is set.
ckuus6.c, 24 Jul 98.

Added an easier way to access command-line arguments.  In:

  kermit -a -b -c ... = word1 word2 word3 ...

"/path/kermit" is assigned to top-level \%0, word1 is assigned to top-level
\%1, word2 to \%2, and so on.  If a Kermit script is started on the command
line, \%0 is set to the pathname of the script rather than the pathname of
Kermit.  cmdini(), ckuus5.c, 25 Jul 98.

Made "show args" work for top level.  doshow(), ckuus5.c, 25 Jul 98.

Made \v(argc) work for top-level.  nvlook(), ckuus4.c, 25 Jul 98.

Now it's a lot easier to write Kermit scripts for UNIX that have "shbang"
lines, and pass arguments to them on the command line -- it works just like
a shell script, except for the "=", which is needed to separate arguments
for Kermit itself from arguments for the script.

Beefed up UNIX zfnqfp().  Previously it was susceptible to "/./", "/../",
"..", "//", and similar tricks.  Now I hope it's bulletproof.  For example,
"\fpathname(/usr/olaf/tmp/./foo/../../x.y)" now returns "/usr/olaf/x.y"
rather than "/usr/olaf/tmp/./foo/../../x.y".  The latter wasn't exactly wrong,
but now we can be more confident if we want to change DISABLE CD in the server
to restrict the user to a rooted directory *tree* rather than just a single
directory.  ckufio.c, 25 Jul 98.

Fleshed out the syslog() and wtmp features of IKS.  I separated the two, and
enabled only wtmp, since I have no idea what syslog() does or how to test
whether we're using it right.  So now Kermit makes a wtmp entry when I log
into the Kermit server, and another one when I log out.  But even after I log
out, "last" says I'm still logged in.

But while testing this, the client Kermit started crashing (this is what
prevented the logout entry from getting into wtmp).  The debug log shows a
ttinl() timer going off while I'm in the command parser, which indicates that
it thinks it got a packet from the keyboard (which it did not) (the crash
occurs because no handler is armed for the SIGALRM).  Furthermore, the log
shows that the streaming flag gets turned off for some reason (which is why
the timer is going off in the first place, since ttinl() is untimed when
streaming).  I disabled the wtmp code in case that caused it, but no
difference, so I turned it back on.

OK, one thing at a time.  wtmp...  As near as I can tell from "man last",
logout and login records are matched by username and "terminal name", which
should form a unique pair.  When somebody logs in to ftpd, it records the
terminal name as "ftp" followed by the ASCIIized pid of the ftpd incarnation,
like "ftp12345".  The "last" program evidently has code in it to strip off the
numeric part after "ftp", so this never shows up in a listing.  If I do the
same thing in Kermit, it seems to work -- "last" shows the session as logged
out, but does not strip off the pid so the listing looks ugly ("kermit92",
instead of just "kermit").  So I made it "kermit_xxxx", where xxxx is the pid
in hex.  I hope this doesn't overflow any buffers anywhere, since this is a
rather long "terminal name".  ckufio.c, 25 Jul 98.

The hostname did not show up in "last" listing since the Kermit server is
communicating over stdio and has no idea what the client host is.  But when
inserver != 0 stdio is really a socket, so we can call getpeername() on it.
And this works, but of course, only if C-Kermit is built with -DTCPSOCKET
(i.e. without NOLOCAL).  I added a ckgetpeer() routine to ckcnet.c to return
the hostname or address of the peer, and call it from the inserver startup
section in ckcmai.c; seems to work fine.  25 Jul 98.

As for the crashing...  It seems to be an aftereffect of recognizing a packet
while in the command parser.  It happens later on, but it never happens if
I don't exercise that code.  It can happen on either end too, not good.
(I knew adding this feature was too easy!)

Rearranged things to allow -x to appear on command line with -A, and if it
does, to skip the Username: prompt and go straight into server mode.  Testing
in this mode shows solid operation, no crashes.  So this seems to confirm that
the crashing problem is caused by the command-mode autoupload feature.
ckcmai.c, ckuus[4y].c, 26 Jul 98.

When -A given on command line, enter server mode automatically if me_iks_start
has been set in the Telnet negotiations.  But this never happens because the
server does not send START KERMIT until after it enters server mode, which is
probably a good thing.  ckcmai.c, 26 Jul 98.

When BYE was sent to the server, it called zkself() immediately, bypassing
zvlogout(), so the logout record was not being written to wtmp.  Made BYE
call ckxlogout() instead if zkself() if inserver.  ckcpro.w, 26 Jul 98.

Moved "Enter Client/Server Mode..." message from ckucon.c to doconect() in
ckuus4.c, so it doesn't need to be replicated in all CONNECT modules, and
added REMOTE LOGIN and REMOTE HELP lines.  26 Jul 98.

Fixed command-mode autodownload code to be active only when C-Kermit is in
remote mode, since it can't possibly work when in local mode.  ckucmd.c,
26 Jul 98.

Allowed server to execute BYE (if it is not disabled) even if user is not
logged in (but not FIN since we don't want not-logged-in users getting to
the prompt).  ckcpro.w, 26 Jul 98.

Reorganized ckxlogin() to have a common exit to make sure prompt is restored,
malloc'd items are freed, etc.  ckuus7.c, 26 Jul 98.

Recent additions to ttinl() to handle Telnet negotiations, etc, failed to
turn off the alarm() at each return point.  I added them, and this fixes the
crashing.  ckutio.c, 26 Jul 98.

Protocol engine was not sending back an error packet in response to
REMOTE HOST commands when nopush in effect.  Fixed in ckcpro.w, 26 Jul 98.

Allowed REMOTE HELP when not logged in, and made the message say REMOTE
LOGIN required in that case.  ckcpro.w, 26 Jul 98.

Added a help message for the Username prompt, and a herald above it.
ckcmai.c, ckuus7.c, 26 Jul 98.

Added code to zvpass(), at the point where the user is logged in, to set
environment variables HOME, USER, and LOGNAME, and to copy the username into
uidbuf[] and make homdir point to the login user's home directory, or if it's
a guest login, to "/".  Now \$() returns the right things for these, and so do
\v(user) and \v(home).  This also fixes the problem of executing the real
user's .kermrc, rather than the effective user's.  ckufio.c, 26 Jul 98.

PWD in the UNIX version at the server's prompt ran the external pwd command.
Replaced this by a call to zgtdir().  ckcmain.c, 26 Jul 98.

Verified that:
 . If you send BYE to the Username: prompt, it logs out the server.
 . If "kermit -Ax" is used to start server mode (so user must log in with
   REMOTE LOGIN), and the client does not negotiate IKS and therefore can
   CONNECT, that ^C^C^C prior to login does not give the user the prompt --
   instead it makes C-Kermit exit, which is exactly what should happen.
 . If you start it as "kermit -AxS", then ^C^C^C also exits (I had to put
   in special code for this).
 . You can not SEND a file to the Username: prompt, or do REMOTE CD, or
   anything else that is not allowed prior to login.

Replaced the following:

  len = (binary && !parity && !memstr && !funcstr) ?
    bgetpkt(spsiz) : getpkt(spsiz,1);

with:

  if (binary && !parity && !memstr && !funcstr)
    len = bgetpkt(spsiz);
  else
    len = getpkt(spsiz,1);

in ckcfns.c, since the former caused the OS-9 compiler to generate bad code.
Confirmed by Gregorie Martin, who also supplied a new OS-9 makefile and a
new ck9asm.a module, allowing 32-bit builds, which are now necessary since
data space is more than 64K in some modules.  27 Jul 98.

Disabled logfile creation by anonymous users.  ckuus4.c, 27 Jul 98.

From Jeff: Implement NVT and Telnet-Binary handling of CR, CRLF, CR-NUL in the
command parser for server-side command input.  This fixes the bug with SHOW
MACROS needing two CRs to confirm.  gtword(), ckucmd.c, 27 Jul 98.

From Jeff: Recognize Ctrl-D as EOF in the command parser.  This allows users
to cancel a login at the Username: or Password: prompt.  ckuus7.c, 27 Jul 98.

Disabled Ctrl-D as EOF except when (inserver && !x_logged), and made Ctrl-C
act like Ctrl-D.  ckucmd.c, 27 Jul 98.

From Jeff: Clear all owner permission bits when creating files as guest,
like wuftpd.  Also, fix an octal mask that missing its leading 0.  ckufio.c,
27 Jul 98.  Notes: When storing files in (say) kermit/incoming, they are
created with ----rw-r--.  This prevents anonymous ftp users from reading
them or overwriting them.  But wuftp uses ----r----- (how does it know?).

From Jeff: Disable FTP, PING, and WHO commands if nopush set.  ckuusr.c,
27 Jul 98.

From Jeff: Minor corrections to Telnet negotiations.  Implement server-side
NAWS.  ckcnet.c, 27 Jul 98.

NAWS stuff didn't quite work -- even though the negotiations are OK, every
time thereafter the server goes to check its screen size, it gets its own
rather than the client's.  That's because ttgwsiz() calls a local ioctl().
To solve this, I changed Jeff's new code in ckcnet.c to set environment
variables for LINES and COLUMNS from incoming NAWS subnegotiations, and then
made ttgwsize() call xttgwsize() (which checks these values) if inserver is
set (there might be a faster way to do this, but this mechanism was already
there for other reasons -- come back and improve later if peformance is a
problem).  ckcnet.c, ckutio.c, 27 Jul 98.

Various interactive-mode features were not working in the Internet Kermit
server: KERMIT READY TO... messages, askmore(), etc.  Since fd 0 is a
redirected socket, isatty() was failing, and backgrd was being set.  Fixed in
conbgt(), ckutio.c.  Similarly, changed is_a_tty() (the isatty() front end) to
return(1) if inserver.  ckcmai.c, 27 Jul 98.

I commented out the code that set SIGHUP to SIG_IGN (see 16 Jul 98 notes).
We don't need it any more.  ckutio.c, 27 Jul 98.

Three failed REMOTE LOGINs in a row did not make the server drop the
connection as it should.  Fixed in ckcpro.w, 27 Jul 98.

Removed "Entering Client/Server..." message from ckucon.c.  27 Jul 98.

Bugs:
 . Client and server get into a loop negotiating SGA (the loop is broken
   automatically after 4, but should not happen in the first place) (not
   really a bug -- needs to be this way for DG Telnet server).
 . If you try to SEND a file to the Username: prompt, you get an error "?Login
   required", as expected, but for some reason the server is still in receive
   mode, sending NAKs, rather than back at the Username: prompt.
 . Something is messed up with packet recognition at the Username: prompt
   again.  The first one is not recognized, but subsequent ones are.

To do:
 . Create special pre-login init.
 . Do what wuftp does about incoming. Consider both anonymous and logged-in
   users.  This is probably something for the pre-login init.
 . If user is guest, don't allow OPEN WRITE?
 . No need to send "kermit -x" if IKS (but no harm either).
 . Fix built-in DIR command to show permissions in UNIX, VMS, etc.
 . Make ckxlogin() do if (me_iks) tn_siks(IKS_START) ???  No, this would
   prevent use of the Username: prompt by those who prefer it.
 . Change "kermit_xxxx" to "iks_xxxx" because of uname.h length limits.
 . DISABLE BYE should have no effect when IKS
 . Add runtime "nolocal" variable, turn it on & enforce it for guest logins.
 . Set local environment variables from NEW_ENV?

Added Atlas/Newcom 33600ifxC modem type -- there's evidently a big demand
for this since they are selling for $9.95.  ckuusr.h, ckudia.c, 28 Jul 98.

Added TX_9LATIN symbol for ISO 8859-15, Latin Alphabet 9.  ckcxla.h, 29 Jul 98.

Added FC_9LATIN and FC_CP858 file character-set symbols.  ckuxla.h, 29 Jul 98.

Changed references to "Latin-15" to "Latin-9".  ckouni.[ch], 29 Jul 98.

After hours of research found that the proposed (but not final) registration
number for ISO 8859-15 Latin Alphabet 9 is 203, so now we have a Kermit code
for it.  Reference: DOCUMENT REGISTER JTC1/SC2, Character sets and information
coding, N 3099 - N 3000, Item E3086, 1998-05-01.  Filled in functions and
tables for Latin-9 and CP858.  Seems to work OK, but needs refinement and
more testing.  Meanwhile, hurray, we're "Euro compliant".  ckuxla.c, 29 Jul 98.

Integrated recent changes from Jeff, 1 Aug 98:
 . Conditionalize printf() replacement in UNIX, since it conflicts with
   Linux curses library.  ckcdeb.h.
 . Change TELOPT_IKS definition from 45 to 47, since 45 has already been
   assigned by IANA for something else.
 . Add some missing #ifdef CK_AUTODL.  ckuus3.c...
 . Refine conditions under which tn_iks(IKS_STOP) is called at the
   top of the parse loop.  ckuus5.c.
 . And when returning from CONNECT mode.  ckuus4.c.
 . Refine conditions for which "Enter Client/Server Mode" msg.  ckuus4.c.
 . Make sure we have a Kerberos principal name in AUTH cmd.  ckuus7.c.
 . Show principal name in AUTH Password: prompt.  ckuus7.c.
 . Save username to uidbuf[] in ckxlogin().  ckuus7.c.
 . Various corrections to ckufio.c.
 . Save peer's IP address even if SET TCP REVERSE not ON.  ckcnet.c.
 . Add tn_push() and tn_wait() to solve the following problem: traditional
   Telnet clients are always reading from the socket.  But when C-Kermit is
   at the prompt, it is not reading from the socket.  When the user says
   "set host blah", C-Kermit sends some Telnet negotiations, but never reads
   the responses until the user goes into CONNECT mode or does an INPUT
   command (or, now, starts Kermit protocol).  The new routines allow
   negotiations to go back and forth until all commands that require an answer
   have completed, or a certain amount of time has gone by, whichever comes
   first, AND also saves any plain text that arrived during this period for
   subsequent processing by the first command that tries to read regular data
   from the socket.  This should allow immediate Kerberos or SRP authentication
   upon initial connection, without swallowing the host's messages or prompts,
   and it also takes care of hosts (like VMS) that issue the login prompt
   in the middle of Telnet negotiations.  ckcnet.c.
 . Various changes to authentication negotiation.  ckcnet.c.

Changed IKS banner to show its own hostname.  ckcmai.c, 1 Aug 98.

Added a new entry for ICL DRS6000 (SPARC) with DRS/NX 4.2MP 7MPlus.
makefile, 6 Aug 98.

Integrated Jeff's changes, 10 Aug 98:
 . Add symbols & cmds for Telnet encryption on/off commands: ckuusr.h, ckuus3.c
 . Allow for non-stdio IKS operation: ckuusy.c.
 . Allow for command parsing on encrypted connections: ckucmd.c.
 . Issue warnings or errors for SEND/BYE/FINISH w/TKO but no server: ckuusr.c.
 . Ditto for GET: ckuus6.c.
 . Ditto for REMOTE: ckuus7.c.
 . Make REMOTE LOGIN prompt for missing info.  ckuus7.c
 . Rearranged assorted TKO/IKS items: ckuus4.c.
 . Recognize REQ, etc, as REQUESTED (vs REQUIRED): ckuus3.c.
 . Updated SHOW FEATURES for Authentication/Encryption/etc: ckuus5.c.
 . Added encryption to console i/o: ckutio.c.
 . Adjustments to login process & for encryption: ckcmai.c.
 . Lots of IKS/TKO adjusments: ckcnet.c.

Fixed up REMOTE LOGIN parsing/prompting code to never exit without restoring
prompt and freeing malloc'd storage, etc.  ckuus7.c, 10 Aug 98.

Changes from Gregorie Martin to work around OS-9 C compiler bugs, and added a
missing clause to snddir() so it would work for OS-9.  ckcfns.c, 11 Aug 98.

Also from Gregorie Martin, separate text and binary filename pattern lists
for OS-9.  ckcmai.c, 11 Aug 98.

Added "set modem data-compression", which was missing from the keyword table;
("compression" was there, but "data-compression" is the phrase used in all the
other commands; left "compression" there but invisible).  ckuus3.c, 11 Aug 98.

A couple minor corrections & changes from Jeff: ckcmai.c, ckcnet.c, 12 Aug 98.

A couple minor changes from Jeff: ckcmai.c, ckcnet.c, 13 Aug 98.

Added a nolocal variable.  When nonzero, setlin() returns an error rather than
opening a connection.  nolocal is set to 1 automatically by -A.  This is a
patch in the true sense, and might need some refinement.  ckcmai.c, ckuus7.c,
13 Aug 98.

Added invisible (and irreversible) NOLOCAL command: ckuusr.[ch], 13 Aug 98.

Added another invisible and irreversible command: DISABLE ENABLE.  This allows
the sysadmin to disable selected services, and prevent the user from
re-enabling them even when they can get to the prompt (as in the client-side
server arrangement of IKS).  ckuusr.h, ckuus[r56].c, 13 Aug 98.

Fixed server end of REMOTE LOGOUT, which didn't work at all.  Various other
combinations didn't work either, from among login required / not required;
logged in already / not logged in; logging in / logging out.  All combinations
work sensibly now.  Note: Logging out does not break the connection, so a
subsequent login is allowed on the same connection.  This might change.
ckcpro.w, 13 Aug 98.

Added code to prevent guests from using SET FILE COLLISION APPEND or RENAME.
However, they can still use OVERWRITE and UPDATE -- this might change.
ckuus7.c, 13 Aug 98.

Changed wtmp record for IKS to say "iks_xxxx" rather than "kermit_xxxx" to
stay within 8 chars, which is the limit in SunOS and probably many other
platforms too.  ckufio.c, 13 Aug 98.

Added code to zprint() and zmail() to fail immediately if called by guest.
ckutio.c, 13 Aug 98.

Ditto at a higher level: after user logs in anonymously, do an implicit
DISABLE PRINT and DISABLE MAIL.  ckcmai.c, ckcpro.c, 13 Aug 98.

Don't allow ENABLE MAIL or ENABLE PRINT if user is anonymous.  ckuus6.c,
13 Aug 98.

And as a failsafe, in case they somehow re-enabled them, have the protocol
module disable them again whenever it is entered.  ckcpro.c, 13 Aug 98.

Fixed getyesno() (which is called whenever we want to print a question and
parse a yes/no answer, e.g. "OK to close?") to not put the answer in the
recall buffer.  ckuus3.c, 13 Aug 98.

Added XXRxxx symbols for top-level R-commands equivalent to each REMOTE
command: RCD, RPWD, RDIR, RWHO, etc.  But not RLOGIN because that already
means something else.  ckuusr.h, 13 Aug 98.

Made REMOTE { L, LO, LOG } be synonyms for REMOTE LOGIN.  ckuusr.c, 13 Aug 98.

Moved REMOTE LOGIN parsing code to its own routine, plogin().  ckuus7.c,
13 Aug 98.

The LOGIN command that we added a few weeks ago can not possibly be of any
use, so I changed it to call plogin().  So LOGIN is now a synonym for REMOTE
LOGIN.  And I added a LOGOUT command that is a synonym for REMOTE LOGOUT.
ckuusr.c, 13 Aug 98.

Added a few R commands: RASG/RASSIGN, RCD/RCWD, RCOPY, RDELETE.  These simply
chain to the corresponding REMOTE commands.  They work fine.  ckuusr.c,
13 Aug 98.

Added the rest: RDIR, REXIT, RHELP, RHOST, RKERMIT, RPWD, RRENAME, RREMDIR,
RSET, RSPACE, RTYPE, and RWHO.  ckuusr.c, 13 Aug 98.

Merged first stage of Jeff's changes to reorganize Telnet protocol support.
All Telnet symbol & struct definitions moved to new ckctel.h.  All IKS_*
and *_IKS symbols changed to KERMIT_* and *_KERMIT.  Many modules, 14 Aug 98.

Added ckctel.h dependencies to UNIX makefile.  14 Aug 98.

Changed C-Kermit version number from 6.1 to 7.0 and test level from Beta.06
back to Alpha.01.  makefile, ckcmai.c, 14 Aug 98.

Fixed command parser to not respond to recall keys when on_recall == 0,
as it is (e.g.) in getyesno().  ckucmd.c, 14 Aug 98.

Chasing down "Receive window full" problems...  First, I found a scenario that
would always create it: start server, go back to client, and tell client to
"remote login blah" (when login not required), "remote logout", "remote cd
invalid-directory", "remote cd valid-directory", "remote dir".  Debug logs
showed some mighty strange paths thru the code...  First discovery: the SERVE
macro definition contains more than one statement, but did not enclose the
statements in braces.  Therefore, subsequent constructions like "if (blah)
xxx; else SERVE;" did not work as intended.  Added braces around definitions
of SERVE and RESUME.  ckcpro.w, 14 Aug 98.

But this did not make the problem go away.  Next discovery: sometimes the
sequence above would result in an error "It's a directory", which is found
only in the REMOTE DELETE code.  How did we get there???  Well, sending the
"Receive window full" error packet set the packet type to E, so the next call
to input() returned 'E'.  But the protocol machine was still in "generic"
state, and "<generic>E" is REMOTE DELETE.  So I had the errpkt() routine
reset the protocol state to 0.  So no more "falling" into the REMOTE DELETE
code.  ckcfn2.c, 14 Aug 98.

Next...  Server sends a "Receive window full" error packet, but it is not
displayed by the client.  Why?  Because C-Kermit always ignores E packets that
arrive in response to an I packet, to allow for the possibility that the server
does not understand I packets.  We can't do anything about this, but it has
probably been hiding the "Receive window full" problem enough that we did not
realize how often it was really happening.

So why is it happening?  Logs show that we are not always calling tinit()
(transaction initialization) after sending a short-form reply to a server
command, or an ACK to an I packet.  I-packet first...  After the code to ACK
the I packet, I replaced the call to pktinit(), which simply reset winlo and
pktnum to 0, with tinit(), which resets everything.  Ten minutes of testing
now shows that (a) this does no harm (and in any case it is proper since the
I/Y exchange is, by definition, a complete protocol transaction), and (b)
seems to isolate the problem to whatever transaction follows a successful
REMOTE CD.  Finally...  the problem with REMOTE CD turned out to be the code I
added on July 21st to send back the contents of a .readme file, if any -- it
neglected to handle the case where there was not a .readme.  Fixed in
ckcpro.w, 14 Aug 98.

I also fixed a potential problem on the server end of REMOTE PWD, in which
it would fail to send a response if the directory name was too long.
ckcpro.w, 14 Aug 98.

From Jeff:

Date: Sat, 15 Aug 98 0:33:04 EDT
From: Jeffrey Altman <jaltman@watsun.cc.columbia.edu>
To: fdc@watsun.cc.columbia.edu
Subject: new files

just about every file has been touched.  The new telnet code is
operational but the initialization stuff has barely been addressed.

Basicly what I have done is implemented all of the major changes to
tn_doop() and its related support functions to use the new model.
I have replaced all variables such as Me_binary, U_binary, ... with
calls to the new TELOPT macros.  I did not make these changes to
VMS specific files such as console and terminal i/o.

me_binary becomes TELOPT_ME(TELOPT_BINARY)
u_binary becomes TELOPT_U(TELOPT_BINARY)

etc.  These macros may be used on both the left and right sides of an
assignment.  What I have not doone is address any of the issues we
spoke about regarding initialization of the ME and U modes.  There is
a new function tn_set_modes() which is called in ckcmai.c that is used
to set the initial defaults.  tn_ini() needs to be modified to read
user defaults for client and server modes.  These fileds of the
structures are not yet defined.

For compilation purposes the tn_binary, tn_echo, tn_auth,
... variables are still declared in ckcnet.c.  These are needed so the
command parser will compile but the variables are not used at all
anymore in ckcnet.c.  So don't try to use them to control telnet
option activation.  They won't work.  I will address these issues
either tomorrow night or Sunday.

Something I noticed is that server mode does not exit anymore when
started by a terminal autodownload "kermit -Iig ..."  This appears to
be a side effect of the changes you made this afternoon.  However, I
have not spent any time to try and track it down.

The changes to ckcnet.c reduced the code by over 400 lines and 100K in
exe size.

(end quote)

IBM added the Euro symbol to a vacant position in CP857; updated the
corresponding tables in ckouni.c.  15 Aug 98.

Incorporated the network code changes from Jeff's message above.  Most
modules, 17 Aug 98.

Made DISABLE apply not only to REMOTE commands sent to the server, but also,
when C-Kermit is an Internet Server, to the corresponding commands given at
the prompt.  For example, if C-Kermit has been told to DISABLE RENAME, then
it won't execute REMOTE RENAME commands in server mode, nor RENAME commands
from its prompt.  ckuusr.c, 17 Aug 98.

Made DISABLE CD when inserver also SET { SEND, RECEIVE } PATHNAMES OFF.
ckuus6.c, 17 Aug 98.

Made wtmp entry always use at least 4 digits for the hex pid.  ckufio.c,
17 Aug 98.

Discovered that "set proto kermit {} {} {}" did not undo the "autosever"
command string.  This uncovered a rat's nest resulting from the fact that this
string is not part of the regular protocol info struct, so I redefined the
struct to include it and removed the special case from all modules that knew
about it.  ckcker.h, ckcmai.c, ckcpro.w, ckuus3.c, 18 Aug 98.

The check in cmdlin() for command-line options not valid with -A was
preventing "kermit" commands, when given at the prompt (e.g. the "kermit -r"
autoupload string from a client), from working.  Fixed in ckuusy.c, 18 Aug 98.

Don't send auto-blah strings ("kermit -r", "kermit -x", etc) if we know the
other Kermit is a server.  ckcpro.w, 18 Aug 98.

Set flow to NONE (except in VMS) for IKS.  ckcmai.c, 18 Aug 98.

Jeff's changes & fixes: ckcnet.h, ckcpro.w, ckcmai.c, ckutio.c, ckcnet.c,
19 Aug 98.

Make ttol() and conol()/conoll() copy their arg before encrypting (ttol()
already did) in case they are called with a literal string.  Buffers are
malloc'd only if/when needed; copy is done only when encrypting.  ckutio.c,
19 Aug 98.

Added partial ttpush() support to ckutio.c within #ifdef TTLEBUF..#endif.
More pieces added by Jeff.  ckutio.c, ckcnet.c, 19 Aug 98.

Fixed spurious "?Packet log wasn't open" message when CLOSE command given
with no operand.  ckuusr.c, 19 Aug 98.

Changed CLOSE command not to ask "OK to close?".  Obviously the user knows a
connection was open or she wouldn't be trying to close it.  ckuusr.h,
ckuus[r7].c, 19 Aug 98.

REMOTE commands that only result in sending text to the client's screen can
have no useful effect when issued from a remote-mode client when the result is
not redirected.  These commands include DIR, TYPE, WHO, etc, but not SET,
ASSIGN, QUERY, etc.  C-Kermit now refuses to execute REMOTE commands that
can have no useful effect.  ckuus7.c, 19 Aug 98.

Due to confusion between console and communications buffers, made the
following conxxx() functions route to the corresponding ttxxx() functions when
(inserver && !local): conoc(), conxo(), conol(), conola(), conoll(), conchk(),
coninc(), congks().  ckutio.c, 20 Aug 98.

Adapted REMOTE HELP text to IKS.  ckcfns.c, 20 Aug 98.

When REMOTE LOGIN prompts for user ID & password, don't put them in the
command recall buffer.  ckuus7.c, 20 Aug 98.

Got rid of LOGIN command, and made LOGOUT act locally rather than being a
synonym for REMOTE LOGOUT.  So:  REMOTE LOGIN must be used to log in from a
client to a server; REMOTE LOGOUT is used to log a client out from a server;
and LOGOUT is used to log out the server from its prompt.  ckuusr.c, 20 Aug 98.

Added HELP LOGOUT and updated HELP REMOTE.  ckuus2.c, 20 Aug 98.

Removed #include "ckucmd.h" from ckcmai.c and ckutio.c.  Added the struct
keytab definition to ckcdeb.h, so all modules can use it without reference to
ckucmd.h.  20 Aug 98.

Got rid of getchar() calls from ckucmd.c, since they were not going thru the
myread buffering, and therefore were wrecking decryption.  ckucmd.c, 20 Aug 98.

Fixes from Jeff: ckctel.h, ckucmd.c, ckutio.c, ckcmai.c, ckcnet.c, 21 Aug 98.

Fixed a typo in tn_ini() that prevented client from sending initial Telnet
negotiations on port 1649.  ckcnet.c, 21 Aug 98.

Added an "iksd" personality, which simply sets inserver to 1 automatically
when the binary is called "iksd".  ckcker.h, ckcmai.c, ckuus4.c, 21 Aug 98.

Added extended-format command-line args for iksd:

 --anonymous:{on,off}
 --syslog:{on,off}
 --permissions:<octal-value> (like wuftpd -- permissions, not umask)
 --wtmp:{on,off}

These are parsed in prescan().  Currently, *all* extended-format options are
parsed in prescan.  Later we'll need a way to separate those that are done
in prescan from those that are done after the init file.  Note: {on,off}
also has synonyms {yes,no} and {true,false}.  ckuusy.c, ckuus4.c, 21 Aug 98.

From Jeff: fix a char declaration to be unsigned char to prevent sign
extension, which was wrecking encryption: ckutio.c.  Prevent encryption from
being negotiated if Telnet authentication failed: ckcnet.c.  Make all
file i/o routines go through con/tt routines when the file is really the
terminal, since the con/tt routines now take care of en/decryption, and
bypassing them destroys the encryption stream: ckufio.c. 22 Aug 98.

Updated the SunOS IKS makefile entry and renamed it to sunos41giks.
This entry does not define CK_CURSES or link with the curses library.
makefile, 22 Aug 98.

Disable file-transfer display for IKS in such a way that tgetent() is never
called by IKS, even if it is compiled in and even if the fullscreen file
transfer display would normally be used.  ckuusx.c, 22 Aug 98.

Modified Jeff's changes to ckufio.c.  The idea was to catch the case where
the client was printing stuff on its "screen" coming back from the server in
response to a REMOTE command.  But in this case, the screen his hidden from
the user anyway, so there is no point going through all the overhead of
encrypting, then printing it -- now these routines simply discard the output
but act as if they had printed it (in terms of return codes, global variables,
etc).  Left Jeff's code in the source file, commented out. ckufio.c, 22 Aug 98.

Defined a new keyword flag, CM_PRE, to be used with long-form command-line
options.  If set, the option is to handled by prescan(), i.e. prior to init
file processing; otherwise it is handled after the init file along with other
command-line options.  ckucmd.h, ckuus[4y].c, 22 Aug 98.

Rules for long-form command-line options are:

 1. All long-form options must begin with "--" (two hyphens) or "-+".  If the
    option begins with "--" it is executed before or after the init file,
    according to its internal keyword flags.  If it begins with "-+", it is
    executed before the init file, regardless of the flag bits.  There is no
    way to force an argument to be executed after the init file if it has the
    CM_PRE bit set.  (The "+" business will not necessarily be advertised...)

 2. No spaces are allowed in the keyword.

 3. If an operand contains spaces, it (or the entire option) must be quoted
    according to the rules of the shell from which Kermit is invoked.

 4. Case doesn't matter in the option keyword (unlike with regular
    single-letter options).

 5. If an operand is required, it must be included.  If no operand is
    required, no operand must be included.

 6. The operand follows the keyword, separated by a colon (:) or equal
    sign (=).  There are no spaces between the separator and the keyword
    or operand.

 7. Long-form option names may be abbreviated according to the same rules as
    interactive keywords.

 8. On/Off operands can be On, Off, Yes, No, True, or False.

 9. Long-form options are available only when the interactive command parser
    is built-in (i.e. not NOICP).

Added code to actually use the new command-line options:
 --permissions are applied as given to anonymously uploaded files.
 --anonymous:off disables anonymous logins.
 --wtmp:off disables wtmp.
syslogging still isn't being done, so no effect there.  ckufio.c, 22 Aug 98.

Discovered that permission-setting code works only if ATTRIBUTES ON, so
anybody could defeat it by uploading files with SET ATTRIBUTES OFF.
Rearranged the code to plug this loophole.  ckufio.c, 22 Aug 98.

After all this, it seems that all sorts of trouble ensues from prescan()
being called twice; for example, "kermit commandfilename" no longer works.
I have no idea why prescan() is called twice, so I commented out the second
call, now all seems well.  ckcmai.c, 22 Aug 98.

Fleshed out the command-line options some more.  Now they are:

  --anonymous    on/off      anonymous login allowed
  -+cdfile       filename    CD message filename
  -+cdmessage    on/off      CD messages on/off
  -+cdmsg        on/off      synonym for cdmessage
  --logsyslog    on/off      syslog logging on/off
  --logwtmp      on/off      wtmp logging on/off
  --permissions  octalnum    permissions for files uploaded anonymously
  --perms        octalnum    synonym for permissions
  --wtmpfile     filename    pathname of wtmp logfile

Those shown with "-+" can be given by ordinary users.  The CD message
items correspond to SET SERVER CD-MESSAGE { ON, OFF, FILE <name> }.
These all work except for syslog.  ckuusy.c, 22 Aug 98.

Minor corrections from Jeff to yesterday's changes: ckuusy.c, ckutio.c,
23 Aug 98.

Added the appropriate #ifndef NOICP..#endif's to long-form command-line
option code.  ckuusy.c, 23 Aug 98.

Finished the half-done IKS-related #ifdef section in ckcdeb.h, 23 Aug 98.

Ensured that /pub/ftp/.kermrc is TAKEn as init file when user logs in to
IKS anonymously.  ckuus5.c, 23 Aug 98.

Added --initfile:<path> to allow sysadmin to change the default init file
for anonymous users.  ckuusy.c, ckuus5.c, 23 Aug 98.

Added MKDIR and RMDIR to list of functions automatically disabled for
anonymous users (which previously included only MAIL and PRINT), since leaving
them enabled clashed with wuftpd behavior (e.g. ftpd could not create a
directory in kermit/incoming, but iksd could).  It is still possible for the
sysadmin to enable directory creation (and removal too).  ckcmai.c, 23 Aug 98.

Another loophole: OPEN WRITE / WRITE / CLOSE WRITE bypassed the
--permission:xxx value.  In fact, there are lots of file creation methods that
did this: logs (even though we have disabled the LOG command), TRANSLATE, and
REMOTE BLAH > file.  And who knows what else.  So I moved the chmod() code
from zstime(), which is called only when receiving files with Kermit protocol,
to zopeno(), which is called whenever *any* file is to be created.  ckufio.c,
23 Aug 98.

Don't let guests SET FILE COLLISION OVERWRITE or UPDATE (they already could
not use RENAME or UPDATE).  This prevents guests from overwriting or changing
or destroying existing files.  ckuus7.c, 23 Aug 98.

Minor corrections to yesterday's work from Jeff, plus beginning of SSL
support.  ckuusy.c, ckcnet.c, etc, 24 Aug 98.

If NOICP defined, then -A implies -x.  ckuusy.c, 24 Aug 98.

When client sends REMOTE LOGOUT and gets the ACK, it now closes the connection
(same as it already did with BYE).  ckuus7.c, 24 Aug 98.

Added openlog() call for IKSD, specifying tag of "iksd" and LOG_PID, and going
to the regular daemon log.  Now syslogging works for regular logins, but the
anonymous ones doen't seem to be making it into the log.  To be continued.
ckufio.c, 24 Aug 98.

Verified that sending huge strings to the IKS (e.g. to the Username: or
Password: prompt) does not break it.  26 Aug 98.

Merged Jeff's recent changes, mostly for SSL / TLS.  Many modules, 28 Aug 98.

Made \v(line) return ckgetpeer() value in IKS.  ckuus4.c, 28 Aug 98.

Fixed \v(nday) not to depend on English day names.  ckuus4.c, 28 Aug 98.

Added --userfile:filename to command line for IKS: filename of forbidden
user file.  Fixed checkuser() routine, which was not working before.
ckuusy.c, ckufio.c, 28 Aug 98.

Added "ok" to list of valid extended option on/off value synonyms.
ckuusy.c, 28 Aug 98.

More SSL / TLS changes from Jeff, many modules, 29 Aug 98.

Changes to extended command-line options:

  --logwtmp changed to --wtmplog (on/off)
  --logsyslog:on/off removed.
  --syslog:<number> added, where <number> = level of logging.

So far this is parse-only, no action.  ckcdeb.h, ckuusy.c, ckufio.c, 29 Aug 98.

Added logging for commands (level 4).  At first I logged all commands but that
was WAY too much.  Now only interactive commands (not TAKE files or macros).
Also, cleaned up login/logout entries.  ckufio.c, ckucmd.c, ckuusx.c,
29 Aug 98.

Discovered that "implied partial dial", which occurs when you use the DIAL
command but terminate the phone number with a semicolon, CONNECTs
automatically when done at top level.  Which is very confusing when you're
dialing a numeric pager.  Fixed in ckudia.c, 30 Aug 98.

Automatically DISABLE ENABLE for anonymous users.  ckcmai.c, 30 Aug 98.

Added missing "extern" to telopt_states[] declaration in ckctel.h, 30 Aug 98.

Spent many hours trying to figure out why syslogging does not work in iksd
when user is logged in anonymously.  It turns out that in SunOS, chroot(),
once called, totally breaks syslog() -- i.e. syslog() will never write another
entry after chroot() is called.  It makes no difference whether openlog() is
called before or after chroot(), or not at all.  So is this a SunOS
peculiarity?  To test, went to build on Solaris (for the first time in months)
and of course had all sorts of trouble compiling.  Once it compiled, anonymous
logins did not work because there is no /pub/ftp directory.  So I temporarily
dummied up a different root for testing, and then all worked OK.  So it seems
to be a SunOS peculariarity?  There seems to be nothing I can do about it.
Sent off a query to the sys folks.  30 Aug 98.

Found that struct utmp member ut_host is not portable, so started building
a pile of #ifdefs for when to include it.  This will be an ongoing project.
ckufio.c, 30 Aug 98.

Added --root:xxx so an alternative root for anonymous users can be supplied
at runtime.  ckuus[5y].c, ckufio.c, 30 Aug 98.

Started adding syslog() code for file creation / deletion / modification.
File creation and appending in zopeno().  File deleting in zdelet().
File renaming in zrename().  File copying in zcopy().  ckufio.c, 2 Sep 98.

Fixed mutually reinforcing bugs in ttpeek() (ckutio.c) and the code in
ckucns.c that calls it, that stopped CONNECT mode dead; ttpeek() wasn't
taking the new local-echo buffer into account, so CONNECT would think there
was nothing to read, when in fact some stuff was sitting in the new buffer,
and so would block on a network read when in fact the network was waiting for
a reply.  Fixed 3 Sep 98.

Fixes from Jeff for a Telnet negotiation problem in ckcnet.c and for an "=="
that should have been an "=" in ckcfns.c (affecting the EOF/Ctrl-Z code).
Also, revision of the C1 control symbols in ckcasc.h to avoid conflicts with
new Microsoft symbols.  4 Sep 98.

Enclosed reference to <asm/termios.h> for Linux-on-Alpha in #ifndef __GLIBC__
to avoid yet another conflict.  ckutio.c, 4 Sep 98.

Microsoft added upper- and lowercase Z caron to CP1252.  I added these to the
CP1252/Unicode translations, and also corrected a typo in the translation of
the 'oe' character from Unicode to CP1252.  ckuouni.c, 4 Sep 98.

Changes from Jeff.  Protect SET FILE DISPLAY FULL tgetent() from trapping if
trmbuf not allocated: ckuus[7x].c; server-side terminal type negotiation:
ckcnet.c, 5 Sep 98.

Fixed a bug that limited the LOCAL command to only 10 variables, even though
the advertised maximum was 64.  dolocal(), ckuus5.c, 5 Sep 98.

Added a check for sequence number out of range to ttinl().  See comments in
source code for a detailed explanation.  ckutio.c, 5 Sep 98.

VMS cdate[] array declaration, used for setting file date,  needed to be 24,
not 23.  ckvfio.c, 5 Sep 98.

For DEC C (VMS or Digital UNIX), when _POSIX_C_SOURCE is not defined, #define
it with a value, such as 1, rather than without one, since its value is used
in comparisons in DEC C header files like unistd.h.  ckcdeb.h, 5 Sep 98.

Various mysterious problems with SEND /AS-NAME: were traced to the keywords
in sndtab[] being out of alphabetical order.  Fixed in ckuusr.c, 5 Sep 98.

However, some additional problems remained, in which certain switches were not
parsed successfully if COMMAND QUOTING was OFF and they were entered without
completion (Tab or Esc).  This was due to failure to set the field length in
one of the paths through cmkey2().  Fixed in ckucmd.c, 5 Sep 98.

Changes from Jeff to start supporting an overhauled way of setting/showing
Telnet options.  Many modules, 8 Sep 98.

Added "OE compliance" -- Latin-9 conversion for DEC MCS and NeXT, which both
contain OE characters.  ckuxla.c, 8 Sep 98.  (I could do the same for DG, but
I doubt anyone would notice.)  (Ditto for Macintosh.)

Changed protocol machine to take connection loss in response to a BYE command
(while waiting for the ACK) as success rather than failure. ckcpro.w, 8 Sep 98.

Preliminary code for dynamic Telnet-wait timer from Jeff.  ckcnet.c, 9 Sep 98.

Removed "if (srvbuf)" from setlin() routine, since srvbuf is an array, not a
pointer, and this crashes the ICL compiler.  ckuus7.c, 9 Sep 98.

Added GETKEYCODE <var> <prompt> for K95.  Lets user get the keycode of any
key event (F-key, Alt-combination, etc) into a variable.  Also changed GETC
to put console in raw mode to read the one character, so any character at all
can be typed, even Ctrl-C, after which we go back to CBREAK mode.  Needs
testing.  ckuusr.[ch], ckuus6.c, 9 Sep 98.

Changed the way the MODEM ESCAPE-CHARACTER is specified and used:

 < 0 means the escape mechanism is disabled.
 = 0 means to use (restore) the default value from the modem database.
 > 0 and < 128 is a literal value to be used instead of the default one.
 > 127 means the escape mechanism is disabled.

This affects "modem hangup".  When the escape mechanism is disabled, but SET
MODEM HANGUP-METHOD is MODEM-COMMAND, it sends the hangup command immediately,
without the <pause>+++<pause> business first.  This is useful (for example)
when sending lots of numeric pages, a process in which we never go online, and
so never need to escape back.  Eliminating the unnecessary pauses and escape
sequence allows a lot more pages to be sent per unit time.  Needs testing.
ckudia.c, 9 Sep 98.

In order to test modem, dial, and serial port items, tried building on HP-UX
10.20 for the first time in months.  Compiled OK (!) but failed to find
sete[ug]id() at link time.  Made it use setre[ug]id() instead.  Obviously this
area will need a lot more attention since we don't want to mess up when
logging in IKS users...  Needs testing.  ckufio.c, 9 Sep 98.

Changes from Jeff to show a spinner during telnet negotiation wait, to reorder
the terminal-type negotiation list, and to check for failure of tn_ini(), e.g.
when connection rejected by TCP Wrappers.  ckuusr.[ch], ckuus7.c, ckcnet.c,
10 Sep 98.

Some #ifdefs to allow compilation on ICL DRS/NX, plus adjustments to the ICL
makefile entries.  ckcmai.c, makefile, 10 Sep 98.

Somehow a DECC Alpha VMS build is picking up both the bzero/bcopy macro
definitions AND the prototypes for bzero() and bcopy().  Added #ifdefs to
prevent this.  ckcnet.h, 10 Sep 98.

Added *.pdf to default binary-patterns list.  ckcmai.c, 11 Sep 98.

Changed the main Linux build to #define CK_NCURSES, which in turn #include's
<ncurses.h> rather than <curses.h>, and links with libncurses rather than
libcurses, since newer Linux systems seem to lack symlinks from curses to
ncurses, and added a "linuxc" entry that still references curses.  However,
neither curses.h nor ncurses.h can be found on the Red Hat 5.1 system I have
access to.  makefile, ckcdeb.h, ckuusx.c, 12 Sep 98.

Building on Linux 1.2 (some old Red Hat version, not sure of the number),
complained of a syntax error in <syslog.h>:

  /usr/include/sys/syslog.h:189: unrecognized format specifier for `'

Building again with -DNOSYSLOG moves the problem to ncurses.h.  The problem
is that both of these header files refer to "printf" in macro definitions, but
(in UNIX) we have defined printf to be a macro that expands to "ckxprintf".
Thus, before including any headers that refer to printf, we have to #undef
printf, and then redefine it afterwards.  YUK!!!  ckucmd.c, ckuusx.c,
ckufio.c, 12 Sep 98.  NOTE: In the future, we should add a new header file,
which is to be included in each module AFTER ALL OTHER header files, to undo
whatever the earlier headers might have done, and to define macros that
substitute homegrown routines for library routines or system calls, so we
don't have to remember to insert little undef...redef clauses around #includes
all over the place.

Back to Linux 2.0.34...  The logwtmp() declaration blew up the compiler,
needed ANSIfication.  ckufio.c, 12 Sep 98.

With the fixes above, and using a new "linuxnc" (no-curses) makefile entry,
we still fail in the link step because the crypt() routine can't be
found.  Digging through the libraries shows it has moved from libc to
libcrypt.  Swell, so we need yet another makefile entry, linuxlcnc ("link
with libcrypt, no curses").  So now it builds on Red Hat 5.1, kernel 2.0.34,
but without curses support.  makefile, 12 Sep 98.

Noticed that the code contained various #ifdef LINUX constructions, but
LINUX was never defined anywhere.  Added a clause to ckcdeb.h to define
LINUX if it was not defined but __linux__ was defined, and also added
-DLINUX to all Linux entries.  makefile, ckcdeb.h, 12 Sep 98.

Defined -DDYNAMIC by default for all UNIX builds, and removed it from all
makefile entries that included it.  ckcdeb.h, makefile, 12 Sep 98.

Found that Linux keeps its wtmp file in a different place than other UNIXes.
Adjusted via #ifdefs.  ckufio.c, 12 Sep 98.

Found that UNIX ttinl() still had one or two return points where it failed to
turn off its alarm(), due to recent changes, and of course whenever that
happened, the alarm would eventually go off, crashing the program.  Fixed in
ckutio.c, 12 Sep 98.

Put Telnet-wait "spinner" display code in #ifdef CKSPINNER, and left it
undef'd, put back the regular dots.  The spinner is not good for speech
devices, scripts, etc, and is unlike anything else in C-Kermit's user
interface, and also wouldn't look right when viewed through any terminal or
emulator using an NRC.  ckcnet.c, 12 Sep 98.

Defined KANJI by default if NOCSETS not defined and NOKANJI not defined; same
as for all other character-set families (Latin-1, Latin-2, Greek, Hebrew,
Cyrillic): ckcxla.h.  Removed all explicit #defines for KANJI from ckcdeb.h
and makefile.  13 Sep 98.

Made some adjustments to the ex-spinner code so it doesn't spurt out a burst
of dots, but only prints one every second (i.e. when there is a timeout), and
labeled this section "Negotiations:" and put "(OK)" at end, like in the DNS
section.  Also, made this section disablable via SET QUIET ON, like the other
sections.  ckcnet.c, 13 Sep 98

In an effort to handle the /dev/modem problem in Linux, and the
lockfile-versus-symlink problem in general, added code to ttlock() to see if
device name is a symlink.  If so, islink is set to nonzero and linkto[] (yet
another static buffer) contains the name pointed to by the symlink.  Using
stat() and then S_ISLNK() does not work on some platforms, so instead we
always just call readlink(), which fails if it is not a link, but returns the
file's real name if it is.  If device name is a link we create a second
lockfile, which is a link to the first one, but based on the device's real
name.  The second lockfile is removed in ttunlk().  This code works everywhere
but in systems that use ttlock() (currently only AIX) and HP-UX, which has its
own dual-locking system.  All the symlink/readlink related code is #ifdef
CKSYMLINK, so it can be disabled on platforms that don't have readlink(), or
where it doesn't work.  ckutio.c, 13 Sep 98.

After yet another prolonged discussion of lockfile names for SCO...  The
concensus of the experts is that the device name should be lowercased for
creating the lockfile, and this is how it was already.  However, Dmitri
Zuryanovich reports from Russia that this is not consistent with mgetty.
Example: "set line /dev/tty1A" creates LCK..tty1a, and while cu and friends
follow the same convention, mgetty creates and checks for LCK..tty1A.  So,
piggybacking onto the previous item, if the given device name is not a
symlink, I pretend that the original name is a symlink.  Then, after
lowercasing the name, if the result is different from the original, I keep the
original name as the basis for the second lockfile, otherwise I create only
one lockfile as before.  If a second lockfile is created, it is deleted
automatically at the same time the first one is.  The possible pitfall here,
of course, is that there might actually be a distinct device with
corresponding lowercase name.  But since that was the name we always used for
the lockfile anyway, this change can't possibly do any additional harm.
ttlock(), ckutio.c, 13 Sep 98.

Changed "show comm" to report any secondary lockfile.  ckuus4.c, 13 Sep 98.

Discovered that when SET MODEM HANGUP-METHOD is MODEM-COMMAND, that if a
HANGUP command is given before a DIAL command was given, it doesn't use the
modem hangup command.  Fixed in mdmhup(), ckudia.c, 13 Sep 98.

Discovered that MODEM HANGUP-METHOD is not displayed by SHOW MODEM.  Fixed in
ckuus3.c, 13 Sep 98.

Verified that SET MODEM SPEED-MATCHING works correctly.  The confusion comes
when users SET MODEM TYPE HAYES (2400 or 1200) to dial a more modern type of
modem -- Kermit automatically SETs MODEM SPEED-MATCHING ON, as it must for any
kind of modem that does not do speed buffering.  Let's keep this in mind when
explaining how to write alpha pager scripts.

Increased character spacing for Rolm DCM dialing from 5 msec to 50, since
some failures had been observed.  Seems to work fine for both Rolm DCM and
600-Series AT-dialing.  ckudia.c, 13 Sep 98.

Found that starting a phone number with "=", which is supposed to indicate
a literal string to be dialed, was no longer stripping off the "=" before
dialing the string.  Fixed in dodial(), ckuus6.c, 13 Sep 98.

From Jeff: Enabled CKSPINNER for K95 and adjusted spinner-vs-dots code.
ckcdeb.h, ckcnet.c, 14 Sep 98.

The SET LINE / SET HOST command was printing an annoying blank line.  Fixed in
gtword() by disabling echo not only if reading from chars already in command
buf, but also if reading a pushc'd character.  ckucmd.c, 14 Sep 98.

Fixed a reference to a null pointer in mdmhup(), from Jeff.  ckudia.c,
14 Sep 98.

Fixed dohexdump() prototypes to avoid ANSI complaints.  ckcdeb.h, 14 Sep 98.

Added assorted casts in tn_doop() to shut up ANSI complaints.  ckcnet.c,
14 Sep 98.

Verified that IKSD writes just fine to syslog() on Solaris 5.1, even after
chroot().  So the problem with syslog() entries disappearing into the void
after chroot() is not universal, and perhaps might be peculiar to SunOS.
We'll see...

Added --syslog:5 (debugging) support.  Automatically opens debug log and
writes debug records to syslog.  ckuus[xy].c, 15 Sep 98.

Added code to turn off syslogging around login/password dialog, so user ID
and Password are not entered in logs for levels 4 and 5 (commands and debug).
this change does not affect the secure entry of Authentication info at syslog
level 1.  ckuus7.c, 15 Sep 98.

Added a system-independent syslogging routine to UNIX C-Kermit:
cksyslog(int,char *,char *,char *).  This needs to be added to any other
ck?fio.c module for builds in which CKSYSLOG is defined.  It allows the system
independent modules to call the syslogging function without using system
dependent code, and (at least in the UNIX case) isolates the #ifdef printf
craziness to one place.  ckcdeb.h, ckuusx.c, ckucmd.c, ckufio.c, 15 Sep 98.

Added incoming server commands to level 4 syslogging.  ckcpro.w, 15 Sep 98.

Changed default prompt to say IKSD rather than C-Kermit or K-95 (etc) when
running as IKSD.  Also changed default UNIX prompt to show current directory
in parens rather than brackets since brackets don't show up right if an NRC
is in use.  ckuus5.c, 15 Sep 98.

Made the syslog messages a bit more consistent:

  login: user host
  login: anonymous host password
  logout: user host
  command: text             <-- Should these also include user
  server: text              <-- and host?  (They do include the
  file[n] name: text        <-- PID, but PIDs can wrap...)

ckufio.c, 15 Sep 98.

Logging commands currently has the failing that the result (success or
failure) is not shown.  Tried moving the logging point from cmcfm() to the
top of the parse loop, and logging the contents of cmdbuf[] (which should
contain the previous command) and the success variable (which applies to the
previous command), but by that time too many things have might have happened
to the command buffer.  So for now we'll leave it as is.

Found a double-ended bug in the READ command, potentially affecting all
versions, but only showing up in the VMS version: the zsinl() function
properly returned -1 on EOF, but the READ command code (too) cleverly ignored
the return code if there was also something in the buffer (to allow reading a
final line that lacked a terminator).  But if the buffer was not cleared
prior to trying to read, the final line would be read successfully forever.
Fixed at both ends.  ckufio.c, ckvfio.c, ckuus5.c, 16 Sep 98.

Added a new level of syslogging: 5 = commands from macros or files.  Debug
level moved up to 6.  ckcdeb.h, ckuusy.c, 16 Sep 98.

Added an optional and separate iksd log.  Opened in zvpass() prior to
chroot(), so works for anonymous logins even on SunOS.  Writes its record in
zclose().  Format is exactly the same as wu-ftpd, except instead of "ftp" it
says "iks" in the 11th field.  A couple items still need to be fixed, and
format of the log needs to be documented.  Also, I need to test if iksd can
share the actual ftpd.log with wu-ftp.  ckuusy.c, ckufio.c, 16 Sep 98.

Sequence-number out-of-range check added to ttinl() on 5 Sep 98 was looking
at the wrong field, spotted by Jeff.  Fixed in ckutio.c, 17 Sep 98.

Added original file-system root to beginning of fullname[] in iksdlog when
user is anonymous and therefore chroot'd, so complete filespec is logged.
Also fixed elapsed-time field, which previously always registered 0.  Also
fixed the i/o field, which had reverse sense.  ckufio.c, 17 Sep 98.

Verified that iksd can log to the same file as ftpd.  However, I noticed that
ftpd does not log transfers by real users, and also that it does not show
the full filespec.  I commented out the code that adds the chroot path to the
filespec since ftpd doesn't show the full real path, and the object is to stay
compatible.  ckufio.c, 17 Sep 98.

Changes from Jeff mainly for new SET TELOPT command.  ckuus3.c, ckuusr.h,
etc., 18 Sep 98.

Supplied missing */ from comment in ckuusr.h.  18 Sep 98.

Fixed various other preprocessor syntax errors.  ckcfns.c, ckuus6.c, 18 Sep 98.

Discovered that {get,end}usershell() is not portable.  So #ifdef City has
another population explosion...  ckcdeb.h, ckufio.c, 18 Sep 98.

Disabled DELETE command for guests.  ckuus[r67].c, ckufio.c, 18 Sep 98.

RENAME is the only file collision option that is safe for guests to use.  All
the others destroy or rename or alter existing files.  Added code to enforce
this.  FILE COLLISION RENAME is set at anonymous login time and the SET FILE
COLLISION command is disabled for guests.  Also the server rejects any REMOTE
SET FILE COLLISION commands.  ckcfns.c, ckuus7.c,  18 Sep 98.

Fixed DISABLE DELETE to also set FILE COLLISION to RENAME and to disable the
SET FILE COLLISION command.  ckuus[67].c, 18 Sep 98.

Fixed COPY command to check if destination file already exists and if so
to fail if DELETE is DISABLEd or if user is anonymous.  ckuus6.c, 18 Sep 98.

Made snddir() and snddel() return 0 upon failure to do their jobs (as now),
or -1 if the given filespec did not match any existing files (new).  ckcnfs.c,
18 Sep 98.

Made protocol module send Error packet if REMOTE DELETE or REMOTE DIRECTORY
was executed on a filespec that could not be found, thus causing the client
command to fail rather than succeed, to match the reasonable expectations of
users.  ckcpro.w, 18 Sep 98.

Made COPY command enforce one-file restriction; no wildcards.  It already
did this in K95.  ckuus6.c, 18 Sep 98.

Don't allow changing of protocol to anything but Kermit in IKSD.  ckuus3.c,
ckcfn2.c, 18 Sep 98.

Added provision for NOIKSD at compile time, which defines all the appropriate
NOblah symbols to disable IKSD-specific code.  If NOIKSD is not defined, IKSD
is defined automatically (but currently not used for anything).  ckcdeb.h,
18 Sep 98.

Changes to SET TELOPT parsing from Jeff, ckuus3.c, 21 Sep 98.

Added TYPE /PAGE (and /NOPAGE).  /PAGE forces askmore() prompting.  /NOPAGE
disables it.  Default (if no switch given) is according to the current COMMAND
MORE-PROMPTING setting.  Prevailing setting is undisturbed by switches, and
is restored automatically if the TYPE command is interrupted with SIGINT.
ckuusr.h, ckuus[r56x].c, 21 Sep 98.

Added --bannerfile:filename, which tells the herald() routine to print the
contents of the given file, rather than what it normally prints.  Uses more-
prompting (i.e. works like TYPE /PAGE).  For use with IKSD, but can also be
used in regular C-Kermit.  ckuus[56x].c, 21 Sep 98.

Fixed herald() to put console in cbreak mode before calling askmore().
ckuus5.c, 22 Sep 98.

Added --help, which lists the available extended command-line options.
ckuusy.c, 22 Sep 98.

Added HELP EXTENDED-OPTIONS, which is like HELP OPTIONS, but for the extended
ones (and also is like --help, but with more-prompting).  Also added a pointer
from HELP OPTIONS to HELP EXTENDED.  Also added a very brief HELP IKSD.
ckuusr.[ch], ckuus2.c, 22 Sep 98.

Added SHOW EXTENDED-OPTIONS, but left it invisible since it's pretty much only
for IKSD sysadmins to check their command lines before going into production.
If an IKSD client user stumbles on it, it won't show them any IKSD-specific
options, only the innocuous ones.  ckuusr.h, ckuus[r5].c, 22 Sep 98.

Prevented access to command-line argument vector via \&@[] array to IKSD
users.  There is no reason they would need to see the command line, and every
reason why they shouldn't.  cmdini(), ckuus5.c, 22 Sep 98.

Added brief synopsis of each command to REMOTE HELP text.  ckcfns.c, 23 Sep 98.

Added a #define for zfnqfp() to strncpy() when ZFNQFP is not defined, so we
don't have to guard every reference to zfnqfp() with #ifdefs.  ckcdeb.h plus
many modules, 23 Sep 98.

Changed all --blah:<filename> options to expand the filename before storing
it, except --cdfile, which is normally relative.  ckuusy.c, 23 Sep 98.

Added --helpfile:<filename> to allow a custom file to be substituted for the
top-level HELP text.  Can be any length, using more-prompting by default.
Also works for regular non-IKSD Kermit sessions.  ckuusr.h, ckuus[y25].c.,
23 Sep 98.

Added --cdmsg:n, n > 1, to mean CD message should also be displayed when CD
(but not BACK) command given at prompt.  Set it to 2 automatically when -A
given on command line.  Uses "type /page".  Works in non-IKSD Kermit sessions.
ckuus[5y].c, 23 Sep 98.

Fixed makelist() to allow recyclying of list.  ckuusr.c, 23 Sep 98.

Changed --cdfile:<name> to also accept a list of filenames in the standard
C-Kermit format for lists: --cdfile:{{file1}{file2}...{filen}}, up to 8.
And changed SHOW { SERVER, EXTENDED-OPTIONS } to show CD message-file list.
ckcmai.c, ckcfns.c, ckcpro.w, ckuus[35y].c, 23 Sep 98.

Changed default CD message file from a single filename to a list.  ckcker.h,
ckcmai.c, 23 Sep 98.

Added SET CD MESSAGE { ON, OFF, FILE <list> }, like SET SERVER CD-MESSAGE, but
applies to command mode rather than server mode.  Also added SET CD PATH to
allow the CD PATH to be set from within C-Kermit.  Note that SET SERVER
CD-MESSAGE FILE and SET CD MESSAGE FILE do exactly the same thing, and one
does (and undoes) the other.  However, SET CD MESSAGE { ON, OFF } and SET
SERVER CD-MESSAGE { ON, OFF } are separate.  ckuus3.c, ckuusr.h, 23 Sep 98.

Added SHOW CD.  Shows current directory, previous dir, cd path, cd message,
server cd-message, and cd message file.  ckuusr.h, ckuus[r5].c, 23 Sep 98.

Added HELP SET CD and updated HELP SET SERVER, HELP CD, and HELP TYPE.
ckuus2.c, 23 Sep 98.

Added a "-7" command-line option.  This is approximately equivalent to -A,
except without the login phase, chroot(), etc, so it is for use by ordinary
users who are already logged in, rather than as a daemon.  It just sets
sstelnet = 1, thus enabling server-side Telnet negotiation, substitute printf,
etc.  Works OK if run redirected under another Kermit that accepts the
incoming connection, but needs additional work to allow:

  kermit -7 -J * 3000

to allow a single copy of Kermit to be started in such a way that it accepts
an incoming Telnet connection and then presents a command prompt to the Telnet
client.  ckuus[47].c, ckcmai.c, ckutio.c, 23 Sep 98.

Updated HELP SET CD PATH text to account for platform differences.  ckuus2.c,
24 Sep 98.

Changes from Jeff, mainly for automatically setting default protocol for
different sockets in SET HOST / TELNET.  ckcnet.[ch], ckuus7.c, 24 Sep 98.

Changes from Jeff, 1 Oct 98:
 . Add SET SESSION-LOG for K95: ckcker.h, ckuusr.c. makefile, ckuusx.c
   Default is binary for K95, text for UNIX, etc.
 . Added DEBUG session-log type: ckuus3.c.
 . Some reorganization of SSL selection code: ckuus3.c.
 . Add SSL support: ckucns.c, ckutio.c.
 . Add NTVT emulation: ckuusr.h, ckuus7.c.
 . Add NTVT unknown authorization method: ckctel.h.
 . Various updates to authentication code: ckcnet.c.
 . Clarifying comments added about CP1258 -- it's for Viet Nam: ckouni.c.

Reformatted ckouni.c to not have long lines, 1 Oct 98.

Changes from Jeff, 19 Oct 98:
 . SET TERM PRINT
 . Additional of NTVT and SSL authentication types
 . Assorted minor corrections

Some minor corrections from Jeff: ckuus[5x].c, 20 Oct 98.

Added RESET command; closes all open files and logs.  Probably could do some
other things too...  ckuusr.h, ckuus[rx].c, ckcker.h, ckcpro.w, 20 Oct 98.

Moved logchar() from cku{con,cns}.c to ckuusx.c, and added logstr() (but
it's not called from anywhere).  These might need #ifdefs for K95.
Prototypes in ckcker.h.  20 Oct 98.

It has always bugged me that Kermit could not automatically switch to an
appropriate character set when receiving a file whose transfer character-set
is announced.  With IKSD, this is no longer just a convenience, but a
necessity.  So...

 . Added initcsets() to initialize charset associations.  These are done in
   a way appropriate to each system with #ifdefs.  initcsets() is called at
   program startup (after sysinit()).  ckcker.h, ckcmai.c, ckuxla.c, 20 Oct 98.

 . Added ASSOCIATE XFER/FILE-CHARACTER-SETS command.  ckuusr.[ch], 20 Oct 98.

 . Added SET { SEND, RECEIVE } CHARACTER-SET-SELECTION { AUTO, MANUAL }.
   ckuusr.h, ckuus7.c, 20 Oct 98.

 . Added S/R CHAR setting to SHOW CHARACTER-SETS.  ckuus4.c, 20 Oct 98.

 . Added SHOW ASSOCIATIONS separately, since there was no good way to put it
   in SHOW CHARACTER-SETS with more-prompting, since SHO CHAR is split between
   modules.  (We need a better method of handling more-prompting!)  ckuusr.h,
   ckuus[45].c, 20 Oct 98.

 . Changed Attribute-packet handler to automatically switch file character-set
   according to incoming transfer charset announcer if RECEIVE CHAR AUTO.  The
   original setting is saved and restored around file transfer and/or keyboard
   interruption.  ckcfn3.c, ckuusx.c, 20 Oct 98.

 . SET FILE CHARACTER-SET blah now automatically sets the transfer charset
   if SEND CHAR is AUTO.  It set it before too, but using 70+ lines of ugly
   code, now replaced by 2 lines of pretty code.  ckuus7.c, 20 Oct 98.

 . SET XFER CHARACTER-SET blah now automatically sets the file charset from
   the associations table if SEND CHAR is AUTO.  ckuus3.c, 20 Oct 98.

 . Added help text for the new commands.  ckuus2.c, 20 Oct 98.

 . Fixed a bug that kept the transfer character-set from showing up in
   transaction log entries for received files.  ckcfn3.c, 20 Oct 98.

 . Fixed the descriptive names that are common to fcsinfo[] and tcsinfo[]
   to be in the same format, and also renamed code pages from "IBM Code Page"
   to "PC Code Page".  ckuxla.c, 20 Oct 98.

So now a user, when receiving a file in text mode that comes with a charset
announcer will automatically get a reasonable translation.  And when users who
are about to send a file give either a SET FILE or SET TRANSFER CHARACTER-SET
command, the other is set accordingly.  The defaults should be entirely
appropriate (and of course can be changed with the ASSOCIATE command), so now
C-Kermit and K95 should almost always "do the right thing" as long as the
sender properly identifies the file character-set of the source file.  And in
fact, this happens by default in K95, since it gets the current code page at
startup and makes this the file character-set value.  Unfortunately there is
no good (or at least remotely portable) way to do the same in Unix.

From Jeff: Deployment of logstr() in many modules.  21 Oct 98.

Added bounds checking to auto charset switch in gattr().  ckcfn3.c, 21 Oct 98.

Ditto for SET XFER CHARACTER-SET.  ckuus3.c, 21 Oct 98.

Ditto for SET FILE CHARACTER-SET.  ckuus7.c, 21 Oct 98.

Fixed ?-help messages for ASSOCIATE command.  ckuusr.c, 21 Oct 98.

Some changes from Jeff to SSL option setting commands.  ckuus3.c, 22 Oct 98.

Added { RECEIVE, GET, MGET } /EXCEPT:<list>.  If a file arrives whose name
matches any name in the exception list, it is rejected using the attribute
refusal mechanism, reason: name.  This does not use the O-packet exception
list mechanism; it is done purely on the client side; thus it can work with
current/older Kermit programs on the other end.  It does, however, require
A-packets to be negotiated and in use, since this is the only way we have of
rejecting a file within a group without cancelling the entire transfer.  But
that's true of the collision-based and other refusals too.  ckuus[26].c,
ckcfn[s2].c, 22 Oct 98.  Later, once C-Kermit 7.0 servers are prevalent, we
can convert to using the more graceful O-packet method.

Various minor fixes to transaction log format.  ckcfn[s2].c, 22 Oct 98.

Inclusion of extended-format command-line options (like --helpfile:blah)
caused command-line parser to skip the next option, oops.  Fixed in ckuusy.c.
Also fixed command-line error message to print actual program name, not
hardwired text.  22 Oct 98.

Previously the wuftpd-like log, enabled by --iksdlog:1 --iksdfile:name, was
available only to the iksd.  I rearranged the code to allow regular user-mode
C-Kermit to use this too, and renamed the options (and corresponding
variables) to xferlog and xferfile.  UNIX only.  ckuusy.c, ckufio.c,
22 Oct 98.

Added SET TRANSACTION-LOG FTP (it already had BRIEF and VERBOSE options) to
let the ftpd-like log be selected by command.  UNIX only.  This bypasses the
regular transaction-log mechanisms, but that's not visible to the user.  It's
hooked into SHOW LOG via special code.  ckuus[35].c, 22 Oct 98.

Fixed FTP log format -- two of the fields were switched.  Also put the actual
username in the username field in the non-IKSD case.  And put the connection
name (network host or serial device name) in the clienthost field for the
non-IKSD case.  ckufio.c, 23 Oct 98.

Made LOG TRANSACTIONS default disposition be APPEND when using the FTP-format
log, for compatibility with the ftp log.  ckuus4.c, 23 Oct 98.

Substituted built-in code for zshcmd() in UNIX zcopy(), because the zshcmd()
version can't be used in IKSD.  It works, but it's not finished -- need to add
informative error returns (see ckcplm.txt), do all the checks that cp does
(e.g. source file is a directory, whether it's ok to overwrite existing files,
etc), and fix up permissions afterwards, e.g. to carry forward the execute
bit.  Will finish after the weekend.  ckufio.c, 23 Oct 98.

Discovered that UNIX zxpand() wrote into its argument (e.g. when concatenating
"/*" to a directory name).  It's been this way forever, and obviously could
have resulted in countless horrible consequences.  Fixed it to make a safe
copy first.  ckufio.c, 25 Oct 98.

Discovered that RENAME did not work when the source file was a directory.
This was due to a deficiency in cmifi2(), which did not allow for the case in
which the argument "d" was nonzero (meaning "parse files or directories"), but
the argument "dirflg" was 0 (meaning "not directories-only").  Fixed in
ckucmd.c, 25 Oct 98.

Fixed UNIX zcopy() to:
 . Check for source file is a directory / is wild / etc.
 . Check for source file == destination file by comparing their inodes.
   This works even for symlinks.
 . Allow destination file to be a directory, in which case the source file
   is copied into it.
 . Overwrite existing destination file if its permission allows.
 . Set new file's permission according to umask but also carry forward
   the source file's exececute permission bits (but this only works if the
   destination file did not already exist -- this appears to be a property
   of UNIX open()).
 . Fail if interrupted by Ctrl-C.
 . Return standardized error codes (listed in ckcplm.txt).
ckufio.c, 25 Oct 98.

Fixed COPY command to:
 . Not allow a directory as the source file (give a parser error and fail).
 . Not allow wildcards (ditto).
 . Print error messages appropriate to zcopy() return code.
ckuus6.c, 25 Oct 98.

Made sure server end of REMOTE COPY and REMOTE RENAME work with new code
(they do), which was the main reason for doing all this.  Added checks within
zcopy() and zrename() themselves against being called by IKSD guests.
ckufio.c, 25 Oct 98.

Problem: REMOTE HOST blah will time out and fail if the "blah" command takes
too long to finish and/or to produce output.  Ditto for sending from a pipe.
zinfill() in this case needs a way to time out when reading from a process,
which can be done (in UNIX) with select().  Since all the hairy
select()-related #ifdefs, etc, are in ckutio.c, I added a new routine there,
ttwait(fd,secs), to wait the given number of seconds for data to become
available on the given file descriptor.  zinfill() calls ttwait() when it
knows it is reading from a pipe, and it works fine (at least in SunOS).  Now
the trick will be to interface this mechanism with the file transfer code:

 . What should the timeout be?  Well, these days we have no idea what the
   other Kermit's timeout interval is, because it might be dynamic.  For
   starters, it might be OK to hardwire this to 1 second.  After all, neither
   Kermit program is doing anything anyway if no output is arriving from the
   pipe, so why not give them something to do?

 . How to return timeout condition?  Have zinfill() return a unique negative
   number (-3 is currently not used), and then make sure everybody else along
   the way knows what it means.

 . Who are the clients of zinfill()?  It is called only through the zminchar()
   macro.  zminchar(), in turn, is called by: kgetf() (Kanji file-transfer),
   bgetpkt(), getpkt(), transmit(), xlate(), \fcommand(), and dotype().  Of
   these, [b]getpkt() and \fcommand() might be reading from a pipe, but
   timeouts are important only during file transfer, so we can ignore
   everything but [b]getpkt().

This means that zinfill() should call ttwait() only when Kermit protocol is
active.  We can test this with a new variable, kactive: ckuusx.c, ckcpro.w,
ckufio.c, 25 Oct 98.

zinfill(), upon timeout, returns -3 to [b]getpkt(), which passes -2 up to its
caller, sdata().  If sdata() gets this, it simply sends an empty data packet
(for testing, it sends a data packet containing a dot).  ckcfns.c, 25 Oct 98.

It works, but will need a lot of testing and refinement (for example, a packet
log shows that after a bunch of timeouts, when the output first appears, a
NUL is inserted into the data stream).  As far as non-UNIX versions go, this
is strictly an matter of making their versions of zinfill() return -3 on
timeout.

The spurious NUL at the beginning of the data packet was caused by the now
invalid assumption that getpkt() will always either read a character or get an
EOF indication.  Since it does at-least-one-character lookahead, it uses the
"first == 1" as an indicator that there was no previous character, and sets
first = 0 the first time through.  But if the first time through it gets a
timeout from zinfill(), the first flag should be left alone.  Now the first
flag is unset only when zinfill() returns an actual character.  [b]getpkt():
ckufio.c, 26 Oct 98.

The second bad assumption was that timeouts would only occur at the beginning;
in fact, they can happen anywhere, any number of times.  Juggling the code to
make sure getpkt() returns partial packets upon timeouts reveals that once
some data is returned by zinfill(), no further timeouts occur.  That's
because fread() is called with INBUFSIZE, and so it blocks until the buffer
is filled or EOF is encountered.  But for the new code to work, it has to
read only what is there, without blocking.  So I made the input file pointer
for pipes (in zxcmd()) nonblocking, and then adjusted zinfill() and getpkt()
to behave appropriately.  It's still not perfect, but it's getting close.
ckufio.c, ckcfns.c, 26 Oct 98.

Fixed a bug in yesterday's changes that broke the case where timeouts occurred
before any data had been read.  getpkt(): ckcfns.c, 27 Oct 98.

Migrated all getpkt() changes to bgetpkt().  ckcfns.c, 27 Oct 98.

Tested the following successfully:

 . remote host echo foo
 . remote host sleep 5;echo foo
 . remote host sleep 5;echo foo;sleep 5
 . remote host sleep 5;echo foo;sleep 5;echo bar
 . remote host echo foo;sleep 5;echo bar;sleep 5
 . remote host echo foo;sleep 5;echo bar;sleep 5;echo baz
 . (etc)

BUG: GET /BIN does not force the server to send in binary mode.  Diagnosis:
Due to changes to ckcpro.w from 14 Aug 98 (see notes above) tinit() can be
called *after* spar(), but whatru is set in spar() but zero'd in tinit().
Hmmm, this also explains why the "who are you" info went missing around the
same time...  Cure: move initialization of whatru (and whoaru[]) to spar().
ckcfns.c, 27 Oct 98.

This seems to take care of everything.  When PATTERNS are OFF on the server,
GET /BIN always transfers in binary mode and GET /TEXT always transfers in
text mode.  However, if PATTERNS are ON, they still take precedence, since
there is presently no way for the server to know *how* the binary bit in the
client's WHOAMI field was set -- because it happened to be the prevailing
mode (in which case the server's patterns should have precedence) or because
the user said GET /BINARY (in which case the client's command should govern).
Unfortunately there are no spare bits in the WHOAMI field to express the
difference.  (It can, however, be easily added to the O Packet.)  In the
meantime, REMOTE SET TRANSFER MODE MANUAL effectively disables PATTERNS in
the server and allows the GET /BINARY and /TEXT switches to operate in the
expected way.

So now the following work too (server has SET TRANSFER PIPES ON):

  get /bin wermit ; (after "remote set xfer mode manual")
  get /bin /as:x.x {!(sleep 5;cat wermit)}

In light of successful experience with GFTIMER, redid UNIX ztime() to call
gettimeofday() if GFTIMER is defined (since that has been working anyway for
many months), rather than the bizarre cascade of historical #ifdef'd code.
The advantage being that gettimeofday() gives us not just date and time to
the second, but also the fraction of the second in microseconds.
UNIX ztime() now also set two variables:

  long ztmsec; Fraction of second in millisec (or -1L if not set)
  long ztusec; Fraction of second in microsec (or -1L if not set)

These variables are defined in ckcmai.c, and externs for them are in
ckcdeb.h, so they can be freely referenced in the code without #ifdefs, but
customers of these variables should always check to make sure they are not
-1L before using them.  ckufio.c, 28 Oct 98.

For time-critical debugging, added SET DEBUG TIMESTAMP { ON, OFF }.  When ON,
it puts an hh:mm:ss.xxx timestamp at the beginning of each debug log line,
where .xxx (1000ths of sec) is included if ztmsec is > -1L.  Timestamping
can be turned off and on at will, even while the debug log is open.
ckuus[23x].c, 28 Oct 98.

Made debug() recursion-proof.  If debug() ever called itself, or called a
routine (such as zstime(), which it now calls for timestamps) which contains
debug() statements, it would recurse forever and crash when the stack
overflowed.  dodebug(): ckuusx.c, 28 Oct 98.

Noticed that all the documentation said SET CLEAR-CHANNEL but the code said
SET CLEARCHANNEL.  Added alternative keywords & abbreviations to make them
both right.  ckuusr.c, 28 Oct 98.

Checked to make sure we still build OK on:

 . Linux (RH 3.0.3): OK
 . Solaris 2.5.1 (gcc): OK
 . SunOS 4.3.1: OK
 . HP-UX 10.20 (no opt): OK
 . UnixWare 2.1.3: OK
 . Sinix 5.42: OK
 . AIX (no space)
 . VAX/VMS 5.5: OK

The first few were OK but Sinix, Unixware, and VMS required a fair amount of
#ifdef juggling and syntax adjustment.  Problem areas in Unixware and Sinix
included: no getusershell() (so must add -DNOGETUSERSHELL); no setreuid() etc
in Sinix, so just use setuid() (man page says it does it all), adding -lcrypt
to LIBS here & there, etc.  ckuus2.c, ckcfns.c, ckcmai.c, ckcnet.c, ckvfio.c,
28 Oct 98.

Noticed that:

  rem host sleep 5;echo one;sleep 5;echo two;sleep 5;echo three

works fine with SunOS server, but stops after "one" with UnixWare, SINIX.
HP-UX, Linux, and Solaris.  Found and fixed a potential problem with the
use of fcnctl() to set the pipe nonblocking, but it made no difference.
Debug log shows:

  getpkt nleft=0
  getpkt zminchar 2=110
  getpkt zminchar 2=101
  ZINFILL feof
  getpkt zminchar 2=-1
  getpkt eof/eot[one]=3

In other words, feof() is returning true, even though the pipe is not closed.
I don't know why, but removing the first of two feof() tests from zinfill()
in this case (reading from pipe) makes the problem go away.  ckufio.c,
29 Oct 98.

Tried building on Sequent DYNIX/ptx(R) V4.4.2:
 . Warnings about trigraphs in comments, e.g. "/* yyyy-mm-dd */".
   So what -- these warnings are too stupid to fix.
 . Typo in _SYS_NML #ifdefs in ckutio.c.
 . struct timeval not declared because SELECT not defined.
 . struct timezone does not exist.
 . gettimeofday() needs to be called with arg #2 = NULL.
 . set[r]e{u,g}id() do not exist.  Added USE_SETUID to ckufio.c for IKSD.
   In fact, I'm not sure that there is any reason at all not to always
   use setuid() and setgid() in IKSD -- but I'm not sure it's safe either.
 . {get,set}usershell() don't exist.
 . Most DYNIX/ptx makefile entries were missing the $(KFLAGS) clause.
 . Fixed these, then updated makefile DYNIX/ptx entries to all have
   -DNOGETUSERSHELL, and added new dynixptx44 entry that also has
   -DSELECT and -DBIGBUFOK.
 . This gets lots of select() warnings, which I fixed with #ifdefs.
 . It also gets warnings on args of getsockopt(), getsockname(), and accept();
   all these fixed with #ifdefs in ckcnet.c.
 . Banner was wrong -- said POSIX instead of DYNIX/ptx, fixed in ckuver.h.

Now it builds and runs fine.  29 Oct 98.

Reconciled Jeff's recent changes with mine, many modules, plus an adjustment
to the getpeername() call for Unixware.  3 Nov 98.

Changes from Jeff to allow fatal error messages from host to be viewed in
case of disconnect during tn_ini().  ckcnet.c, ckutio.c, 4 Nov 98.

Updates for ckvins.txt and ckvbwr.txt, 5 Nov 98.

Made sure that TIOCGSIZE was a synonym for TIOCGWINSZ in Digital Unix, and
that ttgwsiz() worked OK.  Added comments.  Made sure it still builds OK on
DU 3.2 and 4.0B.  ckutio.c, 5 Nov 98.

Allowed "--" as a synonym for "=" on the command line to separate program
arguments from script arguments, a`la getopt().  prescan(): ckuus4.c,
cmdini(): ckuus5.c, doarg(): ckuusy.c, HELP OPTIONS: ckuus2.c, documented in
ckermit2.txt, 5 Nov 98.

Noticed that LOCAL variable stack depth was defined as MACLEVEL rather than
CMDSTKL.  Fixed in ckuus5.c, 5 Nov 98.

As an experiment, added a few lines of code to the TAKE command parser to
allow arguments to follow the filename (also some minor adjustments were
required to xword()).  So now the TAKE command does the same thing as the DO
command, except it does not push the macro stack.  Thus, if any args are
given, they overwrite the current macro args, if any, just as if the user had
given explicit DEFINE or ASSIGN commands for them.  To test, create a file
(say xxx) that contains the SHOW ARGS command and then tell C-Kermit to "take
xxx foo bar baz".  Works great, doesn't seem to break anything.

However, nested TAKEs just keep writing over the same set of arguments, unlike
nested macros or function calls. which save and restore context.  This is a
bit ugly to explain, so perhaps a better course would be to tie the argument
stack to the command level rather than the macro level.  This would be a
rather massive (but mostly mechanical) change, involving all references to:

  m_line[level]     stack of macro invocation lines
  macx[level]       stack of pointers to macro definitions
  macp[level]       stack of pointers to current position in macro
+ m_arg[level][arg] stack of pointers to args at level 0..MACLEVEL
+ m_xarg[level]     stack of pointers to arg vector array
+ n_xarg[level]     stack of dimensions of arg vector array
+ macargc[level]    stack of argc's
? mrval[level]      stack of RETURN values
  topargc           argc at top level
  topxarg           argv at top level

Presumably we could (a) replace all MACLEVEL dimensions for the arrays marked
"+" (and maybe mrval[] too if we want command files to be able to return
values) by CMDSTKL; (b) move the argument setting / restoring code from dodo()
to a common place; (c) call the common routine from both dodo() and dotake();
(d) index all arrays by cmdlvl rather than maclvl; (e) get rid of the many
special hacks for top level; (f) preserve compatibility with current behavior
by having TAKE without args supply current args as default.  This could work,
but if a subordinate command file changed its arguments, the changes would be
undone when it returned to its caller, which is counter to current behavior.
So we can't make this change.

Discovered that \&_[] does not work at top level.  Commented out two lines of
code in chkarray() that prevented it from working.  ckuus5.c, 5 Nov 98.

Worse than that, \&_[] does not work inside FOR, WHILE, SWITCH, XIF.  That's
because dogta() doesn't handle this array.  Fixed in dogta(): ckuus6.c,
5 Nov 98.

Fixed popclvl() to restore \&_[] array when popping back to top level.
popclvl(): ckuus5.c, 5 Nov 98.

So now it is possible for a first-level command file (that is invoked
without arguments) to access the non-Kermit command line options as follows:

  for \%i 0 \v(argc)-1 1 { echo \%i. "\&_[\%i]" }

So, for example, if Kermit was invoked as "kermit -Y -i -- foo bar baz", the
loop would print:

  1. "/usr/local/bin/kermit"
  2. "foo"
  3. "bar"
  4. "baz"

OK, so now back to the problem at hand.  Note that:

  define mtake take
  mtake filename arg1 arg2 ...

allows \%0..9 to be saved and restored.  But it also shifts the arguments
to the right: once inside the command file, \%1 is the filename, \%2 is
arg1, etc.  This can be partially corrected by defining MTAKE as follows:

  define mtake {
     local \%f \%i
     assign \%f \fcontents(\%1)
     for \%i 1 \v(argc)-2 1 {
       assign \&_[\%i] \&_[\%i+1]
       if < \%i 10 _assign \\%\%i \&_[\%i]
     }
     take \%f
  }

This works fine except it does not (can not) adjust \v(argc).  Two solutions
spring to mind: (a) add a SHIFT command to shift all the args to the left one
position (and also move \&_[10] to \%9), adjusting \v(argc) (and \%*) in the
process, or (b) add a built-in MTAKE command.  (a) seems more generally
useful so let's give it a shot...

Added SHIFT [ n ] command.  ckuusr.[ch], 5 Nov 98.

Added doshift(n) routine.  First top-level \&_[] vector.  Then top-level
globals.  Almost got it working, but ran out of time.  Will try to finish
tomorrow.  ckuus5.c, 5 Nov 98.

Fixed doshift(), ckuus5.c, 6 Nov 98.  Now MTAKE can be defined as follows:

  define mtake {
     local \%f
     assign \%f \fcontents(\%1)
     shift
     take \%f
  }

and it works.  Still need to (a) handle \%* (might not be possible), and
(b) document all this.  Also think about adding MTAKE as a built-in command.

Updates to ckubwr.txt based on recent reports.  6 Nov 98.

Some network-related changes from Jeff, mostly in ckcnet.c.  9 Nov 98.

Added HELP SHIFT.  ckuus2.c, 9 Nov 98.

SET CLEARCHANNEL OFF had no effect if the other Kermit wanted to negotiate
clearchannel.  Fixed in spar(), ckcfns.c, 9 Nov 98.

Made SET PREFIXING ALL or CAUTIOUS automatically also SET CLEARCHANNEL OFF.
ckcmai.c, 9 Nov 98.

Added *.lzh to binary types.  ckcmai.c, 10 Nov 98.

DIAL and LOOKUP did not recognize internal PBX numbers if PBX-EXCH and PBX-IN
are set, but PBX-OUT is not set.  No big deal, but confusing.  So now it is
possible to handle a PBX that does not require an outside prefix (in case
there is any such thing).  Fixed in dncvt(): ckuus6.c, 10 Nov 98.

Loading of dial parameters from environment variables at startup had K_PBX_OCP
and K_PBX_XCH mixed up.  Fixed in ckudia.c, 10 Nov 98.

SET DIAL PBX-EXCHANGE allowed only one exchange to be specified.  But some
PBXs have more than one (e.g. 853-xxxx and 854-xxxx).  Changed dialpxx from a
scalar to an array; changed SET DIAL PBX-EXCHANGE command to load the array,
and all code that refers to dialpxx to treat it as an array.  Also changed
startup code to load the array from K_PBX_XCH, which now can be defined as a
series of numbers.  ckudia.c, ckuus[346].c, 10 Nov 98.

But there is still only one PBX-INSIDE-PREFIX.  So we need a way of deriving
the inside prefix dynamically from the exchange that was matched, e.g.:

 SET DIAL PBX-INSIDE-PREFIX \fsubstr(xxx,3,1)

where xxx is some new variable to stand for "the PBX exchange that was
matched", whose evaluation is delayed until dial string processing, similar
to the \v(filename) variable used in SEND and RECEIVE commands.

Defined VN_D_PXX for this new variable, and named it \v(d$px).  Changed
parsing of SET DIAL PBX-INSIDE PREFIX to not evaluate its operand if it is a
function call (i.e. starts with "\f") or if it *is* the new variable.  Changed
dial string processing to evaluate the PBX inside prefix at dial time, after
matching one of the PBX exchanges.  Works great:

  set dial pbx-out  93,
  set dial pbx-exch 853 854
  set dial pbx-in \fright(\v(d$px),1)
  lookup +1 (212) 854-9876 ; gives 4-9876
  lookup +1 (212) 853-1234 ; gives 3-1234
  lookup +1 (212) 765-4321 ; gives 93,765-4321
  lookup +1 (333) 765-4321 ; gives 93,1333765-4321

Also checked that SET DIAL LC-PREFIX works right (I had a report that it was
broken around the end of May -- it applied itself to long-distance, rather
than local, calls).  It seems to be fine now; I must have fixed it:

  set dial lc-prefix 8,
  set dial pbx-out  93,
  set dial pbx-exch 853 854
  set dial pbx-in \fright(\v(d$px),1)
  lookup +1 (212) 854-9876 ; gives 4-9876
  lookup +1 (212) 853-1234 ; gives 3-1234
  lookup +1 (212) 765-4321 ; gives 93,8,765-4321
  lookup +1 (333) 765-4321 ; gives 93,1333765-4321

ckuus[346].c, 10 Nov 98.

Change from Jeff for SET LOGIN PASS vs quoting.  ckuus3.c, 11 Nov 98.

Added "set file character-set cp1252" as a synonym for "set file character-set
latin1".  As far as Kermit file transfer is concerned, they are the same.
The same can not be said, however, for the other Windows 12xx code pages.
ckuxla.c, 11 Nov 98.

Added CP855 as a file character-set, including invertible tables from
CP855 to Latin/Cyrillic and back.  Ditto for Windows CP1251. ckuxla.[ch],
11 Nov 98.

Changed "cp856" keyword to "bulgaria-pc".  ckouni.c, 11 Nov 98.

Added "bulgaria-pc" as a file character set.  The only meaningful (and
invertible) translations are between it and Latin/Cyrillic.  This is the PC
code page known in Bulgaria as CP856, but we don't call it that because the
real CP856 is something totally different (a Hebrew code page).  ckuxla.[ch],
11 Nov 98.

Added CP1250 (Windows Latin 2) as a file character set, with an invertible
translation to Latin-2 and back.  ckuxla.[ch], 12 Nov 98.

Added Polish Mazovia PC Code Page as a file character set.  Translation tables
filled in provisionally, pending confirmation from Poland.  Not invertible.
ckuxla.[ch], 12 Nov 98.

Added some #ifdefs to allow building with -DNOLATIN2.  Verified all is OK with
with -DNOCYRIL &/or -DNOLATIN2.  ckuxla.h, 12 Nov 98.

Changes from Jeff: CKXPRINTF vs curses in ckuusx.c, some casts added in
ckcnet.c, 13 Nov 98.

Added &S0 (DSR on always) to USR init string for SunOS 4.x -- it doesn't work
without it, due to some strange peculiarity of the driver.  Solaris works
without it, other modems work without it on SunOS.  Go figure.  (Note: I used
to have &S0 in ALL init strings that supported it but removed it after
numerous sysadmins complained that Kermit should not mess with it.)  ckudia.c,
13 Nov 98.

In cmcvtdate(),	"if (dbuf[8] = SP) dbuf[8] = '0';" was supposed to have "=="
in the if condition.  Fixed in ckucmd.c, 13 Nov 98.

For IRIX 6.5: added IRIX65 symbol to ckcdeb.h and ckuver.h, plus new makefile
entry.  13 Nov 98.

Missing "int" added to assorted extern declarations.  ckuus[6x].c, 13 Nov 98.

extern int stchr in ttinl() should have been extern CHAR.  ckutio.c, 13 Nov 98.

Back to mid-September work on UUCP lockfiles versus symlink'd devices, in
which we create a lockfile for both the symlink name and the real name, e.g.
/dev/modem and /dev/ttyS0, which works fine.  But what if the symlink points
to a device of the same name but in a different directory?  Example:
/dev/ttyd2 => /hw/ttys/ttyd2 (in IRIX 6.5).  Both lockfiles have the same
name (in this case LCK..ttyd2).  The device is opened OK, but at close time
when we go to delete the lockfiles, we get an error because deleting the first
one also makes the second one disappear (since they are the same).  Fixed
by adding a check for this to ttlock().  ckutio.c, 13 Nov 98.

Added a rather elaborate set of #ifdefs to account for the facts that: (a)
utmp.h might or might not define a ut_host[] member; (b) utmpx.h, which does
define one, might or might not be available; and (c) if utmpx.h is used
instead of utmp.h, then it has a struct timeval ut_tv member rather than a
scalar ut_time member.  This allows compilation on Linux and SunOS, in which
ut_host[] is in utmp.h, as well as on Solaris, IRIX, Unixware, and HP-UX,
which have utmpx.h, and on platforms that have a utmp.h that does not define
ut_host[], and no utmpx.h.  ckufio.c, 13 Nov 98.

Added Mazovia as a terminal character set to K95.  ckouni.[ch], 13 Nov 98.

Converted ckouni.[ch] for compilation by non-ANSIC compilers and cleaned up
formatting, long lines, etc.  NOTE: There is some funniness in the
ucs2_to_utf8() function.  Its ucs2 argument is USHORT, but there is a series
of comparisons of it with numbers like 0x10000, 0x200000, 0x4000000, which
will always fail, so why are they there?  Also note that 0xnnnnUL is not
supported for non-ANSIC compiles, but then I'm not quite sure how to specify
an unsigned long constant whose high-order bit is 1.  Anyway, the changes to
ckouni.c are rather massive, so thorough testing is needed.  13 Nov 98.

this paves the way for moving file-transfer charset translation to the Unicode
base if we decide to go that route.  However, there will still be some
wrinkles:

 . It will involve a three-step process: x -> Unicode -> y, whereas now we
   generally have only 2 steps (file <=> xfer charset).

 . ckouni.o is more than 3 times bigger than ckuxla.o, and the functions
   are a lot more expensive to call, some of them involving long switch
   statements.

 . The translations in ckuxla.c have evolved over time to meet users' needs.
   Some are invertible, some are not (so as to be readable).

 . ckouni.c does not support language-specific transliterations (such as
   u-umlaut => ue when converting Latin-1 to ASCII with SET LANGUAGE GERMAN).

Added support for 153600 and 307200 bps serial speeds, which are supported
(at least) in Solaris 2.5.1.  ckutio.c, 13 Nov 98.

From Jeff: make "sh" an abbreviation for SHOW (because of new conflict with
SHIFT); some TLS refinements.  ckuusr.c, ckcnet.c, 17 Nov 98.

Made the "Show what?" message a bit more helpful.  ckuus4.c, 17 Nov 98.

Added new makefile entry for UnixWare 7.0.1 and built it there OK.  makefile,
ckuver.h, 17 Nov 98.  Makes Telnet connections OK, transfers files over them.
Other tests from ckuins.txt Section 7 passed OK, except no way to test serial
comms, modems & dialing.  Also made a unixware7g entry (for gcc) but it fails
miserably.  I can't tell why, but it appears to have something to do with the
UNIX macro -- gcc seems to undefine it for some reason, so #ifdef UNIX clauses
are not executed (e.g. MAXFCSETS is not defined, which I think could only
happen if an #ifdef UNIX clause was skipped).

UnixWare builds only support speeds up to 38400.  No Bnnnn symbols are defined
for them.  Instead, we are supposed to use tcsetspeed(), giving it a long
representing the desired speed in bps.  But (a) this requires a POSIX build,
which fails rather badly; (b) there is, at present, no tcsetspeed() code in
ckutio.c; and (c) how are we supposed to get the list of supported speeds?

Discovered that "make sco32v504net KFLAGS=-DNOGETUSERSHELL" works OK on
UnixWare 7.  But it still doesn't give us the high serial speeds.

So let's try adding -DPOSIX to the unixware7 make.  Lots of complaints about
tv_sec, timeval, etc, so added #ifdefs for UW7 to #include <sys/time.h>.  But
this doesn't help because of the fascist clauses to prevent struct timeval
from being defined in a POSIX build (see earlier notes about SCO OSR5 on the
same topic).  So now we define the struct ourselves if time.h didn't (luckily
UW7 also defines a macro to indicate it has defined the struct).  Ditto for
struct timezone.  Now it compiles OK, but still lacks serial speeds > 38400.

Meanwhile, the same <sys/time.h> treatment is needed for the network module
too.  ckcnet.c, 17 Nov 98.

Added a tcgetspeed() / tcsetspeed() interface to ttgspd() and ttsspd(), and
then in this case had ttdpdlist() return a hardwired list of all possible
speeds up to 900K, and let the OS complain at runtime if a speed is not
supported.  Now we get:

UX:acomp: ERROR: "ckutio.c", line 5620: undefined symbol: TCS_ALL
UX:acomp: ERROR: "ckutio.c", line 6045: undefined symbol: TCS_OUT

These are the function codes for tc[gs]etspeed().  But "cd /usr/include ; grep
TCS_ *.h sys/*.h" turns up no definitions for these symbols anywhere.  For
that matter, tcsetspeed() is not defined in POSIX.1, nor can I find any
reference to it on any other POSIX-based system I have access to, or on the
web, or anywhere else.  So it must be a UnixWareism.  Fine, let's guess at the
TCS_* values, say 3 2 1?  Compiles OK, doesn't work.  Try 2 1 0, now it works.
However, since we can't use the Bnnnn symbols to build a legal-speed list,
I had to build a hardwired list, containing all the speeds I ever heard of.
ckutio.c, 17 Nov 98.

Now that we can run it, trial and error shows the following speeds are
supported:

 110     1200    150     19200   2400    300     4800    57600   76800
 115200  14400   1800    200     28800   38400   50      600     9600

So I commented the others out of the hardwired list.  ttspdlist(): ckutio.c,
17 Nov 98.

The ttget/setspeed() interface is enabled if USETCSETSPEED is defined, which
is currently the case only for UW7.  These functions do not exist in earlier
versions of UnixWare, so there is no point converting them to POSIX.

Finalized unixware7 makefile target to include -DPOSIX and use the xermit
target for select-based, rather than fork-based, CONNECT.  Also added a short
name for it: "make uw7".  makefile, 17 Nov 98.

After all that work on tcget/setspeed(), it looks like it only APPEARS to
work, but in fact does nothing at all.  tcsetspeed() says it succeeds, and a
subsequent tcgetspeed() shows the speed that was just set, but the speed does
not change.  I verified this by assigning a line (whose nominal speed was 9600
bps), changing the speed to 57600, and transferring a precompressed file over
various modem connections: 14400, 24000, ...  In every case, the throughput
was 900 cps.  So I rebuilt the non-POSIX version, set the serial port speed to
38400 (the max for this build) and got 1600 cps throughput.  Thus, the old
speed-setting API works (but only up to 38400) and tcsetspeed() is a cruel
hoax.

Or is it?  Maybe I guessed the TCS_* values wrong.  Let's try a different set;
TCS_ALL = 0 (the only one we use).  Aha, that does it.  Now I get transfer
rates of 2700 cps over a 24000 bps connection (same precompressed file).  As
further confirmation, the initial transfer rate is about 5700 cps while the
modem buffers stuff up (== the interface speed of 57600) and then decays to
2700 once the pipe is full.  So yay, speed setting works.  (As additional
confirmation, everything falls apart at 115200 bps due to the PC's crummy
UART.)

But modem signals, carrier detection, etc, do not work.  Same reason: POSIX
builds deselect the TIOCMGET definition from <sys/termios.h>.  So we use the
same trick here as in OSR5 -- define it ourselves.  But that's not enough --
we also have to define all the TIOCM_xx symbols for each modem signal, since
those definitions, too, are hidden from POSIX.  ckutio.c, 18 Nov 98.

Ensured that "make unixware2" still works.

Added code to allow user to SET SPEED to any number at all, even if it is not
in the keyword table, if USETCSETSPEED is defined.  As it stands, the user
gets a parse error message, but the request still goes through and succeeds or
fails based on whether the OS accepts the speed.  ckuus3.c, 18 Nov 98.

Built on QNX 4.24.  Needs -DNOGETUSERSHELL, and does not have initgroups().
wtmp log is /var/adm/wtmp.1.  <utmp.h> has no ut_host[] and there is no
<utmpx.h>.  32-bit and 16-bit versions OK.  ckufio.c, makefile, 18 Nov 98.

Now on to IRIX 6.5.1 on the Origin:

  System: SGI Origin 200, 2xR10000 180MHz
  OpeSys: SGI IRIX 6.5.1 + Patches
  Memory: 256 MB
  DiskSp: 15.8 GB

Builds and runs fine.  Speeds up to 115200 supported, but there's no way to
test if they actually work.  Noted that the Indy can run the Origin binary
and vice versa, good.  No changes needed.

Fix from Jeff for a problem that causes "set host *" to loop, eating up CPU
time, till the connection comes in.  Built the result on HP-UX 10.20, since
that's where the looping problem was reported.  Checked against C-Kermit 6.0,
which makes the CPU lights come on solid, and rises rapidly to the top of
"top", consuming 95% of the CPU.  The fixed version does not make the lights
come on, and after a minute or two "top" says it uses 0% of the CPU.
ckcnet.c, 18 Nov 98.

Added a missing #ifndef NOHELP clause in ckuusy.c, 18 Nov 98.

Added some missing #ifdef TNCODE's in ckuus4.c so it could be built with
no network support.  18 Nov 98.  (STILL NEEDS FIXING ON VMS)

Added -DNDSYSERRLIST to OpenBSD makefile target.  19 Nov 98.

Added a solaris7g makefile entry to build on Solaris 7 with gcc.  It works
fine, except for some warnings from curses.h about redefinitions of items
that C-Kermit doesn't use (getwc, putwc, getwchar, putwchar).  This makes a
32-bit version (sizeof int = sizeof long = 4), since gcc doesn't know how to
make a 64-bit one.  It makes Telnet connections OK and transfers files over
them OK.  When dialed in to a Sun serial port, file transfer is a bit flaky
when sending files out (but this particular machine is known to have flaky
serial ports).  Makefile, 19 Nov 98.

Added a couple more missing #ifdefs to allow linking after compilation without
network supportk.  ckcmai.c, ckuus4.c, 19 Nov 98.

Changed password argument to zvpass() and kpass() from "passwd" to "p", since
passwd conflicts with a struct name, which is fatal in some builds.  ckufio.c,
19 Nov 98.

Added #ifdefs to protect all the new gettimeofday() calls from having 2 args
in Motorola System V/88 R4.  ckutio.c, 19 Nov 98.

Built OK on VMS 5.5 with NONET and with UCX 2.0.  19 Nov 98.

While running thru the ckuins.txt testing instructions, I discovered that
?-help doesn't work in a filename after SEND, e.g. "send *?".  This took a
good bit of sleuthing but eventually I fixed with apparently no ill effects.
gtword(): ckucmd.c, 19 Nov 98.

Changed FAST macro definition for IRIX65 to not restrict send packets to
4000 bytes, since this version does not have the Telnet server bug noted in
IRIX 6.2 and earlier.  ckuus5.c, 19 Nov 98.

Added MAINTYPE symbol, which can be defined on the CC command line to answer
complaints about "main: return type is not blah".  ckcmai.c, 20 Nov 98.

Added a note about MAINTYPE to the openbsd makefile entry, pending
verification.  20 Nov 98.

From Jeff: Symbols and keywords added for VT220PC and VT320PC terminal types.
ckuusr.h, ckuus[57].c, 23 Nov 98.

Changed zvpass(), after authenticating the user, to always use setuid() and
setgid(), rather than set[r]e{u,g}id().  This eliminates a lot of #ifdefs
and it's what we want: once we establish ourselves as the authenticated user,
we do not need or want any possibility of switching back to root.
ckufio.c, 23 Nov 98.

Readjusted MAINTYPE to take precedence over all other declarations.
ckcmai.c, 23 Nov 98.

Made #ifdefs around main() declaration in wart agree with those in kermit,
including MAINTYPE.  ckwart.c, 23 Nov 98.

Added symbol HWPARITY and parsing for "hardware parity" (8 data bits plus
parity generated by system / driver / hardware outside Kermit).  Defined
HWPARITY for SVORPOSIX.  Builds OK (e.g. on SunOS) where HWPARITY not defined,
and also on Solaris, where it is.  ckcdeb.h, ckcmai.c, ckuus[34].c, 23 Nov 98.
Will fill in the action code tomorrow...

Fixed some #ifdefs to allow successful compilation and linking with -DNOLOGIN.
ckuus5,c, cku[ft]io.c, 24 Nov 98.  Builds OK now on Motorola SV88R4.0 and
SV68R3.6.  Also on Solaris 2.6 Intel.

Back to hardware parity.  UNIX APIs do not offer any way to set mark or space
parity.  So... SET PARITY HARDWARE { EVEN, ODD }.  If some other platforms
have APIs for 8M or 8S we can add them later.  This setting takes effect only
on SET LINE devices, not on network connections and not in remote mode.

Added SET STOP-BITS { 1, 2 }, only if HWPARITY is defined.  ckuusr.[ch],
ckuus[23].c, ckutio.c, 24 Nov 98.

For convenience and familiarity, added SET SERIAL { 7E1,7E2,...8N1,8E2,... }.
Any choice with 2 stop bits or 8 data bits + parity is available only if
HWPARITY is defined.  ckuusr.[ch], ckuus3.c, ckutio.c, 24 Nov 98.

Updated SHOW COMM to display new parity settings, stop bits, etc.
ckuus4.c, 24-25 Nov 98.

Discovered that ckucns.c, unlike ckucon.c, failed to assign the \v(trigger)
value when a TERM TRIGGER was encountered.  Fixed in ckucns.c, 25 Nov 98.

Discovered that both ckucns.c and ckucon.c failed to reset the \v(trigger)
value upon entry to CONNECT, so a subsequent exit could still show a previous
trigger value.  Fixed in both, 25 Nov 98.

Changed the LOG command to allow logging to pipes.  Very handy.  See Section
1.13 of ckermit2.txt.  ckuus4.c, 25 Nov 98.

Added transparent printing within #ifdef XPRINT, 25-26 Nov 98:
 . UNIX only, and then only in the ckucns.c module.
 . SET TERM PRINT { ON, OFF }: ckuusr.h, ckuus7.c.
 . Added to SHOW TERM.  ckuus5.c.
 . Documented in ckermit2.txt Section 3.3.
Much fancy footwork required to pass all material through transparently,
but not pass the start-printer or stop-printer sequences to the printer.

Changed most UNIX makefile targets from wermit to xermit, to use the new
select()-based CONNECT module, which has much new stuff in it that ckucon.c
does not have.  In general, I changed every entry that has -DTCPSOCKET to the
xermit target unless it was really old and I hadn't heard anything about it in
many years.  makefile, 26 Nov 98.

Added HELP text for recent commands.  ckuus2.c, 26 Nov 98.

If DIAL RETRIES was not set explicitly, then at DIAL time use a retry limit
based on the local country code.  Currently, this is 10 for country code 1
and 1 for all others.  This can be expanded as I get info about other
countries.  ckuus[346].c, 26 Nov 98.

Added SET CLOSE-ON-DISCONNECT { ON, OFF }.  If ON, it means that if we notice
that a serial connection is disconnected (because CD went off), we close the
device immediately.  This releases it for use by others (e.g. removing the
lockfile in UNIX).  OFF by default, for consistency with previous releases.
Supporting code needs to be added for K95; it goes in ttchk() -- see example
in ckutio.c (search for "clsondisc").  ckcmai.c, ckuus[r234].c, ck[uv]tio.c,
26 Nov 98.

#ifdef adjustments to allow building with different features deselected:
many, many modules.  26 Nov 98.  Examples (on SunOS 4.1.3):

 Full:                1155072
 -DNOIKSD             1146880
 -DNOLOGIN:           1138688
 -DNOPUSH             1122304
 -DNOSPL               999424
 -DNOLOCAL:            884736
 -DNOLOCAL -DNOLOGIN   819200
 sunos41mi:            335872
 sunos41m:             212992

Don't let "close connection" fall through if clsconnx() returns an unexpected
value.  ckuusr.c, 27 Nov 98.

Added MANUAL command, which in UNIX runs the "man" command, default topic
"kermit".  In VMS it runs the "help" command, default topic "kermit".  For K95,
I wrote code to parse chapter names and then to run SE on:

  file:///<startupdir>/DOCS/manual/kermit95.htm#<chapter>

but have no way to compile or test, needs fixing.  ckuusr.[ch], 29 Nov 98.

Added a reference to the MANUAL command to the main HELP screen.  ckuus2.c,
29 Nov 98.

Changed HANGUP command to also call ttchk().  This way, if the HANGUP command
forced a serial connection to close (and carrier to drop), this engages the
SET CLOSE-ON-DISCONNECT code.  ckuusr.c, 29 Nov 98.

Added support for 75/1200 bps split speed for Unixware 7.  Untested.
ckutio.c, 29 Nov 98.

Added missing sections to ckermit2.txt: SET [ SERVER ] CD-MESSAGE, SET FILE
PATTERNS AUTO, SET COMMAND AUTODOWNLOAD, LATIN-9, TYPE /PAGE, and RESET, plus
COPY command improvements.  29-30 Nov 98.

Fixed 75/1200 support after testing revealed it didn't work.  ckutio.c,
ckuus5.c, 30 Nov 98.

Built on Red Hat Linux 5.2. Needed -lcrypt added to LIBS.  makefile,
30 Nov 98.

Linux version could not access modem signals.  Got help from Ted Ts'o and
Gert Doering, now it works.  SHOW COMM shows them, CONNECT mode pops back to
command prompt automatically when carrier drops, etc.  ckutio.c, 1 Dec 98.

Built Linux C-Kermit with egcs 1.0.3 on Red Hat 5.2.  Added linuxegcs makefile
entry.  makefile, 1 Dec 98.

Also checked linuxs entry (static linking) -- works, makes a 2.2MB executable
(compared to 914K with dynamic linking).

Made FAST the default for UNIX and VMS (it already was the default in K95);
let's see who hollers.  ckcmai.c, ckcker.h, ckuus[5h].c, 1 Dec 98.

Added SOCKS5 support from Ric Anderson.  ckcdeb.h, ckcnet.[ch], ckuus5.c,
1 Dec 98.

Fixed the MANUAL command to account for NOPUSH/nopush.  ckuus[r2].c, 1 Dec 98.

Supplied missing RMKDIR command.  ckuusr.c, 1 Dec 98.

Verified IKSD on Red Hat 5.2 Linux 2.1.125.  All is OK except, like SunOS,
it has the syslog-vs-chroot bug.  See notes from 30 Aug 98.

Moved annoying error messages from REDIRECT parsing to after confirmation, so
we can use command recall.  This should also be done for any other commands
that issue error messages and fail in mid-parse for non-syntactic reasons.
ckuusr.c, 1 Dec 98.

New & improved HP-UX makefile entries from Peter Eichhorn.  2 Dec 98.

Confirmation from Piet Vloet at Siemens Austria that 8 bits + parity work OK
on Solaris.  2 Dec 98.

kermit -y filename was broken, more fallout from the "call prescan() twice"
business (see notes from 22 Aug), this time because of the argument that was
added that made it skip some things.  I just put it all back to the way it was
prior to 19 July and it seems to work OK (the notes don't shed any light, but
probably the changes were made for some reason specific to K95, so proper
prescan() operation should be rechecked there).  ckuus4.c, 2 Dec 98.

Added a bunch of missing commas separating help-text lines.  ckuus2.c,
2 Dec 98.

Removed now-inappropriate #ifdef NETCONN from extern int ttnproto in ckudia.c,
2 Dec 98.

Added -DNOGETUSERSHELL to all HP-UX entries prior to 8.00.  makefile, 2 Dec 98.

SCO OSR5, and therefore probably all earlier versions, get unresolved
references to "std_syslog" and "openlog" at link time.  Builds OK only with
-DNOSYSLOG.  Added -DNOGETUSERSHELL and -DNOSYSLOG to SCO OSR5 entries, and
-DNOIKSD to all the other SCO entries (except Unixware).  makefile, 2 Dec 98.

Added appropriate #includes for select() to ckucns.c, needed at least for QNX.
ckucns.c, 2 Dec 98.

Built on dozens of platforms, made numerous adjustments to #ifdefs and
declarations.  2 Dec 98.

Added -DNOIKSD to HP-UX 5.x entry.  Makefile, 3 Dec 98.

Fixed a bug in which "run blah\fxxx" (RUN any-string-with-\f-in-it) would
hang.  The problem turned out to be that the RUN command parser always
returned -1 if cmtxt failed, rather than returning cmtxt's return code.
ckuusr.c, 3 Dec 98.

Fixed a longstanding bug in the BSDI version, in which incoming file dates
were set in GMT rather than local time.  It seems in 4.4BSD, localtime() does
not return the local time, but rather Zero Meridian (Zulu) time (GMT), and
must be adjusted by the tm_gmtoff value.  ckcdeb.h, ckufio.c, 3 Dec 98.

It turns out the same bug also affected FreeBSD, so I'm assuming it also
applies to all other 4.4BSD derivatives, and so made the previous change be
#ifdef BSD44.  Tested OK in FreeBSD 2.2.7 and BSDI 3.1.  ckufio.c, 3 Dec 98.

After getting "man" to work on SCO 3.2v5.0.5, I discovered that -lsocket is
required there to make syslog() work.  Added -DSYSLOG to the sco32v5*net*
entries, which already were linking with libsocket.  Added a separate set of
entries for SCO 3.2v5.05.  ckcdeb.h, ckuver.h, makefile, 3 Dec 98.

Noticed that the SCO OSR5 version was sending uppercase filenames.  Started to
work on tracking it down, but now, just when it gets to the filename, it
crashes in the malloc() that is called from sfile().  There does not appear to
be anything wrong with this code, and the same code works fine on dozens of
other platforms.  malloc() is being passed an integer whose value is 1024.
Compiling with gcc rather than cc fixes the problem.  Not very satisfying,
though...  Keeping at it, I found that if I reworked the offending bit of code
and rebuilt with cc, the problem moved to another unrelated bit.  Finally I
tracked it down to a non-ANSI prototype for getcwd() in zgtdir().  Commenting
it out fixed everything.  So what other little time bombs are lurking
throughout the code?  (Lines that were perfectly harmless for years and years
can suddenly become fatal...)  ckufio.c, 3 Dec 98.

The problem with uppercase filenames comes from using "send /bin", and in fact
happens everywhere, not just on SCO.  It's because "send /bin" sets transfer
mode to manual and file type to binary, to force a binary transfer no matter
what.  But manual transfer mode means we don't automatically switch to literal
filenames when sending UNIX to UNIX.  Phooey.  This was fixed as follows:
previously, when we compared system types, we did so only if xfermode == auto.
If they match, we set the transfer mode to binary and file names literal.
Now we compare system types not only if xfermode == auto, but also if the
global (saved) g_xfermode == auto.  In this case, we set file names to literal
if they match, but we set the transfer mode to binary only if xfermode == auto,
i.e. if the *current* transfer mode is auto.  ckcfns.c, 3 Dec 98.

When using new C-Kermit on VMS to make a Telnet connection, it says: "tn_push
has not been defined. data loss!!!!" -- kinda scary...  Copied the le_blah()
code from UNIX to VMS, and enabled the le_puts() call for VMS in tn_push().
But it doesn't work very well -- there is a long pause at the beginning of the
connection, and then 10-20 lines of junk come out (but after that it's normal).
Apparently this much more difficult than I thought, mainly because in UNIX,
the same functions (ttinc(), ttxin(), etc) are used for both serial and
network connections, whereas in VMS, we call netinc(), netxin(), etc, for
network connections.  Put everything back the way it was.  We get the scary
message, and have to hit return before seeing a login: prompt, but after that
all is OK.  To be cont'd...

(Next day...)  It's worse than I thought.  The telnet local-echo buffer
business breaks the INPUT command on Telnet connections, even for the UNIX
version.

Fixed long lines in ckuath.c, ckuat2.c, and ckusig.c.  4 Dec 98.

Fixes from Jeff for INPUT vs local-echo buffer, plus a keyword-table size
error.  ckcnet.c, ckuus7.c, 8 Dec 98.

Changed hardwired references to uid_t and gid_t in the new authentication code
to UID_T and GID_T, which are portably defined in ckcdeb.h, to fix ckufio.c
compilation failure on HP-UX 6.5.  Also needed to add -DNOSYSLOG and -DNOSELECT
(because ckcdeb.h defines SELECT for all HPUX's, but it's not there prior to
7.0 unless TCP/IP is installed).  makefile, ckufio.c, 8 Dec 98.

Fixed UNIXLOGIN macro to allow for the possibility that a login: prompt might
not appear.  Fixed NET macro to include "set login user" to disable sending
of user ID in Telnet negotiations.  ckermit.ini, 8 Dec 98.

All-day project: Got common source and makefile to build cleanly on both
Red Hat 5.2 Linux (glibc) and Slackware 3.5.0 (libc).  Of course the results
are still not binary compatible.  How could they be?  makefile, ckutio.c,
8 Dec 98.

Removed all gratuitous prototypes for getcwd() from zgtdir().  Let's see
who complains.  ckufio.c, 8 Dec 98.

Almost everybody, of course.  Started the long, slow process of adding back
prototypes for those platforms that don't provide them: HP-UX 6.5, Motorola
SV68, etc.  This was handled in various ways -- including <unistd.h> in builds
where it wasn't included before, adding a new DCLGETCWD symbol to CFLAGS of
selected builds, and so on.  zgtdir() now has real _PROTOTYP's for getcwd()
rather than the non-ANSI hardwired ones, and all are in #ifdef
DCLGETCWD..#endif.  But since getcwd() prototypes involve size_t's, this too
needed an escape clause, so I made them all SIZE_T, which is defined by
default to be size_t in ckcdeb.h, but can be overridden on the command line
with -DSIZE_T=int or whatever.  makefile, ckufio.c, ckcdeb.h, 9 Dec 98.

Trying to get tn_push() & friends to work in VMS (cont'd from last week...)
Moved all the code that I had added to ckvtio.c to ckcnet.c, since, for
network connections, all of the ckvtio.c routines call their ckcnet.c cousins
anyway (ttinc() calls netinc(), etc).  The result works ok, except it is stuck
until the user hits the first key.  Killing a process stuck in this way that
had its debug log on reveals the hangup to be in contti(), which is back in
the ckvtio.c module I just moved all this code out of...  Added a(nother)
special hack to contti() to account for the local-echo buffer.  Arranged
ckcnet.[ch] so that TTLEBUF selects the external implementation of these
routines & buffers, and NETLEBUF selects the internal one.  Defined TTLEBUF
for UNIX and NETLEBUF for VMS.  ckcnet.[ch], ck[vu]tio.c, 9 Dec 98.

Defined TTLEBUF for AOS/VS and added the code to ckdtio.c (but, like the
initial VMS try, it still gets stuck at the very beginning).  9 Dec 98.

Numerous source-level adjustments for AOS/VS.  For example, if a module
contains "extern int blah;", the link step will fail if blah is not defined
anywhere, even if it is never used.  Many modules.  9 Dec 98.

SOCKOPT_T adjustments for AIX 4.2 & 4.3.  ckcnet.c, 9 Dec 98.

Changes from Jeff for hardware parity & stop bits for K95, plus other minor
code adjustments.  ckcdeb.h, ckuus[34].c, ckcnet.c, 10 Dec 98.

From Jeff: When an incoming TCP connection has dropped, don't listen for a
new one.  ckcnet.c, 10 Dec 98.

More adjustments for AOS/VS.  ckdcon.c, ckcpro.w, etc.  Now it links without
multiply defined or undefined symbol errors.  10 Dec 98.

Fixed the sticking problem in AOS/VS Telnet: there was a vestigial ttflui()
call in the AOS/VS version of ttpkt().  ckdtio.c, 10 Dec 98.

Increased compiler memory (-qmaxmem) from 6000 to 8000 for AIX 4.1 builds,
and to 10000 for AIX 4.2 and 4.3 (but this is still not enough for some
modules -- no big deal).  makefile, 10 Dec 98.

Adjusted #ifdefs for GETSOCKNAME_T, etc, to allow clean compilation on AIX
4.3 & 4.2, since data types for various sockets library function args changed
between AIX 4.1 and 4.2.  ckcnet.c, 10 Dec 98.

Made SET SPEED command not complain because it's a network connection until
after confirmation (see note on REDIRECT, 1 Dec 98).  ckuus3.c, 10 Dec 98.

Problem: SET PORT blah, SET MODEM TYPE blah, DIAL blah.  Then SET HOST blah.
Now that we have a network connection, HANGUP still sends the modem hangup
sequence.  It *should* send this sequence if SET MODEM TYPE was given *after*
SET HOST (see p.126), but not if it was given before.  Code looks right --
setlin() leaves modem type negative upon exit.  Well, further testing reveals
problems go a lot deeper when we switch back & forth between serial and
network connections -- sometimes lockfiles were left behind, SET SPEED
commands would fail, etc.  The primary cause was the failure of (at least the
UNIX version of) ttopen() to unset the "it's a network connection" variable
in all cases when it opened a serial connection.  I also made another change,
namely that mdmhup() should call ttchk() before sending +++ATH0+++ to make
sure there is still a connection.  If there isn't, don't bother.  ckutio.c,
ckudia.c, 10 Dec 98.

Changes from Jeff for Postscript printer support in K95.  ckuusr.h, ckuus3.c,
10 Dec 98.

Added SET DIAL MACRO command.  ckuusr.h, ckuus[36].c, ckudia.c, 11 Dec 98.

Added LOG CONNECTIONS command definitions, parsing, SHOWing.  Default
filename is CX.LOG in user's home directory, overridable by -DCXLOFGILE="xxx"
on cc command line, or, of course, in the LOG CONNECTIONS command itself.
ckcker.h, ckcdeb.h, ckuus[r456].c.  11 Dec 98.

Added code for writing to the connection log.  The main idea is to write log
records as reliably as possible without going into the system-dependent code,
thus avoiding the necessity to update dozens of modules, many of which can't
be tested.  When a connection is opened, a preliminary log record is written
to a buffer by the SET LINE or SET HOST code (this happens always, even if a
log is not open).  If it was a serial port, then if a DIAL command is given,
it overwrites the original record, adding the phone number info.  The trick is
to catch when the connection closes, so we can add the elapsed time to the
record and write it out to the log (I considered writing separate Open and
Close records, but people wouldn't like having to match them up).  We do this
in the following places:

 . The HANGUP command.
 . The clsconnx() (close connection) routine.
 . When the CONNECT command returns.
 . When INPUT senses connection loss
 . When the file-transfer protocol senses connection loss.
 . In the program exit sequence as a catch-all.

We avoid writing duplicate records by punching out the partial buffer after
writing a record.

Each record is a line of text; the format is:

  yyyymmdd hh:mm:ss username pid p=v [ p=v [ ... ] ]

where the timestamp shows when the connection was made; p's are parameters,
and v's are values:
  T = Connection Type (TCP, SERIAL, DIAL, DECNET, etc).
  H = Originating Host name.
  N = Destination Number or Network host name or address.
  D = Serial connections only: Device name.
  O = Dialed calls only: Originating country code & area code if known.
  E = Elapsed time.
Many modules, 13 Dec 98.

Fixed dial macro to (a) also apply to nonportable numbers, and (b) not apply
when user gives number starting with "=".  ckuus6.c, 14 Dec 98.

Connection logging, cont'd:
 . Flush connection-log writes to disk.
 . Added 2 new syslog levels: DIAL, and All Connections.
 . Added syslogging to dologend() routine.
 . Added a compile-time symbol to force syslogging of desired level.
 . Don't let user set syslogging > 5 (file reading).
Many modules, 14 Dec 98.

Added SHOW CONNECTION command to display current session (from partial log
record in memory), including elapsed time.  ckuusr.[ch], 14 Dec 98.

Added code to force syslogging if built with -DSYSLOGLEVEL=n.  This way
sysadmins can (e.g.) log all dialout calls by all users in syslog.  Various
modules.  14 Dec 98.

Syslogging is documented in iksd.txt and ckuins.txt.  The connection log is
documented in ckermit2.txt.

Recent changes to zgtdir() could result in core dumps if called when current
directory (or "..", etc) is unreadable.  Also went from getcwd() back to
getwd() in SunOS since getcwd() is implemented there via popen() calling the
shell to run pwd, which is gross and slow, and also prints unwanted messages
in the aforementioned case.  But getwd() is "deprecated" and not recognized by
POSIX so we avoid it elsewhere.  To force its use, add USE_GETWD to CFLAGS.
ckufio.c, 15 Dec 98.

Added /COMMAND, /BINARY, and /TEXT switches to TRANSMIT.  ckuus[r24].c,
ckufio.c, 15 Dec 98.

Made STATISTICS show streaming in window-slots field, like file-transfer
display does.  ckuus4.c, 15 Dec 98.

Bug: the dial interval, once interrupted by "pressing any key" goes to 0 once
(as it should) but then stays there for all subsequent redials.  Diagnosis:
conchk() reported the keystroke(), but coninc() was never called to read it.
Fixed in dodial(), ckuus6.c, 15 Dec 98.

It seems that on at least one PC somewhere in the world, ATS2=43 causes an
ERROR response from a Hayes-compatible modem (Dynalink 1456VQH).  But this
command is hardwired into the code for all AT-command-set modems; there is no
command to disable it.  Compensated for this by:

 1. If ATS2=nn gives an error code, we (a) print the message only if DIAL
    DISPLAY is on (rather than always), and (b) set MODEM HANGUP-METHOD to
    RS-232, since we do not know that we can make the modem escape back.

 2. SET MODEM ESCAPE-CHARACTER -1 (or any negative number) now disables the
    sending of the ATS2=nn command to the modem, and also sets MODEM
    HANGUP-METHOD to RS-232.

Note: this is a continuation of related changes from 9 Sep 98.  ckuus6.c,
ckudia.c, 15 Dec 98.

Researched high serial speed API in AIX 4.2/4.3.  Forget it, it's hopeless.
Documented what appears to be the method for "speed mapping" (which can be
done outside Kermit) in ckubwr.txt, AIX section.  15 Dec 98.

New MANUAL command for K95 from Jeff.  16 Dec 98.

Updated help text of LOG, CLOSE, and other commands.  ckuus2.c, 16 Dec 98.

Updated UNIX man page.  ckuker.cpp, 16 Dec 98.

Changed streaming to work automatically in the majority of cases, without
requiring the user to enable it.  RELIABLE has a new setting, AUTO, which is
the new default.  When RELIABLE is AUTO and the Kermit program that initiated
the connection requests streaming, which it does by default when STREAMING is
AUTO (which is also the default) if the connection is reliable (which it
knows, because it made the connection itself), now the remote Kermit accepts
without having to be told to SET RELIABLE ON.  It also offers always, which
should do no harm, since the offer won't be accepted if the local Kermit
doesn't also offer.  This concept will need some proving in the field!
ckcmai.c, ckcfn[s2].c, ckuus[23457].c, ckermit2.txt, 16 Dec 98.

Added missing RQUERY shortcut for REMOTE QUERY.  Also made QUERY a valid
command -- does what RQUERY does.  There's no need for the "R" since there
is no local QUERY command, nor any need for one.  ckuusr.c, 16 Dec 98.

Discovered that when sending a file to QNX whose name contained any segment
longer than 48 chars, the open() failed with ENAMETOOLONG.  Added code to
nzrtol() to truncate each path segment longer than MAXNAMLEN (which is defined
earlier according to time-honored #ifdefs) to MAXNAMLEN bytes.  ckufio.c,
16 Dec 98.

Added variables \v(hwparity) (hardware parity, if any) and \v(serial)
(8N1, etc).  ckuusr.h, ckuus4.c, 16 Dec 98.

Made SET SERIAL nxx also SET TERM BYTE to n.  ckuus3.c, 16 Dec 98.

Changes from Jeff to speed up Telnet negotiations.  ckcnet.c, 17 Dec 98.

Discovered that DIR command did not expand ~ in UNIX.  That's because it was
calling system() (which uses sh) rather than zshcmd() (which uses the user's
preferred shell).  Fixed in ckuus6.c, 17 Dec 98.

Discovered that IF EXIST did not expand ~ in UNIX.  That's because zchki()
did not expand tildes.  Fixed in ckufio.c, 17 Dec 98.

Discovered that \fdate() did not expand ~ in UNIX.  That's because zfcdat()
did not expand tildes.  Fixed in ckufio.c, 17 Dec 98.

All this made me realize that any ckufio.c routine that accepts a filename
as an argument should run tilde_expand() on it, and if I did this, I could
move all kinds of ugly code out of ckucmd.c.  But that would be a rather major
last-minute overhaul, so it's deferred for the next release.

Back to the UNIX DIR command.  If it runs ls, then we can give ls switches,
etc, but we don't get regular filename parsing or a FAILURE return code if
no files match.  If we run the built-in DIR command, we don't see permissions,
owner, group, etc, but we do get filename parsing and an appropriate status
indication.  So I separated LS and DIR, which formerly were synonyms.  Now LS
runs ls, and DIR calls the internal DIR command.  ckuusr.[ch], ckuus6.c,
17 Dec 98.

Meanwhile, the internal DIR command had all sorts of problems.  For example
"dir x" would list all files whose names started with "x".  Also the headings
and footings were a bit annoying, so I took them out.  domydir(), ckuus6.c,
17 Dec 98.

Yesterday's truncate-filename-segments code forgot to null-terminate its
buffer, so receiving a file that had a shorter name than a previous one
resulted in junk at the end of the shorter filename.  Fixed in nzrtol(),
ckufio.c, 17 Dec 98.

Updates to SET PRINTER & other help text, more Telnet updates, and misc
minor corrections from Jeff.  ckcnet.c, ckuus[r2y].c, 17 Dec 98.

Discovered a bad situation in UNIX fgen(), in which a debug() statement
would try to print the filename string even when no files were found and
therefore the state of the string pointer was undefined.  Recent code changes
made this cause core dumps.  Fixed in fgen(), ckufio.c, 17 Dec 98.

Added new system-dependent function: ziperm(filename), returns the file's
permissions in system-dependent symbolic form (unlike zgperm(), which returns
them in system-dependent numeric form).  Probably will need lots of #ifdefing
when I go build on many platforms...  ckufio.c, 17 Dec 98.a

Back to the built-in DIRECTORY command: domydir().  Added /BRIEF and /VERBOSE
switches; /VERBOSE means to print the heading and summary; /BRIEF means to
just list filenames as compactly as possible; if neither is included, a
verbose listing is printed but without heading and summary.  Added askmore()
for paging, plus /PAGE /NOPAGE switches to control it.  Changed date format to
ISO standard yyyymmdd hh:mm:ss -- no English month names or screwy American
month-day-year, and /ENGLISHDATE switch to re-enable English rather than ISO
dates.  Added display of permissions for UNIX.  Rearranged fields to be more
familiar and less DOS-like.  ckuus6.c, 17 Dec 98.

Then I discovered that all the code I had rewritten is duplicated (for OS2
only) in dodir().  I don't understand the ONETERMUPD business so I left it
alone, but I *think* that entire mass of code can be yanked out and replaced
by a call to domydir().

Added some #ifdefs to new UNIX permissions-printing code for symbols that some
platforms might not define.  ckufio.c, 18 Dec 98.

Made zgetfs() return size even if it's not a regular file, since we only use
it for directory listings.  (NOTE: This change should not be made for K95,
since DOS users are not accustomed to seeing the size listed for directory
files).  ckufio.c, 18 Dec 98.

Added dashes to ISO numeric date in DIRECTORY listing -- too hard to read
without them.  ckuus6.c, 18 Dec 98.

Made UNIX DIRECTORY show file size for directories too.  ckuus6.c, 18 Dec 98.

Made K95 call domydir() instead running special code.  ckuus6.c, 18 Dec 98.

Made server-side directory listing code compatible with domydir().  nxtdir(),
ckcfns.c, 18 Dec 98.  (Project for a rainy day: consolidate sndir(), nxtdir(),
and domydir().)

From Jeff: it turns out that the parameter passed to the getc() function that
is given to tn_doop() is not really a dummy after all.  tn_doop() passes a 0
value to the function because it is expecting a blocking read.  This was not
happening.  tn_doop() was also not checking the return code of the getc()
function and was converting it to a char.  So -1 (timeouts) was being treated
as IAC.  Fixed in ckutio.c, ckcnet.c, 18 Dec 98.

From Jeff: Mutexes in K95 for local-echo buffer vs connection.  ckcnet.c
18 Dec 98.

Added a new DIRECTORY command switch, /HEADING, to decouple printing of
headings and summaries from /VERBOSE and /BRIEF.  ckuusr.h, ckuus6.c,
18 Dec 98.

Added a new command to set default options for other commands that take
switches:  SET OPTIONS <command> <switch> [ <switch> [ ... ] ].  ckuusr.[ch],
ckuus3.c, 18 Dec 98.

But this meant that each option requires an opposite, so added /NOHEADING,
and /ISODATE.  ckuusr.h, ckuus6.c, 18 Dec 98.

Filled in SET OPTIONS DIRECTORY [ switches ].  ckuus6.c, 18 Dec 98.

Changed filhelp() to return 1 if it listed all the files, and 0 if the listing
was terminated prematurely (by the user replying "n" to askmore()), to allow
DIR /BRIEF /HEADING to work.  ckucmd.c, ckuus6.c, 18 Dec 98.

Added HELP text for DIRECTORY and SET OPTIONS.  ckuus2.c, 18 Dec 98.

Cleaned out hundreds of lines of cruft from dodir().  ckuus6.c, 18 Dec 98.

Fixed streaming glitch introduced on Dec 16.  ckcfns.c, 18 Dec 98.

Minor changes from Jeff to ckcdeb.h and ckcnet.c, 20 Dec 98.

Moved sh_sort() to ckcmai.c with other general-purpose utilities and added
key & reverse parameters.  ckcdeb.h, ckucmd.c, ckcmai.c, 20 Dec 98.

Added /[NO]RECURSIVE, /NOSORT, /SORT:{NAME,DATE,SIZE}, /ASCENDING,
/REVERSE (= /DESCENDING) switches to DIRECTORY and SET OPT DIR commands:
ckuusr.h, ckuus6.c, 20 Dec 98.

Fixes from Jeff.  ckcnet.c, ckuus6.c, 21 Dec 98.

Moved SET OPTIONS keyword table to top level since aggregate initialization
of structs is not portable.  ckuus6.c, 21 Dec 98.

Filled in zgperm() and ziperm() for VMS.  Made VMS zgetfs() return file size
even for directories.  Added zrelname() to convert a full pathname to one that
is relative to the current directory (needed only for VMS).
ckvfio.c, 21 Dec 98.

Made filhelp() for VMS return zrelname()-shortened names.  ckucmd.c, 21 Dec 98.

Made domydir() work for VMS.  ckcdeb.h, ckuus6.c, 21 Dec 98.

Various directory listing improvements.  Don't give "more?" prompt if last
line that was shown is the actual last line.  Made more-prompting take
wrapping of long lines into account, watching out for lines that are exactly
the column width.  Lots of other checking added, boundary conditions handled,
etc.  ckuus6.c, 21 Dec 98.

Added SHOW OPTIONS.  ckuusr.h, ckuus[56].c, 21 Dec 98.

Updated HELP DIRECTORY text.  ckuus2.c, 22 Dec 98.

From Jeff: Corrections to \fscrncur[xy](); they do not require arguments.
ckuus4.c, 23 Dec 98.

From Jeff: SET TERM SPACING-ATTRIBUTE-CHARACTER (invisible, a debugging tool).
ckuusr.h ckuus7.c, 23 Dec 98.

Tried changing SYS$OPEN() to SYS$DISPLAY() in zgperms(), but result was
error 99684 "invalid internal file identifier".

Changed xxstrcmp() (caseless string compare) to ckstrcmp() (string compare in
which case-matters is a parameter), and defined xxstrcmp() to be a macro that
calls ckstrcmp() with the parameter set to 0, but changed all references to
xxstrcmp(a,b,c) to ckstrcmp(a,b,c,0) anyway.  ckcker.h, ckcmai.c, 23 Dec 98.

Replaced all constructions like:

  x = casematters ? strcmp(a,b,c) : xxstrcmp(a.b.c)

with ckstrcmp(a,b,c,casematters).  Many modules, 23 Dec 98.

Added a "case matters in filenames" constant: filecase (1 for UNIX and OS-9,
0 elsewhere).  ckcdeb.h, ckcmai.c, 23 Dec 98.

Added a "case matters" parameter to sh_sort().  ckcker.h, ckcmai.c, 23 Dec 98.

Changed filename "?" and directory sorts to obey filecase setting by passing
filecase as an arg to sh_sort().  ckucmd.c, ckuus6.c, 23 Dec 98.

Added SHOW ARRAY \&x to display the contents of array x.  Previously SHOW
ARRAY did not take an argument, but simply listed all defined arrays.
ckuus6.c, 23 Dec 98.

Added SORT [ { /CASE:{ON,OFF} /KEY:n /REVERSE /SIZE:n } ] <array>.  Testing
this by reading a file into an array and then sorting it revealed all sorts of
holes in the recently updated string comparison and sorting routines --
e.g. when the key is off the end of the string, or when one of the elements to
be compared is null, etc.  Plugged all of these.  ckuusr.[ch], ckuus[56].c,
23 Dec 98.

From Jeff: Move "<DIR>" to left of size column for sorting purposes.
Fix SET PRINTER /W.. to accept abbreviations for /WINDOWS-Q that worked
prior to adding /WIDTH.  ckuus[36].c, 24 Dec 98.

Discovered that a typo yesterday's changes broke IF EQUAL.  Fixed in doif(),
ckuus6.c, 24 Dec 98.

Changed \ffiles() and related functions (\fdir(), etc) to take a second arg,
an array 'pointer', to make array contain file list, e.g. \ffiles(*.txt,&a).
Element 0 of the array contains the size of the list, and elements 1..n
contain the filenames.  NOTE: This does not work in K95 because I didn't see
any obvious way to access the alternative "znxt" list -- probably we just need
to remove the #ifdef OS2 from the code in fneval FN_FC that calls znext() in
a loop to make a copy of the file list.  ckuus4.c, 24 Dec 98.

Added HELP SORT text.  ckuus2.c, 24 Dec 98.

From Jeff, 24 Dec 98:
 . Fixed memory (de)allocation problems in \ffiles(): ckuus4.c.
 . Add \ffiles() array assignment for K95: ckuus4.c.
 . Add Wyse160 emulation (=WY60+blockmode): ckuusr.h, ckuus[257].c.

Fixed Jeff's corrections (don't call makestr() with uninitialized pointers,
some fencepost errors).  ckuus4.c, 25 Dec 98.

Updated HELP FUNCTION text for \f[r]files(), \f[r]directories().  ckuus2.c,
25 Dec 98.

Fixed some glitches in SORT command parsing.  ckuusr.c, 25 Dec 98.

Fixed UNIX CONNECT module to log incoming characters to session log BEFORE
translation (etc) if session log is binary.  If session log is text, chars
are logged after translation (etc), as before.  ckucns.c, ckucon.c, 25 Dec 98.

Added SET OPTIONS TYPE { /PAGE, /NOPAGE } and added TYPE to SHOW OPTIONS,
just so we don't have only one command we can set options for.  ckuus[r5].c,
25 Dec 98.

A few more fine adjustments to \ffiles() array code.  ckuus4.c, 26 Dec 98.

Realized that we really need to allow the user to specify both the start and
end range of elements to be sorted, in case they really do want to use 0-based
arrays (or they want to sort pieces of arrays for some reason).  Changed
/SIZE:n to /RANGE:n:m.  Also, moved the SORT command code from ckuusr.c to
cuus7.c.  26 Dec 98.

Used the new "parse-a-range technology" to allow SHOW ARRAY a[n:m].  ckuus5.c,
26 Dec 98.

Discovered still more problems in SORT switch parsing, mainly that command
retry and recall were totally fouled up.  The reason was quite subtle.  The
object was to parse SORT [ switches ] array-name.  Now, to allow for the
possibility that the user might type \&a as the array name (i.e. include the
initial backslash), this required the switch keyword table to have a NULL
processing function, rather than the customary xxstring, otherwise cmkey()
would run xxstring on the array name and fail because the result did not match
a keyword from the table.  The problem was that the path taken through cmkey()
when the processing function was NULL had never been used before, and
therefore never debugged: the wordlength variable was improperly set in this
case, and (more interestingly), upon reparse, gtword() would return the
switch together with its argument, and therefore the assumption that it had
broken on the ":" or "=" was violated, and therefore the switch *with* its
argument was looked up in the keyword table, which naturally failed.  Fixed
in cmkey2(), ckucmd.c, 26 Dec 98.

Fixed all array-name parsing functions to allow for the \&@[] array (a
special case).  ckuus5.c, 26 Dec 98.

Another minor correction to \ffiles() array management.  ckuus4.c, 27 Dec 98.

Updated HELP SORT text.  ckuus2.c, 27 Dec 98.

Updates to Telnet code from Jeff to accommodate sparse Telnet option arrays.
ckctel.h, ckcnet.c, 27 Dec 98.

Updated NEWS command.  ckuus2.c, 27 Dec 98.

NeXTSTEP was missing symbol definitions for most of the permission bits in
<sys/stat.h>.  Added #ifndefs for them.  ckufio.c, 27 Dec 98.

Fixed misplaced #ifdef CK_TTGWSZ in domydir(): ckuus6.c, 27 Dec 98.

Defined UTIMEH for HP-UX 9.0.  ckufio.c, 27 Dec 98.

Got rid of getuid(), etc, prototypes for HP-UX 9.0.  ckutio.c, 27 Dec 98.

DECC 5.5 on VMS 7.1 is great at finding stuff the other compilers don't:
 . Missing prototypes for sopkt() and zrelname().  ckcdeb.h, ckcker.h.
 . Missing prototype for lower(), and signed vs unsigned char casts
   for args to various lower(), le_getchar(), etc.  ckcnet.c.
 . Missing prototype for iks_wait().  ckctel.h.
 . Missing prototype for cmswi().  ckucmd.h.
 . sb[] used before declared.  Moved declaration up.  ckcnet.c.
 . Decomposed the statement "len = (xunchar(*p++) * 95) + xunchar(*p++)",
   which elicited a rather stern warning.  ckcpro.w.
 . The prototypes for some of the Kanji translations were in #ifdef KANJI
   in ckcker.h.  But KANJI was defined in ckcxla.h, which was included *after*
   ckcker.h.  Moved the errant prototypes from ckcker.h to ckcxla.h, where
   they belonged.  ckcker.h, ckcxla.h.
 . Removed obsolete reference to me_binary from ckvcon.c.
 . Many more like this.
After all this I get clean builds on VMS 7.1 with DECC.  27 Dec 98.

Removed curses support from QNX16 version.  See notes in makefile.  27 Dec 98.

Fixed typos in ckuus3.c and ckucon.c, noticed during X.25 build.  27 Dec 98.

---7.0 Beta.02---

From Jeff, 30 Dec 98:
 . Define & implement two new responses for Telnet IKS negotiation.
 . Define & implement several features for Pragma Systems telnet client.
 . Fixes for K95 VIEW command.

Changed copyright to 1999.  All modules, 30 Dec 98.

Added BSDI 4.0 target & banner.  makefile, ckuver.h, 30 Dec 98.

Increased Olimit for IRIX 6.4 build to stop warnings.  makefile, 30 Dec 98.

#ifdefs for SCO 3.2v5.0.x perror() prototype vs gcc.  ckcdeb.h, 30 Dec 98.

#ifdefs for SCO 3.2v5.0.x perror() declaration and contents (void vs int
return type).  ckuusx.c, 30 Dec 98.

Added missing #ifdef DEBUG around code in shocps() that referenced deblog.
ckuusx.c, 30 Dec 98.

Added code to check if, upon CONNECTing, the Telnet server is actually an
IKSD in server mode, and in that case to return to the prompt.  ckucns.c,
ck[uvd]con.c, 30 Dec 98.

Broke up a complicated printf() that blew up the Motorola SVR3 compiler.
shotopt(): ckuus4.c, 30 Dec 98.

Fixed some help-text typos.  ckuus2.c, 30 Dec 98.

Jeff pointed out that UNIX C-Kermit is dropping Telnet negotiations because
ttflui() doesn't check for Telnet negotiations.  The big switch statement in
ttinl(), which checks for IAC and if we're doing Telnet protocol, calls
tn_doop(), and then handles its return code, has to be duplicated in ttflui().
So I moved the switch() statement to a new routine, tt_tnopt(), and called it
from ttinl().  This didn't seem to break anything, so then I placed calls to
tt_tnopt() into ttflui() and ttflux().  This didn't seem to break anything
either, but it will need testing in the situations where negotiations were
being lost before.  ckutio.c, 30 Dec 98.

Corrections to yesterday's ckutio.c changes plus some other stuff from
Jeff, various modules, 31 Dec 98.

Adjustments to makefile & source modules for AT&T 7300 and other entries based
on SVR3 and earlier -- add:

  -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE

to CFLAGS, and make sure all the appropriate #ifdefs are in place.  Also,
add #ifndef NOGFTIMER to an unguarded reference to fpfsecs.  makefile,
cku[tf]io.c, ckuusx.c, 31 Dec 98.

Corrected yet another problem in ckindex() when told to search from the right.
ckuus4.c, ckcmai.c, 31 Dec 98.

Fixed IF MATCH to actually pass the SET CASE variable to ckmatch(), like it
was alway supposed to.  ckuus6.c, 31 Dec 98.

Reworked ckmatch() to allow quoting of metacharacters and single-character
matching by [abc] (list of chars) or [a-z] (range of chars), or any
combination.  The code is not exactly elegant but I think it covers every
conceivable combination (which I don't think elegant code can do).  Tested
extensively with "if match" over a hundred patterns ranging from those that
might be commonly used to the truly bizarre.  match.ksc, ckcmai.c, 31 Dec 98.

Changed the match() call in ckufio.c to ckmatch().  Now it is possible to tell
C-Kermit to "send ck[cuw]*.[cwh]".  Of course, it also affects all other
commands that parse filenames, as well as ? file lists, e.g. "send ck[cu]?".
ckufio.c, 31 Dec 98.

Fixed parsing of SET WILD SHELL when NOPUSH/nopush.  ckuus3.c, 31 Dec 98.

Verified ckmatch() works with 8-bit data, includeing 0xff.  However, IF MATCH
neglected to handle braces correctly so strings or patterns containing spaces
didn't work right; fixed in ckuus6.c, 1 Jan 99.

Added a new argument to ckmatch, telling whether to match strings that start
with ".", to make UNIX filename globbing work as before.  The new arg is the
"matchdot" variable, set by SET WILD KERMIT /[NO-]MATCH-DOT-FILES, used only
when calling from within zxpand(), otherwise always 1.  ckcker.h, ckcmai.c,
ckcfns.c, ckuus[56].c, ckufio.c, 1 Jan 99.

Added {string1,string2,...} matching to ckmatch(), in which the strings
themselves can be patterns, recursing to any reasonable level.  ckcmai.c,
ckermit2.txt, 1 Jan 99.

Updated UNIX iswild() to know about new metacharacters, and also to know about
quoting, which it never did before.  ckufio.c, 1 Jan 99.

Problem: At some point since last May (but before Beta.03) I broke parsing
of quoted question marks in filenames, e.g.:

  send cku\?io?

Instead of listing several files like it should, it went nuts.  Found & fixed
the problem in gtword(): ckucmd.c, 1 Jan 99.

Added CKREGEX and NOCKREGEX compile-time symbols.  Use the latter to get rid
of [] and {} globbing in case it produces undesirable effects.  Otherwise
CKREGEX is defined for all platforms.  ckcdeb.h, ckcmai.c, ckufio.c, 1 Jan 99.

Put SHOW PATTERNS in #ifdef PATTERNS so it doesn't show up on VMS, etc..
ckuusr.c, 1 Jan 99.

DISABLE DELETE prevented SET FILE COLLISION xxx in the client.  Fixed the code
so the check is made in the server.  ckcfns.c, ckcpro.w, 1 Jan 99.

More fixes to ckindex() so the optional 3rd argument is treated uniformly for
both left and right searches.  ckcmai.c, ckuus[24].c, ckermit2.txt, 1 Jan 99.

A user reported that an ancient and hacked version of Kermit that is found on
QNX2 and QNX3 systems, when it sends "&" in its parameter string to indicate
it wants to do 8th-bit quoting, demands a response of "&" and does not accept
"Y", which C-Kermit sends.  Added an invisible command: SET Q8FLAG {ON,OFF}.
When ON, this makes C-Kermit reply with the same 8th-bit quote character that
the sender sent; when OFF (the default), it responds with "Y" as it always
did.  ckuusr.h, ckuus[r3].c, ckcfns.c, 1 Jan 99.

DIRECTORY would print nothing and succeed if it ran out of memory when
making a sorted listing.  Now it prints "?Too many files match" and fails.
ckuus6.c, 1 Jan 99.

Updated gettcs() (which picks the intermediate character set for TRANSLATE,
TRANSMIT, and non-K95 CONNECT to account for Latin-9, CP858, and CP1252 for
Euro's sake, just in time!  ckuus4.c, 1 Jan 99.

Updated SHOW CHARACTER-SETS to account for Latin-9 as an intermediate set:
shotcs(), ckuus5.c, 1 Jan 99.

Corrections from Jeff to yesterday's changes.  ckcmai.c, ckuus[23].c. 2 Jan 99.

Discovered that UNIX coninc(x), where x > 0, returned -1 rather than -2 on
timeout.  When coninc() calls ttinc() the fix rather hideous -- see the code.
ckutio.c, 2 Jan 99.

Added SET ASK-TIMER n (sec), to make ASK and friends time out and fail if user
doesn't supply an answer within n seconds.  Works with ASK, ASKQ, GETOK, and
GETC.  ckuusr.h, ckucmd.c, ckuus[r36].c, 2 Jan 99.

Added IF ASKTIMEOUT to let script writer test whether ASK-class command failed
because of timeout.  ckuusr.h, ckuus6.c, 2 Jan 99.

Added --timeout:n for IKSD login.  ckuusr.h, ckuus[25y].c, 2 Jan 99.

Set a default time limit to log in to IKSD at 300 seconds (5 min).  This works
in the Username:/Password: dialog via the ASK-TIMER mechanism, and in
client/server mode via some crude sampling of the system clock (not foolproof;
if user client never sends anything I don't think the server will time out).
ckcmai.c, ckuus7.c, 2 Jan 99.

Updated help text for new commands and reformatted much of the help text for
more consistent indentation and spacing.  ckuus2.c, 2 Jan 99.

VOS updates, etc, from David Lane & Jeff.  4 Jan 99.

VMS updates from John Santos.  ckcnet.c needs saddrlen declared as unsigned.
DEC C 6.0 header files refer to a data type of u_int but don't define it
anywhere, so a definition was added to ckcnet.h.  Changed the name of rdata
state in ckcpro.w to rdpkt, since the name rdata conflicts with a struct
element defined in nameres.h.  4 Jan 99.

Got rid of "Negotiations..." and spinner display when in remote mode.
Only the client should print these.  ckcnet.c, 4 Jan 99.

Problem (which is not new): "dir /recursive */blah" matches all files in the
current directory, because this becomes "./*/blah" and the "*" segment matches
all files in the current directory (see traverse() in ckufio.c).

Fix 1: At the point where we are adding a file because the search is recursive
and the file is not a directory, match it with the original pattern.  This
filters out all the files whose names are different from the desired one, but
since the current segment has "./" prepended to it, "*/blah" also matches
"blah" in the current directory because "blah" has become "./blah".  Also
"dir /recu blah" matches nothing, even if "blah" is in the current directory
and/or subdirectories.

Fix 2: Like fix 1, but point past the leading "./" prior to the comparison.
This makes "dir /recursive */blah" work exactly right, but it prevents "dir
/recursive blah" from matching blah files in subdirectories because the
pattern "blah" does not match "xxx/blah".  But this is the right track.  Note
that * does not match slash in UNIX filename globbing; but in ckmatch() slash
is just another character.  Therefore, it's the responsibility of the file
code to pass the right strings to ckmatch().  The trick is to note how many
directory separators were in the original pattern, and then match strings
containing that many segments.  For example, if the original pattern is
"oofa.txt" (1 segment), and we are matching ./aaa/bbb/oofa.txt (4 segments),
we must strip 4 - 1 = 3 segments from the left before matching.  Similarly, if
the original pattern is */oofa.txt, we strip 2, and match with bbb/oofa.txt.

So now suppose we have a directory tree in which oofa.txt files exist at all
levels.  "dir oofa.txt" shows the one at the current level.  "dir /recursive
oofa.txt" shows all the ones at all levels.  "dir */oofa.txt" shows the ones
one level down.  "dir /recursive */oofa.txt" shows the ones one level down
and lower.  "dir /recursive */*/oofa.txt" shows the ones 2 levels down and
lower, etc etc.  fgen(), traverse(): ckufio.c, 5 Jan 99.

More cleaning up & improving HELP text, especially HELP SET HOST.  ckuus2.c,
5 Jan 99.

Jeff broke the Telnet protocol out of ckcnet.c to a separate module, ckctel.c.
5 Jan 99.

Changed UNIX makefile to account for ckctel.c.  5 Jan 99.

Some changes to IKS server in/out switching from Jeff.  ckcpro.w, 5 Jan 99.

Jeff made dodir() call domydir() in K95.  ckuus5.c, 5 Jan 99.

Jeff made TELNET command add an implicit /TELNET at the send of the command.
ckuus7.c, 5 Jan 99.

Added HELP WILDCARDS.  ckuusr.[ch], ckuus2.c, 5 Jan 99.

Added SET F-ACK-BUG { ON, OFF } (invisible).  ckuusr.[ch], ckuus3.c, ckcpro.w,
6 Jan 99.

Added a section on coping with faulty Kermit implementations to ckermit2.txt,
6 Jan 99.

Added messages to refer UNIX users to installation instructions when access
to lockfile directory and/or dialout device is denied.  ckuus7.c, 6 Jan 99.

Moved common library routines from ckcmai.c to a separate module, ckclib.[ch],
and updated the UNIX makefile to know about it.  6 Jan 99.

Added code to protocol module to catch failure to negotiate Kermit server on
Telnet connection.  ckcpro.w, 6 Jan 99.

Updated the VMS build procedure for ckctel and ckclib.  ckvker.com, ckvold.com,
6 Jan 99.

Updated the OS-9 build procedure for ckctel and ckclib.  ck9ker.mak, 6 Jan 99.

Updated the Plan-9 build procedure for ckctel and ckclib. ckpker.mak, 6 Jan 99.

Updated the DG build procedure for ckctel and ckclib. ckdsrc.lis, 6 Jan 99.

Updated the Amiga build procedure for ckclib. ckiker.mak, 6 Jan 99.

Updated the VOS build procedure for ckctel and ckclib. cklker.mak, 6 Jan 99.

Fixed various glitches in ckcnet/ckctel split uncovered by building in VMS.
6 Jan 99.

Added \fpermissions(file).  ckuusr.h, ckuus[24].c, 6 Jan 99.

Added \v(lockdir) for UNIX.  ckuusr.h, ckuus4.c, 6 Jan 99.

Added IF READABLE and IF WRITEABLE.  Each of these takes either a filename
or a directory name.  Getting them to work for directories was a hack (global
variables again).  Probably in K95 they should just always succeed.  ckuusr.h,
ckuus6.c, ck[uvd]io.c, 6 Jan 99.

  Note: These last several items are mainly in case we ever want to
  write an install-myself script.

Some changes from Jeff to (in)visibility of Telnet-related keywords.
ckuus3.c, 6 Jan 99.

telnet.txt from Jeff added to docs.  6 Jan 99.

Discovered that makelist(), which parses {{xxx}{xxx}...} lists (as in
SEND /EXCEPT:) chokes on {{{xxx,yyy,zzz}}} -- i.e. when you want to put a
new-format wildcard as the exception list.  Fixed in ckuusr.c, 6 Jan 99.

Fixed DIRECTORY /HEADING /RECURSIVE not to list the number of directories,
since it's always 0 (zxpand() does not include directories in its list when
called recursively).  ckuus6.c, 6 Jan 99.

Added DIRECTORY /[NO]DOTFILES for UNIX & OS-9.  ckuusr.h, ckuus6.c, 6 Jan 99.

Added SET HOST /NETWORK-TYPE:{TCP/IP,COMMAND,...}.  No reason not to, and it
was easy.  Also made SET HOST /COMMAND invisible, since it is only a special
case of /NETWORK-TYPE:.  The /NETWORK-TYPE switch does not affect the global
SET NETWORK TYPE.  ckuusr.h, ckuus7.c, 6 Jan 99.

Updated Telnet-related HELP text from Jeff.  ckuus2.c, 7 Jan 99.

The code I put in to prevent "Negotiations...." from coming out of IKSD also
prevented it from coming out of the client.  Fixed in tn_wait(), ckcnet.c,
7 Jan 99.

Discovered the server end of REMOTE DIRECTORY is broken in UNIX for huge
directories.  Local directory listings are fine.  A packet log reveals that
the transfer looks normal, but the data ends early.  Debug log shows "sending
packet out of window" for every data packet, but that always happens when
streaming.  Changed spack() not to log this message when streaming.  ckcfn2.c,
7 Jan 99.

The problem turned out to be not the size of the directory, but the fact that
it contained a file with an 8-bit name, and we were storing the filenames in a
char array instead of an unsigned char array.  Returning an 8-bit signed char
from int nxtdir() caused its sign to be extended, and a negative return signals
EOF.  Fixed in nxtdir(), ckcfns.c, 7 Jan 99.

Discovered that the VMS C-Kermit Telnet client on UCX makes the connection OK,
but loses the hostname.  But only if TCP REVERSE-DNS-LOOKUP is ON and only
with certain hosts.  Discoveries: (1) the fact that gethostbyaddr() returns
non-NULL does not mean that h_name is set; and (2) netopen() writes into its
hostname argument -- gak!  Fixed netopen() to handle case (1) by filling in
the IP address if no name comes back, and also to issue its "blah connected on
port blah" messages a bit more consistently.  Left (2) alone, sleeping dogs
department...  ckcnet.c, 7 Jan 99.

Discovered that VMS tthang(), in the network case, closed and then reopened
the network connection.  Fixed it to just close it.  ckvtio.c, 7 Jan 99.

Fixed a place where quiet was not restored before returning from doconect().
ckuus4.c, 7 Jan 99.

Added code to UNIX traverse() to make it return directory names during
recursive traversal, as well as filenames.  This was a bit tricky due to the
possibility of showing or not showing dot files.  If we are not showing dot
files in UNIX, then we should not descend into any directory whose name
starts with a dot.  (In fact, this issue had never been addressed before,
but now it's fixed.)  ckufio.c, 7 Jan 99.

Commented out the check against summarizing directories in DIR /HEADING
/RECURSIVE, since directory files are now shown.  ckuus6.c, 7 Jan 99.

Checked "send /recursive", and of course it was broken, since gnfile() never
expected to be fed a directory by znext().  We'd have the same problem in K95.
Added a check to gnfile() to skip over directory files; recursive sends seem
to be working again.  ckcfns.c, 7 Jan 99.

Discovered that "send ." no longer recursed.  Did it ever?  ckermit2.txt
is contradictory on this, so I fixed it by removing any claims that "send ."
implied /RECURSIVE.  ckermit2.txt, 7 Jan 99.

"send /recursive ." now dies with a parse error when the current directory
happens to contain at least one subdirectory, and the first file returned when
expanding "." happens to be a directory file.  I patched this in both cmifi()
and zxpand(); the former by checking the global recursive flag (yuk) and the
latter by simply translating "." to "*".  This works OK, but "send /recursive
.." still doesn't work, even though "send .." does.  Well, there's no end to
this, so the clever thing to do is to have zxpand() call xfnqfp() on its
argument up front.  This nicely takes care any kind of crazy path (like
.././../baz/../../foo.bar) that the user could dream up, not to mention
tildes, etc.  But that would be too easy.

In fact, "send /recursive .." actually DOES work.  The problem is the same as
with putting zfnqfp() into zxpand(), or for that matter, specifying a full
pathname or a pathname starting with tilde in combination with /RECURSIVE,
namely that splitpath and traverse go through the ENTIRE FILE SYSTEM, file by
file, which can take hours and in any case grinds the disk to dust.  This is
independent of today's change to make zxpand() return directory files; the
same thing would have happened any time since we added SEND /RECURSIVE, and
indeed it happens with 6.1 Beta.05 from last May: "send /recursive ~/tmp/*"
does the trick quite nicely in /usr/local/bin/wermit.

Hacking away at this, I managed to more or less fix it but some glitches
remain.  First of all, the parsing of "." and ".." etc stopped working again.
But now I can put back zfnqfp() in zxpand() and all's well, except now we
always get fully qualified names rather than relative ones, so I had to back
off on that one for now.  Another problem is that "dir /recursive <dirname>"
only shows directories, not files, in any directory that is subordinate to the
one named in the command.  OK, close...  Will finish this tomorrow.
ckufio.c, 7 Jan 99.

Fixed lingering problems in UNIX wildcard expansion.  ckufio.c, 8 Jan 99.

Changed zxpand to append path separator to any directory names it returns.
ckufio.c.  8 Jan 99.

Since we don't know whether all implementations of zxpand() will return
directory names with separator appended, high-level code that does this in
various places (e.g. filhelp(), cmifi2()) still does it, but only if it was
not done already.  ckucmd.c, 8 Jan 99.

Added DIRECTORY /FILES (to show only regular files) /DIRECTORIES (to show only
directories) and /ALL (default, to show files and directories).  ckuusr.h,
ckuus6.c, ckermit2.txt.  8 Jan 99.

Changed SWITCH to evaluate case labels with zzstring() and then use ckmatch()
on them rather than strcmp().  Now we can have shell-like switch statements
with variables/functions/patterns as cases.  ckuus6.c, ckermit2.txt, 8 Jan 99.

Still have lots of details to clean up, will do them next week.

From Jeff: The Telnet Negotiation delay mechanism has been redesigned once
again.  The requirement is not that WILL/DO negotiations can't be sent before
encryption is active, just that none of the subnegotiation data be sent before
the encryption is in place.  So now there is a method to delay sending
subnegotiation data until after START_TLS, AUTH, and ENCRYPT are complete.
This means that we send all WILL/DO messages other than ENCRYPT before waiting
for the AUTH response.  If AUTH is refused we are done and there should be
almost no delay when connecting at the expense of more complex code.  And
since the NAWS is now sent to the telnetd before "login" is started it works
the first time and the SIGWINCH is not generated in the subprocess which
interrupts the "Password:" read attempt.  Also, it seems that I never added
the DO case for TELOPT_SNDLOC.  We would have negotiated SNDLOC but never sent
the subnegotiation.  So that is now fixed.  (End quote) ckctel.[ch],
11 Jan 99.

Also from Jeff: typo in krbmit entry fixed, makefile, plus some K95-specific
stuff: ckuus[27].c, 11 Jan 99.

Updated HP-UX entries from Peter Eichhorn, 11 Jan 99.

The "Negotiations... (OK)" message was coming out twice, which is annoying
especially now that Telnet connections are so much quicker.  There did not
seem to be any easy way to consolidate the two messages, so instead I added
some code so they would print only upon a negotiation timeout.  So this speeds
up the connection even more (I didn't touch the spinner code, but it probably
could use the same treatment).  ckctel.c, 11 Jan 99.

Made the UNIX DIRECTORY command handle symlinks.  Of course this depends on
the nonportable lstat() function, so another pile of #ifdefs in ckcdeb.h, and
then some additional #ifdef'd code in domydir().  Now we get permissions,
date, size, and name of the symlink, plus a "->" pointer to the linked-to
file.  To do this as efficiently as possible, I made zgetfs() have some side
effects: since it's calling (l)stat() anyway, it also gets the link info, and
also sets a flag saying whether the file is a directory.  But we only take
advantage of this in the DIRECTORY command where it can't do any harm.
Of course, Yet Another Global Flag (diractive) had to be used to indicate to
the low-level routines (zfcdat(), zgperm(), ziperm(), etc) whether to call
stat() or lstat(), since we only want to call it for DIRECTORY commands, not
file transfer, etc.  Yuk.  ckcdeb.h, ckufio.c, ckuus6.c, 11 Jan 99.

As of yesterday, "dir <anypath>/*/filename" didn't work.  Similarly for "dir
<anypath>/*/*/filename", etc.  Fixed in traverse(), ckufio.c, 12 Jan 99.

"directory /recursive blah" (where "blah" is a filename, or in fact any
pattern other than "*") doesn't work -- as far as I can tell, it never did.
This should list all occurences of "blah" in the current (or given) directory
tree, at any and all levels at which it occurs.  After several more hours of
pounding on traverse() I got this working too.  ckufio.c, 12 Jan 99.

But now "dir /recursive" shows dotfiles even when it shouldn't.  Fixed that
too.  But every fix breaks something else.  So now DIR /DIR * doesn't work any
more.  Fixed that.  But now DIR /RECURSIVE /DIR lists each directory twice.
Attempts to fix that broke everything else.  I hate this routine.  Finally
after more fixing, all of the following work:

  dir
  dir /files
  dir /directories
  dir /recursive
  dir /recursive /files
  dir /recursive /directories
  dir oofa.txt
  dir /recursive oofa.txt
  dir /recursive *.txt
  dir *.txt
  dir */*.txt
  dir */*/*.txt
  dir .*
  dir /recursive .*
  dir /dotfiles
  dir /dotfiles /recursive
  dir foo (where "foo" is a directory name)
  dir .
  dir ..

Obviously there are many more combinations, but these are the only ones
that affect which files are shown and which ones aren't.  Also checked:

  \ffiles(*)
  \frfiles(*)
  \fdirectories(*)
  \frdirectories(*)

These work too, with both SET WILD KERMIT /MATCH-DOT and /NO-MATCH-DOT.

But then there was some new trouble matching dotfiles in certain contexts, for
example "dir {{*,.*}}" or "dir [.abc]".  Made a minor correction to ckmatch()
for this.  ckclib.c, 12 Jan 99.

Updated HELP IF text.  ckuus2.c, 12 Jan 99.

Changed TRANSMIT in the text / prompt 0 / pause 0 / echo off case to send
1K buffers rather than lines.  Speeds up transmission by about 35% in this
case.  Didn't bother with binary mode since nobody uses it anyway, and the
changes for that are a bit harder.  ckuus4.c, 13 Jan 99.

Updated HELP DIR, HELP SWITCH, HELP SET FILE, and HELP WILDCARD text.
ckuus2.c, 13 Jan 99.

Got tired of hunting for things in the SHOW FEATURES compiler options list,
so changed SHOW FEATURES to sort them.  Also fixed the paging, which had
drifted a bit with new additions.  ckuus5.c, 13 Jan 99.

Added DIR /[NO]XFERMODE.  If /XFERMODE is included, the directory listing
shows the transfer that would be used for each based on the current patterns.
If none is shown, then the filename doesn't match any patterns.  This seems
like a useful addition to a Kermit directory listing.  ckuusr.h, ckuus6.c,
13 Jan 99.

Added DIR /[NO]BACKUP.  If /NOBACKUP is included, backup files (*.~*~) are
not shown.  ckuusr.h, ckuus6.c, 13 Jan 99.

Added SEND /NOBACKUP.  If /NOBACKUP is included, backup files are not sent.
ckuusr.[ch], ckuusx.c, ckcfns.c, 13 Jan 99.

Added SET SEND BACKUP { ON, OFF } to establish the global setting that SEND
/NOBACkUP would override (SET RECEIVE BACKUP too, for symmetry, but it does
nothing - just prints a message).  Added SET SEND BACKUP status to SHOW
PROTOCOL.  ckuusr.h, ckuus[47].c, 13 Jan 99.

Updated docs and help text.  ckermit2.txt, ckuus2.c, 13 Jan 99.

TRANSMIT was not always sending its last buffer in text mode.  I don't think
it ever did.  Fixed in ckuus4.c, 14 Jan 99.

Changed nzltor() (local-to-remote filename converter) to (a) replace space by
underscore rather than X, (b) replace tilde by hyphen rather than X, and (c)
translate non-ASCII chars to ASCII.  The latter works effectively if the file
character-set has been properly set; otherwise it's no worse than before (this
does not address the larger question of proper translation of filenames).
Converted filenames are now much more readable, especially backup files:
foo.bar.~3~ becomes FOO_BAR.-3- rather than FOO.BARX3X, and accented letters
lose their accents rather than coming across (in most cases) as box-drawing
characters, etc.  ckufio.c, 14 Jan 99.

Trials show that the time to sort a directory listing is imperceptible, at
least compared with the time to read the directory, so I made /SORT:NAME the
default except in VMS, where directory names are returned in alphabetical
order anyway.  I did not do this for server-generated directory listings --
that is a much bigger project, deferred til next time.  ckuus6.c, 14 Jan 99.

Updates to Minix 2.0 support from Terry McConnell, Syracuse U, ckcdeb.h,
ck[tu]fio.c, makefile, 14 Jan 99.

Lots of #ifdef adjustments, casts, etc, for building different configurations,
many modules, 14 Jan 99.

winchh() and sw_armed were used in ckctel.c but unknown to them.  I thought I
could move them from ckcnet.c to ckctel.c, but that didn't work, so I left
them in ckcnet and extern'd them from ckctel.  Builds OK, but NAWS operation
needs to be checked.

Somebody did something to utmp.h in Linux recently which makes it impossible
for any application that includes that file to have variables, functions, or
macros called local, screen, telnet, rlogin, xterm, rsh, ftp, unknown, or X
(see "enum utlogin").  Swell.  (This was noticed in mklinux, but not in the
Intel version -- same kernel number; double swell.)  There was no good way to
avoid the conflict, so (a) I renamed our screen() routine to ckscreen(), along
with all references to it.  (b) was harder, since there are about 1000
occurrences of the string "local" in the C-Kermit source, some of them
embedded in other strings (e.g.  "localtime()") or in comments or text); I
wasn't about to change all of them at the last minute.  Adding -Dlocal=cklocal
doesn't help either; enums are "too powerful".  The obvious solution was to
build for Linux with -DNOWTMP, but that would eliminate some prominent
convenience items, not to mention IKSD logging.  Because of the utter
stupidity of the C language, there was no way to #include <utmp.h> and avoid
these conflicts, so finally I just hardwired the needed definitions from
utmp.h and utmpbits.h into ckufio.c.  YUK!!!  14 Jan 99.

The new TELOPT macros defined in ckctel.h were too complex for some compilers
(preprocessors) to handle so Jeff added a -DNOTOMACROS switch and accompanying
code to allow their replacement by compiled functions.  Also, a correction
from Jeff to logstr().  ckctel.[ch], ckuusx.c, 14 Jan 99.

Discovered the base Solaris entry had not been converted from ckucon to ckcns.
Fixed in makefile, 14 Jan 99.

 hpux500wintcp -- try with xermit.
 look for prototype for inet_ntoa() in hpux headers.

aos kermit got a stack dump / traceback because free() was called from
close() which was called (on the tty) from _exit.  Hmmm -- not Kermit's
problem.

--- Beta.03 ---

Corrections from Jeff to IKS negotiations: ckctel, ckcnet, ckuus4, ckcpro;
plus some character-set fixes: ckouni, 17 Jan 99.

Moved extern int nnets outside of #indef NODIAL so -DNODIAL builds would work.
ckuus7.c, 17 Jan 99.

Added missing "Solaris 7 implies Solaris 2.6" clause to ckcdeb.h, 17 Jan 99.

Some shuffling of #ifdefs in an attempt to fix broken compilation on Sinix
5.43 and Pyramid.  Generalized the "gettimeofday takes one arg instead of two"
business, instead of making it specific to Motorola SV88R4.  ckutio.c,
17 Jan 99.

Removed iks_wait() call that was in the middle of REMOTE command parsing.
No actions should occur until after cmcfm().  This was making "(OK)" messages
appear in the middle of typing any REMOTE command.  ckuus7.c, 17 Jan 99.

Some #ifdef juggling for HP-UX 10.01 to eliminate compiler warnings about
select() and localtime().  ckutio.c, 18 Jan 99.

From Jeff: Some additional changes for VOS; expanded TELOPT command;
various modules, 18 Jan 99.

New TELOPT command options are "ao", "ayt", "break", "cancel", "ec", "el",
"eof", "eor", "ga", "ip", "dmark", "do", "dont", "nop", "sb", "se", "susp",
"will", "wont".  This lets us send any Telnet command at all; e.g. as a probe
to see if the connection is up (e.g. NOP).  (I changed some of the return
codes; pls check.)  ckuusr.c, 18 Jan 99.

Tested this a bit, using TELOPT NOP or TELOPT DMARK as a probe.  If I kill
the remote process, these still succeed, even if I wait a while first.  The
second one fails.  Seems strange -- how do we document this?  "To see if the
server is still there, use "telopt nop, telopt nop, if success ..."

Refined the "Negotiations....(OK)" suppression code a bit.  Much better now,
but still not perfect.  More later...  ckctel.c, 18 Jan 99.

Got access to an SCO 3.2V4.2 system and made necessary adjustments to get
successful builds, mainly #including <sys/time.h> and linking with -lsocket
so we can use gettimeofday for the high-precision timers, etc.  I'm not sure
if no-net systems can run a binary that is linked with -lsocket, but let's
hope so...  Converted these entries to xermit, since we can use select().
makefile, cku[ft]io.c, ckuver.h, 19 Jan 99.

Added sco32v4ns entry to build a version that does not use the sockets
library, select(), or gettimeofday(), just for safety.  Also, this was a good
verification that -DNOGFTIMER still does its job.  makefile, 19 Jan 99.

Took all the -DNOSETBUF's out of the makefile and just set it in ckcdeb.h.
(I thought I had done this before...)  makefile, 19 Jan 99.

Fixed IKSD not to refuse to send a file just because client does not have
TERM AUTODOWLOAD ON.  ckcpro.w, 19 Jan 99.

Some changes from Jeff for K95 keyboard settings.  ckuusr.h, ckuus7.c,
19 Jan 99.

From Jeff, 20 Jan 99:
 . Fix bug in CLEAR INPUT: ckuusr.c.
 . Help text for SET TERM DG-UNIX-MODE: ckuus2.c.
 . Added table of DEC keyboard (terminal) languages + parsing: ckuus7.c.

Fixed some bad notation in the IRIX 6.4 entry (-OPT:Olimit=3000 should have
been -Olimit 3000; the former notation is not used until IRIX 6.5, silly me).
makefile, 20 Jan 99.

Added "-b elf" to SCO 5.0.4 and .5 non-gcc entries to avoid making COFF
binaries (which is bad because...?).  makefile, 20 Jan 99.

Added HPUX6 and HPUX7 symbols to the appropriate makefile entries, since all
the other HPUX's had their own.  Added custom banners for HPUX 6 and 7.  Added
code to the network module to include <arpa/inet.h> for all HPUX except 7 to
pick up the inet_ntoa() prototype (7 is excluded because it does not seem to
have this header file, even though all the others do).  makefile, ckuver.h,
ckcnet.c, 20 Jan 99.  (Builds OK with previous warnings gone on HPUX 9 and 10.)
(Later confirmation received on HPUX 6 and 7.)

NOSPL builds were failing due to unguarded references to mjd() in the
connection log writer.  Changed ckcdeb.h to set NOLOGDIAL if NOSPL was set.
20 Jan 99.

Fixed some typos in ckermit2.txt.  20 Jan 99.

Added code to display READ.ME file from current directory at startup if
srvcdmsg != 0 (mainly for iksd).  ckuus5.c, 20 Jan 99.

Should TERM AUTODOWNLOAD be ON by default in C-Kermit (as it is in K-95)?
 . No, because the book says it isn't.
 . No, because C-Kermit is very likely to be in middle.

But then what about when it is a client of IKSD?  In that case it should be
ON so SEND from the IKSD prompt will always work.  But then if it's in the
middle, we'll still have trouble if the local Kermit also has it on.

So what are the choices?
 . Leave it alone.  But this makes IKSD look bad.
 . Make it on by default?  Causes confusion when C-Kermit in the middle.
 . Turn it on automatically when client of IKSD?  (Save & restore)

Well, yes, obviously we want it on when we're a client of IKSD.  That's not
the question -- the question is what do we do about the other, more local,
Kermit that might also have it on?  There's nothing we CAN do, so don't worry
about it.  Ideally, then, we would change SET TERM AUTODOWNLOAD { ON, OFF }
to { ON, OFF, AUTO }, with AUTO being the new default, meaning "enable
autodownload automatically if I make a connection to an IKSD".  And I started
to do it that way, but ran into conflicts with K95, which has a different and
conflicting set of keywords, plus it was not obvious where the automatic
switching should be done, nor where to undo it when the connection is broken
or some other negotiation would change the rules.  So I simply made the
default be ON for all C-Kermits as well as K95.  It's a lot easier to explain
this way, and in fact the book goes into some detail about it in several
places.  ckcmai.c, 20 Jan 99.

Changed SET FLOW AUTO to always SET FLOW NONE when making a direct serial
connection, rather than setting it to RTS/CTS just because we know we can.
The latter turned out to be a bad idea because a direct connection is very
likely not to be giving us the CTS signal (or even have a wire for it), so any
attempt to write will just hang.  setflow(): ckuus3.c, 20 Jan 99.

Changed "kermit -l" to also call setflow(), so we get consistent behavior
with command-line and interactive device opening and i/o.  ckuusy.c, 20 Jan 99.

SINIX 5.43 changed gettimeofday() to have one arg instead of two.  Added
appropriate #ifdefs to ckutio.c, defines to the makefile entry, and a
designer herald in ckuver.h.  20 Jan 99.

Added -DSELECT -DNOGETUSERSHELL to pyrdcosx entry.  makefile, 20 Jan 99.

Fixed some long lines in ckuus2.c, 20 Jan 99.

Changed BSDI product name from BSD/386 to BSD/OS, to reflect current usage
since the 1.1 release.  makefile, ckuver.h, 20 Jan 99.

Lots of changes from Jeff to get rid of non-CKOUNI possibility in K95.
Many modules, 20 Jan 99.

Bug: "xif 1 { input 10 ), echo Thanks: [\v(input)] }" produces garbage because
the ")" caused the enclosing "\flit()" (which is used internally by XIF and
friends to prevent premature evaluation of its command blocks) to terminate
early.  Fixed in litcmd() by quoting any unbalanced right parentheses.  Also
added a destination length argument to litcmd() to prevent memory leaks.  Also
removed some really obnoxious debug() calls from litcmd().  ckuusr.h,
ckuus[56].c, 21 Jan 99.

Changed ODT 3.0 makefile entry not to contain an underscore, since these don't
show up when underlined (e.g. in Web links).  makefile, 21 Jan 99.

Stripped out some obsolete comments from ckuus4.c, 21 Jan 99.

Added a note about new TELOPT operands and cleaned up some typos in
ckermit2.txt, 21 Jan 99.

Fixed the "Negotations... (OK)" message again.  The idea is: don't print
"Negotiations" unless we get a timeout from tn_wait().  Once we get a timeout
and print "Negotiations", then print "." every second till the wait is up,
then print "(OK)".  Don't print dots or "(OK)" if we didn't print
"Negotiations".  Don't print "(OK)" twice.  AND... only do this upon initial
connection, not during the session.  This way, most people will never see
this message; it will only appear when the connection is taking a long time,
to let them know Kermit isn't dead.  ckctel.c, 21 Jan 99.

Moved lower() to ckclib, and renamed it to cklower().  ckucmd.c, ckuus5.c,
ckclib.[ch], 21 Jan 99.

Got rid of xindex() and replaced all references to it by references to
ckstrchr(), which is in ckclib.  ckufio.c, 21 Jan 99.

New HP-UX makefile entries from Peter Eichhorn; updated "+/-/?" notations in
comments at the top for C-K 7.0.  makefile, 25 Jan 99.

Some compilers have started to choke on "too many defines" in ckuusr.h.  Put
large blocks of K95-specific defines in #ifdef OS2..#endif, Telnet-specific
defines in #ifdef TNCODE..#endif, etc.  ckuusr.h, ckuus2.c, 25 Jan 99.

From Jeff: TELNET /PASSWORD:<pswd>, SET HOST /PASSWORD:<pswd>, for SRP enabled
versions of C-kermit.  To allow scripted operation of SRP connections.  Still
need to figure out how to allow users to call SET LOGIN PASSWORD <pwd> in K95
without the <pwd> being provided in an encrypted form.  But for now, SET LOGIN
PASSWORD will set a flag in K95 indicating that is where the password came
from so we know whether or not to decrypt it in ckuath.c Also, added support
for Preauthenticated Kerberos IV Ticket Getting Tickets, AUTH K4 INIT
/PREAUTH.  This provides an added layer of security by requiring that the
user's password be used to encrypt the ticket getting ticket request.  By
configuring the server to require pre-auth ticket requests it becomes nearly
impossible for an unauthorized user to request a TGT.  Unfortunately, this
does not work in K95 because Leash does not include the necessary
functionality.  It does work in C-Kermit.  ckcnet.c, ckcmai.c, ckuus7.c,
ckuus3.c, ckuath.h, ckuusx.c, ckuusr.c, ckuath.c, 25 Jan 99.

Looking at recursive transfers in VMS...

 . SEND /RECURSIVE actually works as it should, as long as it's given the
   a filespec containing "...".  The code is already there to accept the
   switch and set SEND PATHNAMES to RELATIVE automatically, and the files
   are indeed sent with relative pathnames.

 . GET /RECURSIVE did not set RECEIVE PATHNAMES RELATIVE, so I fixed that.
   ckuus6.c, 26 Jan 99.

 . I considered inserting "..." into the filespec, but that would be going
   overboard, plus how would it work in the middle of a parse, e.g. when "?"
   was typed in the filename, etc.  Also, not all filespecs lend themselves to
   this, e.g. in "define foo [somedir], send /recursive foo:*.*" there is no
   place to put the "..." ("foo:[...]*.*" doesn't work).

The /RECURSIVE switch for GET was in #ifdef RECURSIVE.  That was wrong -- the
client should be able to send this request to the server, even if the client
itself does not support recursive transfers.  The #ifdef was removed.  And for
symmetry, I added RECEIVE /RECURSIVE, which simply sets RECEIVE PATHNAMES to
RELATIVE.  ckuus6.c, ckermit2.txt, 26 Jan 99.

Discovered that when C-Kermit receives a file that has the same name as an
existing file into a directory that has many thousands of files (and FILE
COLLISION is BACKUP or RENAME), it can take a loooong time to make the backup
file name, since Kermit has to read the whole directory to find out which, if
any, backup files already exist.  The delay might be as long as 10-20 seconds,
even a full minute.  But C-Kermit 6.0 takes hardly any time at all in the same
directory.  Is it because of the new pattern matcher (ckmatch() instead of
match())?  Putting back match() makes it take even longer.  traverse() is the
culprit: it's now calling isdir() on every single file, which turns out to be
a surprisingly expensive call.  A little thought revealed it was OK to skip
the call to isdir() in the nonrecursive case, since higher-level code will
take care of filtering out unwanted directory files.  ckufio.c, 26 Jan 99.

Back to VMS...  Compilation of ckuusr.c blows up due to new #ifdefs in
ckuusr.h; it is now necessary to #include ckcnet.h before ckuusr.h, rather
than after, so the various TCP-related symbols will be defined before they are
referenced in #ifdefs in ckuusr.h.  ckuusr.c, 26 Jan 99.

Next problem:  GET /RECURSIVE, when sent to a VMS server, always results in
"Receive window full", even though it works fine with a UNIX server.  Why?
Once again, spurious #ifdef RECURSIVE..#endif around the supporting code.
#ifdefs removed and the command now works.  ckcpro.w, 26 Jan 99.

Except that it's sending the pathnames in VMS format rather than standard
(UNIX) format.  Why?  Because the client said to (K95 has FILE NAMES LITERAL
by default).  This is a problem because what is a non-VMS client going to do
with VMS-format directory names?  Unfortunately, the "fncnv" (filename
conversion) flag is overloaded in this case: we might want to leave the file
names unconverted but still need to convert the directory path syntax.  This
doesn't affect UNIX (even though it has the same bug) because its path syntax
is the same as the standard one.  To work around the problem for VMS only, I
made an additional check in nzltor(), so now we convert the path syntax if
FILE NAMES are CONVERTED *or* if the system ID of the other Kermit is not "D7"
(the VMS system ID).  ckvfio.c, 26 Jan 99.

Additional SNI stuff from Jeff for K95.  ckuusr.h, ckuus7.c, 26 Jan 99.

Minor SNI and help-text changes from Jeff.  ckuus[27].c, 28 Jan 99.

Added horizontal text lines to mark entry to and exit from CONNECT mode (when
not quiet).  These are done only in the CONNECT modules, not in the mainline
code, since terminal-emulating versions should not do this.  Also the lines
are not printed if QUIET is set or during APC transitions.  ckucns.c,
ck[duv]con.c, 28 Jan 99.

If XFER DISPLAY is FULLSCREEN but terminal type is not recognized, fall back
to CRT display, rather than SERIAL.  ckuusx.c, 28 Jan 99.

Added missing help text for SET SEND BACKUP.  ckuus2.c, 28 Jan 99.

"send /recursive ." doesn't work any more, even though "send ." does.  "send
/recursive .." doesn't work any more, even though "send .." does.  "send
/recursive /full/path/name" has gone back to trying to read the entire file
system.  Sounds familiar?  This was all fixed on Jan 7th, but then broken
again some time before Jan 14th.  Fixed again today.  ckufio.c, 28 Jan 99.

Now all the tests from Jan 12th work except "dir /recursive oofa.txt", which
fails to recurse.  One more tiny tweak fixes this and now all tests work
again.  ckufio.c, 28 Jan 99.

Fixed SET OPTIONS DIRECTORY /NOBACKUP, which wasn't working due to a typo.
ckuus6.c, 28 Jan 99.

Changed the server end of REMOTE DIRECTORY to obey SET OPTIONS DIRECTORY
/[NO]HEADING, /[NO]DOTFILES, and /[NO]BACKUP.  In UNIX only, sorted the
directory by name (because in UNIX, we have access to the list pointer).
ckcfns.c, ckermit2.txt, 28 Jan 99.

Fixed server end of REMOTE DIRECTORY to be compatible with local directory
listing format -- no more "<DIR>" in UNIX, show symlinks, don't always
show full pathname (but do show it in headings).  ckcfns.c, 29 Jan 99.

Changed date-time string shown in directory listings when actual date/time
can't be obtained from ????-??-?? ??:??:?? to 0000-00-00 00:00:00, so as
not to put non-digits in numeric fields.  ckcfns.c, ckuus6.c, 29 Jan 99.

"remote directory | sort -r" was sending "| sort -r" as the filespec
to the server, oops.  However, "remote directory | sort -r > foo" works as
expected.  This was a bug in remtxt(), fixed in ckuus7.c, 29 Jan 99.  Now we
can pipe incoming directory listings through local filters for display on
the screen, e.g. to sort in reverse chronological order, etc.  Documented
this in ckermit2.txt Section 5.3.2.

The C-Kermit server drops a character from the directory listing at the end of
each packet, as you can easily see by restricting the packet length to (say)
30 (it's not quite so obvious when the packet length is 8000).  But it's not
nxtdir()'s fault, because nxtdir() returns every character from the listing.
In fact, sdata() is being called with a length that is 1 less than the actual
number of characters obtained from nxdir().  This problem has nothing to do
with recent changes to REMOTE DIRECTORY since REMOTE TYPE has the same
problem, and also REMOTE DELETE, REMOTE HELP, and any other command
implemented by sndblah()/nxtblah().  In fact, it's been there for quite some
time.  But it doesn't happen in regular file transfer, so what's the
difference?  ... Aha, it's in getpkt() -- the manipulation of the "first" flag
(governing lookahead and EOF) was not totally copied from the input-from-file
case to the input-from-function and other cases.  Fixed in getpkt(), ckcfns.c,
29 Jan 99.

From Jeff:  Command interface for KLOGIN and EKLOGIN:
RLOGIN /ENCRYPT /KERBEROS <host> <userid> <protocol>.
ckuusr.h ckuus5.c ckuus7.c ckcnet.h ckcnet.c, 29 Jan 99.

Found some places where the connection log was not being written, namely
in the TELNET and RLOGIN commands.  Fixed in ckuus[3r].c, 29 Jan 99.

The confusion between CLOSE CONNECTION and CLOSE CONNECTION-LOG was just too
dangerous, so even though it's ugly, I changed the name of the connection log
to "CX log": LOG CX, CLOSE CX[-LOG].  ckuus[r2].c, 29 Jan 99.

From Jeff: Internal Telnet reset function.  ckctel.[ch], ckcnet.c, 30 Jan 99.

Due to a typo, the key in DIR /SORT:key was sticky.  Fixed in domydir(),
ckuus6.c, 30 Jan 99.

Discovered that IKSD could be suspended with SUSPEND or Z command (but not
with Ctrl-Z).  SUSPEND/Z also worked when nopush was in effect.  Fixed in
ckuusr.c, 30 Jan 99.

Discovered that if you gave a DIRECTORY command to IKSD in a directory that
can't be read, it would say "?Read permission denied - xxx" where xxx was
a filename.  Changed cmifi() to not show the filename under these conditions.
ckucmd.c, 30 Jan 99.

PRINT command given by IKSD guest gave the wrong error message.  ckuusr.c,
30 Jan 99.

RECEIVE, given by IKSD guest in directory to which it does not have write
access works when it shouldn't.  But then of course it stops when it goes to
write out the first bufferful -- the file is not actually created.  But now
there is about 32K of packets in the pipeline, and all sorts of confusion
ensues, especially when streaming.  Fixed rcvfil() to precheck write
accessibility before accepting the file.  ckcfns.c, 30 Jan 99.

MOVE, SEND /MOVE, etc, were allowed by IKSD to guest users; they did indeed
send the file, but did not delete it.  Still, it should not give the
impression that it worked, so a check was added.  ckuusr.c, 30 Jan 99.

Horizontal-line printing was needed to move to left margin first when
returning from CONNECT mode due to autodownload or APC.  ckucns.c, ck[uv]con.c,
30 Jan 99.

Traverse() test:

  dir
  dir /files
  dir /directories
  dir /recursive
  dir /recursive /files
  dir /recursive /directories
  dir oofa.txt
  dir /recursive oofa.txt
  dir /recursive *.txt
  dir *.txt
  dir */*.txt
  dir */*/*.txt
  dir .*
  dir /recursive .*
  dir /dotfiles
  dir /dotfiles /recursive
  dir foo (where "foo" is a relative directory name)
  dir .
  dir ..
  dir /fullpathname (of a directory)
  dir /fullpathname (of a file)
  dir /fullpathname (of filename with wildcards)
  dir /fullpathname (with wildcards in path)
  dir /files /fullpathname
  dir /directories /fullpathname

All the above work.  The following still try to read the entire file
system.  Will fix in next Beta:

  dir /recursive /fullpathname (of a directory)
  dir /recursive /fullpathname (of a file)
  dir /recursive /fullpathname (of filename with wildcards)
  dir /recursive /fullpathname (with wildcards in path)
  dir /recursive /files /fullpathname
  dir /recursive /directories /fullpathname

Add -funsigned-char to sunos41gcc and solaris25g makefile entries.  makefile,
30 Jan 99.

Numerous #ifdef, syntax, and declaration adjustments when building on many
platforms with different options sets.  Many modules, 30-31 Jan 99.

initopts() was dumping core on some platforms -- char pointers not init'd
to NULL before calling makestr() on them.  ckuus5.c, 31 Jan 99.

--- Beta.04 ---

From Jeff: command interface for RLOGIN /K4 /K5 /ENCRYPT; rlogin (except for
window size) is working again on Unix; rlogin /k4 (except for window size) is
now working on Unix (no root required).  ckuusr.h ckuus7.c ckuus5.c ckcnet.c
ckcnet.h ckctel.c ckctel.h ckuath.h ckuat2.h ckuath.c ck_crp.c, 1 Feb 99.

Server side remote directory file lister didn't have enough %s's in format
string for non-perms case.  ckcfns.c, 1 Feb 99.

Fixed some long lines in ckuus2.c, 1 Feb 99.

The HP-UX 5.00 Wollongong TCP/IP build suddenly stopped working because
of complaints about inet_addr(), e.g.

  "ckcnet.c", line 3411: operands of = have incompatible types

where line 3411 is:

  saddr.sin_addr.s_addr = inet_addr(tcp_address);

inet_addr() can NEVER NEVER NEVER be used without including the #ifdef INADDRX
code around it.  Evidently a lot of calls to inet_addr() were added since
Beta.02, which is the last time I built on this system.  This means that
builds that use INADDRX won't work.  Unfortunately this is the only platform I
have access to that needs it, and it can be accessed only by special
arrangement, since it is normally kept turned off, and every compilation takes
several hours.  Fixed in ckcnet.c, 2 Feb 99.  Fortunately this is not a
show-stopper for Beta.04, since only very old UNIX versions need this, like
Integrated Solutions Inc V8S VME 68020 and Motorola Delta System V/68 R3V5.

Added an hpux500 makefile entry (no net).  2 Feb 99.

Although ckutio.c does not reference bzero(), somehow it is being referenced
from the generated object file (nm ckutio.o | grep bzero) in HPUX 5.00.
So I added a bzero stub to ckutio.c only for HPUX 5.00, only for the no-net
build.  2 Feb 99.  (Later it turned out that a macro defines memcpy or memset
as bzero somewhere...)

Removed references to INADDRX for DG/UX from makefile and ckcnet.h.  2 Feb 99.

More from Jeff on Kerberized Rlogin.  ckcnet.[ch], ckuus[47], etc, 2 Feb 99.

From Jeff: Fix a bug in which return value of ckgetpeer() was not checked for
NULL when writing wtmp record, causing IKSD to crash when accessed by a host
that could not be found in DNS.  And fix ckgetpeer() itself to return the
peer's IP address if it can't get the name.  ckufio.c, ckcnet.c, 4 Feb 99.

Fix from Jeff for draining problem.  ckcfn2.c, ckctel.c, 6 Feb 99.

For some weeks now there has been a problem with the VMS UCX version: when
sending files on a TCP/IP connection with streaming, the transfer gets stuck
after sending the EOF (Z) packet; the Z packet is sent OK, but C-Kermit never
reads the ACK.  Ctrl-C'ing out and CONNECTing back reveals the ACK still
sitting there waiting to be read.  And yet: (a) This does not happen in
non-UCX VMS versions or in UNIX versions; (b) it does not happen in the UCX
version when the debug log is turned on.  The problem was traced to netinc();
it seemed that once select() failed, it would never succeed again.  Jeff
guessed that a failing select() in UCX (and who knows where else) might alter
its parameters ("help cc socket_routines select" was uninformative), and that
moving the select() initialization (FD_ZERO(), FD_SET() into the for-loop
would fix the problem, and indeed that seems to have done the trick.
ckcnet.c, 7 Feb 99.

UNIX C-Kermit was failing to send the first byte of each file (or actually,
the first byte of each 32K bufferful read from disk) due to a typo in a debug
statement I added to zinfill() after Beta.04 was released.  Fixed in ckufio.c,
7 Feb 99.

From Lucas Hart: Fixed osf makefile entry to pass CC and CC2 values along,
and add a du40gcc tarket.  makefile, 7 Feb 99.

Fixed various minor syntactic warnings from gcc on DU 4.0.  ckcfn2.c,
ckuus[rx].c, 7 Feb 99.

Another mysterious problem...  After releasing Beta.04, I finally was able to
build on AIX 4.1, but discovered that it had suddenly and for no apparent
reason started exhibiting the "terminal buffering reset after using curses"
problem, so that characters typed at the prompt would not echo until Return
was pressed, even though concb() had been been called to put the console back
in CBREAK mode.  This did not happen on earlier C-Kermit builds on AIX 4.1,
nor does it happen in the current build on AIX 4.2 or 4.3, nor, as far as I
can tell, on any other platform either.  The classic remedy to this problem is
to use newterm() rather than initscr() to initialize curses, accomplished by
adding -DCK_NEWTERM to the makefile entry.  This seems to have fixed the
problem.  I wonder if this means the same should be done in later AIX
versions, even though we presently have no adverse symptoms.  makefile,
8 Feb 99.

Jeff pointed out that the server does not set the success flag internally
when it executes a command that generates a short-form response.  Fixed in
ckcpro.w, 8 Feb 99.

IKSD was improperly calling syscmd() to check disk space (of course, it didn't
work, but it was acting like it did -- returning an empty report rather than
an error).  Unfortunately, there is no good way to internalize disk-space
checking code in UNIX since the methods for doing so are COMPLETELY unportable
(and unreliable), so I made the server return an appropriate error when given
a REMOTE SPACE command and nopush is effective.  ckcpro.w, 8 Feb 99.

There were a few lingering problems with directory-tree recursion.  As noted
above, "dir /recursive /xxx", where /xxx was any full path (i.e. starting with
slash), would appear to hang because it was reading the whole file system.
Also "dir /recursive .." did not work at all.  Also "dir /recursive ." gave
incomplete results.  These were fixed by slightly altering the decision about
whether to recurse in UNIX traverse(), without breaking anything else, except
"dir /recursive blah" (where blah is a filename with no wildcards); this was
fixed by adding one more condition to the same decision.  Now we seem to pass
all tests.  ckufio.c, 8 Feb 99.

Changed sinix543 makefile target to sni543, and added sni544.  SNI says the
name SINIX was dropped after 5.42 in favor of Reliant UNIX.  makefile,
ckuver.h, 8 Feb 99.

Added Ctrl-Z (and ^Z+0x80) to SET PREFIXING CAUTIOUS to accommodate
connections to UNIX hosts that have old versions of C-Kermit that don't know
how to disable SIGTSTOP.  ckcmai.c, 8 Feb 99.

\v(lockdir) lopped off the final character of the directory name on some
systems (e.g. Linux) but not others.  Fixed in nvlook(), ckuus4.c, 8 Feb 99.

Fixed ckutio.c (again) to use the right #ifdef around gettimeofday().
9 Feb 99.

Removed -K option from sni54[34] entries, where it is no longer valid.
makefile, 9 Feb 99.

Fixed local SPACE command to error out if nopush and an external command or
program is required.  ckuusr.c, 9 Feb 99.

Added -DK_NEWTERM to the Linux target, in response to a rash of complaints
about loss of CBREAK mode on tty after curses display.  Did NOT add this to
the AIX 4.2 and 4.3 entries, even though it was suddenly necessary for 4.1,
since trials on 4.2 and 4.3 show that it completely hangs the program.
makefile, 9 Feb 99.

From Jeff: Preserve user ID and Password around failed SET HOST, TELNET,
and RLOGIN parses.  ckuus7.c, 9 Feb 99.

Another correction for #ifdefs around gettimeofday().  ckutio.c, 10 Feb 99.

Built for the first time on VMS 7.2, and with UCX 5.0, and with TGV 4.2A, and
with DECC 6.0, and miraculously no source changes were needed.  10 Feb 99.

Changes from Jeff for Windows-95-specific SET WIN95 items and help text,
including new SET WIN95 8.3-FILENAMES { ON, OFF }.  ckuusr.h, ckuus[27].c,
10 Feb 99.

Added some casts to suppress warnings about pointers not assignment compatible
(signed vs unsigned char).  ckcfn2.c, ckcnet.c, 10 Feb 99.

Folded long lines in ckuath.c, 10 Feb 99.

Added a missing #ifndef NOSERVER..#endif clause to some code in ckcfn3.c.
10 Feb 99.

Simplified UNIX traverse() to eliminate some redundant function calls.
ckufio.c, 10 Feb 99.

Spent some more time with UNIX traverse() to see why it's skipping some files
it should pick up in some cases, but made little progress.  To be continued.
ckufio.c, 10 Feb 99.

Fixes for DG/UX: add declaration for tv, tz to ckutio.c; add NOGETUSERSHELL
and CK_NEWTERM to, and remove CK_POLL from, makefile entries.  11 Feb 99.

Verified that SINIX 5.42 does not need CK_NEWTERM.  11 Feb 99.

Mark Berryman said that "u_int" errors go away in UCX 5.0 builds if you
#include <if.h>.  This works great in UCX 5.0, but UCX 2.0 has no <if.h>.
There is also a warning about the data type of the length argument to
getpeername.  It needs to be unsigned int in UCX 5.0, but signed in previous
versions.  We need to (a) find a UCX-5.0-unique symbol in the UCX header
files, or (b) a logical name or symbol we can pick up in the DCL build
procedure, or (c) create a new build target or somesuch.  11 Feb 99.

Back to UNIX traverse.  After yesterday's changes, we now pass all tests with
the following exceptions:

 1. "dir /recu <filename>" shows directory names as well names of files
    that match <filename>, which might or might not be wild.

 2. "dir /recu /tmp" skips most files and directories in /tmp.

This last one is quite odd, since the same commands work fine in other
directories on the testbed system.  What's different about /tmp?

Added zrewind() to ckufio.c.  Rationale: DIRECTORY calls cmifi(), which
calls zxpand to expand the file list.  If this succeeds, then DIRECTORY itself
calls zxpand again.  But as long as the same argument and criteria are used
each time, the second call should be unnecessary -- all we need to do is
use the list from the first time, which is still there.  zrewind() resets the
list pointer to the beginning and returns the count.  Obviously this is for
UNIX only, since other implementations do not necessarily create an internal
list.  But when it can be used, it cuts the time in half -- quite noticeable
in long directories.  ckuus[56].c, ckufio.c, 11 Feb 99.

And of course it also makes debugging easier since we only have one invocation
of zxpand to deal with...  OK, so back to traverse....

Hmmm...  traverse() knows whether a file is a directory when it calls
addresult() to put it on the list.  But then addresult() calls isdir() again
to find out if its argument a directory.  Added a second parameter to
addresult() to let the caller tell it in advance whether it's a directory, or
if it must be looked up.  This eliminates lots of redundant stat() calls and
speeds things up even more.  After this, and after cleaning up traverse() line
by line, it all seems to work except for a couple minor glitches that I can
clean up tomorrow.  ckufio.c, 11 Feb 99.

With hints from Mark Berryman, added autodetection of UCX 5.0 to CKVKER.COM;
if detected, it adds UCX50 to CFLAGS.  The issue here is that <if.h> must be
included in UCX 5.0 to pick up the definition of u_int (and who knows what
else), but it does not exist in earlier releases.  Corresponding #ifdefs in
the code take care of the special considerations in the modules.  Now C-Kermit
builds without complaint and without any special CKVKER.COM command-line
invocation on UXC 2.0, 4.0, and 5.0 as well as on TGV 4.0.  ckvker.com,
ckcnet.[ch], ckuus[45].c, 12 Feb 99.

Fixed the following problem noticed by Jeff: if protocol is XMODEM, then
RECEIVE /PROTO:KERMIT gives an error if an as-name was not specified.
doxget(), ckuus6.c, 12 Feb 99.

Changed the name of zrewind() to zxrewind() to make it look more like a friend
of zxpand() and not an analog of rewind(), which resets a file pointer, and
which we might want to add later for some reason.  Added a symbol that says
whether we can use it, ZXREWIND, and defined it for K95 and UNIX, since Jeff
added it for K95.  Changed all calls to zxrewind() to be in #ifdef
ZXREWIND..#endif.  ckcdeb.h, ckufio.c, ckuus[56].c, ckcplm.txt, 12 Feb 99.

In several spots in cmifi(), zxpand() was called a second time to rewind the
file list; replaced these calls with zxrewind().  ckucmd.c, 12 Feb 99.

Ditto in the spot in fneval() where zxpand() was called to rewind the list
in K95.  ckuus4.c, 12 Feb 99.

Corrections from Jeff to yesterday's changes, plus new IF AVAILABLE options
for encryption, SSL, SRP, NTLM, etc, plus a couple =='s that should should've
been ='s.  Changed AVAIL_blah to AV_blah since macros must be unique within 8
chars in some cpp's.  ckcpro.w, ckucmd.c, ckuus[26].c, 13 Feb 99.

Some debug() statements fixed by Lucas Hart, especially one in a VMS section
of domydir() that referenced a pointer that had not yet been init'd.  ckuus6.c,
13 Feb 99.

From Lucas Hart: fix for VMS isdir() to recognize a search list as a directory
so (e.g.) "cd sys$manager" can work.  ckvfio.c, 13 Feb 99.

Added zxrewind() for VMS.  ckcdeb.h (define ZXREWIND for VMS), ckvfio.c,
13 Feb 99.

Hit upon an idea to make /RECURSIVE work for VMS: in fgen(), before the
lib$find_file() loop, call zfnqfp() to get the full filespec including
directory brackets, then insert "..." before the closing bracket IF (a)
"recursive" was set, (b) the argument filespec did not already contain "...",
and (c) there actually was a closing directory bracket.  Checked first to see
if LIB$FIND_FILE() itself had an option for recursive searching; it doesn't.
This fully enables SEND /RECURSIVE and DIR /RECURSIVE, plus GET /RECURSIVE
when send to a VMS C-Kermit server, without the user having to include "..."
in filespecs, and eliminates lots of "buts" and "excepts" in the documentaion.
ckcdeb.h (define RECURSIVE for VMS), ckvfio.c, ckermit2.txt, 13 Feb 99.

"dir blah" in VMS did nothing if BLAH.DIR;1 is a directory.  It should do the
same as "dir [.blah]".  Cause: failure to reset fcount in zxrewind; fixed in
ckvfio.c and ckufio.c, 13 Feb 99.

Lucas said that in VMS, "dir foo.dir" should just list the FOO.DIR file,
rather than the files in [.FOO], as it currently does.  Whereas (I think) "dir
foo" and "dir [.foo]" should list the contents of the directory rather than
the directory file itself, as they do now, and as "dir foo" (where foo is a
directory name) does in UNIX and K95.  Added code to cmifi() to make this
distinction.  Now "dir [/recursive] foo.dir" (or *.dir, etc) lists directory
files; the others list contents.  The FOO.DIR -> [.FOO] conversion is skipped
only when the DIRECTORY command is active, because we need this conversion
at other times.  ckucmd.c, ckermit2.txt, 13 Feb 99.

On a similar note, there is no way in UNIX to obtain the "ls -d" behavior,
i.e. to list a specified directory file, rather than the files in the
directory.  We'll return to this later...

Back to UNIX traverse()...  "dir /recursive oofa.txt" lists not only all
oofa.txt files in the current directory tree, but also each directory that
contains an oofa.txt file; example:

  (/w/fdc/tree/) C-Kermit>dir /rec oofa.txt
  drwxrwx---       512  1999-01-28 16:53:59  subdir/another/          <--
  -rw-rw----      6067  1999-01-07 21:21:43  subdir/another/oofa.txt
  -rw-rw----      3537  1999-01-12 18:07:46  subdir/oofa.txt
  drwxrwx---       512  1999-01-12 20:18:15  subdir/thisdir/          <--
  -rw-rw----      6067  1999-01-12 16:00:42  subdir/thisdir/oofa.txt
  -rw-rw----      2192  1999-01-13 11:03:14  oofa.txt
  (/w/fdc/tree/) C-Kermit>

It should only list the files themselves; the entries marked by arrows should
not appear.  Of course, including the /FILES switch produces the desired
result.  Also, "dir /rec *.txt" does not show this problem.  So that means
it only happens when the original filespec was wild.  So don't add a directory
name to the list when recursing if the original filespec was not wild.
ckufio.c, 13 Feb 99.

Next: directories whose names start with "." should not be opened if matchdot
is 0 and if the "." was not specified in the user's pattern.  Fixed by adding
another test to traverse().  ckufio.c, 13 Feb 99.

Next: "dir /recursive */*.txt" lists all files in the current directory, even
if they don't match "*.txt", but correctly selects only *.txt files in lower
directories.  Changed a comparison.  ckufio.c, 13 Feb 99.

Next: "dir .*" doesn't list dotfiles anymore unless /DOTFILES included.  Added
another test.  ckufio.c, 13 Feb 99.

Now UNIX C-Kermit passes all "traverse.txt" tests in its local DIR command.

After yesterday's changes, plain old "dir" in VMS acted recursively due to
missing parens in a while condition; fixed in cmifi().  ckucmd.c, 14 Feb 99.
Now the VMS version passes all tests.

Changed VMS zgetfs() to call stat() to get file size and directory status,
since it can succeed where RMS fails, e.g. when permissions don't allow
opening.  This removes lots of nasty -1's from the directory listing.
However, permissions are still lost when the file can't be opened.  ckvfio.c,
ckcfns.c, ckuus6.c, 14 Feb 99.

UNIX C-Kermit server's directory listings sent to client did not handle
symlinks.  Fixed in nxtdir().  ckucmd.c, 14 Feb 99.

Minor updates from Nigel Roles for Plan 9.  ckucmd.h, ckufio.c, ckpker.mk,
14 Feb 99.

Jeff renamed os2_setflow() to ttsetflow().  ckudia.c, ckuus6.c, 15 Feb 99.

Updated HELP SET NETWORK text.  ckuus2.c, 15 Feb 99.

Faced up to the fact the having a single variable for flow control is an idea
whose time is past.  Added a connection-type switch for SET FLOW, so now SET
FLOW can take an optional switch (/REMOTE, /TCPIP, /MODEM, etc) to set the
default flow control for a particular type of connection without affecting the
others.  Added a flow control table with appropriate flow values for each type
of connection.  Added SHOW FLOW to show the table plus the current flow
control.  Got rid of SET FLOW AUTO, since now it's meaningless (the command is
still accepted, but does nothing).  Now you can flip around among different
kinds of connections and get the right kind of flow control without thinking
about it (usually).  NOTE: At first I thought the best default for remote mode
would be KEEP, but that doesn't work at all when coming in via Telnet -- it
totally wrecks file transfer.  So for now, at least, it's NONE.  ckcdeb.h,
ckuusr.h, ckcmai.c, ckuus*.c, ckermit2.txt, 15 Feb 99.

Setting SIGINT and SIGQUIT to SIG_IGN was left out of the ckucon-to-ckucns
transition.  It didn't matter in most cases, since ttvt() puts the console
into raw mode, but in HP-UX, the HP-9000 <RESET> key still raises SIGINT,
which under these conditions kills C-Kermit when hit twice.  So the
appropriate signal() calls were added to conect() after the ttvt() call.
ckucns.c, 15 Feb 99.

Added SHOW TRANSFER (XFER) to SHOW all the SET TRANSFER items.  ckuusr.h,
ckuus4.c, 15 Feb 99.

Filled in new and missing SET TRANSFER items in HELP SET TRANSFER text.
ckuus2.c, 15 Feb 99.

Added missing zxrewind() prototype to ckcdeb.h.  15 Feb 99.

Noticed that if I give a TYPE command at the IKSD> prompt, and the file
contains any 0xff bytes, these are sent bare, thus forming a random Telnet
command for the client Changed the TYPE command to double 0xff characters if
(sstelnet || inserver).  ckuus6.c, 15 Feb 99.  There are probably other places
where this could happen...

Added a tgetent() stub for VOS.  ckuusx.c, 15 Feb 99.

In VMS, we use zrelname() to reduce a fully qualified filespec to a relative
one, to save space in the directory listing.  Thus if my current directory is
D0:[FDC] and I say "dir [fdc.text]oofa.txt", it will print "[.TEXT]OOFA.TXT"
instead of "DISK0:[FDC.TEXT]OOFA.TXT".  However, if my current directory is
[FDC.TEXT] and I say "dir [-]login.com", it prints "[.TEXT]LOGIN.COM" instead
of "[FDC]LOGIN.COM" or "[-]LOGIN.COM".  So zrelname() was fixed to take into
account the case where the current directory is a subdirectory (one or more
levels down) of the file's directory, in which case it prints [-] or [--],
etc, for the file's directory.  ckvfio.c, 15 Feb 99.

From Jeff: some #ifdef adjustments to prevent undefined auth/crypt symbols:
ckuus6.c; some auth/crypt changes to ckcnet.c and ckuath.c; debugging
statements added to ckcfn2.c packet/checksum routines.  16 Feb 99.

From Jeff: initialize lots of automatic variables in functions all over the
place.  Many modules, 16 Feb 99.

Back to zrelname() in VMS.  There were some glitches, plus it did not handle
the case where the file directory is not a subdirectory of the current
directory, nor vice versa, but the two shared a common ancestor.  ckvfio.c,
16 Feb 99.

Various (CHAR *) / (char *) casts.  ckcfns.c, ckcnet.c, 17 Feb 99.

The "dironly" and "fileonly" hacks have become unbearable.  A piece of code
such as domydir() can set or unset them prior to calling (say) zxpand() or
cmifi(), but loses control the minute the called routine does the same, or
calls some other routine that might do the same.  So I added a new API:
nzxpand(s,flags), which is zxpand() with a second argument: flags == 1 means
files only; 2 means directories only; anything else (normally 0 or 3) means
files and directories.  I brutally expunged all references to the dironly and
fileonly variables from all files, and replaced all zxpand() calls in the
mainline code with nzxpand() (this won't break weird platforms -- see
ckcdeb.h).  I think everything will work much better now.  ck[duv]fio.c,
ckvfio.c, ckucmd.c, ckuus6.c, ckcdeb.h, ckcplm.txt, 17 Feb 99.

Some corrections from Jeff to yesterday's changes.  ckcdeb.h, ckuusy.c,
ckufio.c, 18 Feb 99.

Added zrewind() for AOS/VS.  ckcdeb.h, ckdfio.c, 18 Feb 99.

Changed nzxpand() to be totally parameter-driven; flags word now contains
flags for dironly, fileonly, matchdot, recursive, etc.  ckcdeb.h, ckcfns.c,
ckcpro.w, ck[duv]fio.c, ckucmd.c, ckuus[46y].c, 18 Feb 99.

Added NOXFER symbol, which, if defined, deselects all file-transfer code
(Kermit and XYZMODEM) at compile time.  This is for building C-Kermit strictly
as a scripting and communications engine, when memory is at a premium, e.g. in
Linux-based embedded systems.  -DNOXFER removes about 300K on Intel, 400K on
Sparc.  All modules changed with very few exceptions.  Built OK with and
without -DNOXFER on UNIX and VMS.  Added a "linuxso" target for building a
< 400K version that includes full scripting and serial communications, but
no networks, help, character-sets, etc, that would not be used in a typical
embedded application.  18 Feb 99.

Added autodetection of <if.h> to CKVKER.COM for picking up u_int in UCX
versions below 5.0.  19 Feb 99.

A user noted a limit of 1024 on array size -- this was a totally arbitrary
and needless restriction, so I removed it.  Now an array can be any size
at all (until and unless a malloc() fails).  ckuusr.c, 21 Feb 99.

Changed UNIX version to not set BRKINT -- I have no idea why it ever did.
This causes big problems with UNIX workstations that have a BREAK key,
especially if it is badly positioned (as on HP keyboards, where users hit it
accidentally while trying to type Esc).  ckutio.c, 21 Feb 99.

UNIX "send ./?" was listing dot files when it shouldn't.  Fixed in traverse().
ckufio.c, 21 Feb 99.

Fixed some more CHAR/char complaints.  ckuus6.c, 22 Feb 99.

CD command makes disk spin if <ESC> typed in the middle of a directory name,
whereas Beta.04 didn't do this.  This is because traverse now calls isdir() on
every file.  Fixed this by calling isdir() only when we know we have to.
traverse(), ckufio.c, 22 Feb 99.

Discovered that SEND /RECURSIVE *to* C-Kermit no longer works: zchko() says
access denied.  I'm not sure how or when this happened, but the problem was
that when we check writeability of nonexistent paths, access() fails.  zchko()
needed to be changed to peel back path segments until we reached one that
existed before calling access on it.  (If we can create a file in an existing
directory, then we can also create a directory, and in fact a whole tree.)
ckufio.c, 22 Feb 99.

Discovered that the following sequence:

  cd subdir, dir .., cd .., dir /recu /dir .

gives a bizarre listing.  It turns out that cmifi() skipped calling nzxpand()
in this case, and so zxrewind gave us the list from *previous* call, which is
of course no longer valid in the new context, so zgetfs() and friends all
fail.  Fixed in cmifi2() by ensuring it ALWAYS calls nzxpand() (at least when
diractive is nonzero).  ckucmd.c, 22 Feb 99.

Discovered that "dir /recursive /tmp/fdc/foo" (i.e. a full absolute path
containing no wildcards) takes forever because traverse reads the whole file
system.  Of course this was fixed several times before, but then subsequent
fixes (specifically, for "dir /recursive foo.bar" -- same thing, but path
NOT absolute) broke it.  Fixed in traverse(), ckufio.c, 22 Feb 99.  The
/RECURSIVE switch is ignored in this case, which makes C-Kermit do the same
thing as "ls -lR /tmp/fdc/foo".

Peter Eichhorn tested yesterday's code in a directory that contained 10,000
files: "ck abc<ESC>" still took forever and made the disk spin a lot.  It
turns out the change I made yesterday also needed to be made in another place.
Now it's fast again.  ckufio.c, 23 Feb 99.

Added -DNOTTYLOCK to AIX 3.x targets, since ttylock() evidently does not work
right there (the code compiles OK but says "access to lock denied", even
though it has all the same perms and owner/group as cu, whereas if built to
use do-it-yourself lockfile handling, it works OK).  makefile, 23 Feb 99.

Problem: We have (say) a UNIX-to-UNIX connection with all defaults,
client/server.  We say "get blah.txt".  The file is sent in text mode because
of the "*.txt" pattern, but the transfer is interrupted.  So then later we say
"reget blah.txt".  This is refused because the "*.txt" pattern puts it into
text mode again and REGET must be in binary mode.  Two problems:

 1. The file did not have to be sent in text mode in the first place if
    C-Kermit had recognized that the connection was between "like systems"
    AND character-set translation was not active.  In this case, we can skip
    looking thru the patterns and just stick with binary mode.

 2. [RE]GET /BINARY did not work when the filename matched a text pattern on
    the server side.  Fixing this required defining a new transfer-mode
    WHATAMI bit for the initialization string, but since the WHATAMI field was
    already full, a new WHATAMI2 field was added.  Now GET /BINARY, REGET
    /BINARY, GET /TEXT, etc, always work exactly as expected.  ckcker.h,
    ckcpro.w, ckcfns.c, ckuus[r6].c, ckermit2.txt, 24 Feb 99.

These (and the next two) are rather fundamental changes and need a pretty
heavy workout.

Made RESEND and SEND /RECOVER both imply /BINARY since they won't work any
other way.  ckuusr.c, ckermit2.txt, 24 Feb 99.

Ditto for REGET and GET /RECOVER.  This, in turn, forces manual transfer mode
at the server, and now even "reget oofa.txt" will work, at least assuming
client and server have compatible (i.e. non-length-changing) text-file
formats.  ckuus6.c, ckermit2.txt, 24 Feb 99.

Added SEND /[NO]DOTFILES.  ckuusr.h, ckuus[r2].c, ckermit2.txt, 24 Feb 99.

Discovered SHOW FILE wasn't working right.  Diagnosis: feol was declared as
extern int rather than extern CHAR.  Fixed in ckuus4.c, 24 Feb 99.

Added dynixptx216c target to makefile, from Roger Allen.  24 Feb 99.

Made "cop" be an OK abbreviation for "copy".  ckuusr.c, 24 Feb 99.

Changes from Jeff for K95G.  ckuus[7x].c, 24 Feb 99.

Updated sunos41gcc+krb and +srp makefile entries from Jeff.  25 Feb 99.

The CD Message was fractured in IKSD -- forgot to add a terminating NUL at
the end of the string when making the IAC-doubled copy.  ckuus6.c, 25 Feb 99.

Promptly removed the aforementioned code because it really belongs in the
printf (puts, putc, etc) substitute that we are already using for server-side
telnet and IKSD.  ckuus6.c, 25 Feb 99.

From Jeff, 25 Feb 99:

 . IAC doubling added to ckxprintf() and ckxfprintf().  ckcdeb.h, ckutio.c.

 . Check for stdout/stderr in ckxfprintf().  ckutio.c.

 . Removed commented-out IAC doubling from dotype().  ckuus6.c.

 . Moved allocation of keymap/macro from cmdini() to before sysinit() for
   the benefit of K95G which starts being delivered keyboard input during
   sysinit().  ckcmai.c, ckuus5.c.

Added encryption indication to SHOW CONNECTION.  ckuus3.c, 25 Feb 99.

Peter E reported that transfers between two Kermit programs failed when there
was an Rlogin command between them and C-Kermit 7.0 was the file sender, but
such transfers did not fail in earlier releases.  Diagnosis: C-Kermit 7.0
unprefixes <LF> by default; if a packet contains "<LF>~." this breaks the
Rlogin connection.  Packets contain this sequence when a file has a line that
begins with 14 repeated characters.  Since Kermit has no way of knowing there
is an Rlogin command in the middle, we have to prefix LF by default.
ckcmai.c, 25 Feb 99.  (Ditto when 'cu' is in the middle.)

Peter E also noticed that C-Kermit would crash under certain conditions on
some versions of HP-UX when its debug log was active during file transfer.  It
looks like the debug(F011,...) handler did not allocate quite enough memory
when given a really long string (like 32K).  Fixed in dodebug(), ckuusx.c.
Also, the "debug(F011,"ZINFILL fread",zinbuffer,zincnt);" call was overkill
anyway since now we're reading 32K chunks from the disk.  Changed it to just
show the count; ckufio.c, 25 Feb 99.

Minor syntactic corrections to yesterday's changes.  ckuus3.c, ckutio.c,
26 Feb 99.

Changed C-Kermit's default file type from text to binary.  ckcmai.c,
ckermit2.txt (Sections 0, 4, and 4.3), 26 Feb 99.

Renamed hpux90mot target to hpux90m68ko for consistency.  "-funsigned-char"
added to CFLAGS of all HP-UX gcc targets.  makefile, 26 Feb 99.

When making SEND /RECOVER imply /BINARY, I accidentally also made
SEND /RECURSIVE imply /BINARY.  Fixed in doxsend(), ckuusr.c, 26 Feb 99.

Back to client/server conveniences...  Client SEND /RECURSIVE does not
automatically SET RECEIVE PATHNAMES RELATIVE in the server, but GET /RECURSIVE
does.  Why is this?  Because GET /RECURSIVE uses a special packet type but
SEND /RECURSIVE does not.  The user should not have to deal with this.  Added
PATH_AUTO to ckcker.h.  Added SET RECEIVE PATHNAMES AUTO: ckuus7.c.  Made AUTO
be the RECEIVE PATHNAMES default: ckcmai.c.  Fixed SHOW FILE to display the
new value: ckuus4.c.  Defined a WMI2_RECU bit for the new WHATAMI2 field:
ckcker.h.  Set this bit in rpar() if recursive > 0, and set RECEIVE PATHNAMES
to RELATIVE automatically in spar() if RECEIVE PATHNAMES was AUTO, plus set a
flag this was done so AUTO would be restored at the end of the transaction or
upon interruption: ckcfns.c, ckuus[25x].c, ckermit2.txt, 26 Feb 99.

Fix to cmifi() from Jeff to make sure it calls nzxpand() in K95 even if
user gives only a disk letter.  ckucmd.c, 26 Feb 99.

Fixes from Jeff to DIR /ENGLISHDATE and Rlogin problems reported by Lucas
Hart.  ckuus[67].c, 28 Feb 99.

Jeff suggested we keep incomplete files only when receiving in binary mode.
Added [ REMOTE ] SET [ FILE ] INCOMPLETE AUTO, which means KEEP when in binary
mode, DISCARD otherwise.  ckuus[2346].c, ckcfn[s3].c, ckcmai.c, ckcpro.w,
ckermit2.txt, 28 Feb 99.

The change I made on 24 Feb to use binary mode whenever the two Kermits are
on like platforms and there was no charset translation was broken by setting
the default file type to binary.  Fixed in sfile(): ckcfns.c, 28 Feb 99.

Added /MOVE-TO: and /RENAME-TO: switches, which were already available for
SEND, to GET and RECEIVE.  This rounds out our "atomic file movement"
repertoire.  ckcmai.c, ckuus[56x].c, ckcfns.c, 28 Feb 99.

Numerous corrections to internal crossrefs in ckermit2.txt from Peter E.
28 Feb 99.

Got rid of the long and hideous mass of #ifdefs around the tv and tz
declarations in ckutio.c by adding NOTIMEZONE / HAVE_TZ and NOTIMEVAL /
HAVE_TV symbols to ckcdeb.h.  1 Mar 99.

Moved call to fxdinit() (fullscreen file-transfer display initialization) from
main() to screen(), and ensured we don't call it unless we have to, we don't
execute it more than once, and we don't print any error messages when in
background or batch.  This fixes numerous problems; e.g. the screen was a
total shambles before if the terminal type was unknown, pointless warnings
about terminal type when the file transfer display would not have been
fullscreen anyway, etc.  ckcmai.c, ckuusx.c, 1 Mar 99.

Added -DDCLGETCWD to CFLAGS for is5r3jc.  makefile, 1 Mar 99.

Fixed arrangement of horizontal lines around file transfer and around
CONNECT-mode help text.  ckucns.c, ck[duv]con.c, 1 Mar 99.

Updated SHOW FEATURES list to say "No making connections" if NOLOCAL defined,
and fixed some typos.  ckuus5.c, 1 Mar 99.

Fixed an unguarded reference to tcharset in ckcfns.c, 1 Mar 99.

Updated help text for RECEIVE and GET, plus help text for new K95 Kverbs from
Jeff.  ckuus2.c, 1 Mar 99.

"send blah", where blah is a file that lacks read permission, did not produce
an error message.  Fixed in ckuusr.c, 1 Mar 99.

Changed {SEND,RECEIVE,GET} {/MOVE-TO:,/RENAME-TO:} to save and restore global
values snd_move, snd_rename, rcv_move, rcv_rename values.  ckuus[r56x].c,
1 Mar 99.

Added global {SEND,RECEIVE} {/MOVE-TO:,/RENAME-TO:} values to SHOW FILE,
and finally added askmore() to SHOW FILE, yuk.  ckuus4.c, 1 Mar 99.

Added SET { SEND, RECEIVE } { MOVE-TO:, RENAME-TO: } to set global values
for these.  ckuus[27].c, 1 Mar 99.

Changes to SHOW DIAL for TAPI and SET WIN95 OVERLAPPED-IO from Jeff.
ckuus[47].c, 1 Mar 99.

Updated HP-UX 10.30 and 11.00 targets from John Bigg of HP: makefile, 2 Mar 99.

Yesterday's change broke the SET TRANSFER DISPLAY command.  Fixed in ckcmai.c,
ckuus[7x].c, ckcker.h, 2 Mar 99.

Fixed SET TRANSFER DISPLAY SERIAL to wrap dots based on actual terminal width
rather than assuming 80.  ckuusx.c, 2 Mar 99.

SEND /NOBACKUP was broken by a missing comment closer.  ckuusr.c, 2 Mar 99.

Ditto for GET /DELETE.  ckuus6.c, 2 Mar 99.

"type /?" bad news -- since its FDB had file first and switch second, "/?"
tried to build a list of all files in the root directory.  Rearranged to have
switch first, file second, like all the other commands.  ckuusr.c, 2 Mar 99.

Fixed an unguarded reference to pipesend.  ckcfns.c, 2 Mar 99.

Started work on PURGE command (to remove all but a given number of backup
files).  Will finish tomorrow.  ckuusr.[ch], ckuus7.c, 2 Mar 99.

Added ^D and ^U to default prefixing table, since these act like LF when
followed by ~ when going through an Rlogin connection.  ckcmai.c, 3 Mar 99.

Syntax corrections.  ckuus[27x].c, ckvcon.c, 3 Mar 99.

It seems that streaming transfers are sensitive to "X" interruption if it
happens in a certain spot -- just at the beginning and/or just at the end.
Found and fixed a spot in input() that might have been causing this (no,
it didn't fix it).  ckcfn2.c, 3 Mar 99.

filhelp() was calling isdir() on every file.  This is no longer necessary,
since the parsing function that called it has already filtered out file and/or
directory names by calling nzxpand() with the appropriate flags.  Commented
out this call to isdir().  ckucmd.c, 3 Mar 99.

SEND /RECURSIVE ./?<Ctrl-U> left recursive flag stuck on.  Moved the resetting
of recursive and matchdot to the top of the reparse loop, rather than the top
of the parse loop.  ckuus5.c, 3 Mar 99.

Sending to IKSD, logged in as anonymous, was failing with "directory creation
failure" even when sending a regular file not containing any directory parts
in its name.  The problem was in zmkdir(), but I can't imagine why we weren't
seeing the same failures before (and we weren't -- lots of people were
uploading stuff to incoming thru IKSD).  zmkdir() is always called when
receiving a file to see if the file contains any directory parts, and if so,
to try to create them.  zmkdir() unconditionally failed if called by guest.
Fixed it to fail only when called by guest AND it would have had to create a
directory.  ckufio.c, 3 Mar 99.

Meanwhile, zmkdir() actually *would* create directories even when in server
mode and MKDIR was DISABLEd, oops.  Fixed in zmkdir(), ckufio.c, 3 Mar 99.

An SSH-related update to ckcnet.c from Jeff.  3 Mar 99.

Discovered that dialing out from VMS (yes, I can finally do it!) tends not
to work at all.  Why?  VMS does not support RTS/CTS but the modem's factory
default is to use RTS/CTS.  The modem init string might have 30-40 characters
in it, or more (e.g. USR).  VMS gets data overruns on its serial port when
reading back the echo and then loses the OK, because it has not yet sent the
command to the modem that tells it to use local Xon/Xoff flow control.  SET
DIAL PACING 150 does the trick.  Changed the startup value for DIAL PACING to
be 150 if CK_RTSCTS is not defined, and changed the initial DIAL FLOW value
to be XON/XOFF for VMS, rather than AUTO (although AUTO actually did result
in Xon/Xoff, but why bother).  ckudia.c, 5 Mar 99.

Made default flow control in VMS for all types of connections it supports be
"Xon/Xoff" (which really translates to TTSYNC/HOSTSYNC, which means "use an
appropriate method of flow control instead of dropping incoming bytes on the
floor for no reason").  ckcmai.c, 5 Mar 99.

With these changes, VMS dialouts work -- a little rocky on the initial init
string, but once the flow control is set on both ends, the connection is fine;
downloads go fast, but uploads are faster.  There are no hiccups or glitches,
even at 38400 or 57600 bps on the Alpha PWS 433/au.

Fixed some silly dialing messages, like "Will redial in 1 second, press any
key to redial immediately...".  ckuus6.c, 5 Mar 99.

Fixed "red" to be an acceptable synonym for REDIAL on VMS.  ckuusr.c, 5 Mar 99.

Discovered all kinds of problems dialing without flow control -- SET DIAL
PACING was not being obeyed in many places.  Fixed in ckudia.c, 6 Mar 99.

When dialing out from VMS and then being hung up on by the remote, VMS system
services would thenceforth refuse to return the modem signals, and so ttchk()
returned 0 or -1 (indicating ttgmdm() failure) rather than -2 to indicate the
connection was lost, and therefore EXIT would give the message "A serial
connection might be active... OK to exit?".  Fixed by keeping Yet Another
Global Status Variable.  ckvtio.c, 6 Mar 99.

The long modem setup sequence was unnecessary and annoying when redialing,
so now we jump around on the 2nd and subsequent attempts.  ckudia.c, 6 Mar 99.

Got rid of the separate ATT or ATP command when the user had not given a SET
MODEM COMMAND { PULSE, DIAL } or a SET MODEL DIAL-COMMAND command, making the
dial command be ATDT or ATDP instead.  ckudia.c, 6 Mar 99.

Enabled connection log in VMS.  ckvfio.c, 6 Mar 99.

VMS was still complaining "terminal type not supported" when given a SET
TRANSFER DISPLAY FULL command.  Fixed in doxdis(): ckuus7.c, 6 Mar 99.

Filename shown in VMS file transfer display is much too long.  Changed
screen() to call zrelname() on it.  ckuusx.c, 6 Mar 99.

The sequence DISABLE DELETE, SET FILE COLLISION UPDATE would fail because of
a misplaced security check.  The check was moved into the protocol module
where it belongs.  ckuus7.c, ckcpro.w, 6 Mar 99.

Removed about 560 lines of #ifdef OLDTBCODE..#endif junk from ckudia.c.  If
anybody ever wants it back they can get it from version 6.0.  6 Mar 99.

The big problem with dialing without hardware flow control is that the first
thing we send to the modem is a big long init string, like:

  ATQ0E1V1X4&A3&S0&C1&D2&N0&Y3S14=0

The modem can take it, but the computer might not be able to absorb the echo
(or worse, the response), especially at high speeds.  So it's essential to set
up the flow control first, before sending any long strings to the modem.  But
this requires that the modem is first set up to produce result codes.  So --
for AT-command-set modems only -- we now send ATQ0<CR> first, up to four
times, looking for an "OK" or "0" response, and taking various (increasingly
drastic measures) if it doesn't come (send BREAK, hangup, etc), and then we
set the modem's flow control, and THEN we send the init string and the rest.
This works way better.  ckudia.c, 6 Mar 99.

Added SET HINTS { ON, OFF }.  ckuusr.[ch], ckuus3.c, 6 Mar 99.

Since control-char unprefixing is now the default, this is likely to cause
trouble to some people.  If sending a file fails and PREFIXING is not ALL,
and the transfer was not deliberately interrupted, we now print a hint (if
HINTS are ON) to try it again with SET PREFIXING ALL (or PARITY SPACE, or
ROBUST, ...) -- our first hint.  Made a similar set of hints for failure to
RECEIVE or GET files.  And a few others.  ckuus[r345].c, 6 Mar 99.

SET PREFIXING ALL sets prefixing to PX_ALL; now so does SET CONTROL PREFIX ALL.
ckuus3.c, 6 Mar 99.

 -- add hints for dial failure.

Corrections from Michal Jaegermann <michal@ellpspace.math.ualberta.ca>:
 . One of the sprintf's in nxtdir() did not have enough %s's: ckuus4.c.
 . An sprintf in \v(nday) referenced a long with %d: ckuus4.c.
 . Missing parens around 4th xxscreen() arg supplied in ckuusx.c & ckcfn2.c.
 . Superfluous pointer dereference (*p++;) in arraynam: ckuus5.c.
 . ckxlogin/out() prototypes moved from ckuusr.h to ckcdeb.h.
 . ckxlogin() called with one too few args: ckcpro.w.
 . Various static declarations of unused or nonexistent variables or functions.

Also, he objected to Kermit sending the user ID ahead on TELNET connections --
"There is not a shred of guarantee that a login on remote will be the same as
a local one" -- and suggested the default be not to send it.  This will
obviously be controversial, but I tend to agree, erring on the side of safety
and predictability (for scripts).  For now I just made a symbol NOSENDUID that
can be added to CFLAGS to reverse the default at compile time.  A more
intelligent default might be to send the ID if we're on the same "network"
(whatever that is), and not send it otherwise.  Or maybe not.  ckcdeb.h,
ckctel.c, 7 Mar 99.

Tightened up dialing procedures some more -- e.g. combined the speaker and
volume commands.  Found that my abbreviated redialing code from yesterday had
(more than) a few problems.  The most important lesson is that it's not
sufficient to just keep sending the ATDTnnnnn command.  First we have make
sure the modem is still sentient; thus the "send ATQ0" loop must be executed
before each redial as well as before the original call.  ckudia.c, 7 Mar 99.

My understanding of the VMS terminal driver is that if the device has the
TT$M_MODEM characteristic, then:

 1. When the application opens the device, VMS turns on DTR.
 2. The CD signal is ignored until it comes up; after that, loss of
    CD causes the SS$_HANGUP error.

After 6 hours of experimentation with dialing and redialing on VMS, I made two
discoveries: (1) attempts to read from a /MODEM device during dialing
(i.e. before CD has ever been turned on) often result in SS$_HANGUP, and so
this error must be ignored during dialing; and (2) VMS periodically blinks DTR
and RTS on the device while it is not presenting the CD signal; Kermit is not
doing this, VMS is doing it.  This can be observed simply by telling Kermit
to "set line tta0" and then watching the modem lights for a few minutes.

This of course causes any normal modem to immediately abandon a call in
progress.  The remote answers the phone, we hear the negotiation tones going
and then suddenly "click" and NO CARRIER.  ATI6 (to a USR Courier) says
"Disconnect reason: DTR dropped".  The modem lights confirm -- VMS turns off
DTR (and RTS) for 5 seconds right in the middle of the modem-to-modem
negotiations.  The only reason dialing out ever works at all is that DTR stays
up for 30 seconds at time.  If a call is placed at just the right instant and
is answered within 30 seconds, VMS leaves DTR on thereafter.

Of course we can give the modem the DTR override command (AT&D0), but this
eliminates the possibility of hanging up the call by dropping DTR, and in fact
would leave open a rather gaping security hole.

A workaround was eventually identified: Tell the modem to make DSR track CD.
Explanation: when a port is opened, as soon as VMS sees DSR with no CD, it
starts the 30-second-on/5-second-off DTR/RTS blinking cycle.  Therefore if the
modem does not turn DSR on, and VMS won't blink.  This is less than satisfying,
though, because it is exactly opposite of (say) SunOS, where you can't dial
out unless DSR is ON.  There should be a way to tell VMS to leave DTR up solid
when making a dialout call.  Init strings of all AT-command-set modems changed
to include "&S1" within #ifdef VMS..#endif.  This is no help at all for modems
that are do not use the AT command set.  ckudia.c, 7 Mar 99.

David Sanderson <dws@sgi.net> noticed that window-size-change interrupts
weren't working any more; cause: <signal.h> was left out of the ckcnet/ckctel
split.  Fixed in ckctel.c, 7 Mar 99.

From Jeff, 8 Mar 99:

 . ckutio.c - ttinc() returning -3 is a special return value that
   indicates that the "Session Limit" has expired.  SET SESSION-LIMIT.  I
   do not think that this has been implemented in Unix or VMS yet.  I
   have changed all references to -3 in ttinc() to -4.

 . ckuath.c - lots of rlogin stuff.

 . ckcdeb.h - Some NT Kerberos defines and the new NOSENDUID cannot be
   defined if CK_AUTHENTICATION is defined since the UID is required for
   successful completion.

 . ckcnet.c - k5 rlogin and some other little things.

Fixed SHOW COMM for VMS to show the actual speed rather than "unknown" and
also not to write "(closed)" after the device name.  The source of confusion
was that CK_TTYFD is defined for VMS, but instead of referencing the ttyfd
variable (which is always -1 in VMS) we have to call the vmsttyfd() function.
ckuus4.c, 8 Mar 99.

Verified that it is indeed IMpossible to get the current speed of a serial
device in VMS.  The IO$_SENSEMODE() call returns the permanent speed, not the
current, actual one.  Added notes to the code about this so I don't waste
another half-day on this one.  ckvtio.c, 8 Mar 99.

Added -DNOREDIRECT to all SCO targets prior to 3.2v4.0.  makefile, 8 Mar 99.

Made transaction log unbuffered.  ckufio.c, 8 Mar 99.

Fixed zvpass() in UNIX not to accept guest logins with empty passwords.
ckufio.c, 8 Mar 99.

More Kerberos changes from Jeff: ckcdeb.h ckuath.c ckuus3.c ckutio.c ckcnet.c,
8 Mar 99.

Fix from Jeff for IKSD negotiation problem, in which client could send
RESP_STOP in response to REQ_START even when autodownload was ON.  ckctel.c,
8 Mar 99.

Made switch completion print "=" rather than ":" as the separator in VMS, for
switches that take args.  ckucmd.c, 8 Mar 99.

Changes from Jeff to ckcnet, ckutio, and ckuath.c, mainly for Kerberos 5,
9 Mar 99.

Fixed hint for failed RLOGIN commands -- it was in the wrong place.
ckuus[r7].c, 9 Mar 99.

Changed VMS zfcdat() to return the file's creation date, not modification
date, to match VMS customs and usage, not to mention the fact that VMS
C-Kermit, when receiving a file, sets the *creation* date (not modification
date) from the A packet.  Suggested by Lucas Hart.  9 Mar 99.

Straightened up a mess regarding -DNOREDIRECT (it was not checked in enough
places) and also made sure that NETCMD could not be defined if NOREDIRECT
was defined.  ckcdeb.h, 9 Mar 99.

Fixed badly confused #ifdefs around "ping" and "pipe" commands.  ckuusr.c,
9 Mar 99.

More Kerberos-related changes from Jeff to ckcnet, ckutio, etc, plus
ckuus[45].c, 9 Mar 99.

Cleaned up the logic of UNIX zgetfs() a bit with respect to symlinks.
Now "dir /dir" lists symlinks to directories, and "dir /files" lists symlinks
to files.  This was (I hope) the last remaining problem with the DIRECTORY
command skipping files it should have listed.  ckufio.c, 9 Mar 99.

Supplied a missing "\" in the unixware2 makefile target.  9 Mar 99.

Increased size of \v(filespec) buffer and removed warning about overflow.
ckuus[rx].c, 9 Mar 99.

Changes to SCO XENIX 2.3.4 makefile entry to update it to 7.0.  9 Mar 99.

Put all of ckctel.c within #ifdef TNCODE..#endif, since there is no point in
compiling it if TNCODE is not defined, and it chokes the SCO 3.2.4 compiler
with "expression too complex".  Various other minor tweaks to ckutio.c,
ckucon,c, ckctel.c, and ckuver.h for XENIX.  9 Mar 99.

Moved #include <signal.h> to above #ifdef SIGWINCH, since <signal.h> is where
SIGWINCH is defined (David Sanderson).  ckctel.c, 9 Mar 99.

Fixes from Jeff to prevent IKSD from issuing Login: or Password: prompts when
it is in server mode, and therefore accepting null passwords for anonymous
users.  ckcdeb.h, ckcmai.c, ckuus7.c, ckcpro.w, 9 Mar 99.

Patches for NetBSD from the NetBSD group.  ckcdeb.h, cku[ft]io.c, ckuusx.c,
10 Mar 99.

Minor adjustments to the makefile to build on XENIX 2.3.4 with curses.
10 Mar 99.

More Kerberos changes from Jeff.  ckctel.c, 10 Mar 99.

Added check for guest to { SEND, GET, RECEIVE } { /MOVE-TO, /RENAME-TO }.
ckuus[r6].c, 10 Mar 99.

Updates for DG/UX 5.4R4.11 on m88k.  makefile, ckuver.h, ckuus[r5].c,
10 Mar 99.

Updates for DG/UX 5.4R3.10 on m88k.  makefile, ckutio.c (had to simplify the
GTODONEARG #ifdefs to unconfuse its cpp), 11 Mar 99.

Changed message about CONNECT failing because no CD to a hint.  ck[uv]con.c,
ckucns.c, 11 Mar 99.

Changes from Jeff to accommodate (nonstandard) SAK Telnet option from IBM:
ckuusr.h, ckuus[r3].c, ckctel.[ch], 13 Mar 99.

Moved sw_armed and winchh() from ckcnet.c to ckctel.c, and added some needed
#ifdefs to allow nonet builds.  13 Mar 99.

Made rlog_naws() not static because it is called from ckctel.c module.
ckctel.c, ckcnet.c, 13 Mar 99.

Added -funsigned-char to SCO OSR5 makefile entries.  makefile, 13 Mar 99.

Discovered that the DIRECTORY command returned total garbage for perms, size,
and date on SCO 5.0.5.  It seems that lstat() is available and pretends to
work (returns 0), but in fact puts junk in the stat buffer.  Added -DNOLSTAT
to SCO targets.  (The SCO man page also mentions a statlstat() function but it
works just as poorly as lstat()).  However, even using stat() and testing with
S_ISLNK() failed to reveal symlinks.  Therefore a forced call to readlink()
was required in this case.  But even that did not work -- it turns out SCO
readlink() doesn't like it if a "/" is on the end of a directory name.  So now
we strip it off before calling readlink().  zgetfs(): ckufio.c, 13 Mar 99.

  Actually the problem with lstat() seems to be more like this: On some
  platforms lstat() is to be used ONLY on symlinks; first stat() must be
  called to see if it is a symlink() and then (only) if it is, then call
  lstat() on it.  But on other platforms, stat() does not tell you if a
  file is a symlink; you must call lstat() on all files to find out which
  ones are symlinks.  Yet on OTHER files, lstat() still doesn't tell you if
  a file is a symlink -- it either behaves like stat() or else it returns
  garbage.  In that case you have to call stat() and then readlink() on
  each file to see if it is a link.

Another discovery: if DIR /RECURSIVE encounters a symlink to a directory, it
follows it even if the linked-to directory is in the same directory, in which
case it descends the same tree again.  This happens on all UNIXes.  So isdir()
also has to check if it's a link, which fixes this problem.  But breaks CD,
etc.  Another hornet's nest.  I think I fixed it but it might need more work:
isdir() says a file is a directory if it is a directory OR if the recursive
flag is NOT set and it is a link to a directory.  ckufio.c, 13 Mar 99.

Previous change needed additional work for SCO 5.0.5.  Generalized
SCO-specific #ifdefs to be usable on any UNIX build: -DNOLINKBITS means that
neither S_ISLNK() nor _IFLNK test is reliable and readlink() should be called
instead.  Added this to SCO CFLAGS.  ckufio.c, makefile, 14 Mar 99.

SCO 3.2v4.2 supports symlinks but C-Kermit doesn't sense them.  Added
-DNOLSTAT -DNOLINKBITS to the make targets.  XENIX entries are OK since it
doesn't support symlinks anyway.  makefile, 14 Mar 99.

Later, this was found in "man NS lstat" on OSR5.0.5:

  lstat obtains information about the file named by path. In the case of a
  symbolic link, lstat returns information about the link, and not the file
  named by the link. It is only used by the NFS automount daemon and should
  not be utilized by users.

Send from remote, interrupt with X at local, connect back to remote.  REMOTE
prints SEND-failure hint ("interrupted" not set).  Fixed in ckcfn[s3].c,
14 Mar 99.

Added -DDCLPOPEN to SCO 3.2v4.2 makefile entries to suppress warnings about
getcwd() and -DDCLPOPEN for popen().  Also added a new symbol, DCLFDOPEN, to
force C-Kermit to declare fdopen() to suppress warnings about that one too,
and added -DDCLFDOPEN to the 3.2v4.2 targets.  Now it builds without
complaint.  makefile, cku[ft]io.c, 14 Mar 99.

Updated the install target in the makefile to actually do most of the right
stuff.  15 Mar 99.

Added code to look around for the ckermit2.txt file at startup and keep a
record of where (if anywhere) it was found.  This is used in various messages
and help text: NEWS, SUPPORT, SHOW FILE, etc.  Also, updated assorted HELP,
NEWS, INTRO, etc, texts.  ckuins.txt, ckuus[245].c, 15 Mar 99.

Updates to ckuusr.c and ckctel.c from Jeff.  15 Mar 99.

Finished PURGE command.  UNIX only.  ckuus[27].c, 15 Mar 99.

Fixed a few fencepost errors in the PURGE command.  ckuus7.c, 16 Mar 99.

Fixed znext() (again!) to return a positive number if it returned a file,
and 0 when no more files left.  ckufio.c, 16 Mar 99.

From Jeff: integration of the TELOPT command with the Telnet protocol state
machine.  ckuusr.c ckctel.c ckuath.c ckctel.h ckuus5.c ckuus2.c, 16 Mar 99.

Added SET OPTIONS PURGE.  ckuusr.h, ckuus[237].c, ckermit2.txt, 16 Mar 99.

The WHOAREWE mechanism was slightly off kilter: it was not setting FILE NAMES
LITERAL unless the TRANSFER MODE was AUTOMATIC.  In fact, it should always use
literal file names when it recognizes a kindred spirit, regardless of the
transfer mode -- text/binary file transfer is independent of filename
conversion.  This was causing REGET to fail -- the original file would come
with a literal filename, the REGotten file would come with a converted one,
thus appearing to be a different file and thwarting recovery.  whoarewe():
ckcfns.c, 16 Mar 99.

Forgot to make the FAST, CAUTIOUS, ROBUST HELP-keywords invisible, so the
80x24 top-level "?" screen was overflowing.  ckuusr.c, 16 Mar 99.

Added -DCK_NEWTERM to Unixware entries -- buffering problem after file
transfer...  It's beginning to look like I should use newterm() whenever it's
available.

Fixed VMS-specific #ifdef foulups in ckudia.c and ckctel.c, 16 Mar 99.

Updates to makefile from Jeff for KRB & SRP.  16 Mar 99.

Adjustments for 16-bit QNX build.  Had to remove a couple features (CSETS,
KVERBS, etc) since ckuus4.o segment got too big.  ckuus3.c, makefile,
16 Mar 99.

Telnet changed to request binary mode in the other direction only if the
TELOPT setting for that direction is REQUEST.  This fixes stairstep problem
when Telnetting to the BSDI Telnet server.  From Jeff.  ckctel.c, 17 Mar 99.

Lots of picky little changes from compiler complaints on many platforms.
Most modules, 17 Mar 99.

It looks like AIX 4.2 needs CK_NEWTERM after all.  But AIX 4.3 hangs at the
end of a file transfer if built with CK_NEWTERM.  So no more sharing makefile
entries between AIX 4.2 and 4.3.  makefile, 17 Mar 99.

Had to add -DCK_NEWTERM for IRIX 5.3.  makefile, 17 Mar 99.

Support for VMS PRN files from Lucas Hart.  ckvfio.c, 17 Mar 99.

VMS CONNECT was missing a crucial IKSD start/stop negotiation.  ckvcon.c,
18 Mar 99.

UNIX builds without CKSYMLINK could not expand wildcards due to a missing
#else part in the #ifdef CKSYMLINK..#endif clause in isdir().  ckufio.c,
18 Mar 99.

I thought that UNIX znewn() took MAXNAMLEN into account when creating backup
names, but I must have dreamed it.  File transfer failed miserably when
sending files to a 14-char file system when the backup name would be longer
than 14 chars.  Rewrote znewn() to lop the minimum necessary number of
characters from the end of the filename before creating the backup name, and
tested the result on a real 14-char file system with filenames ranging from 10
to 14 and with backup numbers crossing decade boundaries; all OK now.
ckufio.c, 18 Mar 99.

Some weeks ago I noticed that sometimes the DIR command on HP-UX 5.00 would
produce a phantom entry like:

  ----------        -1  0000-00-00 00:00:00

Today I discovered that the phantom entries are deleted files, and there can
be lots of them.  It turns out that on some platforms, read() from a directory
(or readdir()) can return deleted files, so the result of each read should be
checked immediately for existence by looking at the inode.  The code to do
that was already there, but now in the wrong place due to the many additions
for recursion, etc.  Fixed in traverse(), ckufio.c, 18 Mar 99.

From Jeff, 18 Mar 99:
 . Fix an IKSD deadlock: ckctel.c.
 . Make TELOPT command wait for responses: ckuusr.c.
 . Add SET TELNET BUG INFINITE-LOOP-CHECK: ckuus[23].c, ckctel.c.
 . Some fixes for SAVE KEY: ckuus7.c.

From Jeff, 19 Mar 99:

  We received reports from Lucas Hart that the IKSD would not respond to
  packet requests from VMS C-Kermit 7.0 Beta 5.  It was determined that
  VMS C-Kermit was not adhering to Telnet Protocol and was sending bare
  CRs on the wire from spack() when TELOPT_ME(TELOPT_BINARY) was WONT.
  Why was this happening when the code to properly handle Telnet
  Protocol was in spack() and worked fine on Unix and K95?  It turns out
  that TCPSOCKET was not defined in ckcfn2.c because in VMS we define
  TCPSOCKET conditionally depending on the TCP/IP stack that is being
  used.

  I doubled-checked all of the other files that reference TCPSOCKET to
  determine if they failed to include ckcnet.h or included it in an #ifdef
  TCPSOCKET.  ckcfns.c failed to include ckcnet.h at all and no other
  file wrapped ckcnet.h in an ifdef.

  Tests show VMS C-Kermit now works fine.

Added ckcnet.h to dependencies for ckcfns.c and ckcfn2.c.  makefile, 19 Mar 99.

Added prototypes for tn_wait() and tn_push() to ckctel.h.  19 Mar 99.

The DG/UX 5.4R3.10 version did not have any of the "check if chars waiting at
the console" methods enabled.  Added -DSELECT to the makefile entries, but
that made ckutio.c blow up in the preprocessor, which apparently does not like
#ifdefs inside function call argument lists.  Rearranged the gettimeofday()
call in msleep().  ckutio.c, 20 Mar 99.

Assorted minor fixes to the UNIX makefile.  20 Mar 99.

---Beta.05---

From Jeff, 23 Mar 99:
 . A fix for \fword() and \fsplit().  ckuus4.c.
 . Telnet details... close in progress ... ckcnet.c, ckctel.c.
 . Add DONT/WONT Kermit to "-0" command-line actions.  ckuusy.c.
 . Force K95 to restore the cursor in SET TERM CURSOR.  ckuus7.c.
 . Authorization/encryption changes.  ckuath.c, ckuat2.h, ckctel.c, makefile.

If the first command line arg is a filename, do not automatically execute the
initialization file.  If the script author wants the init file to be executed
she can include a TAKE command in the script.  Prior to this, there was no
way to *prevent* init file execution when a script was invoked in this manner.
prescan(), ckuus4.c, 23 Mar 99.

Along similar lines: a rather drastic change to promote the use of C-Kermit as
a scripting tool -- if a filename is given as the first command-line argument,
the rest of the words on the command line are arguments for the script, NOT
for Kermit.  So no more "scriptname -x -y = arg1 arg2 arg3 ...".  Now it's
just "scriptname arg1 arg2 arg3 ...", just like writers of scripts in any
other language would expect.  If the first command-line arg is NOT a filename,
the behavior is as before; this required considerable code juggling between
prescan() and cmdini(), and also required that ckcmai() *always* call cmdini()
before prescan().  Thus the conditional internal call to cmdini() from within
prescan() was removed.  Now we can have Kermit scripts that behave exactly
like shell scripts: no init file execution, no messages, no banner, etc, and
argument passing is exactly the same.  ckcmai.c, ckuus[45].c, and documented
in the new section 7.19 of ckermit2.txt, 23 Mar 99.

At Jeff's suggestion, redid yesterday's work to preserve existing behavior
mainly so as not to break K95 startup scripts & shortcuts.  New syntax is
the same, except the "kerbang" line now must end with " +" (a space and a
plus sign).  ckcmai.c, ckuusr.h, ckuus[45].c, 24 Mar 99.

From Jeff: Put back the fix to \fword/split() that was lost in yesterday's
edits.  ckuus4.c, 25 Mar 99.  Later, Mark Sapiro (who reported the problem)
verified the fix.

From William Bader: Cleanup of the older SCO makefile targets.  Some of these
have a limit of 25 -D's in a cc invocation, and so a common block of
definitions for these targets was moved to ckcdeb.h.  Plus he found a data
declaration at the entry to a switch() statement (a no-no): ckuus3.c.  Plus a
place where strcpy() was copying something to itself in doxsend(): ckuusr.c.
Built from new sources & makefile on SCO OSR5.0.5 (5 different targets) -- all
OK, but that proves nothing about the others.  25 Mar 99.

Added BUILDID=yyyymmdd to makefile.  It doesn't do anything; it's just there
for anybody (like Peter E) who uses shell scripts to do lots of builds from
intermediate (e.g. inter-Beta) test versions and wants a unique ID.  makefile,
25 Mar 99.

Added brace-stripping to EXIT message.  ckuusr.c, 25 Mar 99.

Added help for the "+" option.  ckuus2.c, 25 Mar 99.

Cleaned up the hideous #ifdef mess around #include <sys/time.h> in ckutio.c
by moving it to ckcdeb.h.  Any make targets that are not covered by the new
symbol SYSTIMEH, or are improperly covered by it, can add -DSYSTIMEH or
-DNOSYSTIMEH.  Did quick builds on SunOS, SCO, HP-UX, and AIX to make sure I
didn't break anything big.  ckcdeb.h, makefile, ckccfg.txt, 25 Mar 99.

Added vanity banners for Motorola SV/68 and SV/88.  makefile, ckuver.h,
25 Mar 99.

Changed prescan to handle the case where "+" is given with nothing after
(it just errors out).  ckuus4.c, 25 Mar 99.

Changed SHOW FILE and SHOW PROTO to add SHOW XFER to their Also See lists.
ckuus4.c, 25 Mar 99.

Added a new symbol USE_STRERROR, which should be defined if strerror() is
available for use.  Added a new FreeBSD 3.x makefile target that defines this.
plus designer heralds for the three FreeBSD versions.  makefile, ckuusx.c,
ckcdeb.h, ckuver.h, 25 Mar 99.

FAST, CAUTIOUS, and ROBUST did not work as top-level commands because I put
them in the command keyword table but never filled in the action routines.
Since they were invisible anyway, I just removed them.  Now they are executed
as macros, just as they were before.  ckuusr.c, 25 Mar 99.

Minor corrections to yesterday's Motorola SV/68 and /88 fixes from Gerry
Belanger.  ckcdeb.h, makefile, 26 Mar 99.

Another updated SCO makefile target from Wm Bader.  26 Mar 99.

Moved the flonam[] declaration so NOSPL builds would work. ckuus4.c, 26 Mar 99.

Although statements of the form:

  if <condition> .\%a = <definition>

worked correctly, the same construction used for a macro:

  if <condition> .macroname = <definition>

was parsed incorrectly, so subsequent "if defined macroname" would fail when
it should succeed.  Fixed in dodef(): ckuus6.c, 26 Mar 99.

Added DIR /MESSAGE:text to append the given message to the end of each
directory listing line.  Handy in scripts.  ckuusr.h, ckuus6.c, ckermit2.txt,
26 Mar 99.

Changed SHOW OPTIONS to call prtopt() to manage word wrap and page pausing,
rather than just doing printf's, since lines can easily get longer than the
screen.  ckuus[r567].c, 26 Mar 99.

Added a "netbsdxx" target, which includes -DNOIKSD.  makefile, 26 Mar 99.

Updated sys3upcgm target to remove redundant -D's.  makefile, 26 Mar 99.

Fixed the SET HOST hint about Rlogin being a priv'd port not to appear unless
they actually were trying to make an Rlogin connection.  ckuus7.c, 26 Mar 99.

From Jeff: More fixes to auth and encrypt stuff, added /USERID to SET HOST
command switches: security modules + ckuusr.h, ckuus7.c, 27 Mar 99.

From Jeff: Allow /USERID switch to take empty value; update SET HOST help
text; ckuus[27].c, 29 Mar 99.

One of the more embarrassing and unprofessional aspects of Kermit's script
language is the IF/XIF distinction.  A simple change allows multiple commands
on one line if the line is surrounded by braces and commands are separated by
commas:

  C-Kermit> { echo one, echo two }
  one
  two
  C-Kermit>

This, in turn, makes it possible to have constructions like:

  if <condition> { command, command, ... }
  else if <condition> { command, command, ... }
  else if <condition> { command, command, ... }
  else { command, command, ... }

Another simple change allows XIF statements to include any statement after the
"else" token, just as C programmers would expect:

  xif <condition> {
     commands
  } else xif <condition> {  <-- This is new.
     commands
  } else while <condition> {
     commands
  }

But the real goal is to consolidate IF and XIF without breaking existing
scripts; difficult because "XIF <cond> { commands } else { commands }" is one
command, whereas "IF <cond>" followed by ELSE is two commands.  So I finagled
the internal rules:

 a. If an IF command has a THEN-part that starts with "{" then treat it as XIF.
 b. If an XIF command lacks an ELSE-part, treat it as an IF.

This seems to allow all combinations, plus others not recognized before.
Aside from testing each case individually I also changed all XIFs to IFs in
ckedemo.ksc, and it worked fine.  So bye bye XIF.  ckucmd.h, ckuusr.h,
ckuus[56].c, ckucmd.c, ckermit2.txt [1.21,7.20], 29 Mar 99.

More auth stuff from Jeff: ckcnet.c, ckuath.c, ckuus3.c, ckuus5.c, ckuus7.c,
makefile, 29 Mar 99.

More auth stuff from Jeff: ckuath.c, ckuus7.c, 30 Mar 99.

Added #ifdef NOSHOW around the SHOW OPTIONS routines.  ckuus[r7].c, 30 Mar 99.

Moved IF/WHILE-condition evaluator to a separate routine, boolexp().  Changed
boolexp() IF/WHILE parser to use chained FDBs rather than only cmkey() so it
can parse not only regular IF/WHILE conditions, but also numbers and "fields".
ckuus6.c, 30 Mar 99.

Added flag for cmfld() as an option to parse items within parentheses instead
of within braces.  This allows it to parse the parenthetical expression in
"if (<condition>) <command>" as a field even if it contains spaces. ckucmd.c,
30 Mar 99.

But the idea of parsing a parenthesized expression as a field and then
reparsing it proved unfruitful so I gave up on that and simply made "(", ")",
"&&" (and AND), and "||" (and "OR") keywords with the appropriate semantics.
This has numerous advantages (?-help still works for the condition words, etc)
but requires space around every token.  The result executes ckedemo.ksc
without a hiccup and after some debugging, also handles boolean expressions
of pretty much arbitrary complexity.  ckuus6.c, ckermit2.txt, 30 Mar 99.

More auth stuff from Jeff: ckuusr.h,ckuus[37].c,ckcnet.c,ckuath.c, 30 Mar 99.

From William Bader, 31 Mar 99:
 . Updated SCO targets: makefile.
 . Move USE_MEMCPY to after all system headers have been included: ckcdeb.h.
 . Break down complex printfs for Xenix C compiler: ckctel.c, ckuus4.c.
 . Xenix 2.3.4 cc adjustments to ckufio.c.
 . Additional #includes for SCO Xenix 2.3.4 TCP/IP: ckcnet.h.

WHILE command wasn't working after yesterday's changes.  Fixed by putting
parens around the condition generated for the WHILE macro.  ckuus6.c,
31 Mar 99.

Made XIF invisible.  ckuusr.c, 31 Mar 99.

If "while true { get x.x }" is given in remote mode, typing lots of ^C's
caused a core dump every time.  There was a window between when the console
was restored to its previous modes (the ttres() call in proto()) and the
interrupt handler was re-armed (in parser()).  I hacked around this by having
proto() re-arm the interrupt handlers before ttres() is called (which, in
remote mode, restored the terminal's sensitivity to ^C, etc).  ckcfn2.c, 31
Mar 99.

The ^C^C^C pseudointerrupt at server command wait always set success = 0.  In
fact, it should leave the success variable alone if any file transfers have
been attempted; should set it to 1 if no file transfers have been attempted
since server mode was started, and should set to 0 if a transfer was in
progress.  Fixed in ckcpro.w, 31 Mar 99.

Reinstated FAST, ROBUST, and CAUTIOUS as top-level keywords (which simply
run the macros of the same name), so now completion and HELP work for them.
However, they are still invisible due to limited real-estate on the top-level
"?" screen.  ckuusr.c, 31 Mar 99.

Discovered that two top-level keyword symbols had the same value.  Fixed in
ckuusr.h, 31 Mar 99.

Assorted improvements to HELP texts.  ckuus2.c, 31 Mar 99.

Made /LOG and /LIST and /VERBOSE all be synonyms for each other in the PURGE
and DELETE switch tables.  Ditto for /NOLOG, /NOLIST, and /QUIET. ckuus[67].c,
31 Mar 99.

Changed askmore() not to ask if not at top level.  That's because the terminal
modes are likely to be messed up and so single-character responses (like space
bar, "n", etc) can't be processed correctly anyway.  ckuusx.c, 31 Mar 99.

Added DIRECTORY [ other-switches ] /ARRAY:x [ filespec ].  If the /ARRAY:x
switch is given (x is the array name, required), the filenames are put in the
array, rather than listed.  This allows the DIRECTORY file-selection switches
to be used to build a custom file list easily and quickly.  ckuusr.h,
ckuus6.c, 31 Mar 99.

Fixed some long lines in ckuath.c.  1 Apr 99.

Backed off on yesterday's askmore() change -- apparently it is not needed
after all.  ckuusx.c, 1 Apr 99.

Added three simple routines to allow rudimentary screen formatting by scripts:
ck_cls(), ck_cleol(), and ck_curpos(row,col).  In UNIX, these rely on
termcap/terminfo; elsewhere they use the built-in stuff (MYCURSES, SMG, etc).
ckuusr.h, ckuusx.c, 1 Apr 99.

Added SCREEN { CLEAR, CLEOL, MOVE <row> <col> }.  These all work fine on a
termcap system (SunOS), on terminfo system (SCO, HP, Solaris), and on VMS with
SMG, but obviously need wider testing.  The UNIX versions of these commands
use the tgetent() info (which we were already getting) thru calls to
tgetstr(), tgoto(), and tputs().  They don't depend on curses at all, and
curses does not need to be initialized for these commands to be used (but SMG
does; the new code takes care of that).  (I realize that some of these new
commands have synonyms in K95; these are indicated in the K95 HELP SCREEN
text.)  Also ensured that -DNOCURSES builds still work.  ckuusr.[ch],
ckuus[x2].c, 1 Apr 99.

Reinstated screen-clearing on Ctrl-L in the parser.  ckucmd.c, 1 Apr 99.

Made CLS a visible command in all versions, not just K95.  ckuusr.c, 1 Apr 99.

Auth changes from Jeff: ckuus[37].c, ckuath.c, 2 Apr 99.

Fixed long lines in ckuath.c, 2 Apr 99.

Makefile changes for AT&T 7300 and SCO UNIX.  2 Apr 99.

Discovered that the NOT operator does not always work as intended in compound
Boolean expressions.  E.g. in "if ( not true || false )" evaluates to true
rather than false because NOT affects everything that follows.  NOT is a unary
operator that should bind only to the quantity or expression immediately to
its right.  To fix:

 . I added a new math operator, "prefix !", which inverts the truth value
   of its operand (as distinct from "prefix ~", which flips the bits, and
   "postfix !", which is the factorial operator).

 . Used this to implement NOT internally.

ckuus[56].c, 2 Apr 99.

More auth changes from Jeff: ckuath.c, ckcnet.c, ckuus3.c, 2 Apr 99.

From Jeff: Make 2nd [x]makestr() arg const in ANSIC builds.  ckclib.[ch],
2 Apr 99.

Changed GETC to not supply a gratuitous CRLF if given from a script (i.e.
cmdsrc() != 0).  ckuus6.c, 2 Apr 99.

Added != to repertoire of logical operators for Boolean assertions, as in
"if ( != \%c 3 ) ..."  ckuusr.h, ckuus6.c, 2 Apr 99.

Deduced that termcap/terminfo cursor coordinates are 0-based, not 1-based.
Adjusted the curses version of ck_curpos() accordingly.  ckuusx.c, 3 Apr 99.

Discovered a new problem: missing macro parameters were not being replaced
by an empty value.  For example:

  def cd { cd \%1 }
  xx

would cause an error, rather than defaulting to the current directory as it
should.  Hmmm, actually, it's an old problem -- it was always there.  Years
ago, we went to extreme lengths to try to accommodate backslashes in filenames
in K95: cmifi() prescans the string (using the chkvar() function) to see if it
contains variables.  So if the user said "cd c:\blah\foo", the scan would not
turn up any variables, and so we would not pass the string through the
evaluator, which would have eaten the backslashes (or worse).  But what about
"cd \%a"?  Is "\%a" a variable or an actual directory?  To solve this dilemma,
chkvar() would send a copy of "\%a" to the evaluator and see if it had a
definition.  If it did, chkvar() would say it was a variable.  If it did not,
chkvar() would say it was not a variable, and so therefore it would not be
evaluated.  It turns out this has rather disastrous consequences for macro
arguments that are omitted.  In the "xx" definition above, \%1 does not have a
definition, even though it is a variable, and therefore it is not evaluated,
and therefore "\%1" is given literally to the CD command.  The only sensible
fix for this is to change chkvar() to check the syntax of the variable, but
not whether it has a value.  That means if any PC users want to refer to a
file that has the same syntax as a variable, they'll need to double the
backslash.  chkvar(): ckuus6.c; cmifi2(): ckucmd.c, 3 Apr 99.

This was (at least) a double-ended problem.  It also turns out the evaluator,
zzstring(), gave a failure return code if a variable was empty, which is
wrong -- emptiness is a perfectly valid value for any variable.  zzstring():
ckuus4.c, 3 Apr 99.

There's more.  cmifi(), rather than checking the return code from zzstring(),
checked the length of the result (0 == failure, > 0 == success), which, again,
prevented substitution of an empty variable value.  cmifi() was changed to
test the zzstring return value; if negative we return a parse failure; if 0 or
greater but the result was empty, we substitute the given default.  ckucmd.c,
2 Apr 99.

In fact, the improper-checking-of-zzstring-success syndrome was pervasive
throughout all the ckucmd routines and similar fixes had to be applied to most
of them.  ckucmd.c, 3 Apr 99.

The mess in cmofi() was especially bad.  Instead of calling chkvar(), it had
its own inline -- but slightly different -- version of chkvar(), which in any
case did not accomplish its purpose.  For example, "mkdir c:\123" (the classic
example) created a directory named "{".  But cmifi(), which does use chkvar(),
could not handle "cd c:\123" or "rmdir c:\123" when \123 referred to "{".  So
I changed cmofi() to use chkvar() like cmifi() does -- at least now they are
symmetrical.  For total consistency, I put every reference to chkvar() in
ckucmd.c in #ifdef OS2..#endif (previously some of them were this way and some
weren't).  Obviously this will need testing and debugging in K95.  ckucmd.c,
3 Apr 99.

Meanwhile, chkvar() was also called by IF DEFINED.  Since chkvar() no longer
checks if a variable is defined, the IF DEFINED code had to be changed to
check this itself.  doif(): ckuus6.c, 3 Apr 99.

Bulletproofed all cm...() routines against null pointers passed as arguments.
ckucmd.c, 3 Apr 99.

In running the big script torture tests I saw a few glitches, and in trying to
isolate them, was able to produce a core dump consistently.  At some time in
the past not revealed in my notes, some of the cm...() routines were "fixed"
to not write into their help-message argument (xhlp), by first copying it to a
global malloc'd buffer using makestr() (thus freeing the previous one, if
any), and then changing xhlp to point at the malloc'd buffer.  This seemed
like a safe bet, and I'm still not sure why it wasn't, but these very makestr()
calls (the free() in particular) were the location of each crash, which
usually occurred only after the program had been running for quite a while.
Changing the global malloc'd buffer to a series of local automatic ones cured
the problem.  ckucmd.c, 3 Apr 99.

Or did it?  There were still some infrequent glitches evident in any scripts
involving arrays, or more to the point, arrays explicitly declared with the
DECLARE statement that included a list of initial values.  Turns out I was
malloc'ing BYTES rather than WORDS for the array pointers in the DECLARE
parser.  This was obviously a serious memory leak and could have had any
consequences at all.  The bad code has been with us since 18 Jun 1997 (i.e.
after 6.0 was released, but before K95 1.1.13.  I doubt, however, that this
has been the cause of any crashes in real life, because who uses array
initializers?).  Fixed in ckuusr.c, 3 Apr 99.

After these changes, "send *" wouldn't work.  This one was really scary.
Something was writing over cmarg2.  I traced it to zfnqfp() in ckufio.c.
There was a loop that, under certain bizarre conditions, might not terminate
properly, and when it didn't it could write all over memory -- and it seems
today was my lucky day at creating bizarre conditions. I put in a better
termination test and also rearranged some code that didn't make sense.
ckufio.c, 3 Apr 99.

Certain debugging statements write memory addresses, PIDs, etc, into the debug
log, some of them periodically -- e.g. for every command, which makes it very
difficult to automatically compare long debug logs.  I commented out many of
the debug statements that do this.  ckutio.c, ckucmd.c, ckuus4.c, 3 Apr 99.

After all this I ran hundreds of script torture tests and transferred many
gigabytes of files in both directions with no trouble.  I'm not 100% confident
that all holes are plugged, but some are.  Progress...

The next day...

New simplified makestr() from Jeff -- I just took it without looking at
it very much.  But I used it all day and it seemed OK.  Script torture tests
still work, etc.  ckclib.c, 4 Apr 99.

Putting zfnqfp() back the way it was before yesterday brings back the
overwriting of cmarg2, so something is still wrong.  Added code to zfnqfp()
to force a core dump at various places (before and after the code that writes
over cmarg2), and then got a backtrace with gdb.  In all cases, the stack
looked just fine.  Built a version with the malloc debugger.  Can still
replicate the error, but the malloc debugger finds nothing wrong.  Built a
version on an entirely different platform (PC with SCO 5.0.5, with both gcc
and with SCO cc) and got exactly the same problem, so it's not architecture or
compiler dependent.  So this pretty much narrows it down to plain old bad
code.  But the zfnqfp() code looks just fine.  The problem involves its tmp[]
buffer, an automatic array.  The 9th and subsequent bytes written into this
buffer appear as the value of cmarg2 (if I make the buffer static global the
problem disappears).  Therefore cmarg2 must be pointing at a memory address 8
bytes to the right of this automatic buffer -- but how could that happen?
Searching through doxsend() revealed the following mistake:

  if ((x = cmtxt(m,"",&cmarg2,NULL)) < 0)
    goto xsendx;

This dates from about July 1997 so was present in C-Kermit 6.1 and K95 1.1.14
and later.  The mistake was forgetting that the string pointer returned by any
cm...() routine points to an ephemeral string (in fact it is the atom buffer);
whatever string it points to must be copied to a safe place before calling any
further cm...()'s.  So of course the buffer pointed to by cmarg2 in this case
had probably been recycled 100 times by the time we finally needed it.  The
fix is to treat "send foo bar" exactly like "send /as-name:bar foo", using the
same data structures and buffers, etc, and then setting cmarg2 from them after
the command has been confirmed.  doxsend(): ckuusr.c, 4 Apr 99.

Could this have caused a core dump?  I don't think so.  It just meant that
cmarg2 (the "as-name" pointer) might have been pointing to a random string,
which would result in either (a) a file being sent with the wrong name, or
(b) C-Kermit refusing to send a file because an as-name was given when the
source specification was wild.

Meanwhile, I removed about 400 useless lines from ckuusr.c that were left
behind from before all the SEND-class commands (except PSEND) were routed to
doxsend().  Made a new addsend() routine that consolidates the ADD SEND-LIST
code which was previously scattered all over.  4 Apr 99.

Fixed a bug in ADD SEND-LIST: it wasn't putting the full pathname in the send
list, so if you changed directories, it wouldn't find the files -- or worse,
it would send the wrong ones.  The code to get the full pathname was there,
but it wasn't working right.  This goes all the way back to 6.0.  Fixed in
ckuusr.c, 4 Apr 99.

Made an improvement to ADD SEND-LIST: the file type (text or binary) is
defaulted according to our pattern lists, rather than the prevailing file type
if (a) PATTERNS are ON, and (b) we actually have pattern lists, (c) the
prevailing file type is not IMAGE or LABELED, and (d) the file matches a
pattern.  ckuusr.c, 4 Apr 99.

Fixed a bug I introduced yesterday.  Don't supply default in cm...() functions
when giving help -- only when the field is actually being entered (via field
or command termination or by completion).  Otherwise we get incomplete menus
when the user types "?" -- in fact, the menu only contains one item if a
default was included in the cm...() call.  ckucmd.c, 4 Apr 99.

After all these changes, made sure that SEND, MSEND, MAIL, PSEND, ADD, REMOVE
still work.  Some didn't, but now they do.

Added IF OPEN CONNECTION (fails if remote, gets ttchk() result if local)
and IF OPEN CX-LOG.  ckuus6.c, 4 Apr 99.

The preponderance of "output blah\13" in scripts is (a) ugly, (b) confusing
to newcomers, and (c) begs for a command to send a "line", so I added LINEOUT,
which is just like OUTPUT, except it supplies a carriage return at the end
(following Telnet rules, newline settings, etc).  (I thought of calling it
OUTLINE but that means something else).  ckuusr.[ch], ckuus5.c, 4 Apr 99.

Corrections from Jeff to yesterday's code: ckuus5.c, ckucmd.c, ckuusr.h,
5 Apr 99.

Discovered that when sending from a SEND-LIST, the file type given in the
ADD command was ignored if TRANSFER MODE was AUTO and PATTERNS were ON.
Fixed sfile() to use the file type from the SEND-LIST.  ckcfns.c, 5 Apr 99.

^C^C^C at Kermit in remote RECEIVE mode was giving an annoying hint message.
Fixed in parser(), ckuus5.c, 5 Apr 99.

Made CLEAR SCREEN a synonym for SCREEN CLEAR.  (Yes, so now we have *four*
commands that do the same thing.)  ckuusr.[ch], 5 Apr 99.

SCREEN { CLEAR, MOVE, CLEOL } doesn't work in IKSD.  I wonder why.  It knows
the terminal type (and TERM is defined).  Maybe tgetent() fails when called
from a process that does not have a tty.  Added some diagnostics.  Also made
the SCREEN command default to using ANSI sequences in UNIX if tgetent() fails.
If this bothers anybody, I'll add SET commands or something.  Otherwise, it'll
be like K95 host mode, which uses ANSI sequences no matter what (actually we
might be able to do better in 1.1.18 -- if it knows the client's terminal type,
it also knows the clear-screen, cleol, and curpos sequences, right?  So then
the SCREEN command could "just work" if the ck_blah() routines were filled in
for the 'sstelnet' case, no matter what the client's terminal type, as long
as it was recognized & supported by K95).  ckuusx.c, 5 Apr 99.

Gerry Belanger reported compilation errors with the new tgetstr() and tputs()
calls.  Problem 1: tgetstr() was called before #include <curses.h>.  The
obvious solution would have been to move the #include higher up, but it turns
out it is where it is for a reason, namely that it clobbers numerous other
symbols that we depend on.  So the actual solution was to extract the tgetstr()
calls to a separate routine and put the new routine below the #include.  Since
there was no point in having it return a value, I made it VOID but then it
wouldn't compile -- eventually I rediscovered that VOID was one of the macros
that <curses.h> clobbers.  Problem 2: tputs() wants a function pointer as its
3rd arg (OK) but the function must be one that takes an int as a parameter, not
a char.  I was using conoc(), of course, but that takes a char.  So I installed
a stupid interface routine that takes an int, converts it to a char and *then*
calls conoc().  Isn't there a better language than C?  ckuusx.c, 5 Apr 99.

Corrections to new ckuusx.c after trying to compile it on FreeBSD 2.2.7
myself.  ckuusx.c, 6 Apr 99.

Removed the old, commented-out doget() routine, about 250 lines.  ckuus6.c,
6 Apr 99.

Changed REMOTE HOST and REMOTE KERMIT to copy the cmtxt buffer to a safe place
before use; not strictly necessary, but it's poor practice to take advantage
of this special case.  ckuus7.c, 6 Apr 99.

New VOS network module from Jeff.  cklnet.c, 6 Apr 99.

Added support for Motorola Codex modems.  ckuusr.h, ckudia.c, 6 Apr 99.

Discovered that streaming transfers to C-Kermit on HP-UX 8.00, 9.00, or 10.20
in remote mode do not work at all -- they lose characters galore; this is
probably true, therefore, for all HP-UX versions.  In each case, if I turn off
streaming and reduce the packet-size x window-size to 500, uploads work.  (But
there's no problem with streaming downloads.)  Further experimentation shows
the problem goes away if I tell the remote C-Kermit to "set flow xon/xoff"
prior to transfer.  Evidently the HP-UX Telnet server treats "flow none" as a
request to drop characters, just like VMS.  Pretty silly!  Changed default
remote-mode flow-control for HP-UX from NONE to XON/XOFF (also tested KEEP and
RTS/CTS and neither one works), and updated file-transfer failure hints
accordingly.  ckcmai.c, ckuus5.c, ckermit2.txt, 6 Apr 99.

Changed \fsplit() to not require an array argument, in which case it simply
returns the word count.  Also not to require that the array, if specified, be
predeclared -- if it is not, it is created dynamically.  Also to allow an
empty array argument followed by break and/or include arguments.  Also to
work with no arguments at all, in which case it returns "0".
ckuus4.c, 6 Apr 99.

Changed DECLARE with initializers to accept empty subscript brackets in which
case the array is sized according to the number of initializers (like C) --
including none at all.  Also changed DECLARE to evaluate the initializers
rather than copy them literally -- otherwise there would be no way to
initialize an array element to the value of a variable, rather than its name.
This way, a literal name can still be given according to normal rules,
e.g. "dcl \&a[] = \\%a ..."  ckuusr.c, ckermit2.txt.  6 Apr 99.

Auth stuff & help text from Jeff: ckcmai.c, ckuus2.c, ckuath.c, ckcssl.h,
7 Apr 99.

Added date-time format info to HELP DATE and then added a reference to this
from all other HELP texts that involve date/times.  ckuus2.c, 7 Apr 99.

Added [wk]ermit to UNIX binary patterns.  ckcmai.c, 7 Apr 99.

Increased the command buffer length from 10K to 64K for (BIGBUFOK + not NOSPL)
builds.  This allows for longer strings, macros, etc.  Tested wermit10k
against wermit64k running ckedemo.ksd (minus the interactive parts) side by
side on the same computer under various loads (this is a compute-bound script
with no i/o).  wermit64k is 10% to 30% slower under various loads.  In 21
trials, wermit10K was faster than wermit64K 19 times and the same 2 times; on
average the wermit10k version was 19.7% faster.  Changing the buffer to 32K
reduces the difference to a fairly constant 10%.  The big hit in all cases
comes in the evaluation of recursive user-defined functions (because we have
to replicate the command buffers for every level of recursion).  If we remove
the recursive function from the script, there is no difference in execution
time among the three versions.  So... whereas:

 . There will always be SOME limit on string length;
 . Most people will never write or use a recursive function;
 . Other script languages like DCL have a 32K limit;
 . 64K is (more) likely to cause trouble on segmented architectures;
 . In SunOS at least the buffer size doesn't affect the executable size;
 . Kermit is a very high level language so scripts are relatively short;
 . Nobody has complained about the 10K restriction on script length;
 . Long macros can always be decomposed anyway;
 . The only complaint has been about the max length of a variable's value;
 . It would be a bad idea to add a runtime SET command for this (since it
   would pull the rug out from under the very command parser that was
   parsing it)...

... I changed the buffer length to (32K - 1).

Added \v(inwait) = timeout value of most recent INPUT command.  ckuusr.h,
ckuus4.c, 7 Apr 99.

Defined a bunch of switches to the DELETE command to make it more consistent
with DIRECTORY, PURGE, and SEND.  ckuusr.h, ckuus6.c, 7 Apr 99.

Filled in the DELETE switch definitions:
  /LIST = /LOG = /VERBOSE    (These were there before but I redid them)
  /NOLIST = /NOLOG = /QUIET  (ditto)
  /[NO]HEADINGS
  /[NO]DOTFILES
  /[NO]PAGE
  /EXCEPT:<exception-list>
  /BEFORE:<date>, /NOT-BEFORE:<date>, /AFTER:<date>, /NOT-AFTER:<date>.

And added SET OPTIONS DELETE and added DELETE options to SHOW OPTIONS.
Still needs fine tuning, help text, and maybe a few more switches, etc.
ckuus[356].c, 7 Apr 99.

From Jeff, IKSD fixes:

 . initialize socket for non-blocking I/O and OOB inline

 . correct handling of CKXPRINTF definitions in ckuusx.c that was
   resulting in data corruption on encrypted sessions.

 . Many corrections to data transfer and negotiations for SSL/TLS

 . Traced further data corruption on encrypted sessions to the
   output of informational messages to the socket during negotiations.
   The messages were meant for the end user but when IKSD is being
   used they should be skipped.  Solves lots of miscellaneous issues.

 . Discovered that when DES is not available from K95CRYPT.DLL and
   not exported from the Kerberos DLLs we can't performed Mutual
   authentication.  I'm not sure whether we care or not at the
   present time.

 . Do not initialize Telopt negotiation defaults until after sysinit()
   so that we can make responsible choices based upon installed
   libraries.

Plus: The ckgetpid() prototype should not be #ifdef CKGETPID, corrections for
Stratus.  ckcmai.c ckuusr.h ckuus6.c ckutio.c ckuath.c ckctel.c ckcnet.c
cklnet.c ckuusx.c, 8 Apr 99.

Later...  The Stratus version builds!  (Dat Thuc Nguyen built it with TCP/IP
and X.25 support on two architectures.)

Parameterized fileselect() and moved it to ckclib.  ckcfns.c, ckclib.[ch],
8 Apr 99.

Changed DELETE to use fileselect().  ckuus6.c, 8 Apr 99.

Added cmgkwflags() to get keyword flags after successful cmkey() parse.
This makes it much easier to check if a switch requires an argument.  Added
appropriate calls everywhere (or at least most places) switches are parsed.
ckucmd.[ch], 8 Apr 99.

Today's project is to make SEND, DIRECTORY, DELETE, and PURGE use the same
set of file-selection switches, and then use fileselect() based on them:
 DIRECTORY:
  /[NOT-]{BEFORE,AFTER},/LARGER,/SMALLER,/EXCEPT.
 DELETE:
  /[NOT-]{BEFORE,AFTER},/LARGER,/SMALLER,/EXCEPT.
 PURGE:
  /[NOT-]{BEFORE,AFTER},/LARGER,/SMALLER,/EXCEPT,/[NO]DOTFILES,/[NO]HEADING
Also added /SIMULATE to DELETE and PURGE for testing / previewing.  Also Added
/ASK to DELETE and PURGE (like "rm -i") because people ASKed for it; this
required adding a "quit" option to getyesno().  ckcfns.c ckclib.c ckclib.h
ckcpro.c ckucmd.c ckucmd.h ckuus3.c ckuus5.c ckuus6.c ckuus7.c ckuusr.c
ckuusr.h ckuusx.c ckermit2.txt.  8 Apr 99.

From Jeff -- corrections to yesterday's work, plus pseudoimplementation of
the Telnet LFLOW option.  ckctel.c, ckcnet.c, ckuusr.h, ckuus[r36].c, ckucmd.c,
9 Apr 99.

Added /QUIET /VERBOSE (and their synomyms) to COPY and RENAME, for the benefit
of script writers who want to provide visual feedback easily.  ckuus6.c,
9 Apr 99.

Added SET DIAL METHOD AUTO and made it the default.  This means that if Kermit
knows your local country code, and it is on the list of countries in which
tone dialing is universally available, tone dialing is used automatically.
The initial list includes North America, the UK, Germany, and Sweden.  There
is also a list for countries in which pulse dialing is required (initially
empty).  Also added SET DIAL { TONE-COUNTRIES, PULSE-COUNTRIES } to modify the
lists, and updated SHOW DIAL to show the lists.  Also allow setting of dial
method from K_DIAL_METHOD environment variable.  ckuusr.h, ckuus[346].c,
ckudia.c, ckermit2.txt, 9 Apr 99.

IKSD login fix for AIX (and probably others) from Jeff.  ckufio.c, 9 Apr 99.

Added Finland to tone-dialing default list.  ckudia.c, 11 Apr 99.

Added prototypes for tn_sxdisploc() and tn_sndloc() to ckctel.h, 11 Apr 99.

Added a default: break; case to a switch statement that has no cases if
none of {AUTH,CRYPT,IKSD} are defined.  ckctel.c, 11 Apr 99.

Changed date/time parsing to allow YESTERDAY, TODAY, TOMORROW, + or - <number>
{ DAYS, WEEKS, MONTHS, YEARS }.  This affects all date fields and switches (so
you can say, for example, "delete /before:today *" or "send /since:yes *"), the
DATE command, and also the date-related functions, particularly \fcvtdate().
ckucmd.c, ckermit2.txt, 11 Apr 99.

Minor corrections to yesterday's date work after more testing.  ckucmd.c,
12 Apr 99.

Added HELP PURGE, HELP DELETE.  Updated HELP DATE text to show new options.
ckuus2.c, 12 Apr 99.

Removed trailing blanks & tabs from just about every source file.  12 Apr 99.

Oops, the trimming was done with the EMACS "trim" command, which has the
unfortunate side effect of also tabifying the file, even the insides of string
constants.  Put 'em all back the way they were before, then wrote a trim
program that trims trailing whitespace from all the files in its arglist
without messing with tabs.  Checked to make sure HELP and SHOW text is still
formatted correctly.  All modules, 12 Apr 99.

Updated HELP text for other changes since Beta.05 that had not yet been
reflected in the HELP command.  ckuus2.c, 12 Apr 99.

Fixed date arithmetic to handle years prior to 1000, but only back to 0.
Negative years (or years after 9999) are not handled due to limitations of the
fixed yyyymmdd notation.  ckucmd.c, 12 Apr 99.

Fixed parser foulups when editing back into a /SINCE, /BEFORE (etc), or
/EXCEPT switch in domydir(), dodel(), and dopurge().  Also Fixed PURGE and
DELETE /SIMULATE to automatically select /LIST also, since what's the point
otherwise?  Also added the PURGE and DELETE defaults to the SHOW OPTIONS
display.  ckuus[67].c, 12 Apr 99.

Adjustments to make -DNOICP builds work.  ckuus[4y].c, ckucns.c, ckcnet.c,
12 Apr 99.

Fixed another problem in \fsplit(), in which it wasn't dealing correctly with
the no-array-specified case.  ckuus4.c, 13 Apr 99.

From Jeff: Kerberos ticket auto-delete/destroy: ckcnet.c ckcnet.h ckuath.h
ckuus2.c ckuus3.c ckuus7.c ckuusr.h ckuusx.c, 13 Apr 99.

Fixed messed-up spacing in ckcpro.c because of tabification of ckwart.c that
was not undone yesterday.  ckwart.c, 13 Apr 99.

Increased sizes of INPUT buffer, TAKE and DO stacks, and some other stuff for
BIGBUFOK builds.  ckuusr.h, 13 Apr 99.

When C-Kermit was in CONNECT mode and the Kermit on the far sent an I packet,
causing the local Kermit to enter server mode automatically, and then sent a
FINISH request, the local Kermit would return to its prompt rather than
resuming CONNECT mode.  Diagnosis: the FINISH handler never set the success
variable, so the autodownload code thought a transfer had failed and therefore
deliberately did not resume CONNECT mode so the user could see the error
message.  Solution: the server should set success = 1 when a FINISH has been
executed successfully.  ckcpro.w, 13 Apr 99.

Bug: A command file makes a connection, then if success takes a command file
and then CONNECTs.  The command file defines a macro that includes an ASK
command and assigns it to a key.  User presses key, and ASK reads a linefeed
that was "pushed" by the command parser due to its command state.  Attempted
to work around by setting a global flag, "askflag", whenever ASK, ASKQ, GETOK,
etc, are active, to bypass the pushing (and therefore also the popping).
Can't test in C-Kermit because no Kverbs, but at least it seems to do no harm;
needs to be tested in K95.  ckucmd.c, ckuus[56].c, 13 Apr 99.

Eliminated a bunch of unresolved references at link time for NOICP builds
by shuffling declarations & #ifdefs.  Various modules, 13 Apr 99.

SSL/TLS changes from Jeff.  ckcnet.c, ckutio.c, ckcssl.h, 14 Apr 99.

Jeff fixed my fix to the ASK bug.  ckucmd.c, 14 Apr 99.

Added Netherlands & Belgium to tone-countries list.  ckudia.c, 14 Apr 99.

Made NOICP imply NODIAL, since there's no way to dial if there is no
interactive command parser.  This eliminated various unresolved references
at link time.  Also made NOICP imply NOCKXYZ (no external protocols), since
there is no way to choose them without an interactive command parser.
ckcdeb.h, 14 Apr 99.

Moved declaration of noprinter from ckuus3.c to ckcmai.c for NOICP.  14 Apr 99.

Now that I can build a NOICP version, I checked command-line option processing.
As suspected, items handled by prescan() were not being handled in the NOICP
build.  Rearranged prescan() code and calls to make everything work.  ckcmai.c,
ckuus4.c, 14 Apr 99.

The NOICP version did not handle the "command-line personalities" business
(e.g. act like Telnet if called Telnet).  Fixed by juggling #ifdefs in
ckcmai.c, 14 Apr 99.

However, when a NOICP version of Kermit is called Telnet, there is no way for
it to transfer files: no file-transfer command-line options, no command parser
to escape back to, and autodownload doesn't work because it depends on having
a command parser.  For UNIX/NOICP only, I implemented autodownload by having
the CONNECT module call proto() directly.  ckcker.h, ckucns.c, 14 Apr 99.

The NOICP telnet client can send files fine (via autoupload/server), but can't
receive them.  It goes into receive mode but then fails to advance its packet
number and ACKs packet 1 with ACK(0).  The sequence number in the ACK is
winlo, which the debug log shows is set to 1 at this point.  Further debugging
shows that winlo is reset to 0 when rcvfil() calls zfnqfp().  However, adding
debug() calls within zfnqfp() made the problem go away.  Hours later, the aha
experience: zfnqfp() itself was not the culprit -- it was the parameters
passed to it by rcvfil().  Very non-obvious: we were writing into the fspec[]
buffer using CKMAXPATH as the max length.  However, fspec[] was sized to CMDBL
if NOMSEND was defined, which happens when NOICP is also defined.  Normally
CMDBL is (much) longer than CKMAXPATH, but in the NOICP case, CMDBL
(command-buffer length) is 508, whereas CKMAXPATH (on the platform in
question, at least) is 1024.  Since we were using strncpy() to write the
results into the buffer, and since (at least this version of) strncpy()
right-pads with NULs all the way the end of its destination buffer based on
the given length, this wrote all over memory.  Fixed by setting a variable,
fspeclen, to the length of the fspec[] buffer, and using that in all
references to its length, rather than CKMAXPATH.  I don't think this
particular problem would ever have occurred before today, but there were many
other places where fspec[] was the object of a strncpy() (directly, or
indirectly thru zfnqfp()), and any of these might have been the source of a
memory leak, since some of them specified CMDBL as the length and others
CKMAXPATH.  Fixed in ckuus[r46x].c, ckcfn[s3].c, ckcpro.w, 14 Apr 99.

Why does rcvfil() call zfnqfp() and then <rfile>F also calls it after calling
rcvfil()?  Changed <rfile>F to use fspec[], which rcvfil() always sets.  This
eliminates the redundant call to zfnqfp().  ckcpro.w, 14 Apr 99.

Anyway, after all this, it is possible to build a NOICP version of Kermit
that can upload and download files (but since it has no user interface, file
transfer must always be initiated by the remote via autoup/download).

More SSL changes from Jeff: ckcnet.c, ckutio.c, 14 Apr 99.

Juggled #ifdefs & declarations to make "sunos41x" build.  ckcfns.c, ckuusx.c,
ckutio.c, 14 Apr 99.

Did the same for some other builds on SunOS:

  sunos41gcc:    1.3MB <-- Full build for SunOS with gcc.
  ditto+NODEBUG: 1.1MB <-- Full build but no debugging.
  sunos41m:      229KB <-- Command-line only - no interactive commands.
  ditto+NOLOCAL: 212KB <-- Ditto, remote only.
  sunos41mi:     377KB <-- Minimum interactive - no script language.
  ditto+NOLOCAL: 360KB <-- Ditto, remote only.
  NOXFER:        917KB <-- Full scripting & comms but no file transfer.
  NOXFER+NOICP:  229KB <-- Communications only - no scripting or file transfer.

Many modules affected.  14 Apr 99.

Some fallout from the April 3rd work regarding application of defaults for
missing command fields -- Peter E noticed that on HP-UX, "echo" by itself
would print some garbage.  Sigh, cmtxt() and some of the other functions were
returning a pointer to an automatic array in this case, which of course is
likely to be pointing to something else after the function exits.  Fixed in
ckucmd.c, 15 Apr 99.

Fix from Jeff for K95 not finding its init file under certain conditions.
ckuus5.c, 15 Apr 99.

If VMS C-Kermit received a file whose name contained any parts that were more
than 39 chars long, the transfer would fail because zmkdir()'s sys$parse()
call failed with "Bad filename" (RMS$_FNM).  Changed VMS zmkdir() to ignore
this error.  There is still a potential problem with an illegal name given by
the user as an as-name, but that's easily overcome by not giving an illegal
name (we don't run as-names thru nzrtol() on purpose, because we want the user
to be able to have the final word).  ckvfio.c, 15 Apr 99.

Implemented PURGE the cheap way for VMS -- as a built-in macro that calls DCL
PURGE.  ckuus[r257].c, ckermit2.txt, 15 Apr 99.

Changed \v(model) in HP-UX to not run the "model" command.  This was bad
because (a) running external programs is a no-no in captive environments like
IKSD and when nopush is in effect, and (b) because a frequent result of
running "model" is the string "not found".  Now we treat HP-UX like any other
UNIX and have \v(model) return the machine name from uname() if the model
has not been filled in (some uname() implementations fill it in, some don't).
ckuus4.c, 15 Apr 99.

Verified that I can send to C-Kermit on HP-UX 8.00 on a Telnet connection with
streaming (since we now default to Xon/Xoff in HP-UX for remote mode).  This
is to an HP-9000/385 about 3000 miles from here.  As noted in the beware file,
this kind of transfer is painfully slow.  Bypassing the Telnet server with
"set host *" gets 10 times the speed.

Juggled some more #ifdefs in ckctel.h to make sure we don't have switch
statements with no non-default cases.  15 Apr 99.

Peter E reported various other problems with HP-UX 8.00.  First, that Kermit
thought it was in the background after escaping back from CONNECT.  He says
this started happening during the Beta.04+ period.  But the code related to
background testing hasn't changed in a very long time.  Anyway, I was able
to fix it by observing that the conbgt() "signal test" was finding its old
SIGINT handler was SIGN_IGN, which it takes to be a sign of backgroundness,
so I switched the conint() and concb() calls that are done before calling
conbgt() after returning from CONNECT (but only for HPUX8).  Not very
satisfying, since it doesn't address the real cause -- whatever it is.
doconect(): ckuus4.c, 15 Apr 99.

While I was at it, I went to build an optimized version on HP-UX 8.00 and saw
(as Peter had reported) that ckuusr.c takes forever to compile, so I went to
the hpux80 makefile entry and did the trick to make it build this module
without optimization -- the same trick that was already there for ckcpro.c.
But then I noticed that not all of the CFLAGS had been copied into the ckcpro
section -- which might very well explain numerous peculiarities in the HP-UX
8.00 version.  So I changed the hpux80 entry to have consistent CFLAGS.
makefile, 15 Apr 99.

Warnings occur on HP-UX 10.20 ANSIC-C builds 10 about lines 4091, 4114, and
4136 in ckuusx.c: too bad.  The warnings come from calls to tputs(), whose
third argument is supposed to be a pointer to a function that (a) has a
certain return type (such as int or void), and (b) takes a certain type of
argument (such as int or char).  "man tputs" says one thing, but the
prototypes in curses.h and term.h each contradict the man page -- and each
other.  No combination of int/int, void/int, int/char, etc, would shut the
warnings up.  Despite the warnings, however, the code works fine, so no
changes.

In anticipation of lots more trouble with tputs(), made all references to
its return type and its argument type symbolic: TPUTSFNTYPE and TPUTSARGTYPE,
with default definitions of int and int; these can be overridden on the
cc command line.  ckuusx.c, 16 Apr 99.

Improved SEND/RECEIVE/GET failure hints a bit.  ckuus5.c, 16 Apr 99.

"get /etc/hosts x.x" did not work if both Kermits had PATHNAMES ON.  In this
case zchko() was being called on the packet name rather than the as-name.
Fixed in rcvfil(): ckcfns.c, 16 Apr 99.

Dat Thuc Nguyen had problems debugging a script involving fsplit().  It soon
became apparent that the real problem was the lack of informative error
messages.  So I changed the way SET FUNCTION DIAGNOSTICS and SET FUNCTION
ERROR work so they stand a chance of doing some good without people having to
know about these commands in advance:

 . FUNCTION ERROR is now ON by default, rather than OFF.
 . FUNCTION DIAGNOSTICS, rather than FUNCTION ERROR, now governs whether
   an error message is printed when a function fails.

I also added an array-index-out-of-bounds error for \fsplit() (to cover the
case where it is called with a predeclared array).

In checking these changes, I discovered that local arrays become global if
there is no global copy of the same array.  For example:

  define xx {
    local \&a[] = one two three
    show array a
  }
  xx
  show array a

The second "show array a" shows the local array which should have been
destroyed when xx finished instead of saying "?Array not declared".
Diagnosis: popclvl() had no way of knowing whether a local-array pointer was
NULL because no array of that name had been declared at that level (in which
case it should leave the global definition alone) or because there was no
global definition originally (in which case it should delete the current
definition).  This was handled by pushing a "secret code" on the
local-variable stack for this array.  dolocal(), pusharray(), popclvl():
ckuus5.c, 16 Apr 99.

Also discovered that popping local arrays off the stack never worked at any
level unless scalar variables were also on the stack at the same level.
Fixed in popclvl(): ckuus5.c, 16 Apr 99.

More authentication / encryption changes from Jeff: ckcnet.h, ckuusr.h,
ckuus[37].c, 16 Apr 99.

More authentication / encryption changes from Jeff: ckcnet.h, ckuusr.h,
ckuus7.c, 17 Apr 99.

HP-UX 8.00 adjustments to makefile, 17 Apr 99.

Plus more HP-UX adjustments to makefile from Peter E, 17 Apr 99.

Fixed unbalanced quotes in the sco32v4netgcc makefile entry, 17 Apr 99.

Further improvements to GET-class command failure hints.  They're obnoxious,
but they're pretty useful.  ckuus5.c, 17 Apr 99.

For months, I've been hearing of a problem with the fullscreen file-transfer
display in VMS but was never able to reproduce it.  Finally I got the needed
hint -- it happens only when autouploading.  The problem occurs when we use
printw() to write on the bottom screen line.  For some reason, only when
autouploading (go figure), an extra CRLF comes out and pushes all the labels
up one line.  The stupid solution was to not write on the bottom line (in VMS
only).  ckuusx.c, 17 Apr 99.

Tried to give VMS C-Kermit the ability to send "keepalive" packets while in
server mode executing a subprocess that takes a long time to produce output
(as the UNIX version can -- see notes from Oct 25).  I made the VMS
get_subrc_line() routine do a timed read and then added all the appropriate
tests, return codes, etc.  It doesn't break anything; REMOTE HOST commands
still work fine.  But the timeout feature doesn't work.  To test, put VMS C-K
in server mode and then tell the client "remote host wait 00:00:30".  VMS C-K
is supposed to send back an empty data packet every second but it doesn't.
The debug log shows that it does indeed return a timeout indication, but only
after the subprocess exits.  ckvfio.c, 17 Apr 99.

Notes on the Beta.06 build-all...

 . After building on each platform, I transferred a 3MB binary file to the
   remote just-built version to make sure the default FLOW /REMOTE selection
   was appropriate.  Some of these transfers exceeded 500000 cps -- through
   the Telnet server!  (Results: only HP-UX and VMS need Xon/Xoff; all the
   others work OK with NONE.)  Then I used the same new binary to make a
   Telnet connection back to here and send itself, thus testing the network
   code, file-sending code, etc, as well as the fullscreen file-transfer
   display.  Also Ctrl-L or "cls" was typed at the C-Kermit> prompt to
   ensure the new SCREEN code works.

 . On HP-UX versions where I had access to a serial port, I made sure I
   could CONNECT to the port and escape back, and still have a prompt.
   The mixup with SIGINT is apparently peculiar to HP-UX 8.00.  This is
   handled by adding -DCKCONINTB4CB to CFLAGS.  It was not needed in
   HP-UX 5.21 or 10.20.  Don't know yet about 6.x, 7.x, or 9.x.

 . Discovered that you must SET PREFIXING ALL when sending binary files
   thru the Ultrix Telnet server.  Made a note in ckubwr.txt.

 . Digital UNIX (both 3.2 and 4.0) gets a segmentation fault when calling
   tgetstr() (yes, after a successful call to tgetent()).  Curses works, but
   termcap calls don't.  Added -DNOTERMCAP and supporting code to avoid these
   routines, and added -DNOTERMCAP to the DU entries.  I guess they really
   mean it when they say in the man page that these are "old" routines and
   you should use curses instead.  ckuus[5x].c, makefile, 17 Apr 99.

 . NOTE: In case anybody wants to look into a better workaround for tgetstr()
   in DU, note that DU's curses.h says "#define tgetstr _bsd_tgetstr", but
   then the latter doesn't appear in any header files or man pages I can find.
   Also the DU 3.2 and DU 4.0 man pages disagree on the calling conventions
   (even though the header files show the normal ones).

Next day...  Spent a few more hours on the OSF/1 tgetstr() problem to no
avail.  A short test program that calls tgetent(), tgetstr(), and then
tputstr() works OK, but the exact same sequence in C-Kermit gets the
segmentation fault.  The difference is probably due to some conflict or
confusion in the many more header files included by ckuusx.c than by the short
test program (which includes only curses.h).  There's all kinds of crazy stuff
going on in OSF/1 curses.h that is obviously extremely sensitive to what other
symbols have been defined, what universes we're in, etc.  No amount of
finagling helped, not #including <term.h> before <curses.h>, not calling
_bsd_tblah() explicitly, not #undefing the tgetstr (etc) macros, etc, so I
left the NOTERMCAP definition in place.  Very unsatisfying.  18 Apr 99.

Further build-all observations:

 . Streaming transfers into AIX 4.2 or 4.3 (through the AIX Telnet server)
   consistently failed, when exactly the same kind of transfers into AIX 4.1
   worked without incident.  The error reported by AIX is "interrupted system
   call".  Changing flow control, packet length, prefixing, parity, etc, makes
   no difference.  Streaming transfers work perfectly, however, if the AIX
   Telnet server is removed from the picture (e.g, by using "set host * 3000"
   on AIX, or by using Rlogin instead of Telnet).  They also work perfectly if
   the Telnet connection is forced into binary mode (C-Kermit command "set
   telopt requested requested").  (But oddly enough, transfers are much slower
   through the Rlogin server or the binary-mode Telnet server than through
   the same Telnet server in NVT mode.)  Otherwise "set streaming off" does
   the trick.

Finally figured out how to squelch ANSI compiler warnings from HP-UX 9 and 10
about tputs().  makefile, ckuusx.c, 18 Apr 99.

Added -DDCLGETCWD to sco234* entries.  makefile, 18 Apr 99.

Added prototype for pusharray() to ckuusr.h, 18 Apr 99.

---Beta.06---

From Lucas Hart: Proper implementation of timed reads for pipes (mailboxes)
in VMS, allowing REMOTE HOST keepalive.  ckvfio.c, 19 Apr 99.

Somehow in all these years I never heard of the UNIX realpath() function.
Changed zfnqfp() to use it if CKREALPATH defined.  It does what zfnqfp() does
(including all the "../.././../" stuff) plus resolving symlinks.  We'll see
how portable it is in the next build-all.  So far it's OK on Sun, HP-UX 10,
and SCO OSR5.  ckufio.c, ckcdeb.h, 22 Apr 99.

Added -DCKCONINTB4CB to all HP-UX 7.xx makefile entries.  23 Apr 99.

Added sys3upcgfd target, from Peter Mauzey.  makefile, 23 Apr 99.

From Jeff, 23 Apr 99:
 . Corrections to X.25-but-no-TCP builds: ckctel.c.
 . SET TELNET TRANSFER-MODE: ckuusr.h, ckuus[23].c, ckctel.c, ckcpro.w.
 . \v(authstate), \f(krbflags), ckuusr.h, ckuus4.c.
 . IKSD login/auth improvements: ckcmai.c.
 . Fixes to command-line/command-file botches from kerbang changes: ckcmai.c.
 . Make Telnet Option keywords not depend on #ifdefs: ckuus3.c.
 . Various other auth/crypt changes: ckuat[h2].[ch], ckuus7.c.

From Martin Whitaker, 23 Apr 99:
 . Fixes for OS-9: ck9fio.c, ckuus5.c.
 . Bad IF stmt in doxconn(): "if (xx = ttchk() < 0) dologend();"
   Should be: "if ((xx = ttchk()) < 0) dologend();"
 . Ditto in dodial(): "if (y = conchk() > 0)" -> "if ((y = conchk()) > 0)"
 . ttnet not found at link time in no-network builds.  ckcnet.c.
   (Why is #ifdef CK_LOGIN commented out around that big section in ckcmai?)
   (Maybe it should be #ifdef something else?)

Regular and -DNONET builds on SunOS were OK.

Fixed \fsplit() not to dump core if given an empty string. ckuus4.c, 23 Apr 99.

Changed SET LINE to not print open() failure message if QUIET ON and SET LINE
command not given from prompt.  This makes the GETLINE script run smoother.
ckuus7.c, ckutio.c, 23 Apr 99.

Put QUIET variable (quiet) on the command stack, so a macro or TAKE file can
SET QUIET ON or OFF without affecting its caller.  This was done differently
from the other stackable settings (like INPUT CASE, etc) since the 'quiet'
variable is used in so many places, even in modules that must not have any
notion of such things as a command stack.  This way the quiet variable can
be used just as it always was; only those routines that change command level
need to be concerned with pushing and popping it.  ckuus[356].c, 23 Apr 99.

Added IF QUIET so scripts can test SET QUIET setting when printing messages.
ckuusr.h, ckuus6.c, 23 Apr 99.

Changed DIAL to cancel automatic redialing if call failed because no dialtone.
ckuus6.c, 23 Apr 99.

Added the following dial-modifier variables:
 \v(dm_lp) Long pause
 \v(dm_sp) Short pause
 \v(dm_pd) Pulse dial
 \v(dm_td) Tone dial
 \v(dm_wa) Wait for answer
 \v(dm_wd) Wait for dialtone
 \v(dm_rc) Return to command mode
The modifier strings are obtained by calling getdm() in ckudia.c.
ckuusr.h, ckuus4.c, ckudia.c, 23 Apr 99.

Added /HEAD:n and /TAIL:n switches to TYPE.  ckuus[r256].c, 23 Apr 99.

Fixed TYPE /TAIL:n to work when n > file lines.  ckuus6.c,24 Apr 99.

Added TYPE /MATCH:pattern -- like grep (but only works for one file).  And
TYPE /WIDTH:cols, for truncating lines (e.g. to prevent wraparound).  Added
TYPE /PREFIX:string to put any desired string at the head of each line.  Added
TYPE /COUNT to only count (matching) lines, but not print them - like "wc -l".
Added /WIDTH:n to SET/SHOW OPTIONS TYPE.  ckuusr.[ch], ckuus6.c,24 Apr 99.

Added:
 \v(ty_ln)  TYPE line number
 \v(ty_lc)  TYPE line count
 \v(ty_mc)  TYPE match count

\v(ty_ln), or any other variable(s), can be used with TYPE /PREFIX.  Examples:

  TYPE /PREFIX:{\v(time): }   <-- puts time of TYPE command on each line.
  TYPE /PREFIX:{\\v(time): }  <-- puts current, running time on each line.
  TYPE /PREFIX:{\\v(ty_ln): } <-- puts line number on each line.
  TYPE /PREFIX:{\\flpad(\\v(ty_ln),3): } <-- Ditto, right-adjusted.

After a TYPE command, SHOW VAR TY gives the statistics: line count of file,
plus count of lines that matched if a pattern was given.
ckuusr.h, ckuus4.c, 24 Apr 99.

Improved parsing of Windows Printer Queue name from Jeff.  ckuus3.c, 24 Apr 99.

Brought ckermit2.txt up to date.  24 Apr 99.

From Jeff: missing default return for getdm().  ckudia.c, 26 Apr 99.

With hints from Lucas Hart, fixed the Digital UNIX termcap problem from April
18th.  Once again, the problem derived from referring to a termcap/terminfo
function (in this case tgetent()) before the <curses.h> include.  The solution
was to move fxdinit() to below the #include.  Verified on DU 3.2 and 4.0.
ckuusx.c, 26 Apr 99.

Defined NOREALPATH for HP-UX 8.00 and earlier.  Verified that realpath() is OK
in HP-UX 9 (and we already knew about 10).  ckcdeb.h, 26 Apr 99.

From Jeff, fix IKSD login to not assume anonymous if we don't know who the
user is after authentication (mainly for TLS).  ckcmai.c, 26 Apr 99.

Using unsigned chars for buffers and pointers in dotype() caused all sorts of
stupid mindless fascist warnings to spew forth from picky compilers, so I made
the offending items regular (signed) char instead.  Can I still TYPE 8-bit
text files on platforms where C-Kermit can't be built with -funsignedchar?
Seems OK on HP-UX 10.20.  Time will tell about the others.  Checked to see
whether HP-UX ANSI compiler has an option to treat all chars as unsigned (it
doesn't).  ckuus6.c, 26 Apr 99.

Fixed declaration/ifdef glitches for VOS x25-but-no-tcpip build.  cklnet.c,
ckuscr.c, ckuus4.c, 26 Apr 99.

When executing Kerbang scripts, the console was not in cbreak mode, so
askmore() didn't work normally.  That's because concb() was called only when
C-Kermit reached top level (e.g. after executing the init file).  But now
we're executing ASK[Q], GETOK, GETC, and askmore() without ever reaching top
level, so I added concb() calls for all these.  ckuus[56].c, 26 Apr 99.

From Jeff: Fix for END given at top level trying to free stuff that was never
malloc'd.  ckuusr.c, 27 Apr 99.

Changed DIAL to cancel automatic redialing if call failed because of a
dialing directory error, access is forbidden, blacklisted, or locked.
ckuus6.c, 27 Apr 99.

From Lucas Hart: Fix gcc warnings in VMS gftimer(), ckvtio.c; add missing
#define for cklongjmp() in one of the #ifdef cases in ckcsig.h.  27 Apr 99.

In working on REVIEW 2.0 (one of our demo scripts) I discovered a subtle but
annoying problem: although the \&_[] array could be accessed at top level,
and in an IF command, and in a FOR loop, it could not be accessed in a FOR
loop that was inside an IF statement.  Similarly, the \v(argc) variable was
clobbered inside a FOR loop.  It seems the _GETARGS command was not quite
completely implemented.  Also, one critical step was lacking from addmac().
Both fixed in ckuus[56].c, 27 Apr 99.

Added \v(maclevel), mainly for debugging.  ckuusr.h, ckuus4.c, 27 Apr 99.

The following (new) construction did not work:

  if ( condition ) { commands } else if defined \%x { commands... }

We needed an additional layer of quoting in the else part.  doif(): ckuus6.c,
28 Apr 99.  Verified that all script torture-tests still work, and added a
long "if ... else if ... else if ... else if ... else" section to the IFTEST
script.

Dat Thuc Nguyen reported the following problem:

  define try_this { END 999 }           ; Sets \v(return) to 999
  try_this
  if FAIL echo RETURN1="\v(return)"     ; This displays 999
  try_this
  if FAIL { echo RETURN2="\v(return)" } ; This displays nothing, why?

This was yet another problem caused by the fact that IF ... { ... } (the
Command Formerly Known as XIF) is implemented internally as a macro (whereas
IF without braces is not), so it was looking in the wrong place on the stack
for the return value.  However, fixing this was not just a simple matter of
adding mrval[] to the items handled by _GETARGS and _PUTARGS, since dodo(), as
part of macro startup, initializes the RETURN value to NULL.  To make it not
do this for IF, FOR, WHILE, and SWITCH, while still doing for all other
macros, I added another command-stack flag, CF_IMAC (Internal Macro), which at
present is used only to prevent initialization of the macro's return value
(unfortunately it is ephemeral -- if we don't reset it right after use, it is
propogated to all lower levels -- so other applications for it are not
practical).  ckuus[56].c, 28 Apr 99.

Rearranging the declarations in ckuus4.c yesterday for the VOS x25-but-not-tcp
build caused tn_exit, ttnproto, tcp_incoming, autodl to come up missing on
nonet builds.  Fixed in ckuus4.c, checked by building with -DNONET, 28 Apr 99.

fxdinit() was not being included in non-curses builds after I moved it.  Fixed
(again) by juggling #ifdefs (again).  Fixed in ckuusx.c, fixed by building
with -DNOCURSES.  28 Apr 99.

Failure to open init file was not giving an error message.  Added code to
print a message in doinit(): ckuus5.c, 28 Apr 99.

Some Telnet authentication changes from Jeff.  ckctel.c, 30 Apr 99.

The MINPUT command, when typed at the prompt, was not getting into the
reparse() buffer.  Another case of not calling cmcfm()...  Fixed in ckuusr.c,
30 Apr 99.

Changed SET BELL to be available in all versions, not just K95.  ckcdeb.h,
ckuusr.h, ckuus[r237].c, 30 Apr 99.

Added WILDCARD-EXPANSION setting to SHOW FILE.  ckuus4.c, 30 Apr 99.

Did a little digging on realpath():
 . SVID for SVR3 does not have it.
 . SVID for SVR4 does not have it.
 . POSIX 1003.1 does not have it.
 . ISO/IEC 9945-1 does not have it.
 . Apparently it originated with SVR4.2.

Determined the following UNIX platforms have it:
 . SunOS 4.1 and all Solaris
 . AIX 4.1 (and therefore 4.2, 4.3...)
 . Sinix 5.42
 . Digital UNIX 4.0.
 . HP-UX 9 and later.
 . SCO OSR5.0.5
 . QNX 4.25
 . Unixware 2.1.3
 . Red Hat Linux 5.2
 . IRIX 5.3 and later
 . NeXTSTEP 3.3
 . DG/UX 5.4R3.10 and later

Determined the following UNIX platforms do not have it:
 . HP-UX versions through 8.xx (we knew this already)
 . Motorola SV/68R3
 . SCO UNIX 3.2v4.x and earlier
 . SCO XENIX
 . Digital UNIX 3.2
 . Ultrix 4.3 (and presumably all other versions).

Expanded NOREALPATH section of ckcdeb.h to include all these.  2 May 99.

Tentative fix to Dat Thuc Nguyen's bug report regarding numeric STOP/END value
not being propogated up the call stack as \v(return).  popclvl(): ckuus5.c, 2
May 99.

New HP-UX 6 through 8 makefile entries from Peter E.  Changing -DSVR3 to
-DSIG_V seems to cure some performance problems in these versions, and
eliminates the need for -DCONINTB4CB.  Also it seems hardware flow control
never worked in HP-UX 8.xx because -DSTERMIOX was missing from CFLAGS, so
this was added to the hpux80 entry.  makefile, 3 May 99.

kermit -C "" caused an infinite loop.  Fixed in ckuusy.c, 3 May 99.

The -C "command, command, ..." list did not work if tabs were used instead
of spaces.  Fixed in ckuusy.c, 3 May 99.

Fixed serial and CRT displays to wrap long filenames.  ckuusx.c, 3 May 99.

This did not work:

  _define abc\%1 { blah blah }
  if defined \m(abc\%1) ...    <-- should succeed but fails.

Fixed in ckuus6.c (IF DEFINED did not handle compound macro names), 3 May 99.

From Jeff: Fix an off-by-one error in initializing the pointer list in
xwords(): ckuus5.c; cosmetic changes & typo fixes: ckctel.h, 4 May 99.

Added CK_NEWTERM to openbsd target.  makefile, 4 May 99.

Moved prototype for setbell() outside of #ifdef OS2.  ckuusr.h, 5 May 99.

Revisited the xwords() problem, undid Jeff's change.  xwords() itself was not
the problem; the problem was in some of the calls.  ckuus[r357].c, 5 May 99.

Found another problem in \fsplit(): given the name of an array, e.g. "a" or
"A", we blindly compute the array base without first checking the case.
Changed dclarray() to return the array-base index for use by the caller,
rather than simply 0 to indicate success, and then changed the callers to use
the returned value rather than computing it themselves.  ckuus[45].c, 5 May 99.

From Raul Kacirek <raulka@raulka.mv.com>: Fixed a mismatched quote mark in the
is3 makefile target.  6 May 99.

Added a bunch of symbols for new commands, etc, to ckuusr.h:

  XX_INCR     _INCREMENT           (like INCREMENT but evaluate LHS too)
  XX_DECR     _DECREMENT           (like DECREMENT but evaluate LHS too)
  XX_EVAL     _EVALUATE            (like _ASSIGN + \feval())

  XXARRAY     ARRAY                (Array ops -- copy, sort, declare, destroy)
  XXHTTP      HTTP                 (HTTP ops)
  XXPARSE     PARSE                (parse keyword, file, number, etc...)

  XYEVAL      SET EVALUATE         (old/new EVALUATE syntax, tsk tsk)

  IFXXCK      IF C-KERMIT          True if C-Kermit but not K-95
  IFXXK9      IF K-95              True if K-95
  IFXXMS      IF MS-KERMIT         True if MS-DOS Kermit
  IFXXWI      IF WILD <filespec>   True if filespec contains wildcard chars

  VN_XF_BC    \v(xfer_badpacket)   (Transfer blockcheck errors)
  VN_XF_TM    \v(xfer_timeout)     (Transfer timeouts)
  VN_XF_RX    \v(xfer_retransmit)  (Transfer retransmissions)
  VN_M_NAM    \v(m_name)           (Modem full name)

  FN_SEARCH   \fsearch()           (Search for pattern in string)
  FN_XLATE    \fxlate()            (Translate string character set)

But did not implement any of them yet, and might not anyway, we'll see.
6 May 99.

Corrected a minor error in yesterday's changes regarding dclarray() in the
DIRECTORY /ARRAY:&a code.  domydir(): ckuus6.c, 6 May 99.

Implemented _INCREMENT and _DECREMENT.  ckuus6.c, 6 May 99.

Correction to a Kerberos #ifdef from Jeff.  ckuus7.c, 7 May 99.

Added symbols for modem-signal variables \v(m_sig_xxx) to ckuusr.h, 7 May 99.

Implemented:
 \v(m_name)
 \v(m_sig_cd)  \v(m_sig_dsr) \v(m_sig_dtr)
 \v(m_sig_cts) \v(m_sig_rts) \v(m_sig_ri)
 \v(xfer_badpackets) \v(xfer_timeouts) \v(xfer_retrans)
ckuus4.c, 7 May 99.

Changed EVALUATE <expression> to EVALUATE <variable> <expression>.  This is
an incompatible change, but I doubt it will break any scripts, since the
old EVALUATE command was pretty useless.  But to be nice, I added an invisible
SET EVAL { NEW, OLD } command to choose the new or old syntax (default = new).
Then I added an _EVALUATE command, which is to EVALUATE as _ASSIGN is to
ASSIGN and _INCREMENT is to INCREMENT, etc.  Now we have a nice, symmetrical
set of variable-assignment operations providing a choices of whether (and
how, and how much) to evaluate the LHS and/or the RHS, to facilitate OOP-like
constructions.  ckuusr.c, 7 May 99.

Examples:

  _assign Words::\%1.count[\%2] \feval(\m(Words::\%1.count[\%2]) + 1)

can now be written as:

  _increment Words::\%1.count[\%2]

and:

  _assign complex::\%1.re \feval(\m(complex::\%1.re) + \m(complex::\%2.re))

can be:

  _evaluate complex::\%1.re \m(complex::\%1.re) + \m(complex::\%2.re)

Changed [_]{IN,DE}CREMENT, when given a variable that is not defined, to
automatically define it with a value of 0.  ckuus5.c, 7 May 99.

Integrated Jeff's PAM code.  ckuus7.c, ckufio.c, 7 May 99.

Finished SET EVAL.  ckuus3.c, 8 May 99.

Added IF { C-KERMIT, K-95, MS-KERMIT }.  ckuus6.c, 8 May 99.

Made "!" a synonym for NOT in IF conditions.  ckuus6.c, 8 May 99.

Added IF WILD <filespec> <command>.  ckuus6.c, 8 May 99.

Added ckitoa() and ckltoa() -- the opposite of atoi() and atol().
ckclib.[ch], 8 May 99.

Added \fsearch(pattern,string,start) and \frsearch() -- just like \findex()
and \rindex(), except the object to search for is a pattern rather than a
literal string.  ckuusr.h, ckuus[24].c, 8 May 99.

Fixed Yet Another Bug in \frindex(); it was misinterpreting its optional 3rd
argument.  ckuus4.c, 8 May 99.

Shadow password support from Jeff.  ckufio.c, 8 May 99.

"make linuxc" (Linux on systems that have curses but not ncurses) didn't work
because it had -lcrypt hardwired into it instead of using the trick of looking
for it first.  Made new "linuxc" and "linuxnc" (no curses at all) entries.
makefile, 8 May 99.

When adding \f[r]search() I also broke up the huge switch() statement in
fneval() into a bunch of smaller ones, but neglected to prevent them from
falling thru to the default (error) case at the end.  Fixed by Jeff in
ckuus4.c, 10 May 99.

From Martin Whitaker: Recursive directory traversal and built-in DIRECTORY
command for OS-9: ck9fio.c, ckcdeb.h, 10 May 99.

Changed ckitoa() and ckltoa() to return string pointers from a revolving 1K
buffer pool, rather than a single buffer, so that successive calls within the
same statement would return distinct pointers.  Converted lots of crufty code
mainly in the ckuus*.c routines to use ckitoa() when appropriate, like when
numbers need to be passed as function parameters in string form, e.g. as
defaults for cmnum() calls, or in calls to setgen() by client for REMOTE SET.
Also handy for debug() when you want to put a number in both the second and
third fields.  ckclib.c, ckuus[r34567].c, 10 May 99.

Discovered that DIRECTORY prints total garbage for permissions, size, and date
in Unixware 7.  Diagnosis: lstat() doesn't work in Unixware 7, even though it
does work in earlier releases.  Adding -DNOLSTAT to the Unixware 7 makefile
targets fixes it.  10 May 99.  (SCO evidently does not believe in lstat()
since it also does not work in XENIX, SCO UNIX, or OSR5.)

From Jeff: fix a typo in ckuus7.c from yesterday's changes.  11 May 99.

Added HTTP command parser.  It's completely contained in ckuusr.c within
#ifndef NOHTTP.  ckuusr.c, 11 May 99.

Added ARRAY command to collect all array ops together: DECLARE, SORT, SHOW,
etc.  Made top-level DECLARE and SORT commands invisible.  Old syntax still
works, of course.  ckuusr.h, ckuus[r5].c, 11 May 99.

Moved the array-segment-parsing code from SHOW ARRAY to a separate routine,
arraybounds().  SHOW ARRAY \&a[12:16] still works.  ckuus5.c, 11 May 99.

Added ARRAY COPY <source> <target>.  This copies an array much more quickly
than a script FOR loop.  Furthermore, either or both of the source and target
arrays can include range specifiers, so this command can be used to copy
pieces of arrays, or to create an array that is a piece of another array, etc.
A few quick tests look OK, but needs more verification.  ckuusr.c, 11 May 99.

Discovered that the following:

  $ kermit + filename arg1 arg2 arg3

would execute the file and pick up the args, as adverised, but then would say:

 "filename" - invalid command-line option, type "wermit -h" for help

Similarly, there would be a complaint if the first arg was "=".  Both fixed in
ckuusy.c, 12 May 99.

Finished ARRAY COPY.  Added ARRAY { DESTROY, CLEAR, SET, RESIZE }.  Changed
[ ARRAY ] DECLARE to accept array-name syntax consistent with the other ARRAY
commands.  Changed [ ARRAY ] SORT to allow range specification in the array
brackets.  ckuus[r7].c, 12 May 99.

Added \farraylook(array,pattern) to search an array and return the index of
the first matching element.  ckuusr.h, ckuus[24].c, 12 May 99.

Removed trailing whitespace from source file lines: ckuus[r345].c, 12 May 99.

New ckuath.c from Jeff, 13 May 99.

Removed "search" keyword from arraytab[] and fixed a type in rszarray().
ckuusr.c, 13 May 99.

Filled in HELP ARRAY and updated HELP EVAL.  ckuus2.c, 13 May 99.

Added \v(match), which contains the string that matched the pattern most
recently given to ckmatch(), e.g. by IF MATCH, \fsearch(), \farraylook(),
wildcard comparisons, etc.  But then I removed it since it turns out that most
calls to ckmatch() internally append a "*", so the result is usually more than
you expect.  What we really need is something like SNOBOL's:

  STRING ( PATTERN . RESULT )

I'll come back to this later...  ckuusr.h, ckuus4.c, 13 May 99.

Realized the arguments to \farraylook() were in reverse order from those in
all the other string-search functions -- \findex(), \fsearch(), etc -- so
reversed them.  ckuus[24].c, 13 May 99.

Discovered that top-level \&_[] array was dimensioned 1 greater than it should
have been.  Fixed in cmdini(): ckuus5.c, 13 May 99.

Fixed Yet Another Problem with Kerbang invocation: "kermit + file arg1 arg2..."
would pick up the args and execute the file OK, but then would say "arg1 -
invalid command-line argument".  Changed command-line parser to simply return
if the first argument was "+".  (I thought I fixed this problem yesterday, but
in reality I only shifted it to the right.)  ckuusy.c, 13 May 99.

Added IF LOCAL <command>.  ckuusr.h, ckuus6.c, 13 May 99.

Upped MAC_MAX from 4K to 16K for BIGBUFOK builds and from 0.5K to 1K for
other builds.  ckuusr.h, 14 May 99.

Added \v(setlinemsg) to contain the error message that was generated by the
most recent SET LINE / PORT / HOST (or TELNET or RLOGIN) command, if it failed.
ckuusr.h, ckuus[47].c, 14 May 99.

From Jeff: Move misplaced #ifdef in \v(setlinemsg) code.  ckuus7.c, 18 May 99.

The following modems had software flow-control commands defined, but were
missing the CKD_SW capability: Microlink, Telepath, Motorola X-Jack, Quickcomm
Spirit II, Megahertz AT&T V.34.  Fixed in ckudia.c, 18 May 99.

Wrapping of long filenames in Serial and CRT displays did not take the length
of the first name into account.  Fixed in dpyinit(): ckuusx.c, 18 May 99.

From Brian Tillman: Updated ckvker.com and ckcnet.h for Wollongong Pathway 3.1.
18 May 99.

From Jeff: Preserve printer settings between invocations.  ckuus3.c, 19 May 99.

From Jeff: Perform reverse DNS lookup when a numeric IP address is given and
Kerberos is available so a successful Kerberized connection can be achieved.
(Previously we skipped the reverse lookup for numeric addresses, but for
Kerberized connections we need the hostname to get the Kerberos realm.)
Added #ifdef CK_KERBEROS to the new tests.  ckcnet.c, 19 May 99.

Added missing dosort() prototype.  ckuusr.[ch], 19 May 99.

Dale Dellutri reported that in the sequence "set flow keep", "set line tta0",
"connect", the device's flow control changed when it shouldn't have.  This is
because the SET LINE code calls setflow(), and for some unknown reason the "if
(!autoflow) return;" statement in setflow() was commented out.  There's
nothing in the notes about it, nor any comment in the code.  Clearly we should
not be switching the flow control automatically if it was set to something
specific like KEEP or RTS/CTS.  Was the commenting-out done for a reason???  I
guess there's only one way to find out...  Restored the if (autoflow) test to
setflow().  But that didn't help -- it seems that setlin() was also setting
the flow control directly, without going through setflow(), in the serial
device case (there must have been some logic behind this but I don't see it
now).  Changed setlin() to call setflow() like everybody else.  ckuus[7x].c,
19 May 99.

changed cmkey() to not print "?No keywords match" if QUIET is ON.  Changed
command-file reader not to print "Command file: filename, line number" when
QUIET ON.  And when it does print "Command file:", now it also prints the
name of the active macro, if any.  ckucmd.c, ckuus5.c, 19 May 99.

Added /opt to the list of UNIX directories to search for Kermit text files.
ckuus5.c, 19 May 99.

Several weeks ago when writing a script, I wanted to send an ATI6 command to
a USR modem and the parse the results (about 20 lines of text that end with
"OK") on fly like so:

  set flag off
  set input echo on
  while not flag {
     minput 10  Blers  Retrains  Speed  OK
     switch \v(minput) {
       :1, clear input, input 2 \10, .blers := \fword(\v(input),1), break
       :2, clear input, input 2 \10, .retrains := \fword(\v(input),5), break
       :3, clear input, input 2 \10, .speed := \fword(\v(input),1), break
       :4, set flag on, break
     }
  }

I was discouraged to find that this didn't work at all (on Windows 95).  Huge
chunks of the modem's report were lost.  I looked closely at the INPUT/MINPUT
code but found nothing to explain it:  Reads are not buffered -- we do ttinc()
or coninc() to get each character and deposit it in inpbuf[] one at a time.
Therefore, reading stops as soon as we have a full match, so we have not read
ahead at all.  CLEAR INPUT simply clears inpbuf[], which contains only the
chars that INPUT read, and resets inpbp to the beginning of the buffer.
Therefore "input 2 \10" should read to the next linefeed, and there should be
no wraparound since we just cleared the inpbuf[] buffer.  But lots of stuff
(many lines at once) were being lost anyway.

So instead I did it like this (get the whole report in one gulp and then parse
it afterwards):

  output ATI6\13
  input 20 OK
  if fail end 1
  .\%x := \findex(Retrains Granted,\v(input))
  if \%x .retrains := \fword(\fsubstr(\v(input),\%x),3)
  .\%x := \findex(Blers,\v(input),\%x+16)
  if \%x .blers := \fword(\fsubstr(\v(input),\%x),2)
  .\%x := \findex(Speed,\v(input),\%x+16)
  if \%x .ospeed := \fword(\fsubstr(\v(input),\%x),2,,/)

which worked fine (so no, it wasn't a flow control problem).

Today I went back to investigate, but this time on an HP workstation with
HP-UX, and the first method worked perfectly.  I tried it on Windows with an
external USR modem and it worked perfectly too.  So either some fix that we
made in the last couple weeks cleared up the problem, or else it's something
to do with the Compaq (TAPI) Winmodem, so who cares.  So this clears away
a big item from the list.

Changed UNDEF <name> to parse but ignore text after the <name>.  This provides
a clean way to comment out a macro definition without removing it or putting
semicolons in front of each line.  ckuus6.c, 19 May 99.

Fixed a typo in yesterday's flow-control changes (comment-close typed as
*? rather than */).  setflow(): ckuusx.c, 20 May 99.

From Jeff: /NOPOSTSCRIPT switch for SET PRINTER to under previous /POSTSCRIPT
switch.  ckuusr.h, ckuus3.c, 20 May 99.

From Jeff: Updated HELP text for SET TCP REVERSE-DNS-LOOKUP for Kerberos.
ckuus2.c, 20 May 99.

From Jeff: new security.txt and telnet.txt, updated iksd.txt.  20 May 99.

Fixed some mistakes in the Compaq modem definition, and raised the max speed
parameter for Compaq and USR to 115200.  Made the maximum speed warning a
hint.  ckudia.c, 20 May 99.

Added SIG_V and SIG_I to SHOW FEATURES.  ckuus5.c, 20 May 99.

Made SET LINE messages in UNIX about access to lock or device a hint.
ckuus7.c, 20 May 99.

Added \v(textdir), the directory where the C-Kermit/K-95 text files are kept.
ckuusr.h, ckuus4.c, 20 May 99.

Added \ftablelook(), just like \farraylook() except it assumes the table is
sorted, allows array elements to have fields, requires a nonambiguous match,
and returns -2 on an ambiguous match.  ckuusr.h, ckuus[24].c, 20 May 99.

From Jeff: move a mispaced brace in setlin(): ckuus7.c, 21 May 99.

Merged copyright text into VERSION command except in K95 where it wouldn't
fit.  ckuusr.c, 21 May 99.

Made the HTTP command (not filled in yet) invisible.  ckuusr.c, 21 May 99.

Fixed a glitch in filename completion that affected UNIX but not K95:
"send ./foo<ESC>" would lose the next two name characters after "foo" in the
expansion.  cmifi2(): ckucmd.c, 21 May 99.

Moved XYB_xxx definitions from ckuusr.h to ckcker.h for NOSPL/NOICP builds.
21 May 99.

Moved all cmdlvl declarations outside of NOSPL sections.  ckuus*.c, 21 May 99.

Fixed Solaris 2.3 and 2.4 banners.  ckuver.h, 21 May 99.

Fixed TCPware "show net" display to say TCPware instead of UCX.  ckuus4.c,
21 May 99.

Fixed linux entry to accept KFLAGS from other Linux entries.  makefile,
21 May 99.

Multinet 4.2 on VMS 7.1 with DECC 6.0 needed <if.h>.  ckcdeb.h, 22 May 99.

Shuffled some #ifdefs and version numbers and redid the overlay structure to
enable building on 2.11BSD (first time in 3 years).  ckcker.h, ckcfns.c,
ckustr.c, ckustr.sed, ckubs2.mak, 23 May 99.

---Beta.07---

Added Base64 conversion routines.  ckclib.[ch], 26 May 99.

Updates from Jeff, 26 May 99.
 . Some misplaced case statements fixed in ckcnet.c.
 . Initial work on HTTP routines: ckuusr.c, ckcnet.[ch].
 . Additional PRINT switch work -- decoupling port parameter setting
   from bidirectional mode: ckuus3.c.

Added -DNOREALPATH to AT&T 3Bx and System III entries, and to all AIX entries
prior to 4.0.  makefile, 26 May 99.

Added include for inet.h to Wollongong section of ckcnet.h.  26 May 99.

Fixed a typo in the Wollongong section of the VMS build procedure.  ckvker.com,
26 May 99.

Changed PA-RISC level indicator for HP-UX 10.20; John Bigg of HP says 10.20
and up do not support PA-RISC 1.0.  makefile, 26 May 99.

Changed optimization flag for SNI 5.44 from -F to -K.  makefile, 26 May 99.

The Base-64 functions did not null-terminate their results, thus forcing the
caller to do it.  Changed them to deposit a NUL after the result (if the
buffer had room for it).  ckclib.c, 27 May 99.

Added \fb64encode() and \fb64decode().  ckuusr.h, ckuus4.c, ckclib.c,
27 May 99.

Fixed \funhexify() to return an appropriate error if called with a non-hex
string.  ckuus4.c, 27 May 99.

Fixed solaris25x25 makefile target -- it had unbalanced quotes.  However the
make doesn't work at all -- the SunLink X.25 9.x header files are broken.
makefile, 28 May 99.

In gtword() (the "token getter" of the command parser), there were a couple
places where we compared the user's keystroke with NL (== whatever '\n' is
defined to be) when we meant to be checking for LF (linefeed).  This needed
fixing for OS-9, where '\n' is CR.  This fix also applies to the Macintosh
in case C-Kermit is ever built there again.  ckucmd.c, 28 May 99.

Added a NOTTGWSIZ symbol to allow builds without CK_TTGWSIZ to test for
spurious dependencies.  In UNIX this must be used with -DNORLOGIN, since
Rlogin requires ttgwsiz().  ckcdeb.h, 28 May 99.

In the NOTTGWSIZ version, the DIRECTORY command did not list anything, and the
TYPE command referenced an initialized variable.  Fixed in ckuusr.c, ckuus6.c,
28 May 99.

A bunch of similar fixes: ckuus[r67x].c, 28 May 99.

Modernized HELP SET FILE (TYPE).  Kermit had changed so much out from
underneath it that it was positively misleading.  ckuus2.c, 28 May 99.

With the help of DJ Hagberg at Global Atmospherics, Inc, got past some of the
initial difficulties with SunLink X.25 9.xx header files.  ckcnet.h, 28 May 99.

In ckucmd.c, #include "ckcnet.h" was after the includes for ckucmd.h and
ckuusr.h, and this caused some conflicts with the SunLink header files.  Moved
it up to after ckcdeb.h and ckcnet.h, and before ckucmd.h and ckuusr.h.
Now the X.25 version builds OK on Solaris 2.6.  ckucmd.c, 28 May 99.

Added #ifndef NOCOTFMC around the code in tthang() that closes and reopens
the device, so we can disable when necessary (or not needed).  This is to see
if it helps with a problem in Unixware 2.0.3, where the TCSETAW ioctl returns
an "invalid argument" after the close/open.  ckutio.c, 1 Jun 99.

Adjusted HELP SET FILE TYPE text again.  ckuus2.c, 1 Jun 99.

Removed the spurious "?Directory already exists" message that MKDIR always
printed.  ckuusr.c, 1 Jun 99.

From Jeff, 1 Jun 99:
 . Add missing cmdate2tm prototype to ckucmd.h.
 . Adjust http prototypes in ckcnet.h.
 . Adjust some prototypes in ckuath.h.

Moved cmdate2tm() from ckucmd.c to ckutio.c, since it is highly unportable.
Made a symbol CMDATE2TM that must be defined before we can use this routine,
and defined it by default for UNIX.  Made another symbol NOCMDATE2TM to
override the default definition.  If this routine is to be used on non-UNIX
platforms, it must be copied to their ck*tio.c modules and adapted, but this
can work only when struct tm is supported.  Therefore, to make it more widely
useful, we need to define a portable abstraction.

 . Some Kerberos-realm-getting changes in ckuus7.c
 . HTTP code fleshed out ckcnet.c.

The HTTP code in ckcnet.c is not going to be easily portable.  It includes
<time.h>, which is not portable to all platforms.  Even in UNIX, there are
many varieties where it is <sys/time.h>, or has an entirely different name.
That's why I moved cmdate2tm() to ckutio.c, which already has #ifdefs to take
care of this.  This will need some serious sorting out before we go public.

Also, you refer to _timezone in http_date() but it's not defined anywhere
(at least not in SunOS).

Also, there are calls to nonportable routines like memset(), etc.

Fixed the call to http_index() in ckuusr.c to have the right number of args.

From Jeff, IKSD and Kerberos fixes:

 . syslog'ing was not being performed since the syslog flag was saved
   before the syslog was opened and then restored after it was opened.

 . syslog'ing was not being performed during login because the syslog was
   purposely turned off during login.  I assume to hide passwords.  This
   is a legitimate concern and I specificly turned off the syslog in the
   readpass() and in ckxlogin() around the password reading code.

 . When iksd was compiled with CK_PAM anonymous users would not be
   prompted for a password and would be summarily rejected.

 . corrections to yesterday's kerberos autoget ticketing.

 . Defined CMDATE2TM for K95.

ckufio.c ckuusr.c ckuus7.c ckuath.c ckucmd.c ckcdeb.h ckcmai.c, 2 Jun 99.

Changed HTTP code in ckcnet.c to check SYSTIMEH symbol (which is defined in
ckcdeb.h) before deciding which time.h file to include.  Also added some
comments and #ifdefs to HTTP code in ckcnet.c, but it will never be truly
portable in its present form.  It does, however, build OK on at least Solaris,
SunOS, HP-UX, and Linux, and presumably also in Win32 and OS/2, so it's worth
keeping.  2 Jun 99.

Added /ARRAY: switch to the HTTP command parser for INDEX.  dohttp() gets
the array letter as a new 9th parameter (NUL if none).  The action (actually
assigning stuff to the array) is filled in, but not used, in http_mkarray()
in ckcnet.c.  I guess http_index() needs to call http_mkarray()?  2 Jun 99.

Still more #ifdefs added to the SCREEN support code to allow for the case
where tputs() requires a pointer to a void function.  ckuusx.c, 3 Jun 99.

tthang() for some reason stopped working on Unixware 2.0.3.  It used to work
OK in C-Kermit 6.0, and line-by-line comparison of the tthang() code showed
no change since then.  It was following the System V path, first trying to
manipulate the modem signals (because TIOCMBIS, TIOCMBIC, and TIOCM_DTR were
defined) and failing because these ioctl's were not actually implemented
(errno 22), so then falling through to the section that gets the current
speed, saves it, sets it to 0, waits a bit, and then restores the speed.
The speed-restoring part was failing (ioctl(ttyfd,TCSETA,...)) with errno 22.
I have no idea why.  Tried "make unixware2 KFLAGS=-DPOSIX", failed miserably.
So I duplicated the BSD44POSIX speed setting code in #ifdef HUP_POSIX, which
is defined internally for non-POSIX builds (e.g. Unixware prior to 7.0) that
need to do POSIX-style hangup.  Later, the fix was verified to work on UW2.0.3
but who knows what effect it will have on 1.x or 2.1.  ckutio.c, 3 Jun 99.

Added -DNOREALPATH to Plan 9 makefile.  ckpker.mk, 3 Jun 99.

From Michal Jaegermann:

  With a separate 'libcrypt' in glibc there is also a header file
  <crypt.h> which provides a prototype for 'crypt()'.  Without including
  it a return value from crypt is losing a half of its significant bits
  with 64-bit pointers as crypt() type defaults to int.  To work around
  required "frugal" preprocessors (comments in ckcdeb.h) I added
  HAVE_CRYPT_H define in makefile flags where -lcrypt is used with Linux
  and a corresponding conditional include in ckcdeb.h

  time_t type on Linux/Alpha is long but 'tv_sec' field in 'struct timeval'
  is int.  I heard that is a POSIX requirement.  Looks to me more like a
  bug but quite likely is both.  The net effect is that using an address
  of tv.tv_sec (ckufio.c via macro, ckutio.c) where an address of time_t
  is needed results in a unaligned trap.  I bracketed these changes with
  LINUX as 64-bit apps on Sparc and on the future ia64 **may** have the
  same problem.  In any case an overhead is totally negligible so why
  not be safe.  In case ckufio.c 'ut.ut_time = time(NULL);' would likely
  work equally well but I wanted to a keep a consistent style.

  There is a bunch of unused variables (quite likely some are used with
  other defines active) but 'static char lockname[DEVNAMLEN+1]' is
  needed only with USETTYLOCK defined.  'static suftab' in ckuus3.c is
  not used by anything at all.

  Wrong format in sprintf resurfaced in some new place (ckuus4.c) and
  ckussx.c requires a bunch of prototypes from <term.h>. Undeclared
  functions always make me nervous on Alpha. :-)

Michal's patches installed in makefile, cku[ft]io.c, ckuus[34x].c, 3 Jun 99.

Added an HTTP feature-selection section to ckcdeb.h.  Since the HTTP code is
not portable, it is disabled by default except for SunOS, Solaris, Linux, and
HP-UX 10 (the places where I've built it successfully so far), and K-95, and
disabled by default elsewhere unless -DCKHTTP is given on the CC command line
or in the makefile target.  ckcdeb.h, 3 Jun 99.

Redid HTTP parser so /ARRAY switch applies to all subcommands and INDEX has
same filename operands as GET and HEAD:

HTTP [ /AGENT:<string> ] [  /HEADER:<list of strings> ] -
     [ /PASSWORD:<string> ] [ /USER:<string>  ] [  /ARRAY:<array> ] -
     { { GET, HEAD, INDEX } <remote> <local> }, -
       { PUT, POST }  /MIME:<string> <local> <remote> }

ckuusr.c, 3 Jun 99.

Cast all string args to ttol() to (CHAR *) in the http_blah() routines.
ckcnet.c, 3 Jun 99.

Tried building with -DCKHTTP in AIX 4.1.  Found that "struct tm" was not
defined.  Why not?  There was a clause in ckutio.c specifically to avoid
including <time.h> if AIXRS was defined.  I can't remember why, so I assume it
must be some peculiarity of AIX 3.x, so I included it after all for AIX41.
That makes ckutio.c compile.  ckcnet.c had the same complaint.  In this case
it was deliberately including <sys/time.h> rather than <time.h> if AIXRS was
defined.  Adding an escape clause for AIX41 here too fixed it, and now we can
build for AIX 4.1 with HTTP.  ckutio.c, ckcnet.c, 3 Jun 99.

Added -DCKHTTP for AIX41 and Unixware.  ckcdeb.h, 3 Jun 99.

Changes for COHERENT 4.2 from Fred Smith: ckcdeb.h, ckcnet.h, ckctel.c,
cku[tf]io.c, 4 Jun 99.

From Jeff: Renaming of ck_krb_ functions to make sense since they are no
longer tied specifically to Kerberos.  ck_krb_* were renamed to ck_tn_* when
Telnet-related or to ck_auth_* when used for authentication.  Fixed prototypes
in headers to be in the right place and not duplicated.  Many modules,
4 Jun 99.

A command like "take xxx" (where xxx does not exist) could give a message like:
"?Error in TAKE command file: Line too long or contains NUL characters".
That's because TAKE searches an internal "TAKE path" if the filename is not
absolute and it can't find the file in the current directory, and a file "xxx"
that is a directory happens to exist in the TAKE path.  TAKE tries to execute
the directory.  Fixed in ckuusr.c, 4 Jun 99.

If an error occured in a macro that was invoked from a command file, the
error message would erroneously identify the macro name as the command file
name.  Fixed (I think) in ckuus5.c, 4 Jun 99.

Implemented SHOW STACK for non-Macintosh platforms (it shows the Kermit
command stack -- macros & command files).  ckuus5.c, 4 Jun 99.

The stack display was a lot more informative than the previous error message,
so now we show it every time there's an error in a command file or macro,
unless QUIET is ON.  ckuus5.c, 4 Jun 99.

New Coherent 4.2 makefile entry from Fred Smith.  7 Jun 99.

Changed parsing of "help function" to allow "help func substr" or "help func
\fsubstr" or "help func fsubstr".  Also fixed "help func" to always go into
the recall buffer.  ckuus2.c, 8 Jun 99.

Moved rdigits() and chknum() from ckucmd.c to ckclib.c.  ckucmd.[ch],
ckclib.[ch], 8 Jun 99.

Added isfloat().  ckclib.[ch], 8 Jun 99.

Added a selection of floating-point functions: \ffpadd(), \ffpsubtract(),
\ffpsqrt(), etc.  Each has one or two floating-point args, and then an
optional "decimal places" (d) arg.  These functions are included if FNFLOAT is
defined at a compile time.  In UNIX at least, it is also necessary to add
"-lm" to LINKFLAGS, since the math functions are not included in the regular C
library.  Enabled this stuff in SunOS and Linux.  So far so good.  Will have
to add them in to others as we go along -- too dangerous to enable by default.
ckuusr.h, ckuus4.c, 8 Jun 99.

Added \fabsolute().  ckuusr.h, ckuus4.c, 8 Jun 99.

Peter Eichhorn verified that -DFNFLOAT works on all HP-UX releases 6.5 thru
10.20 and updated the makefile targets.  9 Jun 99.

Discovered that C-Kermit's expression evaluator did not accept '+' as a
unary operator, so added it.  ckuus5.c, 9 Jun 99.

Fixed a bug in evaluating signed "d" arg in fp functions.  ckuus4.c, 9 Jun 99.

Added rounding for fp results when d > 0.  ckuus4.c, 9 Jun 99.

Added \ffpround(), \ffpmin(), \ffpmax(), \ffpsin(), \ffpcos(), \ffptan().
ckuusr.h, ckuus4.c, 9 Jun 99.

Fixed \fmod(), \fmin(), and \fmax(), which were all broken by "goto fnend"s
that were inserted before they had a chance to write their results to the
result buffer.  ckuus4.c, 9 Jun 99.

Changed IF <, <=, =, !=, >=, and > to take floating-point operands and to
allow the <number> in "IF <number> <command>" to be a floating-point number.
ckuus6.c, 9 Jun 99.

Verified that FP builds OK on Unixware 2 and 7; updated the makefile targets
accordingly.  makefile, 9 Jun 99.

Added \v(math_pi), \v(math_e), and \v(cmdbufsize).  ckuusr.h, ckuus4.c,
9 Jun 99.

Added HELP FUNC text for all new functions.  ckuus2.c, 9 Jun 99.

A report of an infinite loop during INPUT seemed to indicate that a hack that
had been added to boost efficiency by preventing extraneous calls to gtimer()
was, in fact, having the opposite effect.  Removed the hack.  Also, if INPUT
got a NUL, it went straight back to the top of the loop, skipping the
termination checks, thus allowing the burst count to go negative; I fixed this
by having jump ahead to the termination checks in that case.  But the log
revealed that the NULs were not data, but in fact were being returned by
coninc() when read(0,&ch,1) failed with errno 19, "No such device" -- not your
normal kind of error when reading from standard input.  Changed coninc() to
return -1 rather than 0 if read() returns 0 and sets errno to nonzero.  I
don't know how to test this, since I have no idea how the guy got read() from
stdin to get error 19.  At least the changes don't seem to break anything --
login scripts still work, INPUT from the controlling terminal still works.
ckuus4.c, ckutio.c, 9 Jun 99.

Fixed bsdi2, 3, and 4, plus assorted Solaris makefile targets to pass along
KFLAGS.  makefile, 9 Jun 99.

More FNFLOAT verifying:
 . VMS/Alpha:   OK (so updated ckcdeb.h).
 . BSDI 3.1:    OK (so updated makefile targets).
 . AIX 4.3:     OK (ditto)
 . DU 3.2:      OK (ditto)
 . DU 4.0:      OK (ditto)
 . SINIX 5.42   OK (ditto)
 . Solaris 2.4: OK (ditto, for all Solaris versions).

Made sure we can still build without FNFLOAT defined, then added -DFNFLOAT
and -lm to all (non-Test) SunOS entries.  9 Jun 99.

Updated ckcdeb.h to not allow FNFLOAT if CKFLOAT not defined or if NOFLOAT
is defined.  9 Jun 99.

The CONINTB4CB business was done in only one of two places that needed it.
Added it to the other place (but more work needed here for SV/68 R3V6).
ckuus4.c, 10 Jun 99.

Changed some -FNFLOAT's to -DFNFLOAT.  makefile, 10 Jun 99.

Changes from Jeff: prototype for ck_krb_rlogin() needed #ifdefs; additional
support for SRP; new blah-export makefile targets for building with Kerberos
or SRP but without forbidden modules, etc.  ckcnet.[ch], ckuus4.c, ckufio.c,
ckuath.c, makefile, 10 Jun 99.

Added prototypes for readpass() and readtext() to ckcdeb.h, 10 Jun 99.

Defined NOHTTP automatically if OS2ORUNIX is not defined.  Now we can build
a network version again on VMS.  ckcdeb.h, 10 Jun 99.

Fixed a printf() in showstk() that had a %d with no int to print.  10 Jun 99.

Jeff noticed that packet recognition at the command prompt sometimes doesn't
work when packets contain spaces, which cause gtword() to return.  Mostly they
work anyway, because the piece of the packet before the space usually does not
correspond to a top-level command keyword or token, and so we continue
absorbing packet characters until the CR or LF is reached.  It's awkward,
however, since the command parser is beeping and spewing out error messages
all the while, and packet detection probably *could* fail if a piece of
("word" in) a packet corresponded to something legal in a command at that
point.  I made an initial stab at fixing this problem by setting a global
variable, kstartactive, whenever kstart() thinks it's in a packet, and
unsetting it whenever it gets any control character besides SOP (since control
characters can't appear within an S or I packet).  This seems to work OK.  You
can get in trouble by typing ^A at the prompt, but you get out of it again as
soon as you type another control char.  Needs testing and maybe some
refinement.  ckcnf2.c, ckucmd.c, 10 Jun 99.

Installed a new initfloat() routine to be called at startup when FNFLOAT is
defined, which determines by inspection (a) the precision of floating-point
numbers, and (b) whether printf("%f",x) does rounding.  This way we don't need
any #ifdefs or system/hardware-dependent code.  On a Sparc, we get 16 decimal
digits of precision (more like 16.25).  As a reality check, assuming 3.3219282
bits per decimal digit, that gives us 54 bits for the mantissa, allowing 10
bits for the exponent and sign, which seems about right. ckuusr.h, ckcmai.c,
ckuus[45].c, 11 Jun 99.

Changed floating-point output code to (a) create an sprintf() format string
for the desired number of decimals; (b) let sprintf() do the rounding if
initfloat() says it can; (c) set all digits beyond the precision to 0 rather
than return random digits.  ckuus4.c, 11 Jun 99.

Made \v(math_e) and \v(math_pi) return the number of digits appropriate to
the machine precision.  ckuus4.c, 11 Jun 99.

From Jeff:
 . Define FNFLOAT for K95.
 . Protect refs to fp_digits in v(math_*) functions with #ifdef FNFLOAT.
 . Changes for compatibility with new Kerberos credential cache APIs.
 . Kerberos 4 realm was not being evaluated when the credentials cache is
   not a file.
 . Fixes for the IKSD packet problems (bad code).
 . When entering CONNECT mode iks_wait() must request a response.
   Otherwise, the receipt of an initial START can result in a premature
   exit to command mode.  This is not a change in the TKO protocol.
ckuath.c, ckctel.c, ckcpro.w, ckuusr.c, ckuus4.c, ckcdeb.h, 13 Jun 99.

Fix from Jeff for fprintf(stderr,...) front end for WRITE ERROR, which has
been writing to stdout instead of stderr ever since ckxprintf() was added for
IKSD.  ckutio.c, 13 Jun 99.

Fixed WRITE and WRITELN { SCREEN, ERROR } to handle EOL as requested.
ckuusr.c, 13 Jun 99.

Put the finishing touches on floating-point functions: handle the case where
the d arg is a variable with an empty value; fix HELP FUNC to handle ambiguous
keywords better, etc.  ckuus[245].c, 13 Jun 99.

Checked to make sure that gtword() was calling kstart() only if COMMAND
AUTODOWNLOAD was ON.  It was.  ckucmd.c, 13 Jun 99.

Minor code rearrangement in zvuser() to squelch "statement not reached"
warnings in non-Kerberos builds.  ckufio.c, 13 Jun 99.

Added -DFNFLOAT to NeXTSTEP targets; -lm was not needed in this case.
makefile, 13 Jun 99.

Added a status indication to SHOW CONNECTION (active, closed, or unknown),
which is obtained from calling ttchk().  ckuus3.c, 13 Jun 99.

Started Adding  new general-purpose file i/o commands:

  FILE { OPEN, CLOSE, READ, WRITE, REWIND, LIST } [ switches ] <channel> ...

These are parsed and executed if CKCHANNELIO is defined (it isn't defined yet
except if you "make blah KFLAGS=-DCKCHANNELIO).  Non-UNIX platforms need
z_xxx() routines filled in.  The idea is to allow multiple open files at once,
in any combination of read/write/append mode, referred to by their channel
number, which is assigned by FILE OPEN.  It works, but is not finished --
still need to:

 . Add more robustness to parser.
 . Make execution (esp. of READs) more efficient.
 . Pass error codes / messages back upon failure.
 . Put prototypes in header files.
 . Hook into IF OPEN command.
 . Document the API.
 . Document the commands.
 . Find out how to reasonably set Z_MAXCHAN in UNIX & elsewhere.
 . Add HELP text.
 . Test test test.

For now I'm leaving CKCHANNELIO undefined so people can build the current
sources normally without noticing it.  ckuusr.h, ckcker.h, ckuusr.c, ckuus7.c,
ckufio.c, 13 Jun 99.

Fixed \v(math_pi) and \v(math_e) to NUL-terminate themselves; when will I
learn to remember that strncpy() can't be trusted to do this...  ckuus4.c,
14 Jun 99.

From Jeff: IKSD should not request the client to stop processing Kermit
packets simply because it is entering server mode.  ckcpro.w, 14 Jun 99.

From Jeff:
 . make \v(authstate) work for the client side connection
 . added \v(authtype) so a script can determine which method is being
   used to authenticate with the host.
ckuusr.h ckuus4.c ckuath.c, 14 Jun 99.

More work on the FILE command:

 . Added more robustness to parser.
 . Passed error codes / messages back upon failure.
 . Put prototypes in header files.
 . Documented the commands in ckermit2.txt.

So far only on SunOS.  ckcker.h, ckuusr.h, ckuus7.c, ckufio.c, 14 Jun 99.

Added "fi" as abbreviation for "finish", since "file" introduced a conflict.
ckuusr.c, 15 Jun 99.

Added #include <time.h> for SV68R3V6.  ckutio.c, 15 Jun 99.

Added some preprocessor tests for maximum number of open files: OPEN_MAX,
FOPEN_MAX, etc.  ckufio.c, 15 Jun 99.

Got z_getpos() working and improved the FILE STATUS display.
ckufio.c, 15 Jun 99.

Changed sv68r3v6 target to use wermit rather than xermit, since the xermit
built lost its mind when escaping back from CONNECT.  makefile, 16 Jun 99.

Added FOPEN, FREAD, FWRITE, FCLOSE, etc, as shortcuts for FILE OPEN, etc.
ckuusr.[ch], 16 Jun 99.

Added \v(filemax) and \v(fileerror).  ckuusr.h, ckuus4.c, ckufio.c, 16 Jun 99.

Straightened out parsing of read and write filenames.  ckuus7.c, 16 Jun 99.

Got READ/WRITE mode working.  ckufio.c, 16 Jun 99.

Made it possible for FREAD /CHAR and FWRITE /CHAR to handle NUL bytes.
ckuus7.c, ckufio.c, 16 Jun 99.

Fixed unguarded references to VN_FERR and VN_FMAX in ckuus4.c, 17 Jun 99.

Added EXEC command for UNIX only under #ifdef CKEXEC.  Like RUN, but overlays
C-Kermit with the given program.  Might be useful for who knows what -- PPP
dialing maybe?  ckcdeb.h, ckuusr.[ch], ckuus[25].c, ckufio.c, ckcplm.txt,
ckermit2.txt, 17 Jun 99.

Added "(R)" "(W)" "(RW)" "[EOF]" etc to FLIST display.  ckuus7.c, 17 Jun 99.

Added file functions:
  \f_status(channel)     = 0 if not open; OPEN flags (1-7) if open.
  \f_pos(channel)        = File pointer.
  \f_handle(channel)     = File descriptor (UNIX).
  \f_eof(channel)        = 1 if at EOF, 0 if not at EOF.
  \f_getchar(channel)    = FREAD /CHAR.
  \f_getline(channel)    = FREAD /LINE.
  \f_getblock(channel,n) = FREAD /SIZE:n.
  \f_putchar(channel)    = FWRITE /CHAR.
  \f_putline(channel)    = FWRITE /LINE.
  \f_putblock(channel,n) = FWRITE /STRING.

Removed all vestiges of BINREAD from code.  ckuus[r6].c, 17 Jun 99.

Changed FILE READ to allow variable name to be omitted, in which case it
just prints what it reads.  ckuus7.c, 17 Jun 99.

Added another arg to z_in() so allow length of buffer to be specified
separately from number of bytes to read.  ckcker.h, ckufio.c, ckuus[47].c,
17 Jun 99.

Documented the new file i/o API, plus the new z_exec() function.  ckcplm.txt,
17 June 99.

Made sure the code builds OK without CKCHANNELIO on HP-UX 10.20 and Linux.
Then tried building with CKCHANNELIO on HP-UX (non-ANSI compiler) and Linux
(ANSI).  It does, a good sign...

File i/o code verified on HP-UX 8.00, NeXT, ...  Since it uses <stdio.h>
features like fopen()/fread()/fwrite()/fclose()/etc, which have been used in
the mainline code since Day One for opening and reading command files, I'm
assuming it will be portable to all UNIXes, and so enabled it by default (i.e.
unless NOCHANNELIO is defined) for UNIX in ckcdeb.h.  Also moved the code to
ckvfio.c for VMS, where it built with no modifications (except I had to define
Z_MAXCHAN "by hand" since DECC defines OPEN_MAX as 5 (!).  Meanwhile, Jeff
copied the code to ckofio.c, where it built with no changes, suggesting we
should put it in a non-system-specific module...  So I moved the z_blah()
material from ckufio.c to ckuus7.c, and removed it from ckvfio.c and ckofio.c,
and took care of any difference in ckcdeb.h, and enabled the code for UNIX,
K95, VMS, and VOS.  18 Jun 99.

Added HELP text for FILE commands and functions.  ckuus2.c, 18 Jun 99.

Added \v(math_precision).  ckuusr.h, ckuus4.c, 20 Jun 99.

OPEN !READ, READ ... was broken on VMS.  I don't see how it ever could have
worked -- the code to handle it was missing from rinfill().  Fixed in
ckvfio.c, 20 Jun 99.

Disallowed FILE OPEN 0 foo.bar, which worked and assigned the channel number
for foo.bar to the macro called "0".  Too confusing.  No numbers allowed here
from now on.  ckuus7.c, 20 Jun 99.

Added support for Multitech MT5634ZPX modem.  ckuusr.h, ckudia.c, 21 Jun 99.

Fixed a typo in the FREAD/FWRITE parser that could result in an infinite loop.
Also fixed a mistake in FREAD parsing that could make it ignore the target
variable.  ckuus7.c, 21 Jun 99.

Added FILE OPEN /BINARY.  ckcker.h, ckuus[27].c, 21 Jun 99.

On some platforms OPEN_MAX or FOPEN_MAX (from which we derive CKMAXOPEN) is
defined as a ridiculously small number so dimensioning our file array to
(CKMAXOPEN-ZNFILS-5) fails at compile time because the result is negative.
However, this tends to be a meaningless definition.  For example, DECC 6.0 for
VMS defines FOPEN_MAX to be the "minimum number of files that the DEC C
compiler for your system guarantees can be open simultaneously", which turns
out to be something like 5 when we all know that VMS will let you open
hundreds of files.  HP-UX 7.05 also has a very small number for this.  Since
we can't use relops in proprocessor directives (not portable), I changed the
code to allocate the file array dynamically to a minimum length of 16.  Let
the code fail at runtime if no more files can be opened.  ckcdeb.h, ckuus7.c,
21 Jun 99.

Updated k95 Windows startup flags help text from Jeff.  ckuusy.c, 22 Jun 99.

Changed z_in() section that reads lines to do its own buffering.  z_in() now
contains three alternative methods for reading lines, chosen by #ifdef.  Ran
exhaustive trials and found no significant difference among the three, so I
went back the original and simplest one: fgets().  ckuus7.c, 22 Jun 99.

Installed a fix for Tru64 UNIX 5.0 from Farrel Woods at DEC; the utmp struct
used 64-bit times, but time() expected a 32-bit one.  ckufio.c, 22 Jun 99.

Added code to UNIX sysinit() to try getting the system configured open
file limit from sysconf(_SC_OPEN_MAX), called only if _SC_OPEN_MAX is defined.
Seems harmless enough, and works on at least SunOS and HP-UX 10.  ckutio.c,
ckuus[57].c, 22 Jun 99.

Added a cast to the malloc() for the array of file structs in z_open(),
plus assorted minor cleanups.  ckuus7.c, 23 Jun 99.

Peter E convinced me that the d=0 format for \ffpxxx() functions was pretty
useless -- who cares what the "default precision" of the underlying C libary
"%f" printf format is?  So I changed it to give the maximum precision of the
hardware.  So, for example, when the precision is 16 digits, \ffpdiv(10,3)
gives 3.333333333333333 instead of 3.333333.  But in making this change I
found that rounding is not done in many cases when d=0.  But it wasn't done
before either.  ckuus4.c, 23 Jun 99.

Kerberos changes from Jeff: ckuath.[ch], ckuus7.c, 23 Jun 99.

Peter E pointed out that server returns full pathname in ACK to F packet
when DISABLE CD is in effect.  Fixed in ckcpro.w, 24 Jun 99.

Fixed a typo in the new MT5634 modem support.  ckudia.c, 24 Jun 99.

Detlev Knorpp discovered that the sequence: "log packets" and then "log
connections" and then file transfer (in that order) makes C-Kermit dump core.
This was because of a typo in diaopn(), in which we closed the packet log
instead of the connection log, prior to opening the new one.  It seems that
logpkt() calls zsoutx() to write a packet-log record, but neither one of these
routines calls chkfn() to make sure the log file is actually open -- they just
assume it is.  Fixed the typo and had logpkt() call chkfn().  ckuus4.c,
ckcfn2.c, 24 Jun 99.

Added FCLOSE ALL to close all open files and FSEEK <channel> EOF to move the
file pointer to the end of the file.  ckuus7.c, 24 Jun 99.

Peter E has been reporting a bug in which FREAD would get an error the first
time it's called on an open file, but then works on all subsequent calls until
EOF.  This was because, for some reason on his HP-UX 6.5 and 7.05 systems, the
following sequence:

  errno = 0;
  x = fgets(buf,len,file);
  if (errno) ...

sets errno to something bizarre like ENOTTY, and z_in() was returning a
failure code in all cases if errno was nonzero after the fgets() or fread().
I changed the code to return an error only if fgets() or fread() actually
failed to return any characters.  Also added debugging statements to catch
when this happens.  ckuus7.c, 24 Jun 99.

Looked into getting \ffpxxx() functions to round when d=0.  Not a chance.
The reason: The digit after the last significant digit is garbage, so it can't
be used to round the last significant digit.  ckuus7.c (comments only),
24 Jun 99.

From Jeff:
 . Changes to allow K95 to be built with NO_ENCRYPTION
 . Correction to ckuus7.c.  ckferror() was being called with the wrong
   variable.
 . Fixes for SRP authentication problems.
ckcdeb.h ckuath.c, ckctel.c, ckuus7.c, 25 Jun 99.

The SRP business is as follows:

Several years ago it was discovered that there was an operating system whose
telnet server did not properly follow the telnet protocol.  In particular,
this OS vendor did not terminate its subnegotiations properly.  Instead of

 IAC SB <option> <data> IAC SE

the vendor sent

 IAC SB <option> <data> SE

Now, prior to implementing authentication and encryption there were no
subnegotiations that would send 8-bit high data.  So adding a check to enable
Kermit to work with this broken server was not a problem.  As it turns out,
when encryption or authentication is being used the chance for the <data> to
contain an SE byte is very likely.  Hence, the string that was supposed to be
128 bytes was truncated at 45 bytes and the rest of the string was treated as
terminal data.  SRP didn't work and you got garbage.  This check had already
been removed for builds with encryption.  I have no removed this check for all
builds.  (End quote)

FILE OPEN channels were not being recycled.  Fixed in z_open(): ckuus7.c,
25 Jun 99.

The SHOW STACK command, which is now also implicitly invoked any time we get a
command error, was not handling the FOR, WHILE, [X]IF, and SWITCH commands as
expected, since these are implemented as 2-level internal macros, in which we
stuff the \%0..9 values from 2 levels up.  The stuffing can not change without
breaking existing scripts, so I added a hack to shostack() to test for these
four cases and make the appropriate substitutions in the display.  ckuus5.c,
25 Jun 99.

Changed ?-help for switches to put a colon at the end of any switch that takes
an arg.  kwdhlp(): ckuus7,c, 25 Jun 99.

VMS C-Kermit 7.0 Beta.07 in server mode would crash if given a REMOTE HOST
command.  It doesn't crash any more, and responds correctly -- I must have
fixed it on June 20th when I fixed the broken OPEN !READ / READ sequence.

Made DELETE /QUIET not print error messages if file doesn't exist.  dodel():
ckuus6.c, 25 Jun 99.

Fixed HELP FUNC parsing once and for all.  Now you can type "help func" by
itself, or (e.g. for \fsubstring()) "help func" followed by "sub", "fsub",
"sub()", "fsub()", "\fsub", "\fsub()", "\\fsub()", "\\fsub", etc etc, without
getting spurious error messages or having to confirm more than once, and a
proper error message is printed if there is no match.  ckuus2.c, 25 Jun 99.

Added x.xxMB (or GB) to DIR /HEADING summary.  26 Jun 99.

Added /BYTE and /LINE switches to FILE SEEK, so now you can FSEEK to a
particular line in a file.  ckuus7.c, 26 Jun 99.

Added FILE COUNT / FCOUNT to return the number bytes or lines in an open file
(without disturbing its current position).  ckuusr.[ch], ckuus7.c, 26 Jun 99.

Added new functions & variables:
 . \f_line(chan) to return line number if known.
 . \v(filecount) to return extern int z_filcount.
 . \fleft() for convenience and symmetry with \fright().
ckuusr.h, ckuus[47].c, 26 Jun 99.

Added /SIZE:n /LPAD:c /RPAD:c switches to FILE WRITE.  ckuus7.c, 26 Jun 99.

Added \f_ermsg(code).  ckuusr.h, ckcker.h, ckuus[47].c, 27 Jun 99.

Added relative seeks: FSEEK { /LINE, /BYTE } <channel> {+,-}<number>.
ckuus7.c, 27 Jun 99.

Renamed FILE-related variables to \v(f_xxx).  ckuus4.c, 27 Jun 99.

Updated help text for FILE commands and functions.  ckuus2.c, 27 Jun 99.

Checked Dale Dellutri's report about SET FLOW KEEP not working in VMS.
Actually, it was working, but the order in which SET LINE/PORT/HOST and SET
FLOW are given is now signicant, where it wasn't before.  27 Jun 99.

Added TRACE [ { /ON, /OFF } ] { ASSIGNMENTS, COMMAND-LEVEL, ALL }.  When ON,
this prints a message every time the value of any variable changes or the
command level changes.  ckuusr.[ch], ckuus[256].c, 27 Jun 99.

From Jeff: Fix to bogus rewind() call, fixes to SSL support & some ttclos()
calls without args.  ckuus7.c, ckutio.c, 28 Jun 99.

Added NOSTAT for VOS.  ckcdeb.h, 28 Jun 99.

Added a quick & dirty adaptation of SET SERVER IDLE-TIMEOUT to non-K95 builds
(K95 already had it).  It's quick & dirty because it can't coexist with SET
SERVER TIMEOUT.  ckcmai.c, ckcfn2.c, ckcpro.w, ckuus[235].c, 28 Jun 99.

Added RETURN value to TRACE ASSIGNMENTS.  ckuus6.c, 28 Jun 99.

While looking at RETURN, discovered that it set success=1 when given a value,
and success=0 when not given a value, which makes no sense.  Changed it not to
mess with success.  ckuus6.c, 28 Jun 99.

Added SET TRANSFER INTERRUPTION { ON, OFF }.  Refers to file-transfer
interruption in local mode, as opposed to SET TRANSFER CANCELLATION, which
refers to remote mode.  ckuusr.h, ckcmai.c, ckuus[234x].c, 28 Jun 99.

From Jeff:

 . Added ckgetfqhostname() to retrieve the fully qualified hostname
   from a partial name.  This is done by performing a DNS lookup and
   immediately performing a reverse lookup on the first IP address in the
   list.

 . Warning: if the function is called on an alias such as "cunix" the
   IP address in the list when calling ckgetfqhostname() may not match
   the IP address in the list when netopen() calls gethostbyname().
   If the function is going to be used as a general call in setline()
   then the result of this function must replace the hostname the user
   typed in the parse buffer.  I have not made this change as I only need
   it to check the realm of the host and we assume that all of hosts
   sharing a common alias will have the same realm.  (although, I am sure
   somebody will prove us wrong.)

 . Added check for Ctrl-C in tn_wait().

ckcnet.c ckuus7.c ckcnet.h ckctel.c, 29 Jun 99.

Removed #ifdef CK_CURSES from around prototypes for ck_cls() and friends,
since these are referenced in the code even when CK_CURSES is not defined,
in which case dummies are provided.  ckuusr.h, 29 Jun 99.

Peter E reported that if HP-UX C-Kermit was in server mode on a serial port
which had been dialed in to, and the user hung up without sending BYE, and
FINISH was disabled, that C-Kermit would go into a loop forever (tying up the
port and, if the debug log was on, filling up the disk).  Diagnosis: (1) the
read() in myfillbuf() SVORPOSIX case returned 0, and so myfillbuf() returned 0
too; (2) mygetbuf(), which called myfillbuf(), returns -2 if myfillbuf()
returns 0; (3) ttinl(), which calls mygetbuf() through the myread() macro,
passes the -2 up to rpack(), which passes it up to input(); (4) input()
interprets -2 (correctly) as "Ctrl-C was typed" and returns 'q' to proto();
(5) proto() says "oh no you don't -- quitting is disabled" and goes back to
its read loop, and (6) the process repeats forever.

How to fix?  First, myfillbuf() should not return 0 if read() returns 0,
because the device was conditioned to return at least 1 byte with (in the
SVORPOSIX case) VMIN > 0, VTIME = 0, and O_NDELAY off.  That is, the read() is
blocking and therefore a 0 return must indicate connection loss or other
unrecoverable error, EVEN IF errno is 0 after the read (which it is in this
case).  Therefore (at least SVORPOSIX) myfillbuf() should return -3
(connection lost) if read() returns 0.  In the FIONBIO case, myfillbuf()
should also never return 0.  And the same is true in the non-SVORPOSIX /
non-FIOBIO case.  In every case the read() is blocking, so should never
return 0.  So I made every instance of UNIX myfillbuf() return -3 if the read
returns 0, except in the Kerberos, SSL, and other cases, which I'm not sure
about.  ckutio.c, 29 Jun 99.

Second, UNIX mygetbuf() had a mistake:

  my_count = myfillbuf();
  if (my_count <= 0) { my_count = 0; ...; return((my_count < 0) ? -3 : -2); }

So it would never return -3 (except in the network case, which had a special
check).  This was fixed by copying my_count to another variable (x), and then
checking x in the return() clause.  ckutio.c, 29 Jun 99.

Third, even when ttinl() returns -3 to rpack(), rpack() was changing it to
-2 before passing back up if FINISH was disabled.  What a mess...  ckcfn2.c,
29 Jun 99.

Fourth, now that -3 passed all the way up the line, what does input() do with
it?  It treats -2 and -3 the same, translating them BOTH to (pseudo) packet
type 'q' (lower case) so the protocol engine can't tell the difference.  So
now we have to either (a) make a new pseudopacket type to indicate connection
loss, or (b) manage yet another global flag.

But wait, there already is one -- 'interrupted' is set by rpack() if ttinl()
returns -2.  Therefore, whenever the input to the state machine is 'q', but
interrupted == 0, we must have connection loss.  Or an idle timeout.  OK, so
two flags...  The code to check these flags was added to the relevant <*>q
cases in the protocol engine.  ckcpro.w, 29 Jun 99.

That should do it...  But note that all this is necessary only when (a) read()
returns 0 but does NOT set errno, AND (b) the client hanging up does cause a
SIGHUP signal -- Kermit already catches both of those cases.  However, the
logs show that (a) and (b) are indeed the case at Peter E's site.

Dat Thuc Nguyen noticed that a closing bracket was not required on a
single-line macro definition; e.g. "def xx { echo foo" was accepted and
actually worked.  Of course ANYTHING should be accepted as a macro definition.
But an error should occur when attempting to execute a malformed macro.  Fixed
in dodef(), ckuus6.c, 29 Jun 99.

Peter E confirms yesterday's changes (and SET SERVER IDLE-TIMEOUT) work OK
on his HP-UX systems.  30 Jun 99.

Moved UNIX SIGHUP arming from conint() to sysinit() so hangups can be caught
earlier.  ckutio.c, 30 Jun 99.

Fixed FILE COUNT to check return code from z_count().  ckuus7.c, 1 Jul 99.

Added a makefile target for DG/UX 5.4R4.20.  makefile, ckuver.h, 5 Jul 99.

FSEEK /LINE \%c EOF followed FSEEK /LINE \%c -1 failed because Kermit didn't
know the current line number.  I changed FSEEK /LINE <channel> EOF to set the
resulting line number.  ckuus7.c, 5 Jul 99.

Added a new error code, FX_LNU = Current line number unknown, for use with
relative line seeks, and changed z_getline() to return it.  ckuus7.c, 5 Jul 99.

Changed FCLOSE ALL to not fail or print a message if no files were open.
Changed FCLOSE ALL to fail if an open file could not be closed (but still
close all the other ones that could be closed).  ckuus7.c, 5 Jul 99.

Added /RELATIVE /ABSOLUTE switches to FILE SEEK, to force relative or absolute
seeking, irrespective of the format of the number.  ckuus7.c, 5 Jul 99.

Added /LIST and /NOLIST switches to FILE COUNT to force display or suppression
of the count.  /QUIET is a synonym for /NOLIST.  ckuus7.c, 5 Jul 99.

Added askmore() to FILE LIST.  ckuus7.c, 5 Jul 99.

Updated HELP FILE texts and fixed HELP FILE COUNT, which was broken.
ckuus2.c, 5 Jul 99.

Improvements to method for getting local host name in K95 from Jeff.
ckcnet.c 6 Jun 99.

Added some minor speedups to FREAD /LINE, FSEEK /LINE, and FCOUNT /LINE.
ckuus7.c, 7 Jun 99.

There was no prohibition against seeking before the beginning of a file, which
could lead to some interesting problems in script loops (e.g. to read a file's
lines in reverse order).  Now it fails silently.  ckuus7.c, 7 Jun 99.

From Jeff:

  I have made the gethostbyname(NULL) call the default in getlocalipaddr().

  I have added DNS SRV record lookups.  This is conditionally compiled with
  CK_DNS_SRV.  If you do not want to compile using it define NO_DNS_SRV.  The
  changes in ckuus7.c from port numbers to service strings is to allow the
  DNS_SRV code to work by default.  I have made appropriate changes to
  netopen() to ensure that each service will be translated to a port number
  even if getservbyname() is not supported.

  Now when you telnet / set host to (e.g.) watsun, the DNS SRV query is:

    _telnet._tcp.watsun

  If a response arrives we use the first host and ignore the rest (it was too
  much work to allow a list of host:ports to be specified).

  I did not need to add any libraries to allow compilation on watsun.  Linux
  requires -lresolv for the res_search and dn_expand functions.

ckcdeb.h ckcnet.h ckcnet.c ckuus7.c ckuath.c makefile, 11 Jul 99.

  Should there be a SET command to control whether this code is used?
  Time will tell...

Fixed a few mistakes (e.g. "out" used as variable and label in same function)
and non-portable constructions (like const and strdup()) in the above.
ckcnet.c, 11 Jul 99.

The June 29th changes to catch communications disconnect were making an
spurious error message ("error 0") come out if you logged out from the remote
while in CONNECT mode.  Commented out the no-longer needed code.  ckucns.c,
ckucon.c, 11 Jul 98.

Rearranged code in the HELP FUNC parser to suppress some harmless compiler
warnings.  ckuus2.c, 11 Jul 98.

Added "--nointerrupts" command-line option, equivalent to "set command
interruption off" + "set suspend off".  This also required changing UNIX
connoi() to set SIGTSTP to SIG_IGN instead of SIG_DFL.  I wonder why it was
SIG_DFL in the first place -- kind of defeats the purpose of "set suspend
off"...  ckuusr.h, ckuus[5y].c, 11 Jul 99.

Since Jeff's changes were rather drastic, tried building today's version on:
 . SunOS/gcc: OK
 . SunOS/cc: Non-ANSI compilations need #ifdefs for "const", then OK.
 . Solaris 2.5.1/gcc: Needed -lresolv added to LIBS, then OK.
 . Solaris 7/gcc: OK.
 . HP-UX 10.20 bundled compiler: OK after non-ANSI changes.
 . HP-UX 10.20 ANSI compiler: OK.
 . HP-UX 8.00 non-ANSI: OK.
 . VMS 7.1 / UCX: HEADER type not defined, C_IN not declared, etc.
 . Linux RH 5.2: OK after adding -lresolv to linuxa target.
 . SINIX 5.42: Bombs out with errors in <arpa/nameser.h>.
 . Unixware 7: OK after adding -lresolv (also for all other Unixware targets)
 . BSDI 3.1: OK.

Defined NO_DNS_SRV for VMS.  ckcdeb.h, 11 Jul 99.

Added -DNO_DNS_SRV to SINIX targets; added -lresolv as indicated above.
Makefile, 11 Jul 99.

Added -DNO_DNS_SRV to HP-UX 5.00, SCO Xenix, and Motorola sv68* targets.
Makefile, 12 Jul 99.

Checked DNS business on FreeBSD 3.1 -- It's OK.  12 Jul 99.

Added FSEEK <channel> { /LINE, /CHAR } LAST, meaning to seek to the final
line or character in the file.  ckuus7.c 12 Jul 99.

Added associative arrays.  ckuusr.h, ckuus[24].c, 12 Jul 99.

Fixed typo in -DNO_DNS_SRV addition to Motorola SV/68 makefile targets.
13 Jul 99.

Added an argument to sh_sort() to allow specification of an optional second
array to be sorted in parallel with the first, and changed the interpretation
of the final argument from "0 = caseless, nonzero = case sensitive" to
"0 = alpha/caseless, 1 = alpha/case-sensitive, 2 = numeric".  Numeric sorts
work for both integers and floating-point numbers, or any mixture.
ckclib.[ch], ckcfns.c, ckuus[4567].c, 13 Jul 99.

Added a second argument to isfloat() to say whether the entire argument string
must be a floating-point number (flag = 0), or to terminate on the first
illegal character (flag = 1, works like scanf()).  ckclib.[ch], ckcfns.c,
ckuus[4567].c, 13 Jul 99.

Changed SORT command to have a /NUMERIC switch and to allow (but not require)
specification of a second array to be sorted in parallel with the first.
ckuusr.h, ckuus[27].c, 13 Jul 99.

Changed addmac() and delmac() to treat associative array names with case
sensitivity, unlike all other macro names, which are case independent.
ckuus5.c, 13 Jul 99.

FOR, WHILE, and SWITCH each defined BREAK and CONTINUE internally, but then
did not undefine them upon completion.  Tried undef'ing them in the built-in
FOR, WHILE, and SWITCH definitions, but this caused trouble with the script
demo torture test, so backed off.  Anyway, now the demo test works fine, even
after all the recent changes with macros & sorting.  13 Jul 99.

Some ckcnet.c changes from Jeff.  13 Jul 99.

Defined NO_DNS_SRV for VOS and AOS/VS.  Makefile, 14 Jul 99.

Discovered that conint() and connoi() were being called all over the place in
a rather undisciplined fashion, and furthermore that in many places, a front
end for them, setint(), was being used instead.  Replaced all calls to
conint() (except, obviously, in the interrupt handler itself) by calls to
setint(), and changed setint() to honor the cmdint and suspend flags in
setting the SIGINT and SIGTSTP traps.  This should allow any combination of
SET SUSPEND {ON,OFF}, --noint, and SET COMMAND INTERRUPT {ON,OFF} to work
right and consistently.  ckcmai.c, ckcpro.w, ckuus[456x].c, 14 Jul 99.

Added some ansification to the nxt*() declarations to shut up overzealous
compilers about the funcptr = nxt... assignments.  ckcfns.c, 14 Jul 99.

Added #include <time.h> for SCO 3.2v4.x.  I wonder why this wasn't needed
in Beta.07?...  ckutio.c, 14 Jul 99.

Removed -DDCLFDOPEN and -DDCLPOPEN from SCO 3.2v4.x makefile targets -- not
only are they not needed (because fdopen() and popen() are declared in
<stdio.h>), but Kermit's internal declarations conflict with the SCO <stdio.h>
prototypes (because of "const").  Makefile, 14 Jul 99.

Made sure that CK_DNS_SRV was not defined if TCPSOCKET was not also defined.
ckcdeb.h, 14 Jul 99.

Added a forward declaration for ck_termset() in the non-ANSI case.
ckuusx.c, 14 Jul 99.

Added {CK,NO}_DNS_SRV display to SHOW FEATURES.  ckuus5.c, 14 Jul 99.

After today's changes, the following SCO 3.2v4.2 builds are OK again:
sco32v4 sco32v4ns sco32v4net sco32v4gcc sco32v4netgcc.  Also builds fine
on SCO OSR5.0.5:  sco32v505 sco32v505net sco32v505gcc sco32v505netgcc.

Added SET DIAL TEST { ON, OFF }, to test all dialing features without actually
dialing (phone number conversion, DIAL macro, retries, pauses, etc).  ckuusr.h,
ckuus6.c, 14 Jul 99.

Moved invocation of DIAL macro from lookup time to dial time, so it is
applied to each number that is dialed, when it is dialed.  ckuus6.c,
14 Jul 99.

Added \v(dialcount), to be used inside DIAL macro -- it tells the number of
the current DIAL attempt.  ckuusr.h, ckuus4.c, ckudia.c.  14 Jul 99.

SET DNS-SERVICE-RECORDS from Jeff.  ckuusr.h, ckuus[34].c, ckcnet.c, ckuath.c.
14 Jul 99.

Moved {CK,NO}_DNS_SRV setting from ckcdeb.h to ckcnet.h, because it needed to
be deferred until we are absolutely sure we know whether TCPSOCKET is defined.
14 Jul 99.

From Jeff: Attempt to initialize the Kerberos principal names from the current
cache file, if any.  ckcnet.c, ckuat*.*, etc, 15 Jul 99.

Discovered some bugs in \faaconvert() when running it on large arrays: (a) the
code assumed all members of the same associative array would be contiguous,
when in fact it is possible for non-members to insert themselves; (b) some
junk was getting appended to long element names.  The latter was because VNAML
was hardwired at 64 but element names built from long filespecs were much
longer than that and overwrote memory, oops.  Fixed by (a) increasing VNAML
(to 4096 for BIGBUFOK builds, 256 for others) and (b) making dodef() check the
length of the name before copying it into the variable-name buffer.  ckuusr.h,
ckuus6.c, 15 Jul 99.

From Peter E: Set the dialcount variable earlier, so it is in sync with
the dial try number reported to the user.  ckuus6.c, 15 Jul 99.

From Jeff: More Kerberos additions.  In particular a new feature to allow
Kermit's TGT getting to be used for K5 even for sites that do not support K5,
to allow deployment of scripts that request K5 and K4 tickets without a scary
message for the user.  When the upgrade takes place the K5 support will just
work without a need to update the scripts.  ck_crp.c, ckuath.h, ckuath.c,
ckcnet.c, ckuusr.h, ckuus7.c, ckuus3.c, ckuus2.c, 15 Jul 99.

Took "--noint" command-line keyword out of the CK_LOGIN section.  ckuusy.c,
16 Jul 99.

connoi() didn't work at all on platforms System V signal handling, notably
Solaris and SCO UNIX 3.2v4.  The first SIGINT would be ignored, the second one
would be caught by the shell, which would kill Kermit.  Fixing this required a
complete overhaul of the UNIX versions of connoi() and conint(), plus some
further improvements in setint().  As a side benefit, the new ones are a lot
simpler.  ckuusx.c, ckutio.c, 16 Jul 99.

Partial completion and ?-help were broken when given in a directory segment of
path leading up to a filename.  This seems to have been broken since the
introduction of nzxpand() in Beta.04.  Fixed in cmifi2(): ckucmd.c, 16 Jul 99.

The RESET command didn't call cmcfm().  Anyway it was pretty useless so I made
it invisible -- no sense cluttering up valuable top-level ? real estate with
it.  ckuusr.c, 16 Jul 99.

Added #include <errno.h> for CKCHANNELIO material for VMS. ckuus7.c, 17 Jul 99.

A round of preliminary builds:
 . SunOS/gcc - ok.
 . SunSO/cc - ok.
 . VMS nonet DECC - ok.
 . VMS UCX DECC - ok.
 . VMS TGV DECC - ok.
 . HP-UX 10.20 non-ANSI - ok.
 . HP-UX 10.20 ANSI - ok.
 . SCO 5.0.5B, all four builds - ok.

Discovered that Ctrl-\ given to UNIX C-Kermit while it's starting makes it
dump core.  Added signal(SIGQUIT,SIG_IGN) to sysinit().  ckutio.c, 17 Jul 99.

Discovered that in the Solaris version, \v(ipaddr) fails, so added
-DNO_DNS_SRV and removed -lresolv from solaris2xg target.  But that didn't
help.  Undid changes to makefile and added a new symbol, CKGHNLHOST, which
means to get the local host IP address the old way (by calling gethostname(buf)
and then gethostbyname(buf), rather than gethostbyname("") and included this
symbol in all Solaris targets.  ckcnet.c, ckuus5.c, makefile, 17 Jul 99.

Discovered the Solaris version would dump core if told to "show variables",
when trying to display the \v(textdir) variable.  Failed to check pointer for
nullness.  ckuus4.c, 17 Jul 99.

Moved CKGHNLHOST definition to ckcnet.h.  Had to define it for:
 . Solaris
 . Unixware
 . Sinix / Reliant
 . AOS/VS

Due to compilation errors in system header files, had to define NO_DNS_SRV for:
 . HP-UX 5.00 through 8.00
 . Ultrix (all versions)
 . NeXTSTEP (all versions)

Had to add -lresolv to:
 . Some Linuxes but not others (see below).

Made new makefile entries for Compaq Tru64 UNIX 4.0E and 5.0 (company and
name change), and added designer banners.  makefile, ckuver.h, 17 Jul 99.

Fixed a typo in the xdelmac() declaration (extraneous extra arg).  ckuus5.c,
17 Jul 99.

Discovered that some Linuxes (e.g. Red Hat) have libresolv.a (in which case it
must be searched for res_search() and dn_expan()) while others (Slackware)
don't.  So I had to change the "make linux" target to dynamically decide on
which combination of -lcrypt and -resolv (4 possibilities) to use.  makefile,
17 Jul 99.

No #including <sys/stat.h> on VMS with VAXC.  Now it builds OK on VMS 5.5.
ckuus7.c, 17 Jul 99.

The old DG MV2500 has trouble booting (hard disk errors) but if you enter the
diagnostic monitor, let it sit there for a while (so the disk can warm up) and
then try booting again, it comes up.  But as always, building gets media
errors on some files, which can usually be gotten around by building the
affected modules again.  After six hours or so I got a working binary, but
even with CKGHNLHOST defined, I still don't get a good \v(ipaddress).

SCO Xenix 2.3.4 needed <time.h> again.  ckutio.c, 17 Jul 99.

Discovered that the VMS UCX version on the Alpha, when sending a file over
Ethernet, its throughput steadily decreases as the transfer goes on, every
time.  It starts at over 100Kcps, and winds up (after about 2MB) at 13Kcps.
Increasing the TCP SENDBUF size from 4K to 16K makes it start at about 400K
and drop to 140K with the same file on the same connection.  Increasing it
beyond that doesn't make any difference.  For receiving, the 4K receive buffer
size seems to be OK -- throughput is about 400Kcps, and increasing the buffer
size doesn't change it.  Made default TCP send buffer size 16K on
VMS/Alpha/UCX.  Ditto for TCPware.  In fact, I made the definition contingent
on VMS and __alpha, which also includes Multinet, except it is ignored in
Multinet since SO_SNDBUF is not defined there.  ckcnet.c, 18 Jul 99.

Put Base-64 stuff in #ifndef NOSPL for PDP-11 build.  ckclib.c, 18 Jul 99.

Discovered that making a TCP connection to a site that refuses the connection
did not print an error message.  A perror() was missing in the ocean of
#ifdefs in netopen() for the UNIX case.  ckcnet.c, 18 Jul 99 (but this change
is too late to make it into most of the Beta.08 binaries).

All Multinet builds now get an avalanche of compiler warnings about socket
routines (socket_read/write/close, htons, getsockname, etc), but they still
seem to work ok...  Comparison of Beta.07 and 08 ckcnet.h and ckcnet.c doesn't
reveal anything obvious.

Removed trailing blanks from all source files.  18 Jul 99.

---Beta.08---

Added -DNO_DNS_SRV to pyrdcosx target.  Makefile, 20 Jul 99.

From Jeff: Kerberos updates, IKSD fix, NAWS fix for when client tells us it
has 0 rows and/or 0 columns.  ckcnet.c ckctel.c ckuath.c ckcpro.w ckuus7.c
ckuus2.c ckuus3.c, 21 Jul 99

Fixed duplicate solaris25gx25 entries; the second one should have been
solaris26gx25.  makefile, 21 Jul 98.

Attempted to cut through the mess surrounding when/how/if to include <time.h>
(or <sys/time.h>) in ckutio.c, since this was a big source of problems in
Beta.08.  The possibilities are pretty much any combination of zero or more of
<time.h>, <sys/time.h>, and <sys/timeb.h>.  The only rational approach is to
use symbols: TIMEH, NOTIMEH, SYSTIMEH, NOSYSTIMEH, SYSTIMEBH, and NOSYSTIMEBH.
By default TIMEH is defined for everybody.  SYSTIMEH is defined for a fairly
long list in ckcdeb.h, and I moved the section that decides about <sys/timeb.h>
from ckutio.c to ckcdeb.h.  Now any of these can be overridden or undone on
the command line without touching the source code.  makefile, ckcdeb.h,
ckutio.c, ckuus5.c, ckuins.txt Section 4.0, 21 Jul 99.

Tested on:

  AIX 4.1           OK       QNX 4.25          OK
  AIX 4.3.2         OK       SCO 3.2v4.2       OK
  BSDI 3.1          OK       SCO 5.0.5         OK
  DG/UX R4.11       OK       SINIX 5.42        OK
  Digital UNIX 3.2  OK       Solaris 2.5.1     OK
  FreeBSD 2.2.7     OK       Solaris 7         OK
  HP-UX 10.20       OK       SunOS 4.1.3       OK
  HP-UX 8.00        OK       Tru64 UNIX 4.0E   ??
  IRIX 6.2          OK       Unixware 2.1      OK
  Linux (RH5.2)     OK       Unixware 7        OK

Peter E verifies good building on HP-UX 6-10.  22 Jul 99.
Gerry B verifies good building on Motorola SV/68 and SV/88.  22 Jul 99.

Moved a misplaced #endif to fix -DNOHELP builds.  ckuus2.c, 22 Jul 99.

Another IKSD fix from Jeff.  ckcpro.w, 22 Jul 99.

Parameterized the final piece of the time.h code.  ckcdeb.h, ckutio.c,
makefile, 22 Jul 99.

Added zcopy() for VMS (from Lucas Hart).  22 Jul 99.

Fixed some prompt stomping in VMS, at least ones I can reproduce.
ckvcon.c, 22 Jul 99.

Fixed Ctrl-\S (status report) in VMS CONNECT crashing C-Kermit (because
temp buf was too small).  Also added more info to report, as in UNIX.
ckvcon.c, 22 Jul 99.

Put lines around status display.  ckvcon.c, ckucns.c, ckucon.c, 22 Jul 99.

Discovered that VMS C-Kermit had no code to get the username.  This means
\v(user) never worked, sending username ahead on Telnet connections never
worked, etc.  Added a GETJPI call to VMS sysinit() to load uidbuf[].  Now
uidbuf[] has the username in it, and \v(user) is set correctly, but VMS
C-Kermit still doesn't send the username ahead on a Telnet connection.
ckvtio.c, 22 Jul 99.

Because VMS did not have the username defined, the SHOW CONNECTION display
was messed up.  Fixed dologshow() to handle empty fields better.  ckuus3.c,
22 Jul 99.

VMS \v(tmpdir) had a slash at the end.  Fixed in ckuus4.c, 22 Jul 99.

Added -lresolve to dgux54420 target.  Makefile, 22 Jul 99.

There is still a lot of stuff in ckcdeb.h that depends on TCPSOCKET being
already defined.  All other versions (besides VMS) assume TCPSOCKET is defined
on the CC command line.  But in VMS, it is defined in ckcnet.h, after ckcdeb.h
is processed.  Changed the VMS build procedure to define TCPSOCKET if
net_option is not NONET.  ckvker.com, 22 Jul 99.

Defined CK_ENVIRONMENT for VMS so it can send the username ahead on Telnet
connections.  This also turns on a lot of other code for VMS that has never
been exercised before.  But it seems to work mostly OK -- e.g. interactions
with IKSD are as expected.  ckcdeb.h, 22 Jul 99.

From Jeff: Server-side support for Telnet New-Env USER variable.  Corrections
to zvpass() to properly handle Telnet Auth status reports.  Modifications to
Username and Password prompting to support username's transmitted by telnet
negotiation, anonymous logins, and null strings.  ckuus7.c ckufio.c ckcmai.c
ckctel.[ch] ckcpro.w, 22 Jul 99.

From Jeff: Modify use of "authentication failed" message when authentication
is rejected by the peer.  Move initialization of iksd prompt to dotakeini()
where we know that we are IKSD.  Add some "unsigned char" casts.  ckctel.c
ckcmai.c ckuus5.c ckuus7.c, 23 Jul 99.

Checked whether SUNWspro cc had a "consider all chars unsigned" option.
It doesn't.  23 Jul 99.

Added sunos41gsc entry that builds with gcc but omits the -funsigned-char
switch so I will see the signed-vs-unsigned char warnings that everybody else
complains about before they see them, and will use this one from now on.
makefile, 23 Jul 99.

Added -lresolv to all SunOS entries since somebody reported link-time
complaints even though I don't see them here.  Adding it does no harm here.
makefile, 23 Jul 99.

Redid shostk() to work in NOSPL builds.  Guarded all references to
trace-related variables with NOSPL.  Made Base-64 routines available to NOSPL
builds since they are also used by ckcnet.c.  ckclib.c, ckuus5.c, 23 Jul 99.

Removed redundant -DNOREALPATH from sys3upcxxx entries that call sys3upc.
Makefile, 23 Jul 99.

Jeff discovered that CHAR was typedef'd "char" (not "unsigned char") in VMS.
It's been that way probably forever, no doubt to suppress some compiler
warnings.  But this breaks some things at runtime, like certain Telnet
protocol operations.  Changed CHAR to be unsigned char for VMS.  This broke
compilation of lots of modules.  Added casts until it built cleanly with DECC.
Then tried it with VAXC...  OK.  Then on HP-UX 10.20 with the ANSI optimizing
compiler... OK.  And with gcc on UNIX without -funsigned-char...  OK.  So now
the user ID is sent if Telnet NEW-ENVIRONMENT is negotiated.  ckcdeb.h,
ckcnet.h, ckctel.c, ckcnet.c, ckvfio.c, 23 Jul 99.

Fixed new GETJPI code to not cut off username at 4 bytes.  ckvtio.c, 23 Jul 99.

Today's changes seem to fix another problem noticed yesterday: the VMS
C-Kermit Telnet client would often display the "login:" prompt as "olgin:".
Previously, this would happen about 25% of the time, but now I can't make it
happen at all (in about 50 trials).

Verified that the code works the same way in VMS 7.2 (which shows lowercase
usernames, etc) -- GETJPI still returns a 12-char field in uppercase.

Discovered that the REVIEW script, when given a list of filenames on the
command line, would get the array dimension wrong and so the filename array
would come out "off center" after sorting (the first filename would be null
and the last one would be skipped).  This is a long story.  The short version
is that when dogta() copied the \&_[] array when entering macro level 1 (0
based), it increased its dimension by 1.  I thought I had fixed this on 27
April, and again on 13 May, but this time I really did.  ckuus6.c, 23 Jul 99.

Authentication changes from Jeff.  ckcmai.c, ckuus7.c, ckuus4.c, ckctel.c,
ckcnet.c, 24 Jul 99.

Added debugging statements to rlogin code -- it seems in VMS we used to
lowercase the getenv("USER") name, but this doesn't help now because it is
overridden by the GETJPI name.  Changed the code to lowercase the name
if a global flag, ck_lcname, is set, and set this flag by default for VMS
only.  Now rlogin from VMS to UNIX works again.  ckcnet.c, 24 Jul 99.

Changed Telnet NEW-ENVIRONMENT to follow the same flag.  Now Telnet from
VMS to UNIX works as expected.  ckctel.c, 24 Jul 99.

Added system type and location to VMS sysinit() so now:
TELNET SENT SB NEW-ENVIRONMENT IS USER<SOH>fdcSYSTEMTYPE<SOH>VMS IAC SE
(location is not picked up because no LOCATION symbol is defined in VMS).
Verified that UNIX telnet server picks up and sets SYSTEMTYPE environment
variable to VMS.  ckvtio.c, 24 Jul 99.

Parameterized length of uidbuf[] with new symbol UIDBUFLEN, and changed all
references to specific lengths, like 64 or 63, to use this symbol, and all
strcpy's into this buf to be strncpy's.  For now the definition is still 64,
since I don't know of any platform that allows longer usernames.  ckcdeb.h
plus many modules, 24 Jul 99.

Adding TCPSOCKET to the VMS CC command line pushed the length of the command
line over the limit for MultiNet.  However, notes indicate that the limit
is arbitrarily chosen anyway, so I bumped it up by 9 characters, which does
not seem to have done any harm since MultiNet builds still work.  ckvker.com,
24 Jul 99.

Added support for the ELSA MicroLink 56K modem, which uses the new standard
ITU-T V.250 (aka V.25ter) command set.  This is the first international
standard AT command set and presumably will be adopted by other modem makers
(especially since Microsoft is pushing it in PC98 follow-ons).  ckuusr.h,
ckudia.c, 24 Jul 99.

Added support for generic ITU-T V.250, slightly different from Microlink
(strictly by the book, no Microlink extensions).  This one is also included
in MINIDIAL builds.  Also fixed some #ifdefs for MINIDIAL.  The keyword is
"itu-t-v25ter/v250" with an invisible alias of "itu-t-v250".  ckuusr.h,
ckudia.c, 24 Jul 99.

In yesterday's CHAR/char orgy, I missed one spot, which broke no-net builds
with ANSI compilers (the declaration of nettoc() in the #ifndef NETCONN
section).  Fixed in ckcnet.c, 24 Jul 99.

Added more casts to networking code to suppress HP-UX ANSI compiler warnings.
rlog_ini(): ckcnet.c, 24 Jul 99.

A few days ago Peter E reported some craziness with new file i/o package on
HP-UX 7, in which it was very confused about what the maximum number of
channels could be.  This was due to (a) overconservativeness in calculating
the maximum number (choosing the smaller, rather than larger, of several
possibilities when the larger was more likely to be accurate, having come
from sysconf()), and (b) then ignoring the value we had just calculated
(i.e. comparing channel numbers against the fixed symbol Z_MAXCHAN rather
than the variable z_maxchan).  Fixed in ckuus7.c, 24 Jul 99.

ADD SEND-LIST parsed its final field (as-name) with cmtxt() and then called
cmcfm().  I changed the cmtxt() call to cmfld().  ckuusr.c, 24 Jul 99.

Lucas H noticed that ADD SEND-LIST <wildcard> TEXT would forget about the
TEXT part after sending the first file that matched the wildcard.  Fixed in
gnfile(): ckcfns.c, 24 Jul 99.

However, this reveals a bigger problem: when a wildcard is given in a
SEND-LIST, there's no way to specify automatic type switching while sending
the files.  This is a hard one, so deferred -- nobody has ever mentioned it,
and there are obvious workarounds, especially now with regular expressions.
Documented in ckcbwr.txt.  24 Jul 99.

Made "if ==" an invisible synonym for "if =".  ckuus6.c, 24 Jul 99.

Added IF COMMAND and IF FLOAT.  ckuusr.[ch], ckuus2.c, 24 Jul 99.

Added \v(cx_time) = elapsed time in session (i.e. since making current
connection, if any, otherwise 0).  ckuusr.h, ckuus[345].c, 24 Jul 99.

From Jeff: fix a misplaced #ifdef in the file code; some authentication
changes.  ckcmai.c, ckuus7.c, 25 Jul 99.

Changed floating-point functions to treat missing or empty arguments as 0.
ckuus4.c, 25 Jul 99.

Fixed IF FLOAT parsing when given a variable with no value.  ckuus6.c,
25 Jul 99.

Noticed that elapsed time of connection was often wrong.  To avoid having to
put dologxxx() calls throughout setlin(), I had placed them after the calls to
setlin().  This was a good idea except that setlin() can call doconect()
(e.g. if command was TELNET, or if /CONNECT switch was included), and
therefore setlin() might not return for hours, in which case the log entry
would not include the duration of the first (and perhaps only) CONNECT
session.  So I moved the dologxxx() calls to the appropriate places in
setlin(), which wasn't so bad after all (since they only needed to go in those
places where setlin() returns successfully after making a connection, but
before any call do doconect()).  ckcmai.c, ckuus[37].c, 25 Jul 99.

Noticed that connections made by command-line options did not start the
connection log & timer.  Fixed in ckuusy.c, 25 Jul 99.

Realized it's not very helpful to have \v(cx_time) return 0 when there is no
active connection, so made it (and SHOW CONNECTION) show the elapsed time of
the most recent session.  ckuus[34].c, 25 Jul 99.

Finally, to make the connection log useful on multiprocessing systems, it was
necessary to not keep it open all the time.  This way, multiple sessions can
write to the same connection log.  LOG CONNECTION opens the log in the
requested mode (new, append) and closes it right away (this is mainly so it
can fail intelligently in case the log can't be opened).  Then, whenever a
session ends, dologend() opens it again (but this time in append mode, no
matter what mode the user chose), writes the record, and closes it.
Collisions are still possible, but in UNIX at least, there is no mechanism for
opening the file in shared mode -- presumably sharing is allowed and you have
to go out of your way to prevent it (e.g. with flock()).  In any case, logging
from multiple sessions seems to work fine now on both UNIX and VMS (and it
definitely did not before today), as does syslogging on UNIX (after some minor
tweaking).  ckuus[34].c, ckufio.c, 25 Jul 99.

So now we have a reliable session-time indicator.  Added session time (and
some other info) to the CONNECT-mode status display.  It could also be used
anywhere else -- e.g. in the K95 status line (if there were room).  The way
to get it is:

  char * p = NULL;
  long t = dologshow(0);       ; Seconds
  if (t > -1L) p = hhmmss(t);  ; Converted to hh:mm:ss

ckucns.c, ckucon,c, ckvcon.c, 25 Jul 99.

SET TRANSFER DISPLAY BRIEF, in its summary line, did not deduct the refused
files from the total number of files transerred.  Fixed in ckuusx.c, 25 Jul 99.

Removed a spurious printf() from REMOTE QUERY left behind from a debugging
session.  Suppressed gratuitous echoing of QUERY result when not at top level.
ckuus7.c, 25 Jul 99.

A fix from Jeff from IKSD login.  ckuus7.c, 25 Jul 99.

Discovered that SHIFT did not work when given within a FOR or WHILE loop
when referencing command-line arguments.  Fixed in doshift(): ckuus5.c,
26 Jul 99.

Got rid of "Interrupt during initialization or command-line processing.
C-Kermit quitting..." message when a Kerbang script is interrupted.  ckcmai.c,
26 Jul 99.

OS-9 fixes from Martin Whitaker.  ckcdeb.h, ckucmd.c, ckuus[6x].c, 26 Jul 99.

Cleanup of overuse of variable "x" in setlin() from Jeff.  ckuus7.c, 26 Jul 99.

Fixed number-of-modems definition in ckuusr.h (forgot to update it for
ITU-T V.250).  26 Jul 99.

Fixed ITU-T V.250 commands that include multiple "extended commands" to
separate them with semicolon (V.250 5.4.5.1).  ckudia.c, 26 Jul 99.

New VMS build procedure from Dave Sneddon, accounts for UCX 5.0.
ckvker.com, 26 Jul 99.

Made sure that --syslog: on command line doesn't affect syslogging when
C-Kermit was built with -DSYSLOGLEVEL=x (the code was already there).
27 Jul 99.

Added a new target to support building IKSD on Unixware7 (needs shadow
passwords) from Jim Whitby.  27 Jul 99.

Mike Freeman reported that VMS C-Kermit crashed when given a REMOTE HOST
command.  Problem: the new timed reads that were added to handle the keepalive
for long-running host commands.  Kermit crashes in the sys$synch(QIOW_EFN)
call on the VAX but not on the Alpha.  "help system $synch" on the Alpha says
this call takes a 64-bit arg on the Alpha only, but only looks at the lower
byte; it doesn't say this on the VAX.  But I doubt that's the problem -- it
might be a missing second arg, but I can't tell.  Sent email to Lucas about it
and undefined PIPETIMER on the VAX in the meantime.  ckvfio.c, 27 Jul 99.

Peter E complained that the following sequence:

  set modem type xxx
  set line /dev/cua0
  set flow none (or anything else)
  ...
  set modem type yyy

undoes the "set flow" command.  But... if the user gave a SET FLOW command,
they probably meant it, and it should be sticky at least until the device
changes.  So now any SET FLOW command (except AUTO, which is the default)
sets autoflow to 0, but any SET LINE/HOST/PORT or TELNET/RLOGIN/etc command
sets it back to 1 so appropriate flow control can be selected for the new
device/connection.  ckuus[37].c, 27 Jul 99.

Lucas got back with a fix for the sys$synch() call, so REMOTE HOST (with
keepalive) works again on both VAX and Alpha.  But it's very slow (VERY slow)
-- I didn't notice this before.  Sent more mail to Lucas.  In the worst case
we can always back off.  ckvfio.c, 27 Jul 99.

Peter E noticed that DIR with no switches was like DIR /FILES, when it was
supposed to be like DIR /ALL.  The problem was in the _CMIFI entry of the
initial FDB (before any switches were parsed).  Fixed in domydir(), ckuus6.c,
27 Jul 99.

From Jeff: SET TELNET BUG SB-IMPLIES-WILL-DO to cope with broken UCX 5.0
Telnet server (client sends WILL TERM-TYPE, server sends SB without first
sending DO, but client is still waiting for DO).  Also various compiler
warning-avoidance and authorization fixes.  Also cleaned-up code for sending
NEW-ENVIRONMENT fields.  ckctel.[ch], ckuus[2347].c, ckufio.c, 28 Jul 99.

Added NOSHOW protection around references to SHOW ARRAY in ckuusr.c.
28 Jul 99.

Fixed an unguarded reference to query.  ckcnfs.c, 28 Jul 99.

Fixed unguarded refs to dolognet().  ckuus7.c, 28 Jul 99.

Added SET SERVER KEEPALIVE { ON, OFF } to control the keepalive feature;
needed for VMS (unless we can get get_subroc_line() fixed), because of how
it slows down the response to host commands.  ckuusr.h, ckuus[235].c,
ck[uv]fio.c, 28 Jul 99.

Moved hhmmss() and parnam() from ckuusx.c to ckclib.c so ck?[tf]io.c routines
could use them without having to haul in ckuusr.h.  ckuusx.c, ckuusr.h,
ckclib.[ch], 28 Jul 99.

Added doiksdinit() to execute the iksd.conf file if -A given on command line,
just after ttopen() and socket setup, but before authentication begins.
ckcdeb.h, ckcmai.c, ckuus5.c, iksd.txt, 28 Jul 99.

Yesterday's fix for SET FLOW was not in exactly the right place.  Moved it
to a better place and now it works as advertised.  ckuus3.c, 28 Jul 99.

Added SET AUTH { K4, K5 } PROMPT { PASSWORD, PRINCIPAL }, parsing only.
Compiles OK but I couldn't test because link fails on ck_krb4_realmofhost.
Also SET TELNET PROMPT-FOR-USERID.  ckuusr.h, ckuus3.c, 28 Jul 99.

Fixes from Jeff for Kerberos builds plus filling in the action portions of the
new SET ... PROMPT commands, plus HELP text for them.  ckuath.c ckuus2.c
ckuus3.c ckuus7.c ckuusr.h, 29 Jul 99

Made sure that the following builds worked OK: NONET, NOSHOW, NODIAL, NOHELP,
NOSPL, NOICP. NOPUSH, NOCSETS, NOLOCAL, MINIDIAL.  A fair amount of work was
needed to get NOICP builds working again, including a NOICP version of
readpass(), in case anybody ever wanted to build a command-line-only C-Kermit
that included authentication, plus the expected #ifdef shuffling in ckcdeb.h,
etc.  Plus more char/CHAR silliness in ckcnet.c.  Also needed to move several
routines out of the NOLOCAL section to make the NOLOCAL version link.  Many
modules, 29 Jul 99.

Also checked builds on:
 AIX 4.1:              OK
 AIX 4.3.2:            OK
 BSDI 3.1:             OK
 HP-UX 8.00 no ANSI:   OK
 HP-UX 9.00 ANSI:      OK
 HP-UX 9.00 no ANSI:   OK
 HP-UX 10.20 ANSI:     OK
 HP-UX 10.20 No ANSI:  OK
 IRIX 6.2:             OK
 Linux (RH5.2):        OK
 Ditto + Kerberos 5:   OK
 Ditto + Kerberos 4&5: OK
 SCO 3.2v4.2 cc:       OK (net and nonet)
 SCO 3.2v4.2 gcc:      OK (net and nonet)
 SINIX 5.42:           OK
 Solaris 2.4 cc:       OK
 Solaris 2.5.1 gcc:    OK
 Solaris 7 cc:         OK
 Unixware 2.1.3:       OK
 Unixware 7:           OK
 VMS/Alpha/DECC/UCX:   OK
 VMS/Alpha/DECC/Nonet: OK
 VMS/VAX/VAXC/UCX:     OK
 VMS/VAX/VAXC/Nonet:   OK

From Jeff: check prompt strings to make sure they use the proper
number and type of % fields.  ckuus3.c, 29 Jul 99.

From Jeff:  Add color to the prompts.  I use the status line color.
ckuus7.c, 29 Jul 99.

Two corrections to tx_cp437(): a-tilde goes to 'a', not 'e', and
Black Square maps to 254, not "unknown".  ckouni.c, 29 Jul 99.

Fixes for get_subroc_line() from Lucas Hart -- major speedup.  ckvfio.c,
29 Jul 99.

Discovered two entries were missing from the xlr[] table at the end of
the Latin/Cyrillic section (4,43 and 4.44).  ckuxla.c, 30 Jul 99.

Added support for Unicode / ISO-10646 in two forms, UCS-2 and UTF-8, Level 1
(no combining characters, no Jamos), each of them as both File and Transfer
Character Sets.  This works only for file transfer so far, not CONNECT,
TRANSMIT, TRANSLATE, etc.  There are still many loose ends, but nothing to
prevent including it in Beta.09 and the final 7.0.  Practically all modules
were touched.  Detailed notes in a separate file, unicode.txt.
31 Jul - 1 Aug 99.

Fixes from Jeff to weekend's Unicode work for K95, plus some authentication
changes.  ckuus7.c ckuath.c ckuus5.c ckuus3.c ckuus4.c ckcuni.h ckuxla.c
ckcuni.c ckuath.h ckouni.c ckcnet.c, 2 Aug 99.

Separated UNICODE and CKOUNI, which were previously synomyms.  Now CKOUNI is
defined only for K95.  ckcxla.h, 2 Aug 99.

Fixed a couple places where xpnbyte() did not return a value.  In fact, a lot
of yesterday's work on on this function seems to have been lost -- I must have
been editing the wrong copy, or copied the wrong file or something...
Reconstructed the lost work, ran all the tests again, still OK.  ckcfns.c, 2
Aug 99.

Changed unknown-char symbol when translating from Unicode to a single-byte
character set from Ctrl-G to the customary question mark.  ckcfns.c, 2 Aug 99.

Added #ifdefs needed to fix NOCSETS builds.  ckcfns.c, 2 Aug 99.

Added Unicode support to the TRANSLATE command.  This required some creative
retooling of xgnbyte() into a more-or-less general-purpose routine that works
for both file transfer and other kinds of translations, and hopefully can be
used by TRANSMIT and CONNECT.  ckcfns.c, ckuus4.c, 2 Aug 99.

Code for K95 popup prompts from Jeff, plus some typos fixed, plus some auth
stuff.  ckuus7.c ckuath.c ckuus3.c ckouni.c, 3 Aug 99.

Added /POPUP switch to ASK[Q].  ckuus6.c, 3 Aug 99.

Fixed K95 parsing of SET TERM {REMOTE,LOCAL}-CHAR LATIN1 and NEXT.  ckcuni.c,
3 Aug 99.

Removed SET TERM CHAR { UCS2, UTF8 } from non-K95 SET TERM CHAR tables (since
there is no supporting code yet), and made SET { FILE,XFER } CHAR { UCS2,UTF8 }
invisible.  ckuxla.c, 3 Aug 99.

Fixed SHOW CONNECTION message in the no-connection case. ckuus[r3].c, 3 Aug 99.

For local reasons, we had to cut off development here and put Beta.09 together
without the complete Unicode implementation.  So now to repeat the testing
from several days ago.  Configuration options:

  Full Unix..ok (SunOS, Unixware 7)
  Full VMS...ok (Alpha / VMS7.2 / DECC)
  NoNet VMS..ok (ditto)
  Krb4.......ok (SunOS)
  Krb5.......ok (Linux)
  Krb4+Krb5..ok (Linux)
  NOUNICODE..ok
  NOCSETS....ok
  NONET......ok
  NOLOCAL....ok
  NODIAL.....ok
  MINIDIAL...ok
  NOSPL......ok
  NOICP......ok
  NOSHOW.....ok
  NOHELP.....ok
  NOPUSH.....ok

Some shuffling of #ifdefs and declarations was needed, as usual, to get all
of these working again.

Fixed a bogus 5-hex-digit hex case label in tx_lucidasub(). ckcuni.c, 3 Aug 99.

Changed ASK/ASKQ to evaluate variables in prompt string.  doask(): ckuus6.c,
3 Aug 99.

Added CKCUNI to VMS build procedure.  ckvker.com, ckvker.mms, 3 Aug 99.

Commented out the questionable section in ucs2_to_utf8() that compares an
unsigned short with all sorts of 32-bit hex constants, since almost every
compiler complains about it, and it doesn't do anything useful anyway (we
don't support UCS-4 yet; when we do we can change the parameter with which
ucs2_to_utf8() is called from USHORT to UINT, and for that matter drop the
"2" from the name).  ckcuni.c. 3 Aug 99.

Fixed UNICODE defines so they are executed only for UNIX and VMS, since the
other platforms don't have their build procedures adjusted yet to include the
new modules and dependencies.  ckcxla.h, 3 Aug 99.

From Jeff: change: "int ttnproto = NP_NONE;" to "int ttnproto = NP_DEFAULT;"
in ckcnet.c, so "kermit -J host" will work.  ckcnet.c, 3 Aug 99.

OK, now starts the build-all...

VMS 5.5 DECC build barfs on #include <conv$routines.h> (file doesn't exist).
Tried again with VAXC.  This one choked on memmove.  Commented out the
#include (actually put it #ifndef BUGFILL7) and went back to DECC.  This will
have to be cleaned up later...

A few last-minute K95 fixes & changes from Jeff (including /POPUP for the
AUTHENTICATE commands).  ckcxla.h, ckuus7.c, ckuusr.c.  3 Aug 99.

---Beta.09---
---1.1.18-CU---

From Jeff:
 . Changed ckcssl.h to ck_ssl.h to prevent copying by ck[cu]*...
 . Verified authentication engine against 3rd authentication servers & clients.
 . Made sure that IKSD sets the socket options appropriately at startup.
 . Made sure that platform-specific variables are not exposed to guests.
 . Prevent deadlocks with TELNET WAIT and encryption.

New OS-9 makefile from Martin Whitaker, adds ckcuni.[ch].  10 Aug 99.

Fixed some #ifdefs in SHOW EXTENDED-OPTIONS to allow building with -DNOLOGIN.
ckuus5.c, 10 Aug 99.

Added a byte-order test to main() start sequence and added byte order display
to SHOW FEATURES.  ckcmai.c, ckuus5.c, 10 Aug 99.

Changes from Jeff for SRP, separate conditionalization of iksd.conf, comments
& placeholders in telnet & crypto modules, fixes to gtword() to be more
tolerant when Telnet server of misbehaving clients (e.g. that send bare CR),
problems with DNS lookups on DU 4.0B caused by sign extension.  ck_crp.c
ckcmai.c ckcnet.c ckcssl.h ckctel.h ckouni.c ckuath.c ckucmd.c ckuus5.c
makefile, 11 Aug 99.

Hoping to stifle the avalanche of compiler warnings on Multinet builds that
we've been getting since Beta.07, reorganized the VMS section of ckcnet.h to
have #ifdef..#else structure, so each product section is mutually exclusive.
I didn't expect it to help and it didn't.  Eventually (long story skipped) it
turned out that the #include <if.h> that was added to ckcdeb.h to pick up the
u_int typedef for UCX 5.0 was forcing the Multinet <socket.h> to be skipped,
so the cure was to put #ifndef MULTINET around #include <if.h>.  This fixes
all Multinet builds without breaking UCX or others.  The critical hint was
from Hunter Goatley: use /LIST/SHOW=INCLUDE.  Built and replaced all of the
Multinet binaries.  ckcdeb.h, 11 Aug 99.

Changed the VMS build procedure to define IF_DOT_H only for UCX.  Not only do
we not use this symbol any more outside of UCX, but also it made the Multinet
CC command line too long.  ckvker.com, 11 Aug 99.

Added SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }, \v(byteorder),
SET RECEIVE UCS BOM { ON, OFF } (parsing only).  ckuusr.h, ckcker.h,
ckuus[37].c, ckuxla.c, 11 Aug 99.

Filled in \v(byteorder) action.  Returns 0=BE, 1=LE.  ckuus4.c, 11 Aug 99.

Added union ckshort definition to ckcdeb.h, 11 Aug 99.

Added preliminary UCS byte-swapping code to xpnbyte().  Compiles OK but is
totally untested.  ckcfns.c, 11 Aug 99.

From Jeff:
 . Updated SSL support for OpenSSL 0.9.4
 . Moved iksdconf stuff to a more correct location in main()
 . Made set telopt /server the default when running as IKSD
 . DU 4.0 inet_addr() thing
ckcnet.[ch] ckuus3.c ckcmai.c ckuus5.c ck_ssl.h ckuath.c makefile, 11 Aug 99.

Fixed long lines in ckuath.c, 11 Aug 99.

Changed the minor edit number from 195 to 196 since we had a private
Columbia-only release.  ckcmai.c, 11 Aug 99.

More changes from Jeff, mostly for the DU4.0 inet_addr() business.  ckuus7.c
ckcnet.c ckuath.c ckcfns.c ckuus3.c ckcnet.h, 12 Aug 99.

Fixed long lines in ckuath.c again, 12 Aug 99.

While I was messing with Unicode support, file transfers started failing for
no apparent reason.  The debug log showed it was because we were calling
ttinl() with a timeout even though we were streaming.  Why?  Somehow timint
was getting set to a positive number.  I'm not going to worry about it now --
I just changed the "just in case" test in rpack() prior to calling ttinl() to
also check for streaming.  (Actually this was a false alarm -- the real
problem was a forgotten kermit-in-the-middle -- but the change seems like a
good idea anyway...)  ckcfn2.c, 12 Aug 99.

OK, back to Unicode...  Discovered that an #endif was misplaced by one line
in ucs2_to_utf8(), totally breaking it.  Therefore translation of UCS-2 to
UTF-8 won't work in K95 1.1.18-CU.  I doubt anybody will notice since (a)
the file-transfer keywords are invisible, (b) Unicode file-transfer support
is undocumented, and (c) they'll probably never type an accented or non-Roman
character natively (the Compose key still works).  But oops, my fault.  Fixed
in ckcuni.c, 12 Aug 99.

Added UCS-2 byte-swapping for the file receiver.  This turned out to be easier
than I thought, although it took some time to realize it.  UCS-2 characters
are (and must be) kept in native order internally, otherwise translation
functions (tables, switch statements, etc) don't work.  Therefore bytes are
swapped only when (a) incoming TCS is UCS-2 (Big Endian by definition) and
receiving machine is Little Endian, or (b) writing out to a UCS-2 file and the
user has specified the opposite endianness of the underlying machine.  Also we
add or don't add the appropriate BOM according to the user's FILE UCS BOM
{ ON, OFF } setting.  xpnbyte(): ckcfns.c, 12 Aug 99.

Changed setxlatype() to NOT set XLA_NONE when Unicode is involved, even if
the TCS and FCS are the same, since we might also need to deal with byte
swapping and BOMs.  ckuxla.c, 12 Aug 99.

Made sure that every conceivable combination works:

       From To   TCS      FCS    BOM  Order
  [ok] Sun  PC   Latin-1  UCS-2  On   Default  (FFFE, A<NUL>)
  [ok] Sun  PC   Latin-1  UCS-2  On   BE       (FEFF, <NUL>A)
  [ok] Sun  PC   Latin-1  UCS-2  On   LE       (FFFE, A<NUL>)
  [ok] Sun  PC   Latin-1  UCS-2  Off  Default  (A<NUL>)
  [ok] Sun  PC   Latin-1  UCS-2  Off  BE       (<NUL>A)

  [ok] Sun  PC   UTF-8    UCS-2  On   LE       (FFFE, A<NUL>)
  [ok] Sun  PC   UTF-8    UCS-2  On   BE       (FEFF, <NUL>A)
  [ok] Sun  PC   UTF-8    UCS-2  Off  BE       (<NUL>A)
  [ok] Sun  PC   UTF-8    UCS-2  Off  LE       (A<NUL>)

  [ok] Sun  PC   UCS-2    UCS-2  On   LE       (FFFE, A<NUL>)
  [ok] Sun  PC   UCS-2    UCS-2  On   BE       (FEFF, <NUL>A)
  [ok] Sun  PC   UCS-2    UCS-2  Off  BE       (<NUL>A)
  [ok] Sun  PC   UCS-2    UCS-2  Off  LE       (A<NUL>)

  [ok] PC   Sun  Latin-1  UCS-2  On   Default  (FEFF, <NUL>A)
  [ok] PC   Sun  Latin-1  UCS-2  On   BE       (FEFF, <NUL>A)
  [ok] PC   Sun  Latin-1  UCS-2  On   LE       (FFFE, A<NUL>)
  [ok] PC   Sun  Latin-1  UCS-2  Off  LE       (A<NUL>)
  [ok] PC   Sun  Latin-1  UCS-2  Off  BE       (<NUL>A)

  [ok] PC   Sun  UTF-8    UCS-2  On   BE       (FEFF, <NUL>A)
  [ok] PC   Sun  UTF-8    UCS-2  On   LE       (FFFE, A<NUL>)
  [ok] PC   Sun  UTF-8    UCS-2  Off  LE       (A<NUL>)
  [ok] PC   Sun  UTF-8    UCS-2  Off  BE       (<NUL>A)

  [ok] PC   Sun  UCS-2    UCS-2  On   BE       (FEFF, <NUL>A)
  [ok] PC   Sun  UCS-2    UCS-2  On   LE       (FFFE, A<NUL>)
  [ok] PC   Sun  UCS-2    UCS-2  Off  LE       (A<NUL>)
  [ok] PC   Sun  UCS-2    UCS-2  Off  BE       (<NUL>A)

Changed SET RECEIVE UCS BOM { ON, OFF } to SET FILE UCS BOM { ON, OFF }.
ckuusr.h, ckuus7.c, 13 Aug 99.

Jeff changed zmchout() calls in ckcfns.c to pnbyte() to solve a problem with
IKSD's execution of REMOTE commands.  But that's not right.  First of all a
lot of stuff is done twice this way (ffc incrementing, crc calculating, etc),
but mainly it's way too expensive.  zmchout() is a highly efficient macro;
doing a function call on every character should be avoided whenever possible.
We can look at this next week.

Also some changes to ckuath.c from Jeff.  Fixed long lines, plus a typo
(the word "NULL" was broken in half around line 5382).  13 Aug 99.

From Jeff:
 . A new approach to handling the issues related to OS/2 and zmchout() in
   ckcfns.c  I just placed the conoc() calls in [b]decode as an if else
   statement.
 . Renamed:  SET TELNET TRANSFER-MODE to SET TELNET BINARY-TRANSFER-MODE
 . Added:  SET TELNET AUTH {HOW-FLAG, ENCRYPT-FLAG} to specify which
   values for the authentication type modifier should be accepted or
   offered.  Primarily for debugging but it does have the ability to be
   used to require a mutually authenticated session.
ckuus2.c, ckcfns.c, ckuath.c, ckuus3.c, ckuusr.h, ckctel.h, ckctel.c,
ckcpro.w, ckuus4.c, 15 Aug 99.

From Jeff:
 . Discovered that OpenSSL is broken on SunOS.  Built OpenSSL on linux.
   Added SSL/TLS support to our multi-authentication mechanism build.  So
   now yclept's IKSD has K5, K4, SRP, and SSL/TLS.
 . Fixed the test for determining when SRP authentication has completed.
 . Don't attempt to display the SSL/TLS shared cipher list on the client.
ckcnet.c ck_ssl.h makefile ckufio.c ckuath.c, 15 Aug 99.

Added UCS settings to SHOW FILE.  ckuus4.c, 15 Aug 99.

Added support for UCS-2 byte swapping to the file sender.  The source file's
BOM, if any, takes precedence.  If it's FFFE, then we swap.  If there is a BOM
(either FEFF or FFFE), we discard it.  If there is no BOM, we swap if SET FILE
UCS BYTE-ORDER is opposite from the machine's native byte order.  After
reading a UCS-2 character and possibly swapping according to these rules, we
assume that the character is in native UCS-2 unsigned short format, and use it
that way in conversions, etc.  Of course if there is no BOM and the user
commands us to use the wrong byte order, the results are junk.  xgnbyte():
ckcfns.c, 15 Aug 99.

Tested by sending 4 files in text mode with FCS == TCS == UCS-2 and SET FILE
UCS BYTE-ORDER BIG-ENDIAN and LITTLE-ENDIAN from both Sparc (BE) and PC (LE),
and looking at the packet logs:

 Machine:              Sparc...    Linux PC
 SET FILE UCS BYTE:    BE    LE    LE    BE
                       --------------------
 1. ucs2be+bom.txt     ok    ok    ok    ok     BOM takes precedence
 2. ucs2le+bom.txt     ok    ok    ok    ok     BOM takes precedence
 3. ucs2be-bom.txt     ok    XX    XX    ok     Setting takes precedence
 4. ucs2le-bom.txt     XX    ok    ok    XX     Setting takes precedence

So all combinations work (XX means we lied about the byte order and so the
bytes were reversed in the packet).  Results are consistent when the transfer
charset is Latin-1.

Next I added some rather crude code to handle CRLF/LF/CR conversion to/from
packets when the TCS is UCS-2.  In this case we need #@#M#@#J in the packet,
with appropriate conversions from/to the file character set.  This will no
doubt need some refinement.  In fact, it really strains the current model
which is a poor design.  The right way to handle line termination is to have
a line-oriented system-dependent file reader that returns each line *without*
its terminator.  Then the high-level code can simply tack CRLF onto the end
(or in this case NUL CR NUL LF), rather than worry about what platform it's
running on and what the previous and next chars are, etc.  ckcfns.c, 15 Aug 99.

Fixed the TRANSLATE command to account for byte order and to follow the FILE
UCS settings.  ckcfns.c, ckuus4.c, 15 Aug 99.

Some changes from Jeff.  ckuus3.c, ckuath.c, 16 Aug 99.

Added COPY /SWAP-BYTES <sourcefile> <destfile>.  ckuus6.c, 16 Aug 99.

Verified that when using UCS-2 or UTF-8 as a transfer character set, it's OK
to break a code sequence between packets.

Fixed UNIX CONNECT module to not translate incoming characters when
transparent print was active.  ckucns.c, 16 Aug 99.

Updated HP-UX 6 and 7 targets from Peter E.  makefile, 17 Aug 99.

From Jeff, 20 Aug 99:
 . Fix \fword()/\fsplit() return value.  ckuus4.c.
 . Added ckgetlocalipaddrs() (but there is already a
   getlocalipaddr(), and some compilers/linkers might not support
   distinctions past the 14th character...)  ckcnet.[ch].
 . Added code for Kerberos check IP addresses: ckuusr.h, ckuus[37].c.
   (Changed "checkaddrs" to "check-address").
 . New ckuath.c (fixed long lines).
 . New cmdgetc(), not static any more. ckucmd.[ch].  Fixes problem with
   askmore() in IKSD.

Fixed Compaq modem DC Off command (&C0 should be %C0).  ckudia.c, 20 Aug 99.

Added UTF-8 terminal character-set translation to UNIX CONNECT module.
ckucns.c, 21-22 Aug 99.  (Still need to migrate this code to other CONNECT
modules, clean it up, etc, and then adapt it to TRANSMIT.)

Verified that UTF-8 changes to ckucns.c did not break previous byte-to-byte
translations (e.g. DGI to Latin-1), then cleaned out temporary debug calls
that were added yesterday.  Also verified that -DNOUNICODE builds still work.
Then streamlined, parameterized, and documented the UTF-8 routines in
preparation to moving them to a common module.  23 Aug 99.

Fix from Jeff to askmore() that I missed before.  ckuusx.c, 23 Aug 99.

Added to the list of countries where Tone dialing is universally available
from table in Elsa MicroLink (German modem) manual.  ckudia.c, 24 Aug 99.

New irix64gcc makefile target from Adam Laurie <adam@algroup.co.uk>, 24 Aug 99.

Added -DNOTERMCAP to linuxnc target since "linuxnc" (no curses) builds were
failing on <term.h> on systems where user said No to installing ncurses.
makefile, 24 Aug 99.

New uw7iksdudk target, accounts for library shuffle between Unixware 7.0 and
7.1 (realpath()), from Jim Whitby <jim@tpsdata.com>.  makefile, 24 Aug 99.

With a helpful hint from Lucas Hart, cleaned up a mess I made in VMS
do_label_send() when working on the signed/unsigned char mess, which broke
LABELED transfers completely.  ckvfio.c, 24 Aug 99.

Yesterday, cont'd...  Added prototypes for b_to_u() and u_to_b() to ckcuni.h,
and moved the routines themselves from ckucns.c to ckcuni.c.  24 Aug 99.

Adapted UTF-8 support to ckucon.c and ckvcon.c.  This brings UTF-8 terminal
emulation to fork()-using UNIX versions and to VMS, and validates the
modularity.  24 Aug 99.

Looked at TRANSMIT command.  It already had K95-specific UTF-8 support added,
but it didn't work at all in UNIX.  Changed it to use the same model used by
CONNECT.  Now it works (sort of), but still needs a LOT of cleaning up.  To
be cont'd...  ckuus4.c, 24 Aug 99.

In the non-K95 version of SET TERM CHARACTER-SET <remote-set> <local-set>, the
default local set was set incorrectly, so defaulting it gave a totally wacky
value.  Not sure when this happened, but it was some time after 6.0.  Fixed
in settrm(), ckuus7.c, 25 Aug 99.

From Jeff: Make K95 "set term {r,l} char dec-m*" consistent with C-K.
ckcuni.c, 25 Aug 99.

If the TRANSMIT command failed in the setup phase, it could leave the
'binary' value altered.  Fixed in translate(), ckuus4.c, 25 Aug 99.

The TRANSMIT command has always assumed the character set of the file being
transmitted was the same as the local end of the terminal character-set pair.
There has never been a way to transmit a file, converting from local (file)
character-set A to remote (terminal) character-set B, but convert the return
echo from B to the local end of the terminal character set, C.  To illustrate:
suppose I want to transmit a file encoded in the NeXT charset to a DG
computer, translating it to DG Multinational, but my terminal only understands
Latin-1, so the echoes should be translated from DG to L1.  The distinction is
important now if we want to TRANSMIT (and translate) UCS-2 file, since UCS-2
is not a terminal character set.  Fixed in transmit(): ckuus4.c, 25 Aug 99.

Found a bug I introduced at the beginning of the Unicode changes -- two
little CKOUNIs that were changed to UNICODE that shouldn't have been, which
gave C-Kermit (but not K95) a random terminal character set upon startup.
ckuxla.c, 25 Aug 99.

Added UCS-2 support to TRANSMIT; cleaned up, commented, consolidated, and
tightened the code.  In fact, almost totally rewrote it.  Surprisingly, this
one turned out to be a lot more complicated than file transfer, CONNECT, or
TRANSLATE, but now it's done except for some minor loose ends.  transmit():
ckuus4.c, 25 Aug 99.

From Jeff:
 . More Telnet authentication changes.  ckcpro.w, ckuath.c
 . New Kerberized AIX 4.1 makefile target.
Fixed long lines and trailing blanks in ckuath.c.  25 Aug 99.

From Jeff, ckcmai.c, ckuath.c, 26 Aug 99:

 . proper handling of the case where the user authenticates as one name
   but wants to log in as someone else.

 . For instance, I want to authenticate as jaltman@CC.COLUMBIA.EDU but
   log into the host as 'root'.

 . When mutual authentication is performed I can get an encrypted
   session, but I still want to be prompted for the 'root' password if
   the 'root' account does not have a .k5login or .klogin file containing
   the authorized principal names.  Under no circumstances should we
   allow a user access to another user's account without appropriate
   credentials.  This is all fixed.

 . AUTH_USER means we know the user and the user is authorized either
   because they are logging into their own account or because they have
   been given permission to access the specified account name.

 . AUTH_VALID means we know the user but the user is not authorized to
   access the requested account without addiitional credentials.

 . AUTH_OTHER means we know the user but do not know the name the user
   wishes to log in under.

 . AUTH_UNKNOWN means we do not know who the user is but the person
   should be allowed to log in.

 . AUTH_REJECT means we do not allow the login to procede (if
   authentication is required)

 . These labels are now consistently used in ckuath.c

Added chartostr() to ckclib.[ch], to turn a char into a string (and if the
char is a control char, to return its name).  Convenient for printfs.
26 Aug 99.

Added charset and term bytesize info to SHOW TRANSMIT.  ckuus5.c, 26 Aug 99.

From Jeff, ckuath.c ckuus7.c ckuusr.h ckcnet.c ckuath.h, 26 Aug 99:
 . auth k4 list should not have switches
 . added a /addresses switch to auth k5 list to display the hostnames and
   ip addresses associated with the tickets.
 . added the ip address to the information displayed by auth k4 list
 . IP Address info is necessary to help debug problems associated with
   multihomed machines.

Added TRANSMIT /TRANSPARENT to force text mode without charset translation,
regardless of current charset settings.  ckuus[r4].c, 26 Aug 99.

Fixed SET TERM CHAR <local> <remote> to use the *terminal* charset keyword
table, not the *file* one, for the remote charset.  ckuus7.c, 26 Aug 99.

Updated HELP text for Unicode.  ckuus2.c, 26 Aug 99.

Fixes from Jeff to a couple syntax errors in yesterday's changes.  ckuus[r4].c,
27 Aug 99.

Changed SET TERM CHAR TRANSPARENT to set a flag that distinguishes between
"transparent" actually having been specified and tcsl == tcsr.  The difference
is important for TRANSMIT.  Changed SHOW TERM to TRANSPARENT only if the user
said TRANSPARENT; otherwise to show the two sets, even if they are the same.
ckuxla.c, ckuus[47].c, 27 Aug 99.

From Jeff: fix for a typo in \v(protocol) evaluation.  ckuus4.c, 31 Aug 99.

Discovered that the TX_blah definitions in ckcuni.h contained a duplicate:
both TX_CP923 and TX_ELOT928 were defined as 94.  And then all the rest were
one too low.  Therefore the end of the txrinfo[] table (of function pointers)
was wrong in the last 8 positions.  Fortunately these were for sets we don't
use.  Fixed in ckcuni.h, 31 Aug 99.

Added support for the Hazeltine 1500/1520 graphics set based on reverse
engineering by Jeff of the HZ1520 "personality" of an IBM 3151 contributed by
John Simkiss.  ckcuni.[ch], 31 Aug 99.

Changed F001 debug() format (never used) to be like F111, except number is
shown in hex.  Also changed F000 to default to hex display for numbers that
are not single-byte chars.  ckuusx.c, 31 Aug 99.

Added special-case handling for UCS Line and Paragraph Separator characters
(LS and PS) to xgnbyte() (for translating file from UCS to Latin-1, etc, when
SENDing or TRANSLATing) and xpnbyte() (for translating incoming UCS2/UTF8 to
Latin-1, etc, when receiving files).  ckcfns.c, 31 Aug 99.

Discovered a bad bug in ucs2_to_utf8() -- it wasn't handling UCS-2 characters
greater than U+07FF.  My fault -- a careless workaround for compiler warnings
about "comparisons out of range".  Fixed in ckcuni.c, 31 Aug 99.

Changed u_to_b() to return(-2) if LS or PS encountered.  ckcuni.c, 31 Aug 99.

Changed UNIX CONNECT module to handle UTF-8 LS and PS (both are always treated
as CRLF).  ckucns.c, 31 Aug 99.

From Jeff:

 . Let's correct something I said several weeks back.  I swapped the
   meanings of AUTH_USER and AUTH_VALID.  AUTH_VALID means that not only
   could we authenticate the user but we were able to confirm that the
   user has authorization to access the specified account.

 . AUTH_USER only means that we could authenticate the user. It does not
   mean the user is authorized to access the specified account.

 . This distinction is very important on the server.  For instance:

     AUTH K5 INIT jaltman@KRB5.COLUMBIA.EDU
     TELNET /userid:root host

   means that the value of \v(userid) on the server is "root" but
   unless there is specific authorization by 'root' to allow access
   by jaltman@KRB5.COLUMBIA.EDU the authtype will be AUTH_USER and
   not AUTH_VALID.  This means that although we know who
   jaltman@KRB5.COLUMBIA.EDU is, jaltman@KRB5.COLUMBIA.EDU must still
   demonstrate via a login that he is allowed access as "root".

 . For Kermit scripts we now have a \v(authname) variable which will
   contain 'jaltman@KRB5.COLUMBIA.EDU'.  That way authorization lists
   can be used for the account specified by \v(userid).

ckcmai.c ckuusr.h ckuus4.c ckuath.c security.txt ckcpro.w host.ksc, 1 Sep 99.

Also from Jeff, a fix to output from REMOTE commands in which the trailing
line terminator was lost.  ckcpro.w, 1 Sep 99.

In XLATE, range-check csets before using them as array subscripts.  ckuus4.c,
1 Sep 99.

Jeff reported that constructions like "if xxx { commands, FORWARD label }"
failed to find the label.  Subtle problem, which seems to have been with us
always.  Diagnosis: the items in the braces are a macro; the FORWARD code
loops thru the macro definition starting at the current position, but only if
there are enough chars left in the macro definition to contain the label.  In
this case there aren't and the test for how the loop ended ("if (i == m)")
didn't work.  This would tend to happen whenever FORWARD was the last command
in a macro.  The correct test is "if (i >= m)".  Fixed in dogoto().  Also
increased max label length from 50 to 64 or 255 (depending on BIGBUFOK).
ckuus6.c, 1 Sep 99.

Somebody asked why we don't have an APPEND command if we have COPY, RENAME,
DELETE, etc.  I added COPY /APPEND -- took three minutes.  Works with other
COPY switches except /SWAP-BYTES.  I used the cheating method (fopen,
fread/fwrite, fclose) since the zcopy() API doesn't provide for appending.
ckuus6.c, 1 Sep 99.

A couple minor adjustments to pattern lists.  ckcmai.c, 1 Sep 99.

Migrated CONNECT changes for Unicode LS and PS to ckucon.c and ckvcon.c,
1 Sep 99.

Thought about implications of LS and PS to TRANSMIT command, but I decided to
do nothing since I have no access to an actual UTF-8 console (e.g. on Plan 9)
and therefore no way of knowing how incoming UTF-8 characters -- especially
LF and PS -- are echoed.

From Jeff:

 . What do we do when the client is logging into IKSD with the following
   properties:

     SET TELOPT AUTH REQUIRED
     SET LOGIN USER anonymous

   Up until today the client would fail because IKSD would see the

     IAC SB AUTH NAME anonymous IAC SE

   message and reject telnet authentication because you can't
   authenticate "anonymous".  However, that is not really true.  Now that
   I properly understand and have implemented the distinction between
   AUTH_VALID and AUTH_USER there is no reason to reject "anonymous" for
   all authentication methods.  When Kerberos is being used it makes
   perfect sense for someone to authenticate using their Kerberos ID but
   then log into the server as "anonymous".  This shows up as:

     authstate = AUTH_USER
     authname  = Kerberos ID
     userid    = anonymous

   Therefore, we automatically log the user in as "anonymous" with
   password equal to their Kerberos ID.

   This does not work with SRP because it is not possible with SRP to
   authenticate as one ID and login as another.

 . Confirmed that \v(userid) is always being set to the correct value.

 . Added a message to zvpass() to indicate anonymous logins for symmetry
   with the non-anonymous login message.

ckcmai.c ckufio.c ckuath.c, 2 Sep 99.

Added support for the Unicode General Punctuation block (0x2000-206f) to the
tx_blah() functions -- various-width spaces and dashes, quotation mark
variations, etc.  ckcuni.c, 2 Sep 99.

Changed UNIX sysinit() to check LOGNAME for userid[] initialization if USER
not defined.  ckutio.c, 2 Sep 99.

Changed the UNIX version to call ckufio.c's whoami() function (formerly
static) to expand \v(user), rather than just printing uidbuf[].  This returns
the ID of the actual logged-in (or su'd) user, and works for IKSD too.  But in
testing this, I discovered that tilde-expansion did not (never did) work in
IKSD so I fixed that too.  ckufio.c, ckuus4.c, 2 Sep 99.

If the nopush variable was set, but NOPUSH was not defined at compile time,
every command that might invoke the shell or another program had to check this
variable, and not all of them did.  One example was "REMOTE blah | command"
(now fixed).  But to ensure no others slip through, I added a check for nopush
in zxcmd(), zshcmd(), and zsyscmd().  ck[uv]fio.c, 2 Sep 99.

Ditto for ttruncmd() and the NET_CMD case of ttopen(), ckutio.c, 2 Sep 99.

Added a new symbol XXNOTAV to ckuusr.h, to be used as the keyword value of any
command that is configured out.  For example, when NOPUSH is defined there was
no PUSH command, but now when NOPUSH is defined, we can leave the keyword in
but make its value XXNOTAV.  All commands whose value is XXNOTAV absorb the
whole command (via cmtxt()) and then print a message to the effect that
"command 'blah' is not configured in this version of Kermit" and fails, which
should be less confusing than beeping and printing a no-such-command message
after the first keyword.  Did this for most classes of top-level commands
except NOXFER (which nobody uses) and NOFRILLS (since the point of that one is
to save space).  ckuusr.[ch], ckuus2.c, 2 Sep 99.

Fixes from Jeff to "help func" + new help text for the Kerberos functions.
ckuus2.c, 3 Sep 99.

Fix from Jeff to a mistake in my ckcuni.c changes yesterday.  3 Sep 99.

New code from Jeff to have SHOW NET display all the IP address of the local
host in case it has more than one.  ckuus4.c, 3 Sep 99.

Fixed some #ifdefs to allow No-Unicode builds: ckuus4.c, 3 Sep 99.

From Jeff: corrections to getlocalipaddr() and getlocalipaddrs(), ckcnet.[ch],
3 Sep 99.

Changed FILE DISPLAY tags from SENDING and RECEIVING to SEND and RECV so server
messages line up better.  ckuusx.c, 4 Sep 99.

Testing RESEND with a "set host * xxxx" server on the far end became confused
very quickly when RESEND seemed to always work instantly without sending
anything.  Reason: When C-Kermit thinks it's in local mode (as it does when
told to "set host *"), it automatically DISABLEs DELETE to protect itself
against autodownload and APC "letter bombs".  But when DELETE is DISABLEd,
FILE COLLISION becomes RENAME.  So if a file named "x" exists and I send a new
copy, the new copy becomes "x.~1~".  If the send is interrupted and then I
"resend x", the receiver looks at the *original* x, not x.~1~ and either says
"don't bother, it's already here" (if my copy is not bigger than the copy on
the other end), or worse, corrupts the result.  Of course the problem goes
away if you tell the connection receiver to ENABLE DELETE.  I don't see any
other way out of this mess...

Anyway, once this was sorted out, many repetitions of sending a file,
interrupting the transfer, and resending it multiple times before the transfer
was finished failed to show any kind of problem or corruption of the received
file.

Those obnoxious HINT messages were coming out every time a transfer was
interrupted from the keyboard.  This was happening because the "interrupted"
flag had become overloaded (see notes from June 29th).  Separated the
different meanings into different flags: "interrupted" means a file transfer
was interrupted from the keyboard by the user; "fatalio" means a transfer was
interrupted because of a fatal i/o error (ttinl() fails or ttchk() returns -1).
Added a catch-all in case input() returns 'q' for neither of those reasons (it
shouldn't).  ckcfn[s2].c, ckcpro.w, ckuus[5x].c, 4 Sep 99.

Sending BYE to a "set host * xxx" server had the rather surprising effect of
logging out the job under which it was running.  Since these jobs are usually
set up by hand, with the owner in attendence, this could be harmful -- letting
another person kill other programs the user might have running (mail, editor,
etc).  So in the TCP server case (but not IKSD) made BYE received by server
cause Kermit to exit rather than log out its own job.  ckcpro.w, 4 Sep 99.

Client, after sending BYE, should not be receiving EXIT warnings.  Made sure
that after sending BYE and receiving the ACK (or failing to after trying),
the client calls ttclos().  ckcpro.w, 4 Sep 99.

Some minor improvements to SHOW PROTOCOL display suggested by Lucas Hart.
ckuus4.c, 4 Sep 99.

Jim Whitby reported complaints about:

  sxx = xls[tcs][csin];		/* translation function */
  rxx = xlr[tcs][csout];	/* pointers. */

in ckuus4.c on Unixware 7.1 ("declaration out of scope").  I was finally able
to reproduce them; xls[][] and xlr[][] were declared twice. ckuus4.c, 4 Sep 99.

Corrected typos in top-level command keyword table for new "not available"
entries.  ckuusr.c, 4 Sep 99.

Preliminary run-through of major feature sets & platforms:

  Full VMS...ok (VAX VMS 5.5-2 VAX C 3.2 UCX 2.0)
  NoNet VMS..?? <-- Doesn't work yet...
  Full Unix..ok (SunOS gcc - ANSI - select())
  Full Unix..ok (SunOS gcc - ANSI - fork())
  Full Unix..ok (SunOS cc - no ANSI)
  Full Unix..ok (HP-UX cc - no ANSI)
  Full Unix..ok (Unixware 7.0 - ANSI)
  Full Unix..ok (Linux RH 5.2 gcc - ANSI)
  linuxnotcp.ok (Linux RH 5.2 gcc - ANSI)
  linuxnc....ok (Linux RH 5.2 gcc - ANSI)
  Krb4.......ok (SunOS)
  Krb5.......?? (Linux) <-- NO
  Krb4+Krb5..?? (Linux) <-- NO
  NOUNICODE..ok
  NOCSETS....ok
  NONET......ok
  NOLOCAL....ok
  NODIAL.....ok
  MINIDIAL...ok
  NOSPL......ok
  NOICP......ok
  NOSHOW.....ok
  NOHELP.....ok
  NOPUSH.....ok
  NODEBUG....ok

As always, much #ifdef and declaration juggling required:
ckuus[r467x].c, ckctel.c, ckcfns.c, ckudia.c, ckuscr.c.  4 Sep 99.

From Jeff: Updated makefile for Linux Kerberos 5 builds, a new error message
for bind failures, some auth changes: makefile, ckcnet.c, ckuath.c, 5 Sep 99.
Linux Krb5 builds now ok.

To clear up ENABLE/DISABLE DELETE vs SET HOST * confusion, changed ENABLED
macro to take tcp_incoming into account (Jeff's suggestion).  Moved
declaration of tcp_incoming to ckcmai.c, added an extern declaration for it to
ckcker.h (where ENABLED is defined, so we can use ENABLED() in any module
without getting confused by undefined symbol errors for a symbol we can't
see), removed extern dcls for it that were previously in ckcnet.c, ckctel.c,
ckucns.c, ckucon.c, and ckuus4.c.  For ENABLE/DISABLE purposes, REMOTE means
(!local || tcp_incoming) and LOCAL means (local && !tcp_incoming).  5 Sep 99.

Some research revealed that errno could be referenced in any version of VMS
(at least back to 5.5) if we include <errno.h>.  Some unguarded references to
errno had crept in since Beta.09, which were making VMS NONET builds fail.
Added #include <errno.h> for VMS to ckcdeb.h.  5 Sep 99.  (Except the SPCVXA
installation, which has messed-up header files.)

Corrected some syntax problems in VMS files: ckvfio.c didn't like arithmetic
involving a mixture of signed and unsigned char pointers; ckvcon.c needed its
chkaes() routine converted from void to int.  Now both UCX and NONET builds
are OK on both VAX and Alpha.  5 Sep 99.

Corrected a typo in the STATISTICS command (introduced yesterday) that could
cause garbage to be printed in the "status" field (or worse).  ckuus4.c,
5 Sep 99.

Cleaned out some declared but unused variables.  Most modules.  5 Sep 99.

Recent changes to haddr_list stuff broke HP-UX 5.00 Win/TCP, had to undef
HADDRLIST for HPUX5.  ckcnet.h, 5 Sep 99.

The new code for \v(user) had the prototype for whoami() inside some #ifdefs
it should have been outside of.  ckuus4.c, 5 Sep 99.

Added NOCSETS and NOSPL to revive 16-bit QNX build.  Then it compiled but
Telnet didn't work.  Built with NONET.  But it still doesn't work -- it beeps
all the time, won't transfer files in remote mode, etc ("send xxx" complains
read access denied when the permissions are fine, etc).  Since nobody has ever
asked for this version, we'll retire until/unless somebody does.  makefile,
5 Sep 99.

On a VMS 7.2 system that has Multinet installed as the production network but
also has UCX xxx available, CKVIOC.C wouldn't build because UCX$C_IOCTL was
not defined for some reason (everything else was OK).  Added a clause to
define as "2" if it was not defined.  ckvioc.c, 5 Sep 99.

From William Bader: new ckvold.com to account for ckcuni.[ch] and ckvold.c
that include fmod() missing from old math library.  6 Sep 99.

Went back and undid the sweeping VMS errno change, since it was fatal on most
Multinet systems.  Instead, added explicit #include <errno.h> directives to
each module affected, after including all other header files, if VMS is
defined and TCPSOCKET is not defined.  ckcdeb.h, ckuus[67].c, 6 Sep 99.

Removed double declarations for "i" from two routines in ckucon.c to fix
X.25 builds.  6 Sep 99.

---Beta.10---

A couple small changes for the Amiga from Steve Walton.  ckusig.c, ckuus5.c,
7 Sep 99.

Some syntax & makefile fixes for Dynix/ptx 2.16 from Roger J. Allen.
ckuus6.c, makefile.  8 Sep 99.

Minor syntax changes for compilation errors in Coherent 4.2 build
("declaration hides parameter", "trailing comma in initializer list", etc).
ckucmd.c, ckuus[23456].c, ckcfns.c, ckctel.h, ckcuni.c, 8 Sep 99.

From Jeff:

 . I removed a bunch of #includes that were no
   longer necessary and reduced the number of #defines.

 . updated the makefile entries for krb5 to use the
   /usr/local/{lib,include} trees instead of the kerberos distribution
   tree since we no longer reference non-public header files.

 . Put in CM_ABR entries for "binary-transfer"

makefile ck_crp.c ckuath.c ckuat2.h ckuath.c ckuus3.c, 8 Sep 99.

New consolidated makefile entries for NetBSD.  makefile, 8 Sep 99.

Corrections to pyrdcosx, sni543, and sni544 entries from Graham Jenkins.
makefile, 8 Sep 99.

New dynixptx216 makefile entries from Roger Allen.  Workaround for asm
symbol-table overflow in ckcuni + new gcc entry.  makefile, 9/9/99.

Fixes from Jeff to typos in my changes from yesterday: ckucmd.c, ckuus4.c,
9 Sep 99.

Put base64 stuff in #ifndef NOSPL and moved query declaration from ckuus7.c
to ckcmai.c to fix 2.11 BSD build.  9 Sep 99.

I had added an escape clause to the SCO 2.3.4 builds for not optimizing
ckuus3.c because last time I tried it seemed to get stuck forever, but
apparently the sticking was because of something else because now it builds
fine, so removed the escape clause.  makefile, 9 Sep 99.

From Jeff: Disable WHO, HOST, etc, in IKSD.  ckcmai.c, ckcfns.c, 9 Sep 99.

From Jeff: Add a note to docs that "-0" includes TELOPT KERMIT REFUSE REFUSE.
ckermit2.txt, 9 Sep 99.

If SET SEND PATHNAMES OFF, strip path from filespec sent back in the ACK to
the F packet.  Believe it or not, there is a Kermit program (for MUMPS) that
compares the returned name to the sent one and fails if they are not the same.
But then I realized that SEND PATHNAMES is already OFF by default, so this
would be a bad change, since it takes away the ability of the receiver to tell
the sender where the file went in the default case.  So I backed off and added
a new (invisible) command SET F-ACK-PATH { ON, OFF }, and it's ON by default.
Documented in Section 4.22.4 of ckermit2.txt.  ckuusr.h, ckcmai.c, ckcpro.w,
ckuus[r3].c, 9 Sep 99.

Discovered that FOPEN /APPEND did not (and never did) work if the file did
not already exist.  The code for this case was there, but never tested, and
needed a small fix.  Now it works.  ckuus7.c, 9 Sep 99.

Noticed that packet i/o statistics were wrong for receiving files when
streaming -- ACKs were counted that shouldn't have been (stats were correct,
however, when sending).  Fixed in spack(), ckcfn2.c, 9 Sep 99.

It was bothering me that to make a Telnet connection to a misbehaving Telnet
server, you had to SET TELNET WAIT OFF first, because this is sticky and
affects all subsequent connections unless you remember to undo it.  So I added
/WAIT and /NOWAIT switches to SET HOST and TELNET to specify [no] waiting
just for this connection.  I implemented it in the stupidest possible way,
which probably needs improvement.  I simply save tn_wait_flg and set it to the
switch value before calling ttopen(), then restore it immediately upon return
from ttopen(), since hanging onto it and restoring it at some later time would
be pretty tricky.  VERY tricky, in fact.  ckuusr.h, ckuus7.c, ckermit2.txt,
9 Sep 99.

Changes from Jeff... refinements to ENABLE/DISABLE for IKSD, generalization
of TELNET / SET HOST switches to (a) include other relevant parameters, and
(b) make then persist throughout the connection and restore them when the
connection is closed; fix a typo in my F-ACK-PATH code; ckuus7.c ckuath.c
makefile ckuus3.c ck_crp.c ckcnet.c ckctel.c ckuus6.c ckuusr.c.  Supplied
some missing #ifdefs in ckuus3.c.  12 Sep 99.

Protected #include <term.h> with #ifndef NOTERMCAP to fix linuxnc build on
systems that actually do not have <term.h> (because they failed to choose
ncurses at Linux install time).  ckuusx.c, 12 Sep 99.

At the suggestion of Markus Kuhn, replaced utf8_to_ucs2() with a more robust
version adapted from Xfree86 xterm (Thomas Dickey).  The previous version
(Mark Davis, Unicode website samples) only works with well-formed UTF-8
sequences.  The new version works equivalently but should handle malformed
sequences properly.  Unfortunately, the caller must treat the return value a
bit differently now, and this can be a bit complicated because under certain
conditions, it can return *two* values (0xfffd followed by valid character)
when a UTF-8 sequence is interrupted by (say) an ASCII character.  ckcuni.c,
12 Sep 99.

With this change, an invalid UTF-8 sequence becomes 0xfffd, and if it was
interrupted by the valid character, the valid char is lost.  This is better
than before, but not ideal.

The callers of utf8_to_ucs2() are:

  ckcfns.c: rc = utf8_to_ucs2(ch,&us);  <-- In xpnbyte()
  ckcfns.c: rc = utf8_to_ucs2(ch,&us);  <-- In xgnbyte()
  ckcuni.c: x = utf8_to_ucs2(c,&ucs2);  <-- In u_to_b()

Let's see if we can fix them...

The problem with u_to_b() (which is called by the CONNECT modules and by
TRANSMIT) is that it has an argument -- the next UTF byte.  So there's no good
way to save up a second value and return it next time, because we'll get
increasingly far behind.  But we can make it return a special negative code,
say -9, to mean: "Use the error character, and then call me again to get the
next character".  But that won't work, because there's no special arg it can
be called with that says to return the saved character, because its arg is a
CHAR.  So we need a second routine for that, u_to_b2().  OK, that was easy:
ckcuni.c, ckucns.c, ckuus4.c, 12 Sep 99.

xpnbyte() and xgnbyte() were a bit trickier but I made a first stab at it.
The resulting Kermit still seems to handle well-formed UTF-8 OK (as it did
before), but supposedly now should handle invalid UTF-8 sequences by the book.
Sent the result off to Markus for more testing.  ckcfns.c, 12 Sep 99.

New (tested) NetBSD entries from Graham Jenkins.  Makefile, 18 Sep 99.

Updated Commodore Amiga source files from Steve Walton, mainly addition
of ttgwsiz() and isdir(): cki*.c, 18 Sep 99.

Added LinuxPPC makefile entry from Nick Strauss <nicks@carriage.chesco.com>.
makefile, 19 Sep 99.

Lucas Hart reported that "set file download-directory ?" listed regular
files as well as directories.  Actually the same was true of any command that
parsed a directory name, including CD.  Fixed in cmifi2(): ckucmd.c, 19 Sep 99.

Mark Sapiro reported that we still have the problem with timestamps of
incoming files in BSDI being off due to DST confusion.  Steve Schultz's
diagnosis was that the BSD44 path was the tm_gmtoff adjustment already
accounted for DST, so when adjusting for DST after that, we were effectively
subtracting two hours instead of one.  The fix of minimum boat-rocking was to
adjust for DST only in the non-BSD44 case, rather than always.  zstrdt():
ckufio.c, 19 Sep 99.

Accumulated changes from Jeff since last week:
 . Make \v(filename) retain name of last file transferred.  ckuus4.c.
 . Fix clearchannel auto.  ckuus[25y].c, ckcfns.c, ckermit2.txt.
 . Fix streaming vs draining after E-Packet while receiving.  ckcfn2.c.
 . NOPUSH was blocking client end of RHOST.  ckuus7.c.
 . REMOTE { SET, ASG, COPY, RENAME } did not set success=1 and so would
   not resume CONNECT mode when invoked via autodownload.  ckcpro.w.
 . Reinstates the use of select() on TCP/IP connections when streaming so
   we can detect connection loss.  ckcnet.c.

The last one + the clearchannel changes also result in a dramatic performance
improvement on certain kinds of connections, notably TCP/IP over ADSL (in one
trial, 4BM of precompressed data was transferred 2.6 times faster than with
FTP.

Fixed \v(filename) to work more consistently, since sometimes it was empty
after a successful file-group transfer because (for some unknown reason)
filnam[] was empty.  Rather than figure out why this would be and "fix" it
(probably breaking something else) I use the WHERE command info if filnam[]
is empty.  ckuus4.c, 19 Sep 99.

Added RELIABLE and CLEARCHANNEL to STATISTICS /VERBOSE display.  This shows
not the settings (usually AUTO, not very informative), but whether the
features were actually negotiated and used.  ckuus4.c, 19 Sep 99.

Added sco32v505udk makefile target on advice from Thomas M. Gill <tom@hcd.net>,
who says in this case -DDCLTIMEVAL must be added.  makefile, 19 Sep 99.

Added uw2iksd entry (Unixware 2, like 7, needs shadow password support for
authentication).  makefile, 19 Sep 99.

At Lucas Hart's suggestion, make bzero and bcopy be macro definitions in VMS,
replacing themselves by memset and memcpy, to squelch the warnings we've been
getting about them all these years.  Probably a bad idea...  (Another idea
would be to *replace* all references to bzero and bcopy with memset &
memcpy but they're not portable either so let's try this first...)  Builds and
runs OK on Alpha VMS 7.1 UCX; Alpha VMS 7.1 TGV; VAX VMS 5.5-2 UCX; VAX VMS
7.1 TGV (this one always got errors before) -- so let's keep it.  ckcnet.h,
19 Sep 99.

The newest DECC compiler, 6.2FT, spews out reams of %CC-W-NOTULALQUA warnings
for constructions like memmove(&xabfhc_ofile.xab$w_lrl,filptr,2), having to do
with struct member alignment.  The consensus is that these warnings are both
harmless and overzealous -- they might be important if we were moving multiple
members of a struct at once and assuming a fixed number of bytes (when the
Alpha might insert padding and the VAX might not).  But we're not doing that.
Suggestions for making the warnings go away (like #pragma nomember_alignment,
or adding compiler switches that only work on some versions of some compilers)
are dangerous, so we'll just live with the warnings.

Lucas says DECC -- at least back to V1.3 (1993) -- has an /UNSIGNED_CHAR
switch (which is not the default).  Tried building C-Kermit on an Alpha with
DECC 5.5-002 with p4 = "/UNSIGNED_CHAR" -- perfect, not a single warning.  In
ckvker.com, at the DECC: label, it is probably OK to change 'ccopt =
"/decc"+ccopt' to 'ccopt = "/decc/unsigned_char"+ccopt'.

Changed VMS C-Kermit IDs from "7.0.195" to "7.0.196" (for ANALYZE/IMAGE).
ckvker.com, ckvold.com.  19 Sep 99.

From Lucas:
 . Fixes for DELETE in VMS, plus implementation of /ASK.  ckuus6.c.
 . Fix recovery from illegal filenames in the LOG command.  ckvfio.c,ckuus4.c.

Added implementation of /LIST to Lucas's implementation of /ASK, and added
code to error out if user included /SIMULATE on platforms that don't support
it.  ckuus6.c, 19 Sep 99.

Fixes needed for VOS, 20 Sep 99:
 . Shuffle declaration of inserver in ckctel.c.
 . Shuffle declaration of xaskmore in ckuus7.c.

Correction to kstart() from Jeff.  ckcfn2.c, 20 Sep 99.

Remove some more now-superfluous bcopy/bzero definitions from ckcnet.h,
20 Sep 99.

For the benefit of DECC 6.2, add a DECC-only replace for the VMS/SMG printw()
replacement that handles "varargs".  ckuusx.c, 20 Sep 99.

There has never been a way to give a DIAL command that specifies a list of
phone numbers to try until one answers, except by creating a dialing directory
and putting multiple entries in it under the same name.  This is a big pain,
especially when using the K95 dialer.  Now the DIAL command accepts "makelist"
notation, as in:

  dial {{7654321}{8765432}{9876543}}

These have to be actual numbers to dial, not names of dialing directory
entries.  Conversely, dialing directory entries can not contain lists like
this.  Otherwise, the numbers are treated as if they had been fetched from the
dialing directory; they can be in literal or portable format, etc.  ckuus6.c,
20 Sep 99.

Updated ICL makefile targets for IKSD.  21 Sep 99.

Fixes for #ifdefs vs Telnet variables from Jeff.  ckuus[37].c, 21 Sep 99.

From Jeff: debug stmt added to ckuath.  Cleaned up long lines.  21 Sep 99.

From Jeff: improved handling of Telnet negotiation timeouts.  ckctel.c,
ckcnet.c, 21 Sep 99.

SET PROTOCOL was invisible for non CK_XYZ builds, but people still need to
use it to set the Kermit upload/download command strings, so made it visible
in all cases.  ckuusr.c, 21 Sep 99.

Fixed HELP SET PROTOCOL for non-XYZ case.  ckuus2.c, 21 Sep 99.

Another tn_wait declaration fix from Jeff.  ckuus7.c, 22 Sep 99.

From Jeff: some improvements to the Telnet negotiation timeout code and
messages.  ckctel.c, 22 Sep 99.

Updated HELP DIAL text for phone-number lists.  ckuus2.c, 22 Sep 99.

It seems that ever since C-Kermit 6.0, C-Kermit prompts and image-mode
commands have not appeared in VMS batch logs.  This was intentional -- most
people did not want them there.  However, there was no way to undo this.
Switched the code around so that starting Kermit with -z on the command line
or giving it a SET BACKGROUND OFF command after it started would enable
issuing of prompts and echoing of commands even in batch.  Also enabled the
file-transfer display in batch, but forced it to BRIEF if it was set to CRT or
FULLSCREEN.  ckcker.h, ckvtio.c, ckuus[3]x.c, ckucmd.c, 23 Sep 99.

Another unhappy discovery: VMS C-Kermit no longer reads image data from a DCL
command procedure executed at the terminal.  This is entirely separate from
the batch issue -- Kermit *does* read image data in batch, even when executing
the exact same .COM file.

Discovered that the -d command-line option also set the timestamp feature -- I
probably put that there for some testing and forgot to take it out.  So now
it's out.  ckuus4.c, 23 Sep 99.

OK, now I can compare the three VMS debug logs...

  congm sys$getjpiw mode_flags=3 <-- Interactive
  congm sys$getjpiw mode_flags=3 <-- DCL
  congm sys$getjpiw mode_flags=2 <-- Batch

So DCL and Interactive look the same.  However, isatty(0) fails for DCL and
Batch but succeeds for Interactive.  So I made a new flag, "itsatty", for VMS
that is nonzero if sys$input is the terminal, which it isn't in a batch job or
in a DCL command procedure.  And I changed the hack in VMS coninc() to return
getchar() if (!itsatty), rather than only if (batch).  Now the documentation
is right again.  ckvtio.c, ckvbwr.txt, 23 Sep 99.

From Jeff: Back off on le_buf echoing changes for all but K95; add
SO_DONTROUTE support.  ckcnet.c, 23 Sep 99.

User interface for SO_DONTROUTE from Jeff.  ckuusr.[ch], ckuus[34].c,
ckcmai.c, 24 Sep 99.

New security.txt and telnet.txt from Jeff.  24 Sep 99.

Peter E reported that LOG commands didn't work any more, e.g.:
  [/tmp_mnt/eip/cku195/b10+04/] C-Kermit>log connections
  ?Invalid: log connections

The problem is because of the change from Lucas Hart of a few days ago, in
which the LOG command returns -2 if zfnqfp() returns NULL.  In this case
zfnqfp() returns NULL because realpath() fails, evidently having something to
do with being called by root.  So I backed off on Lucas's change for the LOG
command to fail if zfnqfp() failed.  The real fix would be for VMS zchko()
(and for that matter, zopeno()) to fail gracefully when given an illegal
filename.  ckuus4.c, 24 Sep 99.

Put \v(line) back the way it was in 6.0, so it always shows something,
rather than returning the empty string when in remote mode.  I don't know why
it was changed, but some people didn't like it.  ckuus4.c, 24 Sep 99.

The old problem with packet 0...
 . Client sends I to server.
 . Server sends ACK(I) back to client.
 . Client sends REMOTE blah to server.
 . Server doesn't receive it, so resends ACK(I).
 . Since these are all packet 0, client thinks this is ACK(REMOTE blah)

Previously we had a heuristic in place for GET: If we sent a GET command and
were answered by an ACK, we knew this had happened because GET can never be
answered by an ACK (see <get>Y state).  But a REMOTE command can get a
short-form answer, which is in an ACK; when the ACK comes, the client prints
the answer and then quits, thinking the transaction is over.  This actually
turns out to be OK with the server too, since as far as the server is
concerned, the I/Y exchange is a complete transaction too.  The problem is,
the requested REMOTE operation never took place.  So a new (ultra-gross)
heuristic was added.  At <ipkt>Y, we save a copy of the contents of the
I-packet.  Then at <rgen>Y, we check to see if the contents of the ACK we just
got match those from ACK(I) and if so, we resend the REMOTE command packet and
wait for another ACK.  All of this code is within #ifdef PKTZEROHACK..#endif,
and confined to ckcpro.w.  It doesn't seem to hurt anything, but it's hard to
set up a test case to actually force the condition.  24 Sep 99.

Added a (char *) cast to rdatap, which is (CHAR *), in the new <rgen>Y code.
ckcpro.w, 27 Sep 99.

Added an x-ref from HELP ECHO to XECHO and WRITE SCREEN.  ckuus2.c, 27 Sep 99.

From Jeff, 27 Sep 99:
 . Fixed typos in SET EDITOR code: ckuus[r4].c.
 . Fixed some mistakes in \v(hwparity) and v(serial): ckuus4.c.
 . Shuffled some Kerberos & SRP #ifdefs: ckcdeb.h, ckcfns.c.

Fixed a problem Jim Whitby noticed with quoting in ELSE statements.  This
problem was introduced when I unified IF and XIF, and occurs only when
ELSE begins on a line, followed by a { command list } rather than a single
command.  The solution (gross) was to make a special version of pushcmd()
(called pushqcmd()) for this situation, which doubles backslashes while
copying, BUT ONLY IF it's a command list (i.e. starts with "{"); otherwise
we break lots of other stuff.  Result passes Jim's test and still passes
ckedemo.ksc and iftest.ksc.  ckucmd.c, ckuus6.c, 27 Sep 99.

After learning that QNX does not always include TCP/IP, added a qnx32nonet
makefile target.  28 Sep 99.

Put the (char *) cast back in the strncmp() call in <rgen>Y; I don't know
why it keeps disappearing....  ckckpro.w. 28 Sep 99.

From Jeff: Fix confusion between #ifdef IKSD and #ifdef CK_LOGIN, allowing
a clean separation of the two concepts, and therefore IKSD implementations
on platforms that don't have authentication.  Most modules, 30 Sep 99.

Put the (char *) cast back in the strncmp() call in <rgen>Y; I don't know
why it keeps disappearing....  ckckpro.w. 30 Sep 99.

Changed ROBUST macro definition to also SET RELIABLE and (where appropriate)
CLEARCHANNEL OFF.  ckuus5.c, 30 Sep 99.

The previous change had no effect since the sequence SET RELIABLE OFF, TELNET
xxx also had no effect -- Kermit would SET RELIABLE ON anyway.  The problem
is that it had no way of knowing whether RELIABLE was OFF because the user
commanded it, or because it was set to OFF automatically when the previous
connection was not reliable.  Fixed with Yet Another Global Flag.  ckcmai.c,
ckuus[37y].c, 30 Sep 99.

From Jeff: Replace a missing line in ckuus4.c from yesterday's merge. 1 Oct 99.

From Jeroen Scheerder <J.Scheerder@csi.nl>: makefile target for Mac OS X 1.0.
(straight "make bsd44" works out of the box).  makefile, 1 Oct 99.

Also from Jeroen Scheerder: supply a missing semicolon in ztime().  ckutio.c,
1 Oct 99.

Added Mac OS X symbols, designer banner. ckcdeb.h,ckuver.h,makefile, 1 Oct 99.

From Michael Weiser <michael@weiser.saale-net.de>: Fill in some missing
#ifndef NOXFER..#endif clauses.  ckucns.c, ckufio.c, ckuus[r47x].c, ckuscr.c,
1 Oct 99.

From Jeff: New IF IKSD command.  ckuusr.h, ckuus6.c, 3 Oct 99.

From Jeff: Hooks for Windows IKSD.  ckuusy.c, ckcdeb.h, ckcmai.c, ckuath.c,
3 Oct 99.

From Gary Brown <gsb@wcom.net>: "Situation: C-Kermit 7.0.196 Beta.10, 4 Sep
1999, on a Linux system configured so the lockfile directory is not world
writable (but it is writable by group uucp, and kermit is setgid uucp).  Bug:
if you do a "set line" to a port that's already in use, Kermit leaves a
temporary lockfile ("/var/lock/LTMP.12345" or the like).  Then if you then do
another "set line," specifying another port, you get a "Sorry, write access to
UUCP lockfile directory denied" error.  Cause: If the (real) lockfile for that
port already exists, ttlock() in ckutio.c calls ttchkpid() to see if it's
stale.  ttchkpid() returns with privileges off, so the subsequent
unlink(tmpnam) fails, leaving the temp file around.  A subsequent "set line"
command fails, apparently because the creat() fails with EACCES, although it
successfully unlinks the file after that, so a third attempt will succeed.
And if the lockfile turns out to be stale, I suspect that the link() will fail
on the next pass through the loop, although I didn't test that case.  Fix: I
think the best bet is to priv_off() before calling ttchkpid() and priv_on()
afterwards (needed in two places)."  ckutio.c, 3 Oct 99.

Added an Openstep 4.2 Makefile target, based on NeXTSTEP 3.3.  3 Oct 99.

First cut at a Shift-JIS to UCS-2 translator (as a separate program).  It has
two big tables for Kanji (about 8K and 2.5k entries, respectively, for a total
of 10.5K unsigned shorts so about 21K bytes, of which 6K is wasted due to
sparseness).  Then it has an algorithmic translation for Katakana and a simple
transformation for Romaji and controls (a very small amount of code).  The
result compiles to about 40K on a Sparc and goes fast: 0.28 sec to convert a
100K Shift-JIS file, or 360Kcps.  Some tuning might be able to bump up the
speed.  To be continued...

From Jeff, 4 Oct 99:
 . Hooks to mainline code for Windows NT authentication: ckcmai.c, etc.
 . Allow password to echo when logging in to IKSD anonymously: ckuus7.c.
 . Fix TRANSLATE command to work in K95 when writing to console: ckuus[r4].c.
The output-file character-set for TRANSLATE now defaults to "ucs2" for Unicode
output systems (e.g. Windows NT console) and the file character-set otherwise.

Rounded up Shift-JIS example files from the net (mostly HTML) for checking,
analysis, and benchmarks.  Streamlined the Shift-JIS/UCS-2 code, plugged some
holes, and added code to handle the User-Defined area (both sets have one).

Updated Mac OS X makefile targets from Jeroen Scheerder.  makefile, 4 Oct 99.

Also from Jeroen Scheerder: a cast to shut up warnings about an arg to
localtime() in ztime().  ckutio.c, 4 Oct 99.

Fixed OpenStep target to build ckcpro.c separately without optimization since
it crashes the compiler.  makefile, 4 Oct 99.

Changed CHAR * tocs to char * to shut up stubborn stupid compilers.  ckuusr.c,
5 Oct 99.

Changed calls to mdmhup() to not fall back on tthang() if mdmhup() fails.
In other words, if SET MODEM HANGUP-METHOD is MODEM-COMMAND, then we use the
modem command; otherwise we drop DTR or whatever.  ckucns.c, ckudia.c,
ckuusr.c, 5 Oct 99.

From Jeff: Don't switch to clearchannel automatically on Rlogin connections.
ckcfns.c, 5 Oct 99.

From Jeff: Fix typos; fix Telnet screen-dimension negotiation for K95 IKSD.
ckcmai.c, ckuusr.c, ckctel.c, 6 Oct 99.

Rolled back SET MODEM HANGUP change -- it broke a lot of other stuff.
ckucns.c, ckudia.c, ckuusr.c, 6 Oct 99.

From Lucas Hart:

  Changes included in ckvio.diff (which also has a ckcmai.c patch for
  isabsolute):

  - Fill in zchko
  - Change log file error handling, zopen and zclose
  - Use parse result to handle <> and rel names in zmkdir; cleanup
  - Extend nzrtol to handle device spec in absolute to relative;
    more <> dir syntax;  no longer need absolute for zmkdir;
  - Convert non-file oriented device name to upper case in zfnqfp
    instead of appending cwd;  replace multiple strncat calls
  - Fix fgen edit 165
  - Fix typo in zrmdir

  Some quick comments on some of the code:

  - "graceful" error handling for log files

  My implementation of zchko does not fail when given an illegal file name,
  because nzrtol may subsequently convert a "multiple dot" Unix name to a
  legal file name, so the illegal file name causes a fopen error in zopeno.
  (Of course, it does make sense to convert the file name before testing
  for write ability, but I'll leave that for your consideration.)

  In zopeno,  perror(name) gave:
  beta10+ > log t xxt+.log
     xxt+.log: non-translatable vms error code: 0x186D4
    %rms-f-syn, file specification syntax error
  which I eventually transformed to a more concise:

    ?fopen file name syntax error : xxt+.log

  (I'm not sure about the declaration of ckvmserrstr; used the same
  form as in ckuus4.c)

  Note that the Unix zopeno has

      #ifdef COMMENT              /* Let upper levels print message. */
	  perror("Can't open output file");
      #endif /* COMMENT */

  but I didn't find where a message is printed (at least where zopen is
  called in ckuus4.c)

  - don't know when the logs are flushed to disk; the log files are no
  longer 'locked by another user' when attempting to view them from
  another process and the files are still open, but I have yet to read
  data.  One step forward.

  - you would suggest looking at zchko :)  I check write capability with
  a RMS write and delete on close.  Easier to code than checking all the
  conditions under which VMS will grant write permission, and ckcplm.txt
  says
      Checks to see if a file of the given name can be created.  Returns:
      -1 if file cannot be created, or on any kind of error.
  (in contrast to the ckufio chko() text which states denial of write
  permission is the only error condition.)

  I still have some zchko questions but I'll send them separately, as they
  may relate to other problems that occur with the original zchko.

  - I don't like to think of how long it took me to find the typo in zrmdir.
  The symptom was that mkdir and rmdir were fine when no device was specified,
  but not on another disk.

  - In zmkdir, I eliminated some old code instead of commenting it out -
  for clarity only;  otherwise I pretty much patched my code in.

  - Hope you don't mind the suggestion for eliminating the multiple strncat
  calls in zfnqfp; the original seems repetitous but is well exercised.

ckcmai.c, ckvfio.c, 6 Oct 99.

Added some clarifications to GET docs & help text.  ckermit2.txt, ckuus2.c,
7 Oct 99.

From Jeff, 7 Oct 99:

 . Added the ability to assign additional IP addresses for embedding into
   a Kerberos 5 TGT.  This is necessary for using K5 through a Network
   Address Translator.

 . Fixed a bug in the telnet negotiations.  If SB START_TLS FOLLOWS has
   been sent then we cannot send addition subnegotiations.  All attempts
   to send sub negotiations should be dropped on the floor.

ckctel.c ckcnet.c ckuath.c security.txt ckuus2.c ckuus7.c ckuath.h ckuusr.h.

Lucas Hart pointed out that "log session /foo/bar/baz/xxx" did not print an
error message when any of the directory path segments after the first did
not exist, as long as the user had write access to the path up to that point.
This points out a flaw in the zchko() design -- it doesn't distinguish among:

 . Can I overwrite an existing file?
 . Can I create a file (or directory) in an existing directory?
 . Can I create a file (or directory) and its parent(s)?

We can't change zchko() without breaking all sorts of things, so the fix
is to add error messages where they are missing at the higher levels.  In this
case, the log-opening functions were printing messages if zchko() detected an
error at filename parse time (in fact, these are printed by cmofi(), the
output-filename-parser) but were not printing any message if the parse
succeeded but opening the log failed.  This was fixed in debopn(), pktopn(),
etc (one routine per log).  ckuus4.c, 7 Oct 99.

Moved makelist() and brstrip() from ckuusr.[ch] to ckclib.[ch].  7 Oct 99.

Added a /REDIRECT switch to EXEC (UNIX only).  I don't know if it will work,
but the idea is that if there is a connection active (ttyfd > -1), this will
dup ttyfd to stdio before calling execvp(), the obvious application being to
use C-Kermit as the PPP dialer, and then overlaying itself with pppd or
whatever.  ckcdeb.h, ckuusr.c, ckufio.c, 7 Oct 99.

Added One Last New String Function: \fstripb(), which strips enclosing braces,
brackets, parens, or quotes from its arg.  Many options available, loads of
fun.  ckuusr.h, ckuus[24].c, ckermit2.txt, 7 Oct 99.

From Jeff: fixes for VOS networking.  ck[cl]net.[ch], 7 Oct 99.

From Jeff: a fix for a problem in which DIR would list two or more unreadable
files, but would fail to list one.  ckucmd.c, 7 Oct 99.

Eliminated double error messages when cmifi() fails when called from cmfdb().
ckucmd.c, 7 Oct 99.

Improved DELETE error message when cmfdb() fails.  ckuus6.c, 7 Oct 99.

From Jeff: enable syslogging for NT; NT login code juggling; more VOS fixes
(mainly for X.25-only build).  ckcdeb.h, ckcmai.c, ckcnet.c, ckuus[347].c,
8 Oct 99.

Received confirmation that EXEC /REDIRECT works, at least on Linux for PPP
dialing.  9 Oct 99.

From Jeff: change many strcpy()'s to strncpy()'s to avoid memory leaks; finish
parameterizing all user-id buffer-length reference to UIDBUFLEN; ditto for
several other kinds of buffers.  ckcfns.c ckucmd.c ckufio.c ckcfn3.c ckutio.c
ckcnet.c ckclib.c ckctel.c, 9 Oct 99.

Worked on Kanji (still offline).

From Jeff: More strcpy -> strncpy: ckufio.c, ckuus[4rx].c; Some corrected
Telnet return codes: ckctel.c, ckucmd.c; updated auth stuff: ckuath.c.
11 Oct 99.

Added ckstrncpy() to ckclib, which does what strncpy() should have done:
handles NULL args, ensures result is NUL-terminated, doesn't gratuitously
right-pad with NULs, and returns something useful: the number of bytes copied.
ckclib.[ch], 11 Oct 99.

Went thru many modules and replaced all strncpy(a,b,n) with ckstrncpy(a,b,n),
and removed subsequent, now superfluous, a[n] = NUL; statements (and also
marveled at the number of places where they were lacking).  Also whenever we
had a sequence like "strncpy(a,b,n); m = strlen(a);" this became simply
"m = ckstrncpy(a,b,n);" since ckstrlen() returns the number of bytes copied.
Also changed length references from (e.g.) XLEN-1 to XUFLEN, since ckstrncpy()
assumes it has been given the actual length of the buffer, and ensures that
the terminating byte or last byte is NUL. ck[cuv]*.[cw], 11 Oct 99.

Changed zfnqfp() define for non-zfnqfp() platforms from strncpy to ckstrncpy.
ckcdeb.h, 11 Oct 99.

Fixed return type of main() to agree with its declaration. ckcmai.c, 11 Oct 99.

Fixed some confusion in setting http_array.  ckuusr.c, 11 Oct 99.

Fixed printfs in shofea() that used "%d" to reference sizeof(), which is long.
ckuus5.c, 11 Oct 99.

In DIR /ARRAY, make sure we have a valid array pointer before referring to it.
ckuus6.c, 11 Oct 99.

Various other syntax adjustments, initializing variables, etc, to suppress
-Wall complaints that were not actually valid.  Many modules, 11 Oct 99.

Tested ckedemo.ksc and found that many strings were missing their final
character.  It seems that ckstrncpy() introduces a new subtlety.  Consider:

  char *p, * s = "oofa";
  int n = strlen(s);
  p = malloc(n+1);

The customary practice at this point is to:

  strcpy(p,s);

and this is absolutely correct (and we should keep doing it this way); we
know the buffer is the right size, and strcpy() sets the last byte to NUL.

However:

  strncpy(p,s,n);

is NOT correct, since it will not write a terminating NUL, even though most
people assume it will.  If, instead, you use:

  ckstrncpy(p,s,n);

the result will be "oof<NUL>" (not "oofa<NUL>"), since ckstrncpy() interprets
the third arg as the length of the destination buffer, not the length of the
source string, and it must ensure the terminating NUL.  Therefore, remember
when calling ckstrncpy() to give the actual, real, entire size of the buffer:

  n = strlen(s);
  p = malloc(n+1);
  ckstrncpy(p,s,n+1);  <-- But in this case it's still better to use strcpy().

To illustrate this a different way, suppose you have a string s = "[1]":

  strncpy(s+1,"2",1);  --> "[2]"

But:

  ckstrncpy(s+1,"2",1);  --> "[" (because it NUL-terminates).

So be careful with this one -- it's not a plug-compatible replacement for
strncpy().  I went thru the code and checked each call, and changed some of
them back to strcpy() or strncpy() when appropriate.  In general the rule is:
use ckstrncpy() to copy a string to a general-purpose big buffer whose length
is a constant, e.g. "ckstrncpy(line,s,LINBUFSIZ);" but use strncpy() to copy a
specific number of bytes from the source string, e.g.  "strncpy(line,s,n);"
followed by "line[n] = NUL;" if the intention is not to insert s at the
beginning of the string that is already in line[], or else
"ckstrncpy(line,s,n+1);".

From Jeff: Corrected a misplaced #ifdef from my changes yesterday, which
caused streaming transfers to fail.  ckcpro.w, 12 Oct 99.

Changed a few ckstrncpy's back strncpy's in ckcpro.w and ckcfn*.c.  The rule
is: use ckstrncpy when you don't know the source length, and you are copying
to a buffer whose length is known.  Use strncpy() to copy a specific number
of bytes from the source to the destination.  12 Oct 99.

Prior to integrating Kanji/Unicode translations, built in various
configurations on Linux to get baselines:

  NOCSETS NOUNICODE NOKANJI
   [   ]    [   ]    [   ]    1329014
   [   ]    [   ]    [ X ]    1325686 (because it's all done by algorithm)
   [   ]    [ X ]    [   ]    1158837 (removes 170K, mostly tables
   [ X ]    [ x ]    [ x ]    1090845 (removes 238K, mostly tables)

From Jeff: Symbols & parsing for TELOPT ... COM-PORT-CONTROL.  ckuusr.h,
ckuus[r3].c, 12 Oct 99.

More minor adjustments to yesterday's ckstrncpy() work. ckuus[57].c, 12 Oct 99.

Began merging Kanji/Unicode code from offline into C-Kermit...  Added tables
to ckcuni.c.  This brings full Linux build up to 1393157 bytes.  Added
functions and prototypes to ckcuni.[ch].  Filled in the appropriate calls in
xgnbyte() in ckcfns.c.  Compiled but didn't test.  Full Linux binary now
1400670 (so only about 7K for the code).  The ckcuni.c source file is now over
700K, about twice as long as any other source module.  12 Oct 99.

Filled in xpnbyte() and then began testing.  Everything worked pretty well
except for occasional strange corrupted spots in the new file when using UCS-2
as the transfer charset.  The problem (which is not new to the Kanji code)
turns out to be: getpkt() calls some routine to get the next byte because
that's what we put in packets: bytes.  Well, if the "get next byte" routine
returns (say) 0x0A, getpkt() had no way of knowing that this was actually part
of a Unicode, and therefore not to treat it like a linfeed, and therefore it
inserted a carriage return into the data stream, which of course changed the
Unicode character.  And then it inserted a (null and a) linefeed next time
around.  The cure involved moving all the end-of-line logic for Unicode to
xgnbyte() and disabling it for Unicode in getpkt() itself. ckcfns.c, 13 Oct 99.

Tested sending from PC (Little Endian) to Sparc (Big Endian): OK.  Tested
non-Japanese transfers (e.g. Latin-1) thru Unicode: OK.  Built with NOKANJI,
NOUNICODE, and NOCSETS to make sure #ifdefs were OK.  Built on HP-UX 10.20
with ANSI compiler.  Added -DMAINISVOID to HP-UX 100 ANSI-C compiler targets.
makefile, 13 Oct 99.

From Jeff: Changes for building on Windows 2000, mainly that NOCRYPT must be
defined before #including <windows.h>: ckcsig.h, ckcdeb.h.  IKSD idle timeout:
ckcpro.w, ckuusx.c, ckcmai.c, ckucmd.c.  13 Oct 99.

Added EUC-JP as preferred keyword for JAPANESE-EUC, according to common usage,
and made JAPANESE-EUC invisible.  ckuxla.c, 14 Oct 99.

Finally gave in and added REMOTE SET FILE CHARACTER-SET.  It simply passes the
character-set name string to the server, which looks it up in its own table;
thus the string must be in the server's syntax.  When the server gets this
command, it also disables automatic character-set selection (otherwise the
command would have no effect).  ckuus7.c, ckcfns.c, 14 Oct 99.

This enables cycling through all the new translations in a script like so:

dcl \&x[] = euc ucs2 utf8             ; xfer charsets
dcl \&y[] = eu uc ut                  ; abbrevs
dcl \&f[] = shift euc jis7 ucs2 utf8  ; file charsets
dcl \&g[] = sj eu j7 uc ut            ; abbrevs

set file char shift-jis               ; local file character-set is Shift-JIS
for \%i 1 \fdim(&x) 1 {               ; for each transfer character-set...
    set xfer char \&x[\%i]            ; set it
    for \%j 1 \fdim(&f) 1 {           ; for each remote file character-set...
	remote set file char \&f[\%j] ; set it
        if fail exit 1 SERVER REJECTED CHARSET
        send /text meibo-sj.html meibo-sj-\&y[\%i]-\&g[\%j].txt
        if fail exit 1 TRANSFER FAILED
    }
}

Ran this test (the source file is Shift-JIS and contains Roman, halfwidth
Katakana, and Kanji) and inspected the results: 9 good, 6 bad:

  meibo-sj-eu-eu.txt  Looks ok
  meibo-sj-eu-j7.txt  Looks ok
  meibo-sj-eu-sj.txt  Is OK (matches original)
  meibo-sj-eu-uc.txt  BAD -- only ascii chars survived
  meibo-sj-eu-ut.txt  BAD -- only ascii chars survived
  meibo-sj-uc-eu.txt  Looks ok - matches meibo-sj-eu-eu.txt
  meibo-sj-uc-j7.txt  BAD -- spurious ">^N" inserted everywhere
  meibo-sj-uc-sj.txt  BAD -- looks like Shift-JIS with NUL between each byte
  meibo-sj-uc-uc.txt  Looks ok
  meibo-sj-uc-ut.txt  Looks ok
  meibo-sj-ut-eu.txt  Looks ok
  meibo-sj-ut-j7.txt  BAD -- Just like meibo-sj-uc-j7.txt
  meibo-sj-ut-sj.txt  BAD -- Just like meibo-sj-uc-sj.txt
  meibo-sj-ut-uc.txt  Looks ok
  meibo-sj-ut-ut.txt  Looks ok

This pintpoints the problem areas pretty well.  These two:
  meibo-sj-eu-uc.txt  BAD -- only ascii chars survived
  meibo-sj-eu-ut.txt  BAD -- only ascii chars survived

are from the new (TCS=EUC)->(FCS=Unicode) section of xpnbyte().  Problem:
xpnbyte() isn't even being called in this case.  Diagnosis: tests in decode()
were in the wrong order.  Once the code was exercised some more bugs were
found and fixed, but there are still a couple spots where translations differ
from (TCS=Unicode)->(FCS=Unicode).  This is not so much an issue of
translation as it is of parsing, keeping track of state, etc.  So this one's
pretty good now; we'll come back and touch it up later.  New score: 11 to 4.

These two:
  meibo-sj-uc-sj.txt  BAD -- looks like Shift-JIS with NUL between each byte
  meibo-sj-ut-sj.txt  BAD -- Just like meibo-sj-uc-sj.txt

are simply forgetting to not output both bytes if the left half is empty.
Fixed in xpnbyte().  Score: 13 to 2.

And these two:
  meibo-sj-uc-j7.txt  BAD -- spurious ">^N" inserted everywhere
  meibo-sj-ut-j7.txt  BAD -- Just like meibo-sj-uc-j7.txt

indicate a problem in the new JIS-7 constructor when it has to write out
halfwidth Katakana.  A tiny error in the state machine.  Final score: 15 to 0.

All fixes confined to ckcfns.c, 14 Oct 99.

From Jeff: Syslogging changes for NT.  ckcmai.c, 15 Oct 99.

Remaining problems with EUC->Unicode translation fixed -- in fact they were
already fixed yesterday; I was looking at old versions of the files.

Now I have a good copy of the meibo file in all five character sets.  This
means I can write a new script to translate it from each Japanese character
set to each other one, similar to the script above.  But the output was too
noisy so I made TRANSLATE suppress messages if QUIET ON.  First results: 15
bad, 10 good.  Reason, there seems to be no code to handle Japanese except
when source or target set is Unicode.  Added code but the score is about the
same.  ckuus4.c, 15 Oct 99.

From Jeff: Changed syslog to accept the Kermit message type instead of the
Unix Syslog message type as the first parameter.  The second parameter is
whether the message indicates success (1) or (failure).  This is so that the
appropriate NT Event Log message type may be selected.  SET SYSLOG added so
the range of messages that are logged may be changed in the iksd.conf file.
There needs to be a test applied to all SET commands that affect logs that
restrict access to the command after a user is logged in to IKSD.  ckcpro.w,
ckuusx.c, ckuus3.c, ckcmai.c, ckufio.c, ckcdeb.h, ckuath.c, ckucmd.c,
ckuusr.c, ckcfns.c, ckuusr.h.  17 Oct 99.

Back to Kanji TRANSLATE...  The whole business was getting way out of hand --
too many combinations, too much duplicated code.  So I junked everything so
far and tried a simpler approach: source -> UCS2 -> target in all cases, using
xgnbyte() to feed bytes to xpnbyte().  Now the score is 15:10.  Ironed out
some confusion over the UCS BOM, improving the score to 20:5.  The bad cases
were JIS7-to-anything-else.  Found & fixed a typo in getj7(), now 25:0.
ckuxla.c, 17 Oct 99.

Moved j7init(), getj7(), eu_to_sj(), and sj_to_eu() out of ckcuni, since they
have nothing to do with Unicode and can be used in non-Unicode builds.
ckcuni.[ch], ckcxla.h, ckuxla.c, 17 Oct 99.

But getting this working is just the first step.  Now the job of cleaning up
the #ifdefs and preserving correct TRANSLATE operation in non-UNICODE and/or
non-KANJI builds.  The first task is to make the xgnbyte()/xpnbyte() also work
for Japanese without Unicode; this is a big plus because it turns out the
TRANSLATE command has never worked for Japanese.  (hours later...) Got
C-Kermit to compile and link again with -DNOUNICODE.  Kanji translations work
except in the halfwidth Katakana spots.  Several hours later all the
no-Unicode combinations worked.  Rebuilt with UNICODE defined; ran the
original test, score is back down to 13:12, ugh.  The good ones are (a)
anything-to-self; (b) anything-to-Unicode.  The bad ones are anything to
Shift-JIS, JIS7, or EUC.  Aha.  So after one more round, these work again too.
So now we have a workable model for multibyte/variable-byte character sets
that can be extended to Chinese, Korean, etc.

Added output function pointers to arg lists for pnbyte() and xpnbyte().
ckcker.h, ckcfns.c, ckuus4.c, 18 Oct 99.

Fixed TRANSLATE <infile> UCS2 UCS2 <outfile> to automatically swap bytes
if <infile> is the wrong byte order.  ckuus4.c, 18 Oct 99.

Tested the following builds, adjusting #ifdefs and declarations until all
of them were stable:

 -DUNICODE -DNOKANJI
 -DNOUNICODE -DKANJI
 -DNOCSETS (saves 350K on Sparc vs full build)
  Non-ANSI compiler: uh oh, ckcuni.c crashes the SunOS assember.

Added -DNOUNICODE to SunOS cc targets.  Also reorganized the makefile to put
antique targets at the end, and to group the remaining targets a little
better.  Also added -DNOUNICODE to the non-antique targets that typically blow
up when we add something new: AT&T UNIX PC, SVR3 and earlier, SV68, Xenix, and
various small-model targets.  makefile, 18 Oct 99.

Rebuilt on Sparc and PC, and ran the file-transfer test from Sparc (BE) to
Linux/PC (LE):

 . PC translation of incoming to EUC, JIS7, and Shift-JIS OK.
 . PC translation of incoming to UCS2 swaps bytes OK but gets bad spots.
 . PC translation of incoming to UTF8 is OK except in one case

The UTF-8 result has all of the Kanji characters replaced by 0xEFBF, which is
the UTF-8 translation of UCS-2 0xFFFD.  This happened only when the PC was
translating from EUC to UTF-8.  It did not happen when translating to UTF-8
from UCS-2 or UTF-8.  Now, since we translate to UCS-2 first, this pretty much
narrows the problem to xpnbyte(): EUC->UCS section.  The problem: eu_to_sj()
was using hardwired byte numbers, rather than indexing through byteorder.
That fixed the UTF-8 problem and the UCS-2 problems.  ckuxla.c, 18 Oct 99.

Ran the exact same test (every combination of Kanji FCS and TCS) in the
opposite direction: PC to Sparc.  It worked perfectly.  18 Oct 99.

As to TRANSMIT...  Well, TRANSMIT can do with character sets only what CONNECT
can do, and C-Kermit CONNECT doesn't handle Japanese.  A major redesign and
rewrite would be required.  I think the trick would be to make ckcputc() be
the analogue of xpnbyte() and ckcgetc() to be the equivalent of xgnbyte() (and
added a note to this effect to ckucns.c).  But this would probably be a week's
worth of coding and testing for a feature nobody has ever asked for.  So we'll
defer Japanese character-set support in CONNECT and TRANSMIT until after 7.0.
Updated ckermit2.txt to reflect the current and probably final state of
affairs for Kanji and Unicode in 7.0.  18 Oct 99.

Removed voluminous debug() statements from x[gp]nbyte().  ckcfns.c, 18 Oct 99.

As an experiment, added a global flag wasclosed, which is set to 1 by any code
that closes a connection (and sets ttyfd to -1), and is tested and reset at
the top of the parse loop.  ckcmai.c (definition); ckuus5.c (test and reset);
ck[uv]tio.c, ck[cl]net.c (set).  For this to work in other platforms requires
similar additions to ck?tio.c.  A closed connection is noticed only in the
command loop, because that's the only place that any user-defined actions can
be executed.  If the user gives a SET LINE/PORT/HOST/etc command while another
connection is still open, there is also a check in hupok(), so if they have
SET EXIT WARNING ON it will work here too.  Otherwise it won't since both the
close and the new open happen within the same call to ttopen().  A second
variable, whyclosed, tells why the connection was closed: 0 is the catch-all
"closed by remote"; 1 = HANGUP or CLOSE by user, 2 = auth failure.  At the top
of the parse loop, if wasclosed is set and a macro called ON_CLOSE is defined,
we set it up and execute it.  The close reason (0, 1, or 2) is passed to the
macro as \%1.  18 Oct 99.

Spiffed up ON_CLOSE a bit by calling it in clsconnx(), which is our new
all-purpose ckuus*.c connection-closing routine, and in the exit sequence,
just before ON_EXIT.  This SEEMS to catch all the places where we need it.
ckuus[57x].c, ckermit2.txt, 18 Oct 99.

Fixed SET FILE CHARACTER-SET to not use the same chained FDBs as REMOTE
SET  FILE CHARACTER-SET.  ckuus7.c, 19 Oct 99.

From Jeff: ckcmai.c: the login functionality has to take place in the first
thread on NT.  ckcfns.c: fix pnbyte() call in reof() to reference appropriate
output function pointer.  ckcmai.c ckuus3.c: minor change to allow SET SYSLOG
to only work on IKSD during the processing of IKSDCONF.  19 Oct 99.

Next project: SEND /ARRAY:<arrayref>.  When done, this command lets Kermit
send the contents of any array.  The major goal is to link file transfer and
scripting.  With this, for example, a Kermit script can read selected lines
from a file into an array, manipulate the lines or the array in any desired
way, and send the result without intermediate files or filters.  Added parsing
to ckuusr.[ch], plus a preliminary test routine that I'll finish & move
tomorrow.  19 Oct 99.

Finished SEND /ARRAY.  Removed test code from ckuusr.c, moved the dummy
agnbyte() routine (get next byte from array) to ckcfns.c, changed zminchar()
macro definition to call agnbyte() when sending from an array.  Faked the
filename as "_array_a_" (or b, etc).  Made sure we can still build with
-DNOSPL.  ckcker.h, ckuus[r2].c, ckcfn[s3].c, ckermit2.txt, 20 Oct 99.

Merged in Jeff's changes mainly for Kerberos and ON_CLOSE reasons for Telnet
protocol-based closure.  Many modules.  20 Oct 99.

Removed the -DMAINISVOID's that were added to the makefile recently and
changed the default type for main() from void to int, and simplified the
hideous #ifdefs around it.  NOW let's see who hollers...  ckcmai.c, 20 Oct 99.

Shuffled some lines in TRANSLATE to avoid "statement not reached" errors in
HP-UX.  ckuus4.c, 21 Oct 99.

Fixed a debug() call in ckcfn3.c, 21 Oct 99.

Peter E reports that when using a Telnet modem server, after the following
sequence of commands:

  dial xxxx <-- does not exist in dialing directory
  dial yyyy <-- does exist in dialing directory

the redial number is xxxx and not yyyy.  It doesn't happen when dialing with a
serial port.  The variable is dialnum.  I don't have a Telnet modem server and
can't reproduce it, and inspection of the code shows that from between the
time the number is fetched and it is stored, there is no different path
through the code for serial and network dialing.  Will have to dummy it up
with a fake modem server:

  set host /connect * 3000
  set terminal newline on  ; (So Enter sends CRLF)

Client does the regular sequence to use it:

  set host 0 3000
  set modem type hayes
  set dial display on
  set dial directory foo ; File that has entry for yyyy but not xxxx
  dial xxxx

In the server window I type OK<Enter> to each setup command and then
NO CARRIER<Enter> to the ATDTxxxx comand.  Then I tell client to "dial yyyy"
and go thru the same sequence at the server.  Now SHOW DIAL on the client
shows the correct redial number: yyyy (not xxxx).

Changed character-set associations for incoming files when transfer character
set is UCS-2 or UTF-8 to be UCS-2 in Windows, UTF-8 elsewhere.  ckuxla.c,
22 Oct 99.

In testing the previous change noticed that SEND /TEXT did not work any more,
i.e. it did not force a text-mode transfer.  Refer to previous notes
throughout 1998 about automatic mode-switching versus SET TRANSFER MODE, etc.
The notes make sense but the code in whoarewe() did not agree with the prose.
Removed a mistaken test on the saved transfer mode.  ckcfns.c, 22 Oct 99.

A minor command-parsing improvement.  Suppose you type "te" and then Esc at
top level.  It beeps because more than one command starts with "te", so then
you type "?" to see what they are but Kermit shows "telnet" as the only
possibility.  So why the beep?  Because of invisible keywords like "telopt",
"terminal", and "text".  But there is no way for the user to discover them.
The improvement is: if ? is typed AFTER the beginning of a keyword field, then
invisible keywords are shown too, but if it is typed at the beginning of a
field, only visible keywords are shown, as before.  ckucmd.c, 22 Oct 99.

Since we have the Base64 conversion routines anyway, added /FROMB64 and
/TOB64 switches to the COPY command.  ckclib.[ch], ckuus[26].c, 22 Oct 99.

From Jeff: Correction to TAPI dialing setup: ckuus6.c; minor Win9x
authentication changes: ckcmai.c.  23 Oct 99.

Added some debugging and commentary to makestr().  ckclib.c, 23 Oct 99.

Put a malloc-failure error check after setting redial number to help catch
Peter E's problem.  Ran the big demo script with debug log to see if any
malloc entries appeared; none did.  ckuus6.c, 23 Oct 99.

There was an inconsistency in macro invocations.  If xx is macro name, it can
be invoked as "xx" or "do xx".  An "immediate" macro can be invoked as
"{ command, command, ... }".  But "DO { command, command, ... }" gave a syntax
error.  Fixed in ckuusr.c, 23 Oct 99.  Restriction: immediate macros can not
take args (this would have been a big deal to program in the non-DO case but
actually pretty easy in the DO case).  The big demo script still works.

Rob Seace <rob@wordstock.com> reported that the getline script did not work
in QNX.  Of course it doesn't, QNX has no UUCP lockfiles or any other method
for locking dialout devices.  But Rob pointed out that QNX has a dev_info()
call that returns the open count.  But we can't really use it as a lock since
we don't necessarily know its full set of behaviors, nor do we know to what
degree users depend on the current behavior.  So I added a new command, which
is visible only in QNX (but which can be given anywhere, but does nothing):
SET QNX-PORT-LOCK { ON, OFF }.  It is OFF by default.  When ON, it allows the
open count to serve as a port lock.  In the meantime (until the next Beta),
added a note to getline.  Then made a new getline that works right with QNX,
which can be installed when Beta.11 is released.  In ckutio.c, I added
a qnxopencount() routine, which gives the device open count.  ttlock() calls
this and fails if the count is > 1 and QNX-PORT-LOCK is ON.  SHOW COMM (fo
QNX only) displays the QNX-PORT-LOCK setting and, if a device is open, the
current open count.

In building on QNX I found some #ifdefs had slipped out of their places as
they are wont to do, and so fixed them.  ckutio.c,

Found that the old bug of curses working only once in QNX seems to be fixed,
whether by Kermit or a newer QNX version I don't know.

Tried resurrecting the 16-bit QNX version, this time with -DNOSPL and
-DNOFLOAT.  It built fine, starts OK, but it beeps when you type a space, CR,
etc, after the top-level keyword.  But aside from that it seems to work OK, so
apparently the problems I've been having till how have to do with the new
floating-point support (plus the large size of ckuus4.c).  The compiler is
Watcom 10.6.  Extensive debugging shows the bell is not being run by Kermit
calling bleep().  Tried building again with TCP/IP and found it would make the
connection, complete the Telnet negotiations, show the login prompt, but
apparently would not send keystrokes.  Comparing logs from the 16 and 32 bit
versions showed that the qnx32 version had FIONREAD defined, but qnx16 did
not.  Fiddled the #includes to force the 16-bit to include <ioctl.h>, and now
it does use the FIONREAD ioctl, which works, but we still get the same
symptom, and I really can not see the difference in the log.  This was all
with ckucns.c.  Switched back to ckucon.c.  No difference.  The debug log
of the 16-bit version looks just like the debug log of the 32-bit version...
Well, to make a very much longer story short, it turns out a piece of
buffer-filling code was lost in the #ifdefs for NOCSETS builds when Unicode
support was added to ckucns.c, and the mistake was copied to ckucon.c.
Fixed in both, 23 Oct 99.  (But we still get the mysterious beep.)

Makefile updated to rehabilitate qnx16.  23 Oct 99.

Fixed a misplaced last-minute #ifdef in yesterday's code that prevented
ckcuni.c from compiling.  24 Oct 99.

Propogated #indef NOCSETS correction to ckvcon.c, 24 Oct 99.

There has always been a confusing lack of symmetry between OPEN and CLOSE.
Also, SET LINE and SET HOST are misnamed because SET is not supposed to be
an action command.  So...

 . Uncoupled the OPEN command from file disposition symbols as keyword
   values, and defined a new set of OPN_xxx symbols for it. ckcker.h,
   ckuusr.h, 24 Oct 99.

 . Made OPEN HOST, OPEN LINE (PORT) be synonyms for SET HOST, SET LINE
   (PORT).  ckuus[36].c, 24 Oct 99.

 . Made CLOSE !READ and CLOSE !WRITE acceptable synonyms for CLOSE READ
   and WRITE, and CLOSE HOST, LINE, and PORT synonyms for CLOSE
   CONNECTION.  ckuusr.c, 24 Oct 99.

Some corrections to typos un_to_sj() noticed by Jeff.  ckcuni.c, 24 Oct 99.

Another longstanding item on the to-do list: INPUT pattern matching.  Expect
can do it, Kermit can't.  I thought of a way to add this that does not involve
huge amounts of redesign or breaking existing scripts.  Since the pattern is
always passed through xxstring at parse time anyway, I added a new function
\fpattern(), which simply returns its argument (after evaluation) and sets a
flag saying it's a pattern.  Then a parallel array of flags is passed to
doinput() along with the regular array of MINPUT search strings.  This allows
both patterns and literal strings to be used with INPUT and lets MINPUT be
given any mixture of patterns and literal strings.  In the matching loop, if
the current search string is a pattern, we call ckmatch() on the pattern and
all right substrings of the string we have input so far.  Crude but effective
(and necessary, since we also want to set a variable to the piece that
matched, and this could not be done otherwise).  ckuusr.h, ckuus[r24].c,
ckermit2.txt, 24 Oct 99.

Updated REINPUT to also accept a pattern.  ckuus4.c, 24 Oct 99.

Protected a comparison of type KEY with > 255 by #ifdefs on platforms where
KEY is CHAR or char.  showkeycode(): ckuus5.c, 25 Oct 99.

Added debugging to dodial() and ckdial() to catch Peter E's bug.  ckuus6.c,
ckudia.c, 25 Oct 99.

Some minor syntax corrections for VMS.  ckvfio.c, ckuus6.c, 25 Oct 99.

Built on VMS with runtime checking of array bounds, pointer values, and
for references to uninitialized variables -- let's hear it for DECC!.  Tested
CONNECT mode, file transfer, and script execution -- no problems were reported.
25 Oct 99.

Added ON_OPEN.  It gets ttname[] as its only argument; probably most other
items are available as \v(things).  More open/close symmetry...  ckuus[7y].c,
25 Oct 99.

Peter's REDIAL problem solved.  It's not Kermit, it's his modem.  The modem is
told to "ATDsomestring" and replies "OK" because "somestring" contains an "s",
which triggers some unknown function in the modem.  To Kermit, "OK" means
"partial dialing successful" and so sets the partial flag, which in turn
inhibits storage of the REDIAL number.  Changed so when the modem replies "OK"
to an ATD command and the Kermit command was not PDIAL and the dial number did
not end with ';', it is now considered an error.  ckudia.c, 26 Oct 99.

Corrections from Jeff to dofast().  ckcfn3.c, 26 Oct 99.

Lots of minor changes from Jeff, plus the beginning of an IKSD command (what
is it?).  ckcdeb.h ckcfn3.c ckcker.h ckuath.c ckucns.c ckutio.c ckuus2.c
ckuus4.c ckuusr.c ckuusr.h ckuusx.c ckwart.c, 27 Oct 99.

Changed UNIX CONNECT-mode Ctrl-\? menu to be clearer and to only list
options that make sense on the current kind of connection.  ckucns.c,
27 Oct 99.

In trying to chase down a report that K95 reported backwards file types
when receiving files from TSO Kermit, which, unlike most other Kermits,
includes the Format of Records within Packets attribute (/), changed gattr()
to handle this attribute in incoming packets (previously it ignored it
except in VOS, and the VOS code was bogus).  This made no difference.  So then
I dummied up C-Kermit to send A-packets with the same fields as TSO Kermit.
This made no difference either -- I still can't see anything wrong.  ckcfn3.c,
27 Oct 99.

Found a couple places in ttinl() where wasclosed wasn't being set, which
prevented ON_CLOSE from running if the connection dropped during a file
transfer.  As a by-product, fixed this case so ttclos() was called, thus
ensuring that subsequent calls to ttchk() would behave as expected, rather
than indicating the connection was still open.  ckutio.c, 27 Oct 99.

Added "iso2022jp" as a synonym for JIS-7.  They aren't exactly the same, but
they're close enough (ISO 2022-JP is specified in RFC1463 and seems to be the
same as DEC Kanji, which we also support as if it were JIS-7, different only
in that JIS-7 includes SO/SI access to halfwidth Katakana and the other two
don't).  ckuxla.c, 27 Oct 99.

Rewrote UNIX ttclos() to handle the case better where close() doesn't return
and we time out.  Now we set O_NDELAY first (if available) we also re-set the
alarm before trying any operation that might hang, such as tthang(), ttres(),
close(), etc, to avoid being stuck for a really long time (or forever), and
in fact, since any or all of these might time out, the new implementation is
a state machine that remembers how far it it got so it doesn't repeat any
previous steps (which has been its mistake up till now).  ckutio.c, 28 Oct 99.

Discovered that mdmhup() (the routine that hangs up a modem by sending +++ATH0
or whatever to it) didn't work right if no prior DIAL command had been given,
since the modem-command response-reading function pointer had not yet been set
up.  Fixed in ckudia.c, 28 Oct 99.

Added more error-checking and debugging to the POSIX section of tthang().
ckutio.c, 29 Oct 99.

Added Rockwell V.90 modem.  ckuusr.h, ckudia.c, 29 Oct 99.

Assorted changes from Jeff: ckuath.c ckuusy.c ckuus5.c ckcnet.c ckuusr.h
ckuusr.c, 29 Oct 99.

From Jeff: ckcmai.c - iksdcfg flag in the wrong place; ckudia.c - typo in new
modem def's; ckuusr.c - correction for OS2; ckuath.c - SSL/TLS improvements.
30 Oct 99.

Dave Sneddon noticed when C-Kermit was in the middle between a terminal and a
VMS system, that SET TERM/INQ on VMS caused errors if SET TERM APC is ON.  The
same thing happens with the VMS and UNIX versions.  I seem to have broken this
when adding the Transparent Print code.  The problem is that escape sequences
from the keyboard are being treated just like escape sequences from the host
-- buffered up and then sent to the "printer" when complete.  Oops.  In fact,
this reveals a HUGE whole that opened up when I converted the UNIX CONNECT
module from two forks to one.  In the 2-fork version, each fork had its
separate data space, thus variables like "inesc" were separate for the
incoming and outbound data streams.  In the single-fork version, the same
state machine and variables were used simultaneously for the host-to-screen
and keyboard-to-host streams, resulting in no end of confusion -- I'm
astounded nobody noticed it till now.  This was fixed by making the state
variables (inesc and oldesc) into 2-element arrays, indexed by 0 = char from
host, 1 = char from keyboard.  Works well without breaking APC and transparent
printing.  ckucns.c, 30 Oct 99.

Same changes for VMS.  Built & tested OK.  ckvcon.c, 30 Oct 99.

From Jeff: some debugging changes for the network modules.  ckctel.c,
ckcnet.c, 31 Oct 99.

Fixed trailing blanks & long lines.  ck[cuw]*.[cwh], 31 Oct 99.

Got rid of startup message "Default file-transfer mode is ...", since it
doesn't give the user any clues about how to change it.  Changed SHOW FILE to
enunciate the relevant info a bit more clearly.  ckuus[45].c, 31 Oct 99.

Fixed Linux ncurses target to allow for ncurses.h being in either /usr/include/
or /usr/include/ncurses/.  From Thomas Dickey <dickey@clark.net>, 2 Nov 99.

Fixed typos Rockwell V.90 modem entry.  ckudia.c, 2 Nov 99.

Changed command module not to print "?Timed out" if ASK-TIMEOUT expires if
QUIET is ON.  ckucmd.c, ckuus6.c, 2 Nov 99.

The notation \fsubstring(\m(name),n1,n2) was annoying me, so I added a
shorthand: \s(name[n1:n2]).  Works like \m(name) except the substring notation
is allowed; the separate letter is to prevent collisions with do-it-yourself
data structures like the ones in the script library.  ckuus4.c, ckermit2.txt
Section 7.24, 2 Nov 99.

Added \fhex2n(), the inverse of \fn2hex(), for converting a hex number to
a decimal one.  Also \fhex2ip() to convert a hex IP address into a dotted
decimal one, and \fip2hex() to do the inverse. ckuusr.h, ckuus[24].c, 2 Nov 99.

SSL/TLS stuff from Jeff: ckuus3.c ckuus7.c ckudia.c ck_crp.c ckctel.c
ckutio.c ckcnet.c ckuath.c ckuusr.c ckuus2.c makefile, 2 Nov 99.

Fixed trailing blanks & longlines in Jeff's files.

Added \foct2n() for symmetry with \fn2oct().  ckuusr.h, ckuus[24].c, 3 Nov 99.

Nested \s(blah[n:m])'s didn't work, e.g.

  \s(block[1025:\fhex2n(\s(block[101:4]))])

Problem: zzstring()'s \?(name) parser didn't allow for nested parentheses.
Therefore some other stuff that should have worked even prior to the
introduction of \s() wouldn't have worked either, e.g. \m(\fxxx(..)).
Fixed in ckuus4.c, 3 Nov 99.

Changed arraybounds() not to fail on negative numbers (because I cheat and
use arraybounds() to parse the range specifier in \s(blah[m:n]) and there
is no reason not to allow negative numbers).  ckuus5.c, 3 Nov 99.

SSL/TLS stuff from Jeff: ckuus7.c ckutio.c ckuath.c, 4 Nov 99.

Peter E discovered an awful bug from the Oct 9-11 [ck]strncpy() work, namely
that, under certain circumstances, after a command file or macro was executed,
top-level commands could no longer be parsed.  It seems that the atom buffer
(atmbuf[]) was the one place where we really did need strncpy()'s property of
zero-filling to the given length, rather than depositing just one terminating
NUL as ckstrncpy() does.  So changed all ckstrncpy(atmbuf,blah,ATMBL) back
to strncpy(atmbuf,blah,ATMBL); atmbuf[ATMBL] = NUL.  I also make cmini()
zero the atom buffer in addition to the command buffer (and in the process
let it use memset() for this rather than a look if USE_MEMCPY is defined --
a significant speedup now that these buffers are so big).  ckucmd.c, 4 Nov 99.

From Jeff: A fix for the annoying problem of Kermits A->B->C, with A and B
both having autodownload enabled.  Since B has it enabled, it should not also
pass the packet on to A, so at the moment when it detects it has a valid
packet, it purposely alters the last few chacters so A will not detect it too.
ckucns.c, 4 Nov 99.

From Jeff: preliminary changes to enable Telnet option debugging in command
mode.  ckctel.c, 4 Nov 99.

From Jeff: Rest of SET TELNET DEBUG, plus propogation of autodownload change
to ckucon.c, plus casts to stifle complaints from yesterday's changes.  Many
modules, 5 Nov 99.

From Joel Soete <JSO@EUROPAY.COM>, changes to support "Trusted HP-UX".
makefile, ckufio.c, 5 Nov 99.

Propogated autodownload change to ckvcon.c. 5 Nov 99.

Added another compact substring notation: \:(variable[start:length]).  This
differs from \s(macro[start:length]) in that the result of expanding the
variable is NOT looked up in the macro table.  So now we have compact
substring notation for all kinds of variables.  ckuus4.c, 5 Nov 99.

Over the past week, I prototyped an IKSD active-sessions database offline,
using fopen, fseek, fread, fwrite, ftruncate, and fflush, which we know to be
highly portable since they've been in C-Kermit 7.0 since the general file i/o
package was added in Beta.08 back in July.

A prototype display module was developed as a Kermit script, iksdpy, which is
what prompted the recent changes to the script language -- hex and IP address
conversion functions, compact substring notation for extracting database
fields, etc.  Unfortunately, however, fread() doesn't work well for the
display module.  Reading the records sequentially poses no problem (and works
well), but suppose we want to read the same record repeatedly by fseek()ing
and fread()ing in a loop.  In this case the C library tends not to refresh its
buffer from the disk so we never see any updates.  The only remedy seems to be
to close and reopen the file each time thru the loop to force a fresh disk
read.  The script does this and it doesn't seem to slow it down much (this is
done only when focussing on a single session).

Preliminary documentation for the database is in the new file iksdb.txt, which
will be merged with iksd.txt shortly.

Now that the prototype seems to be in good shape, I merged the code into
C-Kermit:

 . Data and struct definitions: ckcker.h.
 . Selection (IKSDB) and operating parameters: ckcdeb.h.
 . General-purpose routines (lset, rset, long/hex conversion): ckclib.[ch].
 . Database code: ckuusx.c.

ckuusx.c was chosen for the database code because that was the least bad
existing module to put it in, from the standpoint of size and appropriateness.
I didn't want to create a new module since the amount of new code is not that
large (about 500 lines), and adding a new module is a big pain.  With these
changes, the code compiles and links OK both with IKSDB defined and not
defined (when it's defined it adds only 8K to the image size).  5 Nov 99.

I also built with Kerberos IV and OpenSSL (sunos41gcc+krb4+openssl): builds OK
except for a bunch of warnings from ck_crp.c ("comparison is always 1..."),
but then it acts very strange when started -- can't parse command files, beeps
after every top-level keyword (hmmmm -- the same symptoms as the qnx16 build;
see notes from 23 Oct...)  I don't think this has anything to do with IKSDB --
it smells more like one of those ckstrncpy() things...  Nope, that's not it
(I added code to turn ckstrncpy() back into real strncpy() and rebuilt but it
made no difference: "touch ckclib.c; make blah KFLAGS=-DNOCKSTRNCPY").  I also
built again with -DNOIKSDB: same thing, so it's something else.  5 Nov 99.

Some minor adjustments to top-level command parsing; some of the error
conditions were not giving error messages promptly.  The possibilities are:

 1. Top-level keyword (cmdtab[])
 2. Token (!, etc)
 3. Macro name
 4. Immediate macro (e.g. "{ echo foo, echo bar }").

(1) includes the DO command, which can itself take a macro name or an
immediate macro.  Allowing for all this created a situation in which typing
something invalid as the first word in a command gave no error message (of
course the error was still caught later).  Also "DO { commmand, ... }" seems
to have been broken somewhere along the line.  Fixed in docmd(): ckuusr.c,
6 Nov 99.

Added \fradix(number,r1,r2), general-purpose radix conversion between any two
radices 2-36.  Made all the silly "hex2n, n2oct", etc, functions invisible.
Hurray, finally we have binary numbers, not to mention base 36, etc.  Also
replaced custom code in \fhex2n() and \foct2n() to just the use general radix
code.  ckuusr.h, ckuus[24].c, 6 Nov 99.

Back to IKSDB...  Added --database:{on,off} and --dbfile:<filename>.
ckuusr.h, ckuus[5y].c, 6 Nov 99.

Added dbinit() to initialize database name, my IP address, pid, etc.  Changed
getlocalipaddress() to store not only the string form but also the unsigned
long form in the new var myxipaddr.  ckcnet.c, ckuusx.c, ckcmai.c, 6 Nov 99.

Added call to dbinit() at startup and a call to freeslot() in doexit().
ckcmai.c, ckuusx.c, 6 Nov 99.

Added code to zvpass() to fill in user info.  I didn't check the auth stuff.
ckufio.c, 6 Nov 99.

Tested with IKSD.  Init is good -- PID, IP, peer IP, times, etc.  Login as
real user is good; username is picked up, and then record is freed when user
logs out or exits.  Ditto anonymous.

Filled in state-change updates simply by calling slotstate() from within
cksyslog().  ckufio.c, 6 Nov 99.

Initialized current directory in zvpass() and updated in zchdir().  ckufio.c,
6 Nov 99.

Compiles OK, but it doesn't totally work: the user's initial directory is
not filled in for some reason.  The state changes are not always recorded,
probably something to do with tying it to syslog.

From Jeff: OS/2 adaptations and minor corrections to yesterday's work, plus
more auth changes.  ckuath.c ckufio.c ckuusx.c ckuus7.c ckcdeb.h ckcnet.c
ckclib.c, 7 Nov 99.

Moved ckxlogging & ckxsyslog definitions from ckufio.c to ckcmai.c.
Moved dbopen def from ckuusx to ckcmai.  Put externs for all these in ckcdeb.h.
Then I tried to unify syslogging and the IKSD database with:

  #define LOGSACTIVE(a) ((ckxsyslog>=(a)&&ckxlogging)||dbopen)

and then using:

  if (LOGSACTIVE(SYSLG_PR))
    cksyslog(SYSLG_PR, ...)

But it was a world of trouble.  First of all, it blew up the compiler (gcc
2.7.2) on ckcpro.c.  In cases where it didn't blow up, I still didn't get the
required results.  So then I removed the macro and added separate calls to
slotstate() when I wanted to update the database, which actually gives more
control and therefore better results, at the cost of an extra function call
(but not always).  But now ckcpro.c blows up the compiler again unless I build
it without -O.  Will come back to this...  First:

 1. Moved dbinit() so a record shows up as soon as session starts,
    rather than waiting for login.  ckcmai.c.
 2. Updated state for command mode.  ckuus5.c.
 3. Changed locking method from link() to rename().  ckuusx.c.
 4. Fixed fractured anonymous username.  ckuus7.c.
 5. In Dir field, prepended anonroot for guest.  ckufio.c.
 6. Made username for anonymous be "anonymous:<passwd>". ckufio.c.
 7. #ifdef'd ftruncate() and kill() calls away for K95.

Now it all works pretty well, and should build and run for K95 too, except
there is no stale-pid detection (this can be fixed if the APIs have an "Is
this pid active?" call).  7 Nov 99.

Back to ckcpro.w.  We've been having trouble with it for some time -- more and
more platforms are needing to build it without optimization because -O blows
it up.  I think the problem is that the wart-generated switch() statement has
become too big.  We know there is nothing wrong about having many cases in a
switch() because in the charset modules we have some with hundreds or
thousands of cases, whereas the protocol module only has 73.  So the touchy
item seems to be either the amount of code in the largest case, or the total
amount of code in the switch.

Experiment 1: Build on watsol, which also has gcc 2.7.2, to see if it's
something with watsun (swap space filled up or something).  Success.

Experiment 2: Build on watsun with regular cc.  Success.

Well, these are inconclusive, but we know we have problems elsewhere, so:

Experiment 3: Move the code out of the "received an S packet" case into a
separate routine and rebuild.  gcc still blows up, but cc builds it OK, and
the result works OK -- that is, it receives files normally.

Continuing in this vein I moved the eight longest cases to their own routines,
handled the compilation glitches, added appropriate return values, rebuilt
with gcc (this time with no complaint), and tested each routine successfully.
Nevertheless, this was radical surgery and the patient should be watched
carefully for a few weeks.  ckcpro.w, 7 Nov 99.

Fixed some minor glitches in \fradix().  ckuus4.c, 7 Nov 99.

Built the Kerberized version and tested it OK (the trouble I had last time was
probably because I didn't move the latest ck_*.[ch] files into the build
directory).  Worked fine, authentication and all.  7 Nov 99.

Yesterday's code shuffling in ckcpro.w had the nasty side effect that IKSD
would never issue an interactive login prompt.  The problem was that I
overlooked the QUIT macro, which is used in some of the new routines.  QUIT
can return 0 or 1, whereas RESUME always returns 1.  I was using 0 to mean
"stay in state machine".  Now the new routines return -1 for this, and 0 or
1 are passed up the call stack.  ckcpro.w, 8 Nov 99.

Gerry Belanger reported some compilation errors revealing that IKSD was
not disabled if NOLOGIN was defined, so I fixed that in ckcdeb.h, 8 Nov 99.

Added a missing #endif in ckucon.c, 8 Nov 99.

Ran the code through gcc with:
 -Wreturn-type -Wcomment -Wformat -Wuninitialized
 -Wpointer-arith -Wredundant-decls
and removed various redundant declarations & prototypes, etc.
"-Wwrite-strings" is useless because is produces tens of thousands of
warnings about "discards 'const' from...".  Nothing especially serious was
found, except one printf referencing a long with "%d" and a couple "returns
without a value", which is what I was looking for.  Pretty much all modules
were changed.  8 Nov 99.

Added zchkpid() to ckufio.c, and changed all references to "kill(xxx,0);" in
non UNIX-specific modules to zchkpid().  (This needs to be filled in for K95
and VMS.)  ckcplm.txt, ckcdeb.h, ckufio.c, 8 Nov 99.

As an experiment, I removed the "pop back to command mode after each protocol
operation" feature from IKSD by #ifdef'ing out the "justone = 1;" commands in
ckcmai.c (search for IKSDPOPBACK).  This seems to do absolutely no harm, and
we no longer get the jarring state changes every time we do something (which
are obvious now in IKSDPY); client/server mode stays put, but CONNECT from the
client always forces IKSD back into command mode, and SERVER at the IKSD
prompt still puts it in server mode and makes the client pop back.  FINISH
works right, BYE works right, etc.  8 Nov 99.

Spiffed up IKSDPY a bit; gave it consistent commands in each screen and
a unified "command parser" and help screen rather than 2 different ones.
8 Nov 99.

Revisiting the question of the LOGIN and LOGOUT commands from 20 Aug 98...
Presently LOGIN is not a command.  LOGOUT is a command, but acts only locally;
that is, it works only when given at the IKSD prompt.  To log in and out from
the client requires REMOTE LOGIN and REMOTE LOGOUT.  Why can't these be just
LOGIN and LOGOUT?  Let's see...

	   Client                           Server
  LOGIN     Sends REMOTE LOGIN to server     Says "?Already logged in"
  LOGOUT    Sends REMOTE LOGOUT to client    Logs out (as now).

Made it so.  Seems fine.  If these commands are given to the client when it
has no connection, an error message is printed and the command fails.
Otherwise it acts as shown above.  Why didn't I like it before?  Probably
because I thought that LOGIN could be given at the IKSD prompt to actually
log in.  But it can't, so good, another wart removed.  ckuusr.c, 8 Nov 99.

Updated & incorporated iksdb.txt into iksd.txt.  8 Nov 99.

From Jeff:
 . SRP encryption key generation was broken.
 . Infinite loop in ckuusx.c in K95 only.
 . Extra ENCRYPT messages when encryption can't possibly be used.
 . NTLM AUTH not working on Win2K.
 . IKSD now compatible with Win2K.
ckuusx.c ckctel.c ckuath.c ck_crp.c, 9 Nov 99.

Changed wart to never output lines with trailing blanks.  ckwart.c, 9 Nov 99.

Fixed long lines & trailing blanks in all source files.  9 Nov 99.

Shuffled a couple return()s and #ifdefs in the new routines in the protocol
module to stifle "statement not reached" warnings.  ckcpro.w, 9 Nov 99.

Added -DNOGETUSERSHELL and -DNOSYSLOG to the Unixware 1.x and 2.0 entries.
makefile, 9 Nov 99.

Discovered the DATE command was truncating the last character of the result.
Another ckstrncpy() foulup (subtle difference in the meaning of the 3rd arg:
the number of bytes to copy to strncpy, but to ckstrncpy it's the size of the
buffer, which must be NUL-terminated; thus changing strncpy(dest,date,17)
(which copies a 17-byte date string) to ckstrncpy(dest,date,17) won't work
since the latter will chop off the last byte and replace it with a NUL,
thinking the dest buffer is only 17 bytes long.  ckuus6.c, 9 Nov 99.

A long time ago, before chained FDBs, code was added to allow the SLEEP (WAIT,
INPUT, etc) time interval to be either a number of seconds or else a time of
day (like MS-DOS Kermit), using a gross hack.  I changed this code -- at least
in dopaus() (the routine that handles SLEEP/PAUSE, MSLEEP, and WAIT) -- to use
chained FDBs instead.  ckuus6.c, 9 Nov 99.

Now to the point of all this: I extended the WAIT command to wait for file
events:

  WAIT <time> { MODEM-SIGNALS <signal-list>, FILE <event> <filename> }

The previous syntax is still accepted and works the same way; however, the
modem-signal names are now invisible in the keyword list shown by ? after
the time field; instead you see the two new keywords above (but you can
still put a modem signal name in this field).  If you choose FILE, then
you can choose an event: CREATION, DELETION, or MODIFICATION, and then the
filename and then Kermit waits up to the timeout for the given event to occur
with the given file and succeeds or fails accordingly.  ckuus6.c, 9 Nov 99.

Fixed radix() (and therefore \function()s that call it, such as \fhex2n()) to
use unsigned long internally, so args with high bit on won't go negative.
ckuus4.c, 10 Nov 99.

Fixed trailing blanks and long lines in ckuat*.[ch] and ck_*.[ch].  10 Nov 99.

Compact substring notation was not being careful enough about exceeding
boundaries.  Fixed in zzstring(), ckuus4.c, 10 Nov 99.

Added a little robustness to iksdpy, checking that each record is exactly 4096
bytes long.  Before the previous fix this would cause Kermit to crash; now
this check should not be necessary except to allow a more appropriate recovery
(i.e. quit with a message that the database is corrupt).  Also added clauses
from Jeff to pick up the database in Windows.  iksdpy, 10 Nov 99.

Added a prototype for ttyname() in the Sys V/68 R3V6 case. ckutio.c, 10 Nov 99.

Removed some dangling return()'s from the new routines in ckcpro.w, again
(the same ones I removed yesterday, but somehow the changes were lost).
ckcpro.w, 10 Nov 99.

Took 'extern int inserver' declaration out of #ifdef IKSD..#endif in ckcfns.c,
since this variable should be available in all builds, but with a value of 0
when IKSD is not available (and therefore not active).  ckcfns.c, 10 Nov 99.

Similarly for the 'network' definition in ckuusr.c.  10 Nov 99.

Changed IKSD database-opening code to use "r+b" rather than "r+" in K95 and
VMS.  ckuusx.c, 10 Nov 99.

More work on Unixware 1.x-2.0 makefile entries.  Removed the UNIXWARE
definition and reverted to vanilla SVR4, but with OLD_UNIXWARE defined just
for herald purposes.  This fixes the problem with close() of serial device
hanging.  makefile, 10 Nov 99.

On SunOS: Built OK with NOIKSD.  Built with NOSPL; this required some
corrections to ckuus4.c and ckclib.c (NOSPL removes 300K from Sparc binary).
Built with NONET OK.

On HP-UX 10.20: Built with non-ANSI compiler OK.  10 Nov 99.

On VMS 7.1: Built OK with DECC after supplying a missing exter for ksbuf[].
ckvcon.c, 10 Nov 99.

On SunOS: Built with NOICP (fixes needed to ckuus4.c) but lots of unresolved
references show up at link time but the stupid linker doesn't show which
modules the references occurred in.  Built again on VMS with NOICP to get
better diagnostics.  Results:

 . Moved prototypes for doconect() and setflow() from ckuusr.h to ckcker.h.
 . Adjusted #ifdefs in ckvcon.c and ckuusx.c.
 . #ifdef'd slrestor() references NOICP in ckcnet.c.
 . Moved 'hints' declaration to ckcmai.c.

It still didn't work but the remaining problems were all VMS-specific and
we'll never really build a NOICP for VMS (or if we do they're easily fixed).
Back to SunOS...  After a more shuffling, which is too boring to describe,
the NOICP version built again.  The full version is 1.8MB on Sparc; the
NOICP version is 0.5MB.  10 Nov 99.

Added -lresolv to unixwarenetc target.  makefile, 11 Nov 99.

Fixed trailing blanks & long lines in ckuath.c.  Gave up on ck_crp.c.
11 Nov 99.

Fixed ckradix() (again) to ignore leading 0's (and whitespace) for overflow
detection purposes (another previous fix that was lost).  Also moved ckradix()
to ckclib.c.  ckuus4.c, ckclib.[ch], 11 Nov 99.

A couple corrections to the ISO-8859-7 / Unicode mappings from updated
official UCS maps at unicode.org.  ckcuni.c, 11 Nov 99.

Added definitions, parsing, tables, and routines for KOI8-R and KOI8-U
character sets, ckcuni.[ch], ckuxla.[ch], 11 Nov 99.

Fixed xls[] and xlr[] charset-conversion function-pointer tables from
yesterday's (and earlier) changes (one problem went all the way back to July
1998).  ckuxla.c, 12 Nov 99.

Fixed fcsinfo[] table -- it too has skewed (during the Japanese changes of
a few weeks ago).  ckuxla.c, 12 Nov 99.

While tracking down yesterday's problems, I discovered that something was
amiss with any character-set translation involving Unicode.  When translating
from anything to (say) UTF-8, the non-ASCII characters were translated to
simple, seemingly random, ASCII characters instead of to UTF-8 sequences.
Somehow a temporary variable in xgnbyte() that had been a USHORT had become a
CHAR, thus discarding the high byte of the UCS-2 result (you can't turn your
back for a minute...)  So now translations *to* Unicode work again.  (This
affected all translations, including file transfer.)  ckcfns.c, 13 Nov 99.

But in the TRANSLATE command, translations *from* Unicode always gave a result
in UCS-2 intstead of the target set.  Why?  Because setxlatype() was setting
up the translation from the source set to UCS-2, period.  In all the testing
of the new Japanese/Unicode interface, I must have overlooked the others.
What was needed for TRANSLATE was a special routine to set up translation from
any file character-set to any other file character-set with UCS-2 in the
middle.  This seems to work well and it's a big improvement over the previous
arrangement, in which the "most appropriate" transfer character-set was picked
as the intermediate set, which resulted in loss when the source and
destination sets had characters in common that were lacking from the TCS (this
is especially noticeable with KOI8-R and -U, which are full of line-and-box
drawing characters that are not in ISO 8859-5).  Several dozen tests with
random pairs of charsets, including Japanese, check out fine, and file
transfers seem fine too, as they should be after the previous fix.  So I
changed TRANSLATE to always go through Unicode as long as Unicode support is
built in.  ckuxla.c, ckuus4.c, ckermit2.txt, 13 Nov 99.

Made KOI8-R and KOI8-U tables for ~kermit/charsets/.  koi8[ru].{c,txt},
13 Nov 99.

From Jeff: "Was this one hard to pin down.  (All the encryption bugs are.)
Noticed Sunday night that encryption was breaking with SRP on yclept but not
on other platforms.  Tracked this down to a change in the headers in the newer
SRP distributions.  The old headers were installed in /usr/local/include and
were being read by Kermit instead of the newer ones in
/usr/src/srp/srp..../include/.  Fixed.  While trying to find the above problem
I discovered that encryption didn't work at all with any authentication method
if there the connection was made with SET HOST *.  This bug was caused by two
things.  First, a couple of 'inserver' tests were instead 'sstelnet' which
meant we were encrypting/decrypting when we shouldn't have been.  Second, at
some point the ckcgetc() functions were modified to make calls to ttxin().
But the data returned from ttxin() was never decrypted.  So the state machine
on incoming data was corrupted."  ckucon.c ckucns.c ckutio.c ck_crp.c
ckuath.c, 14 Nov 99.

Changed setting of local and peer IP addresses (the ones used for reporting
and in the IKSD log) to use network format (htonl()).  ckcnet.c, 14 Nov 99.

Tested KOI8-R and KOI8-U terminal charsets in new build of K95 GUI -- both
work fine.  14 Nov 99.

Some syntax improvements for the FOR command:

 . Allow parens around the condition list for consistency with IF and WHILE.
 . If parens included allow increment to be omitted & default appropriately.
 . If command list lacks enclosing braces, supply them.

Allow parens around SWITCH variable too.  Aside from improving consistency and
robustness, these changes pave the way for future extensions, like
"for ( \%i in ck*.[ch] ) ..." (but exercising massive self-control, I deferred
implementation of that til after 7.0).  ckuus6.c, ckermit2.txt, 14 Nov 99.

In preparation for wrapping up Beta.11, did a bunch of builds with various
-DNOxxxx's defined, on various platforms.  NOCYRILLIC (ok), NOAPC (ok),
NOBIGBUF (ok)...  The latter only makes about 12K difference; hardly worth it
any more in these days 2-3MB executables... (but yes, it's still needed at
least for the PDP-11).

NOLOCAL (ok) -- this took a fair amount of #ifdef shuffling, plus I managed
to cut out a lot of additional stuff (e.g. all the file-transfer display
code), reducing the executable size (on Sparc) by 400K.  This one is handy
for building IKSD.  [Note: at the moment NOLOCAL also renders the SCREEN
command useless, but I'll worry about that if anyone complains.]

Also:
 . NOXFER (ok) -- This one also took a lot of shuffling.  Saves 420K.
 . NODISPLAY (ok) -- New; this one disables the file-transfer display.
 . NOSHOW (ok)
 . NOSERVER (ok) -- This one was a big deal.
 . NOREDIRECT (ok)
 . NOPUSH (ok)
 . NOPIPESEND (ok)
 . NOMSEND (ok)
 . NOLOGIN (ok)
 . NOIKSD (ok)
 . NOHELP (ok)
 . NODIAL (ok)
 . MINIDIAL (ok)
 . NOUNICODE (ok)
 . NOCSETS (ok)
 . NOSPL (ok) <-- Builds OK but has the beeping bug (*)
 . NOICP (ok)

Also built on some other platforms:
 . HP-UX 10.20 non-ANSI (ok)
 . HP-UX 10.20 ANSI (ok) (optimizer complains about ckuus[r34].c, ckcpro.c)
 . HP-UX 9.05 non-ANSI (ok)
 . HP-UX 9.05 ANSI (ok) (optimizer complans about various files)
 . HP-UX 8.00 non-ANSI (ok)
 . Linux RH 5.2 gcc 2.7.2.3 (ok)
 . VMS 5.5/VAX VAXC 3.2 UCX (ok) and NONET (??)
 . VMS 7.1/Alpha DECC 6.0 UCX (ok) and NONET (ok)
 . AIX 4.1 (ok)
 . Digital UNIX 3.2 (ok) (DU has 8-byte longs)
 . BSDI 4.0.1 (ok) (Updated makefile target for tputs() complaints)
 . Unixware 7 (ok)
 . Unixware 2.1 ("libelf error: Request error: no string table elf_strptr"???)

Many modules touched in many ways, some of them a lot.  14 Nov 99.

Tracked down the beeping problem first noted on Oct 23rd: when built with
NOSPL, there was a putchar('\07') in docmd() that was not inside any 'if'
clause, and therefore was always executed.  ckuus5.c, 15 Nov 99.

Added the following new CHECK items: FILE-TRANSFER, MAKING-CONNECTIONS,
UNICODE, IKSD, CX-LOG.  ckuus3.c, 15 Nov 99.

Fixed a trailing non-comment after an #endif, ckcfns.c, 15 Nov 99.

Replaced a lost comment-end after an #endif, ckcuni.h, 15 Nov 99.

Fixed a bad mistake I made yesterday, when shuffling declarations around for
NOXFER: I put the extern declaration for feol among the ints, when it should
have been a CHAR.  This completely messed up end-of-line processing during
file i/o.  ckcfns.c, 15 Nov 99.

Checking out Dave Sneddon's renewed complaint about C-Kermit swallowing or
mangling escape sequences while in CONNECT mode, which I thought I fixed a
couple weeks ago.  Detailed analysis of the traffic shows VMS sends:

  <ESC>[c<ESC>7<ESC>[255;255H<ESC>[6n<ESC>8<ESC>[62"p<ESC> F<ESC><RB>

(where <ESC> is Escape and <RB> is right angle bracket).

The CONNECT module passes <ESC>[c through OK to the terminal, and the terminal
sends back the right response: <ESC>[?63;1;2;6;8;9;15;44c.  But when C-Kermit
goes to read the next character from the host, it is '7' -- so it missed the
escape between the 'c' and the '7'.  And in fact, the logs show several other
escapes were missed too.  Let's compare with the UNIX version...  Hmmm, no
problem there.  Next, compare VMS version with TERM APC OFF (which works) with
same version with TERM APC ON (which doesn't).  Difference: chkaes() is never
called if APC is OFF so the problem is obviously in chkaes().  It turned out
to be a misplaced #ifdef XPRINT in one of the switch cases (which dates from
when I added transparent printing a year ago), the one that handles escape
sequences like <ESC>7.  The state-changing statement was inside #ifdef XPRINT,
but XPRINT is not defined in VMS, so the state remained unchanged and the code
to write out the saved-up Escape was never executed.  The same #ifdef was
misplaced in the UNIX version, but it didn't matter there since XPRINT is
defined in UNIX.  ckvcon.c, ckucns.c, 15 Nov 99.

A new set of consistent HP-UX 10.xx and 11.xx makefile targets from Peter E,
which now include regular and Trusted versions for each variation.  makefile,
16 Nov 99.

From Jeff: Beginnings of PTY support.  ckutio.c ckuus7.c ckcdeb.h ckucon.c
ckuus4.c ckucns.c ckuusr.c ckuusr.h, 16 Nov 99.

Added top-level PTY command (not tested), similar to PIPE.  Created PTYORPIPE
macro, which is defined if either NETCMD or NETPTY (or both) are defined.
ckcdeb.h, ckucns.c, ckuus[r7].c, 16 Nov 99.

Realized that it would be useful to know what character the user might have
typed to interrupt a PAUSE, WAIT, INPUT, or similar command from the keyboard,
so added a new variable \v(kbchar) for this.  It is set by any command that
times out and can be interrupted from the keyboard.  If it was interrupted,
this variable is set to the (first) character the user typed.  If it was not
interrupted, it is set to the empty string (thus "sleep 0" can reset it).
\v(kbchar) can be used in applications that need to wait for some event OR a
keystroke, whichever comes first.  For example, iksdpy, which would rather not
mindlessly refresh the screen if the database hasn't changed and the user
hasn't touched a key.  Now instead of being driven by getc and timeout, it's
driven by WAIT 60 FILE MOD <databasefile> -- if user presses a key, it's in
the variable and it's our command.  ckuusr.h, ckuus[46].c, 16 Nov 99.

From Jeff: the new pty modules, ckupty.[ch], plus fixes to Telnet debugging
and BREAK-sending.  ckctel.c, ckcnet.c, 17 Nov 99.

Added ckupty.c production to the xermit target.  makefile, 17 Nov 99.

Converted ckupty.[ch] to Kermit coding conventions (there were still some
#if's and preprocessor logical ops, unguarded ANSIisms, etc); cleaned up
formatting, added copyright & author notices, removed unused HAVE_blah
definitions.  Got it to build OK on SunOS with the non-ANSI compiler, and it
works too.  17 Nov 99.

On to Solaris...  This one was hopeless.  But then I realized that all the
problems were in the utmp/wtmp code.  But we don't need that code.  So I
#ifdef'd it out and poof, it builds and works on Solaris, and still builds
and works on SunOS.  ckupty.[ch], 17 Nov 99.

On to HP-UX.  After more twiddling of #ifdefs, got it to compile with no
complaints, but at runtime it says:

  ?Unable to open slave
  ?Slave failed to initialize

debug log says:

  ttopen PTY[telnet watsun]
  do_pty() Xline[/dev/ptyp3]
  do_pty()[Slave starts]
  getptyslave()
  pty_open_slave()[pty_open_ctty() failed]=44806916 = PTY_OPEN_SLAVE_OPENFAIL
  getptyslave()[Unable to open slave]=44806916
  do_pty()[Slave fails to initialize]
  set host line, errno[]=2

In other words, there is "No such device or directory" as /dev/ptyp3.  But:

  bash-2.00$ ls -l /dev/ptyp3
  crw-rw-rw-   2 root       root        16 0x000003 Jun 10  1996 /dev/ptyp3

The errno=2 indication is a red herring.  I changed the code to print a
better message, now it says:

  /dev/ptyp3: Device busy

Why it's busy, I don't know.  Also we don't want to put words like "slave" in
user messages -- they are upsetting to some people.  Also there is no need for
the "?Slave failed to initialize" message if we already just printed a more
informative message; fixed all this in ckupty.c, 17 Nov 99.

From Jeff: Additional debugging in pty code, add pty modules to other Unix
build targets.  makefile, ckutio.c, ckupty.c, 18 Nov 99.

Fixed PTY command to actually use ptys, not pipes.  ckuusr.c, 18 Nov 99.

Built with pty support on Unixware 7.1.0 and BSDI.  makefile, ckcdeb.h,
18 Nov 99.

Added KTARGET clauses to all UNIX targets except those in the Antiquities
section.  makefile, 18 Nov 99.

Problem: "remote host blah" crashes the client if "blah" is longer than 84
bytes.  This problem exposed many mistakes, each of which needed fixing.
First, conol() was being called with a NULL pointer.  It should defend against
this.  Second, the caller was not setting an error string it should have set.
Third, the caller of the caller was not checking to see if the string was set.
All this fixed in ckcpro.w, ckcfn2.c, ckutio.c, 18 Nov 99.

But why should the limit be 84 when we had just negotiated 4000?  Because...
we call tinit() after the I/Y exchange and it resets the packet length we just
negotiated, tsk tsk...  This is another long-standing problem: tinit() is
overloaded -- it was originally intended to be called before a transaction
starts, i.e. before the S/I/Y exchange, but then we started calling it just
after as well, because of the unfortunately fuzzy definition of "transaction"
in the protocol.  So I changed tinit() to take an argument: 1 to reset
EVERYTHING, 0 to reset only those things that are not set in the negotiations.
Now you can send long REMOTE HOST commands.  ckcpro.w, ckcker.h, 18 Nov 99.

Problem: Typing "mail" by itself causes a core dump.  Cause: a pair of
statements was out of order in doxsend().  Fixed in ckuusr.c, 18 Nov 99.

Built on IRIX 6.5 -- pty code compiles OK but doesn't work:
/dev/ttyp5: No such file or directory...  18 Nov 99.

Added code to ttinc(): if the read fails, and we were reading from a pty,
call ttclos().  But it didn't prevent the annoying "A connection seems to
be open... OK to close?" message, since the upper level code doesn't know
the connection was closed except by calling ttchk(), and ttchk() was not
doing the right thing.  ttchk() was being called to "test the connection",
but it was testing ttyfd only if xlocal != 0, which is silly -- xlocal
might have been reset by ttclos(), but if ttyfd == -1, we can definitely
say we do not have an active connection, no matter what the value of
xlocal!  ckutio.c, 18 Nov 99.

Pty changes, plus more debugging, from Jeff for HP-UX.  ckupty.c, ckutio.c,
19 Nov 99.

Built on FreeBSD 3.3.  Ptys work OK.  But with or without them, it dumps core
when trying to initialize curses.  Tried building it with ncurses rather than
curses; that fixed it.  Also discovered it did not have BIGBUFOK set, so set
it.  makefile, ckcdeb.h, 19 Nov 99.

Tried building on FreeBSD 2.2.7.  Hmmm, same thing -- it dumps core in
fxdinit().  Why and when did this start happening???  Converted the freebsd2
target to ncurses too.  Works fine -- curses, ptys, everything.  Also, added
-funsigned-char to FreeBSD entries, since cc is gcc there.

Dave Sneddon's bug, cont'd...  zkermini() was lopping off the final character
of the init file name obtained from the CKERMIT_INI logical, thanks to global
substitution of cknstrncpy() for strncpy().  In this case, the length of the
source string was specified, rather than the length of the buffer.  Fixed in
zkermini(), ckvfio.c, 19 Nov 99.

Fixes from Jeff for ptys on HP-UX 10 and also to add IRIX 6.x to the list of
pty-cabable builds: ckcdeb.h, ckupty.c, ckucns.c. 22 Nov 99.

Tried building on DU 4.0E and 3.2 -- both OK, ptys work fine; added to list.
ckcdeb.h, 22 Nov 99.

Tried building on HP-UX 9.05.  Compiles and links OK, but doesn't work.  Once
a connection is make (as in "pty telnet localhost") the program seems to hang;
no chars appear on the screen, and you can't escape back.  Tried building on
HP-UX 8.00.  Compiles OK but doesn't link: _vhangup and _ptsname unresolved.
Changed ckupty.c to not define CK_VHANGUP for HPUX8; then it compiles OK, but
hangs when run, just like HP-UX 9.05.  Rebuilt on HP-UX 9.05 without the
ioctl() trap that Jeff added for HP-UX 10.  No change, except now it actually
reads "Connection closed by foreign host."  from the pty but remains totally
impervious to keystrokes.  Juggled #ifdefs to include ptys only for HP-UX
10.00 and above.  ckcdeb.h, ckupty.c

Tred building on SINIX 5.42.  Compiles and links OK but:

  ttopen PTY[telnet 128.59.39.2]
  do_pty()[pty_getpty() fails]=44806914
  set host line, errno[]=2

Since there was a /dev/ptmx, I tried defining HAVE_STREAMS; this was an
improvement; now we get:

  ttopen PTY[telnet 128.59.39.2]
  pty_getpty()[open(/dev/ptmx) success]
  pty_getpty() ttyname()[(NULL)]
  pty_getpty() slavebuf[/dev/ttyp4]
  do_pty() Xline[/dev/ttyp4]
  do_pty()[Slave starts]
  getptyslave()
  ptyint_void_association()[setsid()]
  ptyint_void_association()[open("/dev/tty", O_RDWR)]=-1
  pty_open_ctty() slave[/dev/ttyp4]
  ptyint_void_association()[setsid()]
  ptyint_void_association()[open("/dev/tty", O_RDWR)]=-1
  pty_open_ctty() open failure[/dev/ttyp4]=2
  pty_open_slave()[pty_open_ctty() failed]=44806916
  getptyslave()[Unable to open slave]=44806916
  do_pty()[getptyslave() fails - exiting]
  do_pty()[Slave fails to initialize]
  set host line, errno[]=22 <-- "Invalid Argument"

The user sees:

  /dev/ttyp4: No such file or directory

Added #define HAVE_STREAMS for SINIX to ckupty.h, but won't define NETPTY
for it unless we figure out how to make it work.  22 Nov 99.

Built for DG/UX 5.4 -- ptys work ok, added DG/UX to the pty list.
ckcdeb.h, 22 Nov 99.

Futzed with "show features" paging.  ckuus5.c, 22 Nov 99.

Installed missing pieces of developer tools on local DU 4.0E system.  Added a
cast to an arg of bzero() to shut up DECC.  With that, latest code builds
without complaint, and ptys work fine.  ckcnet.c, 22 Nov 99.

Changes from Jeff for HAVE_STREAMS; now it works on SINIX.  ckcpty.c, etc;
23 Nov 99.

Consolidated {Free,Net,Open}BSD pty support under BSD44.  ckcdeb.h, 23 Nov 99.

Fixed ttopen() to set "ttnmsv" (saved ttname) for ptys too; otherwise, it
when proto() calls ttopen(), it closes the connection.  ckutio.c, 23 Nov 99.

Checked file transfer over pty connections:

 . ssh connections work fine with default FAST settings, streaming, reliable
   ON, etc, but SET PREFIXING ALL is needed because bare control characters
   can make trouble on PTYs -- tab expansion, CR->CRLF, who knows what else.
   8-bit files are sent OK too.  Obviously the transfer rate isn't great.

 . Same deal for rsh / rlogin.

 . For telnet, "set parity space" is also needed to transfer 8-bit data.  But
   the transfer rate is about 10 times faster.  Obviously SET PREFIXING ALL
   is needed here too for the Telnet escape character and probably also the
   interrupt character, etc.

Nothing special needs to be done about tilde on ssh/rsh connections since it
is significant only at the "beginning of a line", and this never happens with
Kermit packets.

Changed SET NETWORK TYPE COMMAND to SET NETWORK TYPE PIPE (but kept COMMAND
as an invisible keyword).  Ditto for switches, etc.  Because now we run
commands on ptys too.  ckuus[r47].c, 23 Nov 99.

Built on NetBSD 1.4.1.  Dumps core in fxdinit(), just like FreeBSD did before
I switched it to ncurses.  Rather than just switch to ncurses again this time,
let's find out what's wrong...  (Important because ncurses is an optional
item, so many people won't have it.)

First, installed NetBSD Project patches from Herbert Peyerl -- BIGBUFOK,
assorted casts, plus support for 7200 bps serial speed which I seem to have
overlooked.  ckcdeb.h, ckuusx, 24 Nov 99.

Back to fxdinit() in BSD44...  The man page for tgetent() says you have to
#include <termcap.h>.  That didn't help.  OK, it also said you had to declare
some variables, like "char *UP, *BC, ..." but that only gave syntax errors.
Tried linking with -ltermcap instead of -ltermlib.  Shuffling order of libs
made no difference.  Tried linking with only -lcurses and neither -ltermcap
nor -ltermlib.  Links OK but still crashes.  Tried casting 2nd tgetent() arg
to (const char *) like it says in <termcap.h>.  Still crashes.  Tried using a
static, rather than malloc'd tgetent buffer (16K!); it still crashes.  But a
newly-built 6.0 still works fine, and it calls the tgetent() exactly the same
way.  What's the difference?

EVENTUALLY...  I found it: tgetent() internally calls cgetent(), which in
turn calls dbopen(), which turns out to be "the library interface to database
files".  But dbopon is also the name of a new variable in Kermit, an int flag
meaning the IKSD database is open.  Unfortunately it is referenced in about
1000 places...  I changed them all to "ikdbopen" and poof, all better.  Many
files, 24 Nov 99.

While on NetBSD, checked UUCP lockfile conventions against cu: OK.  Tried
dialing (with a Multitech modem) -- didn't work at all.  Why?  The modem
responses seem to end with <LF> only, rather than <CRLF>.  Added code to
dook() to allow for this and dialing works again.  But why did it break in the
first place?  If I CONNECT with SET TERM DEBUG ON, I see CRLFs, so it's not
the modem's fault.  Should I worry about this?  The debug log shows ttpkt() is
being called normally and succeeding, so I wonder why DIAL is not seeing the
CR's...  Instead, it looks like each CR is being converted to a LF, so
responses look like "OK<LF><LF>".  ckudia.c, 24 Nov 99.

Back to FreeBSD...  Built it with regular curses, now it's fine of course.
Tried dialing out, that's fine too -- unlike NetBSD, it sees the CRLFs, so the
previous trouble must have been NetBSD-specific.  Checked uucp lockfile
against cu; it's OK.  Access to lockfile & port are thru the dialer group.
24 Nov 99.

Added support for uu_lock() for FreeBSD 3.0 and later.  This is almost just
like AIX ttylock(), but with different names and return values.  It's the
preferred method of line locking on FreeBSD 2.2.2 and later (but no point
making a new makefile entry to differentiate 2.0 from 2.2.2, so it's only in
the 3.0 target -- anyway, the effect is the same either way).  ckcdeb.h,
ckutio.c, makefile, 24 Nov 99.

Fixes to HTTP PUT from Jeff: ckcnet.c, 24 Nov 99.

Changed TRANSMIT /COMMAND to XMIT /PIPE (and left /COMMAND invisible).  Added
TRANSMIT /NOWAIT, which means don't wait for a "prompt" after each line in
text mode.  ckuusr.c, 24 Nov 99.

Testing TRANSMIT...  Various failures were not producing error messages.
Certain successes were not setting SUCCESS.  Also, now that the default file
type is binary, TRANSMIT does not work as expected -- changed TRANSMIT to use
text mode by default, no matter what the FILE TYPE is; therefore TRANSMIT
/BINARY *must* be used to transmit in binary mode, which is, after all, a
rather odd thing to do.  ckuus[r4].c, ckermit2.txt, 24 Nov 99.

Corrected some type mismatches in the IKSD database code.  ckuusx.c,
ckufio.c, 26 Nov 99.

For QNX ptys, added #include <fcntl.h> and #define O_NDELAY O_NONBLOCK, etc,
to make it compile OK, but it fails to initialize the pty at runtime.
ckupty.[ch], 26 Nov 99.

Added prototypes for ttyname() for HPUX 6 and 7.  ckutio.c, 26 Nov 99.

Eliminated a spurious error message from \fsplit() when it was asked to
fill an array with more words than the array could hold.  ckuus4.c, 26 Nov 99.

Fix from Lucas Hart for UNIX nzltor(), in which the last period is kept only
if it is in a filename, not in a directory path segment, since VMS doesn't
allow dots in directory names.  ckufio.c, 26 Nov 99.

SSL/TLS stuff from Jeff, mostly more separation of this from other modules.
ck_ssl.c ck_ssl.h ckuath.c ckuus3.c ckuus7.c ckuusr.h, 27 Nov 99.

The change to ttchk() on November 18th broke remote-mode file transfer on QNX.
Fixed, again.  ckutio.c, 27 Nov 99.

Noticed that CKMAXOPEN was -2 on QNX.  There is no definition for this in the
header files; wrote a little test program and found I could open 390 files
at once; changed ckcdeb.h accordingly.  27 Nov 99.

Fixes from Jeff for QNX ptys.  It all works except for noticing when the
pty process terminates.  ckupty.c, 27 Nov 99.

Added QNX to pty list.  ckcdeb.h, 27 Nov 99.

Added pseudoterminal control to the list of major features included or not
in SHOW FEATURES.  ckuus5.c, 27 Nov 99.

Tested Pty feature on SCO OSR5.0.5 -- it's ok.  Added it to the list.
ckcdeb.h, 27 Nov 99.

Tried building with ptys on SCO 3.2v4.2, but compilation dies with a syntax
error in <memory.h>.  Not worth pursuing.  Added prototype for ttyname().
ckutio.c, 27 Nov 99.

Moved the code to get the name of the controlling terminal in UNIX from
ttopen() to sysinit(), since we only need to get it once, and generalized the
test for local mode in ttopen() to include both the hardwired name (/dev/tty)
and the actual name (such as /dev/ttyp5), and made the name available in a
global string buffer, cttnam[], in case it's useful in the pty routines.
ckutio.c, 27 Nov 99.

Added a new variable \v(ctty) to show the name of the controlling terminal,
which is simply the contents of cttnam[].  For UNIX and VMS.  For the others
it's just CTTNAM (e.g. "CON", "@output", etc).  ckuusr.h, ckcdeb.h, ckuus4.c,
ck[uv]tio.c, 27 Nov 99.

Changed QNX pty code to use cttnam[] instead of "/dev/tty" and removed
NO_DEVTTY definition.  Works OK, ptyint_void_association() opens controlling
terminal, all is OK.  But it doesn't make any difference in close detection.
After logging out from a "pty telnet 0" connection, it reads Telnet's
"Connection closed by foreign host" message, but select() never notices that
the pty process died.  There must be some special API as in HPUX, but our QNX
host doesn't have any man pages and none of my QNX manuals says a word about
pseudoterminals, nor does the QNX website have any technical info.  I suppose
we could check just before select() if the slave pid was still alive but (a)
that could be pretty expensive, and (b) I'm not sure what to do if it isn't --
some cleanup code in ckupty.c probably needs to run.

Changed connection log to replace any spaces in the phone number with
underscores.  ckudia.c, 27 Nov 99.

Fixed misinterpretation of CARRIER message from Rockwell modems as equivalent
to CONNECT.  This one was lost since last May, oops.  ckudia.c, 27 Nov 99.

Somebody pointed out a while back that "?Not valid in this position" was not
a very good error message for "type blah", where "blah" was the name of a
nonexistent or inaccessible file.  A byproduct of chained FDBs.  The problem
is that the message is not issued until after we go through all of the FDBs
and none of them succeeds.  By that time, the real cause for any error is long
gone.  But at least we can construct a better message like "?Does not match
switch or filename", so I made this change in cmfdb(): ckucmd.c, 27 Nov 99.

There was an odd case not caught by the command-file reader.  If command
file's final line was a closing brace (e.g. of a loop or block) but lacked a
terminator, the block would not be completed or executed.  Fixed in getnct():
ckuus5.c, 27 Nov 99.

The MANUAL command was not restoring the console terminal modes before
escaping to the system; thus in VMS (for example) keystrokes didn't echo.
Fixed in docmd(): ckuusr.c, 27 Nov 99.

Went to check out a complaint about UUCP lockfiles on Digital UNIX, but UUCP
wasn't installed, so I installed it.  Couldn't figure out how to use cu (it
would just exit immediately with no message), but the man pages weren't
installed either.  Installed the man pages and read them.  Configured a
"direct" serial device by running uucpsetup -- nothing works unless you do
this first; the original serial devices are useless.  Made a connection with
cu and then checked the lockfile.  Everything is fine: location
(/usr/spool/Locks), name (LCK..ttyxx), and contents (4-byte binary int PID).
But I added -DNOCOTFMC since the original person said it was necessary to keep
SET LINE from hanging -- I tested it here and it's fine (but it was also fine
before).  ckutio.c, 27 Nov 99.

Added a short HTTP section (2.15) to ckermit2.txt, 27 Nov 99.

From Jeff...  ckuusr.c: Fixes the LOGIN/LOGOUT problem on VMS.  This code
should not have been #define CK_LOGIN (since it's for the client).  ckupty.c:
More changes for QNX.  Still can't determine when the slave is invalid.  I am
concerned that write()ing to the pty after the slave is closed does not report
an error.  That leaves me with the impression that the device is still open.
ckcmai.c ckcnet.c ck_ssl.c ck_ssl.h: More removal of SSL code from the main
code.  ckuus3.c: Modifications to getyesno() to support K95.  28 Nov 99.

Checked new stuff on VMS: \v(ctty) OK, LOGIN/OUT fixes OK.  TTY modes around
MANUAL command OK.  28 Nov 99.

Lucas Hart reports that recursive transfers of large directory trees stops
prematurely.  Test case: openssl-0.9.4.  Using the same file set on SunOS I
see even worse than that -- "dir /recursive openssl-0.9.4" doesn't even parse.
Added some debugging to addresult()...  Everything proceeds normally until
after the 166th file is added to the list.  From that point on, we never see
another regular file -- only directories.  Why?  segisdir is set to 1 when it
should be 0 -- a mystery since there is no way this can happen; there are
comments about this in the traverse() code already -- it's been a mystery for
some time.  But this code is so delicate I really can't risk touching it, so
let's see if we can find a workaround...  If I "cd openssl-0.9.4", then "dir
/recursive" works perfectly.  So therefore we can rule out anything special
about the directory tree itself (its size, depth, number of files, order of
files and directories, etc).  It must be something about the initial setup in
splitpath...  Another experiment: "dir /recursive openssl-0.9.4/*" works too.
So maybe the workaround is to simply tack "/*" onto the end if it's a
directory.  No, that's not it -- I already do that.  Anyway, most of this was
a wild goose chase since there was another error in cmifi() that was obscuring
everything: the '&wild' return value was not being set on recursive file
parses in which the filespec did not actually contain wildcards, which
prevented any command that operated on multiple files from working right.
Fixed in cmifi(): ckucmd.c, 28 Nov 99.

OK, back to traverse(), my least favorite place to be...  When we say "dir
openssl-0.9.4" (or "dir openssl-0.9.4/*") we still stop short of listing the
full directory, but when we cd to the directory and don't give a filespec, we
do get the full listing.  So what's the difference?

In the working case (A), a "*" is supplied as the filename, so the initial
isdir() fails since "*" isn't a directory, whereas in the failing case (B)
"openssl-0.9.4" is a directory.  That shouldn't matter, since in the latter
case we append "/*" to make it wild.

So fgen() in case A gets "*" but in case B it gets "openssl-0.9.4/*".  And
therefore splitpath() makes one segment in case A and two in B.  Well,
everything goes along OK for 85 files or so until we get to a certain
directory (one among many).  For some reason, when we retrieve the first file
from it, we call ckmatch() with the original filespec ("openssl-0.9.4/*")
rather than the current name part ("*").  Aha, once again the culprit is
segisdir...

OK, what is segisdir anyway?  As I recall it was a hack to cut down on the
number of calls to isdir(), which are quite expensive, at least in UNIX.  I
think the idea was that if the current segment had a forward link, then it was
guaranteed to be a directory, thus obviating the isdir() call.  OK, let's
see...  segisdir is set up above, but if we open a new directory after setting
it, that pretty much invalidates its meaning, so what good is it in this
context?  Finally I commented out the offending segisdir-based test, which
decides which string to match and this fixes the problem.  But what does it
break?

Dug up my old full-page checklist of directory-traversal tests...  Out of
fifty-some tests, the new version flunks only one that the old one passed:
"dir /recursive */*.txt" (or */*/*.txt, etc).  Hmmm, it's all coming back to
me now, vaguely -- this was the problem that the code I just removed was
intended to fix.  So what's the difference between the two cases?

 A. dir /recursive openssl-0.9.4 --> "openssl-0.9.4/*"
 B. dir /recursive */*.txt       --> "*/*.txt"

The difference, obviously, is left and right *'s.  The only way to keep them
both happy is to carry around the full relative pathame of each file, rather
than just the current segment.  To be continued...  ckufio.c, 28 Nov 99.

Some more SSL changes from Jeff.  ckcmai.c, 29 Nov 99.

Changed traverse() to compare full paths (rooted at starting position), rather
than all the clever stuff with segments.  This fixes B without breaking A;
however it breaks "dir */*.txt", "dir */*/*.txt", etc; any nonrecursive lookup
in which there is a wildcard in a directory path.  Everything else is fine
(except for one thing, which has always been broken, more about this later).
ckufio.c, 29 Nov 99.

The problem is that "subdir" does not match "*/*.txt" and so the subdirectory
is being skipped rather than opened.  Removing the clever trick to avoid
calling isdir() if listing is not recursive fixes this problem, but of course
slows us down.  But worse, it fails to fix "*/*/*.txt".  In this case,
ckmatch() is actually being called correctly:

  ckmatch string[subdir/thisdir/oofa.txt]
  ckmatch pattern[*/*/*.txt]

and fails to match.  Why?  Because it's an unstructured string match; it
doesn't treat filespec field separators differently from any other character,
whereas in UNIX filename globbing, directory separators are fences and can't
be gobbled up by "*", etc.  A simple change to ckmatch() to make "*" treat
"/" as a fence fixes the problem, but of course will break a thousand other
things.  So I changed the "matchdot" parameter to ckmatch() to be an "options"
parameter, bitmapped.  Bit 0 = match leading dot.  Bit 1 = filename globbing
so don't let * span field separators.  Set bit 1 in the appropriate calls,
mainly the ones from traverse().  Purposely did not set it in some other
places like SET FILE {TEXT-,BINARY-}PATTERNS because in that case we really
don't want to treat "/" specially.

Now in truth, "*/*/*.txt" should match "a/b/c.txt" whether it's a filespec or
not.  The above fix address filenames, but "if match a/b/c.txt */*/*.txt"
still does not succeed.  It seems we have two contradictory goals:

    Pattern    String
 A. */*/*.txt  a/b/c.txt
 B. a*bc,      abcbc

If A matches, B doesn't, and vice versa.  Yet both should match.  Currently
it's a matter of whether the "*" matcher searches for the rightmost or the
leftmost occurrence of the thing that follows it.  Until now, the strategy has
been rightmost, in which B worked.  Changing it to leftmost fixes A and breaks
B.  How can we make both work?  It appears to be a matter of whether the thing
that follows the thing that follows the "*" is another "*".  I added this
distinction and now both work, and "match.ksc" still passes.  Now I commented
out the previous filename-globbing change and ran the traverse() test again.
It worked fine, except one thing broke ("../.*").  Restoring the globbing code
fixed that.  But it broke "dir /recursive subdirname" so I removed it again.

So where are we now?  Everything works except:

 a. "directory ../.*" matches too much.
 b. Other unrelated problems involving symlinks are still there.

ckmatch() is being called with "../subdir" and ".*".  Well, clearly without
treating "/" as a fence, ".*" is going to match "../subdir".  But now for some
reason the fence business also breaks recursion.  This code is exactly like a
Whack-O-Mole -- you can't knock one down without making another one pop up.  So
let's leave it like this (no fence) for now; it's not perfect but it's a big
improvement.  The remaining problems are as above.

The symlink problem has several facets.  First, suppose the current directory
contains directory d1 and a symlink, d2, to d1.  Then "dir */*.txt" shows each
file in d1 twice, e.g. "d1/foo.bar" and "d2/foo.bar".  But "dir /recurs" is
smart enough to avoid this.  Oddly enough, UNIX "ls" and "ls -R" behave
exactly like Kermit.

Second, "dir /recursive /tmp/fdc/" says "empty directory" (when it's not).
Why?  In this case "/tmp" is a link to "/usr/tmp".  Here we are opening the
directory 0 times instead of 2 times (as in the previous case), or 1 time
(as we should).  (ls -R does NOT have this problem.)

Third, "dir /recursive /tmp" (same /tmp) just shows the symlink instead of
following it.  (ls -R does NOT have this problem.)

None of these symlink-related problems is new; they've been with us all along.
I'll see what I can about them tomorrow.

From Jeff: changes to the HTTP commands.  The DELETE command is now supported.
Like PUT it is almost never supported due to security concerns but we include
it for symetry.  Fixed several buffer over write errors in the allocation of
memory for the http request buffer.  Changed the local-file for GET and INDEX
to be optional.  If the file is not specified the output goes to the display.
(if we don't like it then we can simply modify the code in ckuusr.c (cx ==
XXHTTP) to ensure that a local file name is specified.)  Added checks to the
dohttp() function to insure that the command will not be attempted when there
is no connection or when Kermit is being used as IKSD.  Finished relocating
SSL/TLS code: Removed lots of variables that either wre not being used or
simply complicated the configuration of SSL/TLS.  With these changes I am now
confortable including SSL/TLS as a feature without any qualifications.
ck_ssl.c security.txt ck_ssl.h ckuath.c ckuus3.c ckctel.c ckuus7.c ckcnet.c
ckcmai.c ckuusr.c ckermit2.txt ckcnet.h, 29 Nov 99.

Fixed long lines & trailing blanks in ck_ssl.c.  29 Nov 99.

Never satisfied, went back to traverse() / ckmatch() problems.  Restored the
pathname fence changes to find out what the problem was with recursion, namely
that "dir /recursive subdir" does not recurse.  Why?  Obviously because
"subdir/*" does not match "subdir/a/b/c..." when "/" is a fence.  But since
the search is recursive, there should be no fences so I changed traverse() to
enable fences only in nonrecursive searches.  This change works, fixes the
"../.*" problem, but breaks two things:

 a. dir */*/*.txt  <-- no match
 b. dir /etc       <-- doesn't show subdirectories

These might actually be the same problem, namely that in nonrecursive
searches, we don't descend far enough.  The solution here is to open
directories not only on recursive searches, but also on nonrecursive ones
when the current search depth is less than the pattern depth.  This fixes
(a) but not (b).  In the latter case we are matching "/etc/blah" with "*"
(because blah is a directory), but the /'s preclude a match.  So one more
adjustment: turn off fences if the match object is a directory.  This
fixes (b).  Now let's run through the big list again to see what we broke:

 a. dir ./.*  (shows all files)
 b. dir ../.* (shows dot files plus directories)

Everything else works except for the symlink problems.

The problem with (a) is that, even though (say) "READ.ME" does not match ".*",
it is still being added because it is the end of a path segment.  Changed the
ELSE part of the big match-result IF statement to apply only if the current
item is a directory (rather than just ASSUMING it's a directory) AND it
matches the pattern OR the search is recursive, This fixes (a) but not (b).
Why?  Because we're matching "../blah" against ".*" without fences because of
the previous adjustment.  OK, but in this case we should be matching with
"../.*", not ".*".  I added a disgusting hack to handle this.

Ran the tests again.  Now we have a problem with "dir /recursive .*".  It
matches (for example) .xxx/oofa.txt.  Should it?  It didn't before...  But
worse, it misses some that it should match.  The problem in both cases is that
it is matching the whole path rather than the current segment, which is how we
got started on this tangent to begin with.  OK, how should it know when to
match only the current segment rather than the entire path?  When the search
is recursive?  OK, that fixes this problem, but breaks "dir /recursive
*/*.txt".  OK, so when the search is recursive AND the pattern does not
contain slashes...  Good, this fixes "dir /recu .*".  Everything else works
now except:

 a. dir /recursive .. (or anything that starts with ..)
 b. dir /recursive ./ (anything that starts with ./)

These were fixed by moving the stripping of any leading "./"'s from fgen() to
traverse(), and changing the "if" for stripping to a "while".  Now we pass ALL
tests except for symlink problems.  Let's look at these now:

 a. "dir */*.txt", where the current directory contains a "foo" directory and
    a symlink, "bar", to foo.  In this case, the contents of the bar directory
    are shown as if it was a separate directory.  But as noted before, ls
    does the same thing.  So does "ls -R */*.txt".  But Kermit's "dir /recurs
    */*.txt" does not -- Is Kermit being too clever?

 b. "dir /recursive /tmp", where /tmp is a symlink, just displays the symlink
    rather than entering the directory.  This is no doubt related to the
    cleverness in (a).  "ls -R /tmp" does NOT have this problem.

 c. "dir /recursive /tmp/fdc", where /tmp is a symlink, says the directory is
    empty when it's not.  "ls -R /tmp" does NOT have this problem.

Conclusion: C-Kermit is being too clever.  How can it possibly know that some
symlink might be redundant when others are not?  It can't.  The clever bit was
located in isdir().  Commenting it out fixes a thru c and makes Kermit behave
like ls and ls -R.  But we'd better run the 60 tests again just to make sure...
Hmmm, they're all OK.

Well, a couple minor problems turned up, but they were there before too:
"dir /recursive ./.*" and "dir /recursive ../.*" are slightly off.  In case
anybody ever notices these, they can be easily worked around.

Finally, one more problem was introduced recently.  In the CD command,
completion no longer works on a directory name (absolute or relative) if the
part entered so far contains a path separator.  Example:

  cd subd<Esc>         works (subdir is a subdirectory of the current dir)
  cd subdir/ano<Esc>   doesn't (ano -> another)
  cd et<Esc>           works (from /) (for /etc)
  cd /et<Esc>          doesn't

Why?  ckmatch is being called with "ano*" and "subdir/another", which don't
match.  Fixing this in the obvious way would, of course, break everything I
fixed already.  So let's try something devious, a hideous disgusting hack
designed to catch exactly this case without disturbing any of the others.
This seems to work, in that it fixes the problem, and we get through almost
all of our test suite without difficulty, until reaching "dir /recursive /etc",
at which point we just hang (I bailed out after 2 minutes).  But removing the
hideous hack didn't change this.  Well, ls -R works, CK Beta.10 works.  Aha,
/etc contains a symlink to the NFS-mounted Columbia University mail spool,
which contains 40,000 directories...  OK, false alarm.  But why does ls -R not
stumble into the same hole?  Because if you give it the -R (Recursive) option,
it doesn't follow symlinks at all unless you include the -L option.  OK, back
to the test suite...  And now for the first time, C-Kermit passes every single
test.  ckufio.c, 30 Nov 99.

So what to do about the /etc problem?  Three choices:

 1. Nothing (keep following symlinks in recursive searches).
 2. Don't follow symlinks in recursive searches.
 3. Add a command or switch.

Option (3) is not practical since it would need to go on every command that
allows recursion, but even then we still have functions like \frfiles().  If I
choose (2), then users won't have any way to defeat it.  So let's stick with
(1); if they get in trouble like I did, they can use circumlocutions.  Added
some notes about this to ckermit2.txt, 30 Nov 99.

So there you have it, another three long days on traverse().  If this ever
comes up again, remind me to throw the whole thing out and start over.  I'd do
it now, but it's working and we have to move on.

From Jeff: Plug some IKSD holes; more SSL/TLS shuffling.
ck_ssl.[ch] ckctel.c ckufio.c ckuus5.c, 30 Nov 99.

Changed DIR error message to more intelligently differentiate a bad switch
from a bad file or directory name.  ckuus6.c, 30 Nov 99.

Tried "pty tn3270 <ibm-mainframe>".  Works fine.  Added a section on this to
the doc.  ckermit2.txt, 30 Nov 99.

From Jeff: corrections to filename-matching code in ckmatch() for non-UNIX
builds: ckclib.c, 1 Dec 99.

From Jeff: The SET LOGIN PASSWORD password is now used for automated Kerberos
logins if the TGT was triggered by an Auto-GET and if the principal and realm
are known.  Otherwise, it is ignored and the user is prompted.  Now the dialer
can be configured with a user's password and it can trigger and auto login.
The same is true for SET HOST /PASSWORD:<pwd> <host>.  ckuath.c, ckuus[37].c,
1 Dec 99.

Discovered that telling the client to "set transaction-log brief", "log
transactions", and then "remote pwd" produced a core dump.  The
transaction-log writing routines were not protecting against null pointers.
Fixed in ckuusx.c, 1 Dec 99.

Lucas Hart reported that "get /recursive" from VMS client to UNIX server
resulted in all files arriving in binary mode.  Sure enough.  The same thing
happens UNIX-to-UNIX so it's not a matter of peer recognition.  On the
Whack-A-Mole theory, tried backing out of the SEND /TEXT change from Oct 22,
but it made no difference (so I backed out of the backing out).  Turns out
the problem was in the GET command parser, introduced on 24 Feb 99 with the
change to make GET /RECOVER imply /BINARY; the problem was a fall-through
from one switch case to the next that was valid before this change, but not
after.  Strange nobody noticed the problem for 9 months.  Let's hear it for
long Betas!  Fixed in doxget(), ckuus6.c, 1 Dec 99.

Built & tested on VMS:
 . get *
 . get /recursive *
 . get /text *
 . get /binary *
 . get blah, get /text blah, get blah (to make sure global mode restored).
All work fine.

Added --privid:{ok,no,...} command-line option for IKSD.  Sets ckxpriv, which
is defined in ckufio.c (so also needs to be defined in other ck*fio.c);
initial value 1 for compatibility with current behavior, but maybe it should
be 0.  Does nothing at the moment, but if 0 should prevent login to IKSD as
a privileged user.  ckuusr.h, ckuus[5y].c, ckufio.c, 1 Dec 99.

From Jeff: "if not iksd" checks added for many top-level commands.  Many
modules, 1 Dec 99.

Added PURGE /RECURSIVE.  (DELETE /RECURSIVE would be easy to add too, except
it would only affect files; we don't have a good way of deleting a directory
tree, or knowing when to delete a particular directory and when not to).
ckuus[27].c, 1 Dec 99.

Suppose I'm in a directory that contains a bunch of files and backup files and
I "send *" with filenames literal.  All the files, including the backup files,
are sent with their own names, like "foo.c.~3~".  OK, fine.  But now suppose I
"send *" again, to the same directory.  Now the backup files get double backup
suffixes, like "foo.c.~3~.~1~".  Changed znewn() to automatically trim backup
suffixes from incoming files before assigning new ones.  ckufio.c, 1 Dec 99.

Peter E pointed out that constructions like:

  define foo {,-
    blah blah
  }

didn't work ("?Macros nested too deeply").  But there's no good reason they
shouldn't.  The rule is that a braced section begins with a line ending with
an open brace.  But ",-" also indicates a line break, so the construction
above should be exactly equivalent to the same construction without the ",-".
Added code to getnct() to account for this situation.  And while looking at
getnct(), I saw an opportunity for a big speedup (or, rather, to undo a major
stupidity): this routine allocated a new read buffer every time it was called.
I changed the code to allocate a new buffer only the first time called, or if
called later requesting a larger size.  I don't have a good benchmark, but a
rough measurement indicates a 100% speedup in the reading of command files and
dialing directories (but only when the command file doesn't actually do any
computation; in most cases the difference is imperceptible).  ckuus5.c,
2 Dec 99.

Another GET command improvement: in GET [ switches ] <remote> <local>,
if <local> has the syntax of a directory name we try to CD to it, but if it
does not exist, GET fails.  Now if it does not exist, we try to create it
before trying to CD to it, but only if it seems to have directory syntax;
for example in UNIX if it ends with "/", or in VMS if it ends with "]"
or ">".  doxget(): ckuus6.c, 2 Dec 99.

Fixed a minor problem in VMS:  Suppose your current directory has a
subdirectory [.TMP].  You tell Kermit to "cd tm<Esc>"; Kermit correctly
expands this to (say) DKA0:[MYNAME]TMP.DIR;1, but when you press Return, it
says "Invalid argument".  Yet if you type "cd dka0:[myname]tmp.dir;1" it
works fine.  Too hard to explain.  Fixed in docd(): ckuus5.c, 2 Dec 99.

Fixed another problem reported by Lucas: if you tell Kermit to "set transfer
mode manual" (or whatever), then put it in server mode, then transfer some
files with a client whose transfer mode is auto (different from the server),
then finish the server, its transfer mode has changed to the client's.  Fixed
by making SET TRANSFER MODE set the global transfer mode as well as the
effective one.  ckuus3.c, 2 Dec 99.

Checked out Lucas's report from a while back about the VMS Kermit server's
response to REMOTE DIR being history-dependent.  As far as I can tell, it
doesn't happen any more.  2 Dec 99.

Lots o' changes from Jeff, mainly for checking in each command whether it may
be given to IKSD.  Mostly ckuus*.c, 2 Dec 99.

Changes from Jeff: minor corrections to stuff from yesterday, conversion of
many (more) sprintf's to ckstrncpy's.  ckcnet.c ckuus4.c ck_ssl.c ckuus2.c
ckuus6.c ckuus3.c, 3 Dec 99.

More c.f.j: ordered authentication type list: ck_ssl.c ckuath.c ckuath.h
ckuus3.c ckuus7.c, 3 Dec 99.

Made SET RECV a synonym for SET RECEIVE so we can write a lot SET SEND and
SET RECV commands and have them line up.  ckuusr.c, 4 Dec 99.

A final touchup to traverse().  There were still some small problems involving
".." in UNIX, but removing one of the special cases I inserted in traverse()
for ".." a couple days ago cleared it up.  Also, the test in fgen() for
automically setting "matchdot" for a given match if the given filespec began
with "." was overlooking the "../blah" case, which also was responsible for
some of the ".." problems.  Fixed in ckufio.c, 4 Dec 99.

Suppose you want to use a version of C-Kermit that is stored on the host as
"wermit" or "ckermit".  If you change your local Kermit's autoupload strings
to to use this name, C-Kermit would still only recognize "kermit" at its
prompt.  Added "wermit" and "ckermit" as synonyms.  ckuusr.c, 4 Dec 99.

New security.txt and telnet.txt from Jeff plus a couple minor source
corrections.  4 Dec 99.

Added a new feature for VMS: SET { SEND, RECEIVE } VERSION-NUMBERS { ON, OFF }.
Normally both are OFF.  If SEND VER ON, the VMS version number is kept on the
outbound filename; if OFF it is stripped.  If REC VER OFF, any VMS version
number on the incoming filename is stripped; if ON, it is kept.  This setting
is independent of FILE NAMES { LITERAL, CONVERTED }.  ckuus[247].c, ckvfio.c,
4 Dec 99.

Noticed that CD command in VMS doesn't work any more -- i.e. instead of
returning to your login directory, it does nothing at all.  It's because of
the seemingly innocent change I made to docd() a couple days ago.  Fixed by
focusing the change a little better.  ckuus5.c, 4 Dec 99.

Noticed that when uploading a file to VMS with specifying a path, it always
went in the home directory rather than the current directory.  Cause: a typo
in the GET-command-improvement code from 2 Dec.  Fixed in doxget(): ckuus6.c,
4 Dec 99.

Noticed that when VMS C-Kermit sends back the full filespec to the sender, it
always ends in ";" without the version number.  Ditto for the transaction log,
etc.  It's been like that forever; it has nothing to do with recent changes.
After some investigation, it turns out that this is howsys$parse() works -- it
doesn't actually go to disk; it only parses the given string.  Added a new
routine, getvnum(), that gets the version number using lib$find_file()
(suggested by Hunter G), and it works, but when the zfnqfp() result includes
the version number, this breaks all sorts of commands, notably LOG.  For
example, if DEBUG.LOG;2 exists and you tell C-Kermit to "log debug debug.log",
zfnqfp() finds DEBUG.LOG;2 and then when we go to open for output we get an
error.  So I backed out of all this and left it as it was.  4 Dec 99.

Updated NEWS text.  ckuus2.c, 4 Dec 99.

Did some preliminary builds to catch major foulups before starting the
build-all: HP-UX 10 (with and without ANSI features, optimization), VMS
(UCX and nonet), FreeBSD, SINIX, ...

Built with various features deselected on FreeBSD: NONET, NOCSETS, NODEBUG,
NOUNICODE, NOHELP, NOSPL, NOIKSD, NOXFER, NOSHOW, NOSERVER, NOPUSH,
NOPIPESEND, NOPTY, NOMSEND, NOLOGIN -- various minor #ifdef adjustment were
needed.  ckuus3.c, etc, 4 Dec 99.

Changed default IKSD database directory from /tmp to /var/log.  ckcdeb.h,
5 Dec 99.

Installed new "Open-Source-Friendly" copyright notice and changed VERSION
command to get the paging right.  ckcmai.c, ckuusr.c, 5 Dec 99.

Changed source-file copyright text to refer to main notice; all modules,
5 Dec 99.

Adapted pty code to NeXTSTEP.  ckupty.c, 5 Dec 99.

Excluded 4.4 BSD #include for <termcap.h> from BSDI, since it doesn't
have it.  ckuusx.c, 5 Dec 99.

Big trouble with Ultrix 4.3 -- first of all it barfs on the new makefile's
KTARGET clauses.  Makefile, 5 Dec 99.

After removing the KTARGET phrases from the Ultrix entries, I get:

  ... -c ckcmai.c
  cpp: error /usr/include/netdb.h:94: Can't find include file sys/bitypes.h
  cpp: error /usr/include/netdb.h:96: Can't find include file sys/cdefs.h

Some header files have disappeared from this computer -- I verified this
by trying to rebuild Beta.10 (which built OK there before) and it gets the
same error.  So I could only build a nonet version for Ultrix.

The SET DIAL TEST { ON, OFF } case was nested inside another case.
Fixed in ckuus3.c, 5 Dec 99 (after most of the binaries were built).

Protected an unguarded "extern int ucsorder" declaration with #ifdef UNICODE
in ckcfns.c (the DG AOS/VS link step will fails if extern declarations are not
resolved, even though they are never referenced), 5 Dec 99.

Something was very wrong in VMS 7.2-1; the SMG-based fullscreen file transfer
display gets: "?refresh: smg$begin_pasteboard_update: %SMG-F-INVPAS_ID,
invalid pasteboard-id".  But this doesn't happen in VMS 7.1 or earlier.
Eventually I concluded, correctly I hope, that the problem was just a
misconfiguration of the terminal database on that machine (because the debug
log said "initscr: smg$create_pasteboard: %SMG-F-UNDTERNOS, undefined terminal
- couldn't access system terminal table".  However, Kermit was handling this
error very badly, spewing thousands of error messages to the screen.  I added
code to the VMS curses-simulation routines to check for this and to switch
automatically to the CRT display when it happens. ckuusx.c, 5 Dec 99.

On one of the Linux systems I have access to, which (last time I heard) was
Slackware 3.5.0 (how do you tell?) now complains when ckupty.c tries to
include <sys/select.h>.  There is no <sys/select.h> or <select.h>.  I had to
make a new Linux target, linuxns, to handle this case.  There must be a better
fix, since the problem happens only in ckupty.c and not in other modules that
use select(), but the better solution will have to wait till after Beta.11.
Hmmm, on second thought, it seems that <[sys/]select.h> is included by ckupty.c
only in Linux, but no version of Linux I have access to needs it.  So I simply
commented out the #include.  (NOTE: according to RH 5.2 "man select", the
needed header files for select() are <sys/time.h>, <sys/types.h>, and
<unistd.h>, but we don't call select() in ckupty.c so it appears we never
needed any of this.  makefile, 5 Dec 99.

Peter E discovered that if you log in to IKSD with REMOTE LOGIN (rather than
by hand), that IKSD accepts only 91-byte packets, and does not respond to
file interruption (X) requests.  The problem seems to be confined to IKSD,
since if you run an ordinary server and REMOTE LOGIN to it, this does not
happen.  Comparison of the debug logs shows that in spar(), urpsiz is 4000
in the normal case, 90 in the problem case.  It turns out that dofast()
(which sets up fast file-transfer parameters) was not being called if there
was no init file.  Moved the dofast() call to the mainline initialization
sequence in main(): ckcmai.c, 6 Dec 99.

Due to a typo, the LOGOUT command was dispatching to the LOGIN routine.
Fixed in ckuusr.c, 6 Dec 99.

The LOGIN and LOGOUT commands, if given with no connection, printed an error
message but did not advance to the next line.  Fixed in ckuus7.c, 6 Dec 99.

William Bader noticed that the SCO OSR5 version did not display a herald when
started.  The same in Unixware 2 (but not 7).  Diagnosis: the SCO compiler was
generating bad code for:

  if (noherald || bgset > 0 || (bgset != 0 && backgrd != 0)) x = 1;

x was 0 before this, all conditions are false, and afterwards x is -32.
Fixed by rephrasing in herald(): ckuus5.c, 6 Dec 99.  (Note: the bug does not
occur in a small test program; i.e. it is not easily reproducible.)

New HELP text from Jeff for SSL and HTTP, plus a minor correction to an
SRP-related ?-help string.  ckuus[23].c, 6 Dec 99.

Added new tru64-40g target.  makefile, 6 Dec 99.

Minor changes to the copyright and permissions notice based on text from
CU counsel.  COPYING.TXT, 6 Dec 99.

Tried building on SCO 3.2v4.2 with PTY support -- no go; we get a syntax
error in a system header file (memory.h).  6 Dec 99.

Fixed an unguarded reference to zmkdir() in the GET parser and generalized the
#ifdefs around z_exec() to allow disabling from the cc command line with
-DNOZEXEC.  ckuus6.c, ckufio.c, 7 Dec 99.

Added #ifndef OPENBSD..#endif around #include <termcap.h>. ckuusx.c, 7 Dec 99.

Trimmed trailing blanks, fixed long lines.  All modules, 7 Dec 99.

---Beta.10---

From Jeff: Added missing TLS and NTLM keywords, plus some minor syntax
adjustments.  ckuus[367].c, 8 Dec 99.

Removed RD as an invisible synonym for RMDIR, now that we also have an
RDIR command.  ckuusr.c, 8 Dec 99.

Restored KTARGET clauses to Ultrix entries with new substitution syntax
from Peter E.  Makefile, 8 Dec 99.

Changes to #ifdefs around #include <termcap.h> for Mac OSX.  ckuusx.c,
8 Dec 99.

From Jeff: Added version string for SSL/TLS; created a hook to identify the
Crypto Dll version number; Fixed a typo "|" should have been "&" that was
resulting in the server responding to ONE_WAY Kerberos authentication
incorrectly.  ckuath.c, ck_ssl.c, ck_crp.c, ckuus5.c, 8 Dec 99.

From Jeff: Many SSL changes and a syntax fix in rset().  ck_ssl.c ckctel.c
ckcmai.c ckctel.h ckuath.c ckclib.c ck_ssl.h ckuus5.c, 9 Dec 99.

Looked into the core dumping problem on SCO 505 when sending a file.  It
happens in the fullscreen display at F-packet time.  The core file is total
garbage.  The debug log shows we crash in zfnqfp().  In OSR5, zfnqfp() simply
hands off to realpath(), which, when called, scribbles all over memory and
dumps core.  Tried adding -DNOREALPATH to CFLAGS and poof, it works.  Fixed in
ckcdeb.h by defining NOREALPATH if CK_SCOV5 is defined.  9 Dec 99.

Added solaris26gnc target for use when libtermlib is missing.  makefile,
10 Dec 99.

A fix from Jeff to my change of Nov 8 in which I "...removed the 'pop back to
command mode after each protocol operation' feature from IKSD by #ifdef'ing
out the 'justone = 1;' commands in ckcmai.c (search for IKSDPOPBACK)..."  This
change prevented the init file from being executed and the server idle time
limit from being set.  Fixed by setting justone = 1 during the authentication /
login phase.  ckcmai.c, ckcpro.w, 10 Dec 99.

Changes from Fred Smith for Coherent 4.2.  ckcdeb.h, cku[tf]io.c, ckupty.c,
ckuusx.c, 10 Dec 99.

Fixed a mixup with #ifdefs in z_exec() -- #ifndef should have been #ifdef.
This affects all Beta.11 builds; the "PPP dialer" feature (EXEC /REDIRECT)
won't work.  Let's see if anybody (besides Peter M) notices...  ckufio.c,
10 Dec 99.

From Jeff: Updated help text for SET AUTH and AUTH commands.  Changed name of
a command to better match common practice.  Decided not to support Tim
Hudson's /etc/ssl.users file.  We will only support the much safer ~/.tlslogin
file for authenticated login with certificates.  ck_ssl.c ckctel.c ckuus2.c
ckuus3.c, 10 Dec 99.

Fixed custom banner for SCO ODT 3.0.  ckuver.h, 18 Dec 99.

A block in zvpass() had a variable p, which causes compiler warnings since
zvpass also has a parameter p.  Changed the former to p2.  ckufio.c, 18 Dec 99.

Changes from Jeff:
 . Increase username/password length for IKSD.
 . Various authentication changes.
 . UNIX CONNECT fix vs IKSD disconnect and local-echo buffer.
 . Some fixes to the weighted running CPS calculation.
 . New code for K95 IKSD to find its configuration file.
 . Enable SHOW at IKSD prompt
 . Enable SSL/TLS is OS/2
Many files.  18 Dec 99.

More SSL stuff from Jeff.  ckutio.c, ck_ssl.c, ckuath.c, ckcnet.c, 19 Dec 99.

Peter E complained that building file lists was a lot slower after the changes
of 28 Nov - 4 Dec.  That's true, but it's because the optimizations and tricks
that were used prior to that to achieve speed gave bad results in many cases.
The whole problem centers around calling isdir() on each file to find out if
it is a directory; this turns out to be quite expensive.  The traverse() code
uses all kinds of scary tricks to avoid this, which is what makes it so
delicate.  It occurred to me that the struct returned by readdir() might
contain some kind of bit saying whether this was a directory; I can't imagine
why it wouldn't, but if it does I can't find it.  Anyway, I got a 5-10%
speedup by making an xisdir() macro and calling it within ckufio.c instead of
isdir(), to avoid the function call.  Then I simplified the conditions under
which xisdir() is called and the places from which it is called.  This speeds
up nonrecursive searches about 100% and recursive ones by about 60%.  But
always remember: you can't fix anything in traverse() without breaking
something else.  The simplification breaks the nice feature of putting a "/"
at the end of directory names in file lists, so I backed off, leaving us
with the 5-10% improvement.  ckufio.c, 19 Dec 99.

Comparing ls -l * with Kermit's \ffiles(*) shows that traverse() is about as
fast and therefore not the bottleneck.  The real bottleneck is the DIRECTORY
command.  Not because it sorts the results (the sort phase is negligible using
the current simple shellsort; substituting the way-more-complicated quicksort
gives no measurable speedup), but because it calls stat() AGAIN on each file to
get the size, permissions, etc.  The only remedy here would involve the
classic space-time tradeoff: we could make traverse() save the stat info for
each file.  But this could be quite big and furthermore would not be used
except in the DIRECTORY command anyway.  It could be done but I don't think
it's worth it since slowness is not noticed unless thousands of files are
involved.  So yes, in UNIX ls -l is faster than Kermit DIRECTORY because ls -l
only calls stat() once on each file.  No changes.  (Except a quicksort routine
was added to ckclib.c but #ifdef'd out.)

Ran traverse() tests, all OK.

Jeff noticed some spurious file transfer failures with "Error 0" since the
previous round of traverse() changes.  He caught C-Kermit in the act with a
68MB debug.log file.  At the end of the last file in the list Kermit sends the
Z packet, gets the ACK, calls gnfile(), which calls znext(), which returns 0
with an empty file name when it reaches the end of the list, as it should.
But for some reason we go back to ssfile state rather than sseot.  Turns out
that when the final file returned by znext() is not selected by fileselect(),
gnfile() returns an empty filename but a positive value.  This bug has been
there since adding the fileselect() code more than 2 years ago.  Fixed in
gnfile(): ckcfns.c, 19 Dec 99.

Added code to ignore PROTOCOL and COMPRESSION messages from modem while
dialing.  ckudia.c, 19 Dec 99.

Added support for Diamond Supra Express V.90 modem.  Incredibly, it removed
the &S0/&S1 command available in earlier Supra models and most other modems.
Therefore it is unlikely this one could ever be used from VMS.  ckudia.c,
19 Dec 99.

Added uw7ssl target for Unixware 7 with OpenSSL.  makefile, 19 Dec 99.

Went over new security.txt from Jeff.  19 Dec 99.

Trimmed trailing blanks from lots of files.  19 Dec 99.

Some corrections from Jeff to ckcnet.c and ckctel.c, plus more SSL/TLS stuff
in ckuath.c, ck_ssl.c.  20 Dec 99.

Changed UNIX sysinit() and syscleanup() to get and restore stdin flags.
ckutio.c, 20 Dec 99.

Added &S0 and &S1 to Supra Express init string -- it's not in the manual, but
it's valid anyway.  ckudia.c, 20 Dec 99.

Fixed a bug in which C-Kermit, when sending a file in local mode and
streaming, could hang if the user canceled with X or Z.  The problem was that
the code in sdata() that bumped the packet number when streaming did not also
bump winlo to match, and so input() did not recognize the resulting ACK from
the receiver because it seemed to have the wrong packet number.  ckcfns.c,
20 Dec 99.

If such a transfer was interrupted at just the wrong time, the Z packet might
not contain the D(iscard) directive.  Fixed in ckcpro.w, 20 Dec 99.

Added "s" to "timestamp" in "set debug timestamp".  ckuus3.c, 20 Dec 99.

Converted '-P' command-line option to mean "literal filenames".  ckuusy.c,
20 Dec 99.

Added missing carriage returns to the end of four Compaq modem commands that
lacked them.  ckudia.c, 21 Dec 99.

Some Supra Express V.90 init string corrections (incl removing Y0, which is
in the manual but not in the modem).  ckudia.c, 22 Dec 99.

From Jeff: Add Telnet environment variables to SHOW TELNET.  ckuus4.c,
22 Dec 99.

Minor fixes for FreeBSD uucp lockfiles from Helge Oldach <hmo@sep.hamburg.com>,
ckutio.c, 22 Dec 99.

If Kermit given a -j or -J arg on the command line and ^C was typed during
the connection phase, Kermit would dump core, probably because the longjmp
buf isn't set up in the command-line parser.  Fixed by adding
signal(SIGINT,doexit) to cmdlin().  ckuusy.c, 22 Dec 99.

Added CHECK PTY.  ckuus3.c, 22 Dec 99.

Back to our old friend, traverse()...  As noted previously, Peter E reports a
drastic slowdown since the Nov 28 - Dec 4 workover.  I added code to count
every stat() call.  In a directory with 54 files, "echo \ffiles(*)" results in
62 calls (the 8 extra are more-or-less constant overhead).  This shows that
traverse() is calling stat() once per file.  However "directory *" in the same
directory results in 227 stat() calls; 62 by traverse and 165 by the DIRECTORY
code.  That's way more than twice as many as there needs to be.  For each
file, DIR calls zgetfs(), ziperm(), and zfcdat(), each of which calls stat()
on the same file.  But ziperm() and zfcdat() should be able to pick up the
info from zgetf's stat() call.  The whole trick is to make sure it's the same
file.  But it's not such a trick -- we just check the diractive flag.  Adding
this to ziperm() reduces the number of stat() calls from 227 to 176.  Then
adding it to zfcdat() brings it down to 121, which is just about the minimum.
In a directory with 2500 files, the DIRECTORY listing starts in 4 seconds,
compared to 6 before this change, about 33% faster.  ckufio.c, 22 Dec 99.

But this is a small gain, and anyway does not affect non-DIRECTORY file lists,
such as file menus on "?", file- and directory-name completion, etc.  The only
way to speed these up is to not call stat() on every file.  But if traverse()
does not call stat() on every file, it doesn't know whether it's a directory.
Why do we care if it's a directory?

 . If it's a recursive search, we must open each directory and read it.
 . If it's a directories-only search, we must not match regular files.
 . If it's a files-only search, we must not match directories.

It is possible to change traverse() to not call stat() if none of these three
conditions is true, and this speeds up list generation a lot, for example
reducing the number of stat() calls in a regular DIR command (with no
switches) to approximately the number of files.  So in the 54-file directory
we're down from 227 to 62 stat() calls.  In a 2500-file directory, we're
seeing results after 2 seconds, rather than 6-8.

The problem with this trick is that it prevents the names of directory files
from being tagged with '/' at the end and showing up nicely in a file list.
Aside from that, we still pass the traverse() torture test.  So it's a
tradeoff.  And whenever there's a tradeoff, there needs to be a SET COMMAND,
so I added a new, invisible command SET FILE FASTLOOKUP { ON, OFF }.  It's off
by default, since most people aren't getting file lists of huge NFS-mounted
directories.  So today's score: 33% speedup without sacrificing anything;
300-400% with SET FILE FASTLOOKUP ON.  ckuus7.c, ckufio.c, 22 Dec 99.

Noticed that a couple details in the flow control handling in ttvt() were
different from those in ttpkt(), which might explain the problem that somebody
reported with switching flow control between OUTPUT statements.  There is,
no doubt, more to do here...  ttvt(): ckutio.c, 22 Dec 99.

Changed CHECK PIPE back to CHECK PIPES.  ckuus3.c, 23 Dec 99.

Rearraged command-line parser SIGINT handler to squelch complaints from picky
compilers.  ckuusy.c, 23 Dec 99.

Changes from Jeff for X forwarding.  ckcdeb.h, ckctel.[ch], 24 Dec 99.

Change from Jeff to command-line parser SIGINT handler to squelch even more
complaints from picky compilers.  ckuusy.c, 24 Dec 99.

Changed setprefix() for NONE (called when clearchannel is negotiated on a
network connection) to always prefix Xon and Xoff, regardless of the flow
control setting, as well as DEL (127), which seems to be particularly
troublesome, in addition to what it was prefixing before (CR, IAC, etc).  This
should allow CLEARCHANNEL to work even with connections to VMS and HP-UX.  Now
I can send from C-Kermit to gkermit on a Telnet connection with only the
following prefixed: 1, 13, 17, 19, 127, 255; unprefixing any of these kills
the tranfer (and sometimes the connection too).  ckcmai.c, 24 Dec 99.

Corrected a truly awful mistake in the command parser.  In any WHILE command,
the first left brace was treated as the beginning of the command list, so if
the condition contained a left brace, the parsing was totally bollixed, as in
"while not equal \m(blah) {\35} { commmands... }".  Fixed in doif() and
gtword(); the latter now sets global cmbptr to be a pointer to the CURRENT
position in the command buffer (cmdbuf[]).  Any higher-level routine can
examine it to see what has been parsed so far and what has not.  ckucmd.c,
ckuus6.c, 24 Dec 99.

Replaced clunky "does incoming file already have a backup suffix" code in
znewn() with cleaner (and better-working) code from gkermit.  ckufio.c,
24 Dec 99.

From Jeff:
 . Make \v(userid) return SET LOGIN USER value if one was given: ckuus4.c.
 . Expand setting of uidbuf[] in sysinit(): ckutio.c.
 . Some corrections to HTTP code: ckcnet.c.
26 Dec 99.

From Carl Friend: Updated targets for CLIX.  makefile, 27 Dec 99.

If '-T' or '-i' is given on C-Kermit command line, then set transfer mode
manual, don't use binary/text patterns, etc.  Giving these options on the
command line should be just like SEND /BIN or SEND /TEXT at the prompt.
ckuusy.c, 27 Dec 99.

Telnet updates from Jeff: ckctel.[ch], ckcnet.c, 28 Dec 99.

Removed all mention of "regular expressions" from the docs.  They aren't
regular expressions.  ckermit2.txt, etc.  28 Dec 99.

Changed zopeno() and zclose() to handle ZCTERM and ZSTDIO better.  ckufio.c,
28 Dec 99.

Corrections to MYDIAL macro in ckermod.ini suggested by David Sanderson, to
account for SET FLOW no longer being sticky.  28 Dec 99.

Show actual value of CK_SYSINI, if defined, in SHOW FEATURES.  ckuus5.c,
28 Dec 99.

Added code to save previous handlers for SIGQUIT, SIGPIPE, SIGUSR1, and
SIGUSR2, and to restore them before any exec(), execl(), execvp(), etc.
suggested by David Sanderson, cku[ft]io.c, 28 Dec 99.

More work on ttvt() to make its handling of flow control parallel that of
ttpkt().  Plus additional debugging, etc.  In response to persistent reports
that changing flow control between OUTPUT statements doesn't work.  ckutio.c,
28 Dec 99.

Revisited the problem of referring to files with spaces in their names.
The obvious way to do this is to put braces around the name, e.g.:

  send {this file}

This hasn't worked in years, maybe never.  The problem was simple: setatm()
was being called with the wrong "break mask" arg in this case (we were telling
setatm() to break on whitespace, but that's silly because the thing we're
putting in the atom buffer is already a "word" by definition, since it was
returned by gtword()).  Fixed in cmifi2(): ckucmd.c, 28 Dec 99.

Other methods are not so easy, however.  "send this\32file" can't work because
of our stupid DOS/Windows filenames; "this\32file" could easily be a DOS
filename (file = "32file", in the "this" subdirectory of the current
directory).  There is simply no way around this without having separate
fundamental parsing rules for different platforms.  Yes, we could first try a
match on this\32file literally, and if it didn't match, then try running it
thru the backslash interpreter and trying again, but this presumes we know
what the user intended when they typed "this\32file" and of course we can't.
Added clarification to ckermit2.bwr.  28 Dec 99.

Changes from Jeff for X forwarding.  ckcnet.c, ckctel.c, 29 Dec 99.

Backed off on yesterday's changes to zopeno() and zclose() -- they totally
broke client/server ops; for example, FINISH would get a "?Can't open file"
error.  ckufio.c, 29 Dec 99.

Made opent() succeed even if zopeno() returns 0, meaning "already open";
after all, that's no reason to fail.  ckcfn3.c, 29 Dec 99.

Fixed a dangling case in the protocol state table, which might have been
harmful if the new rcv_shortreply() returned -1, which normally would not
happen except if the client sends a REMOTE command with the response
redirected to a file, and writing to the file gets an error.  ckcpro.w,
29 Dec 99.  [NOTE: This fix is in error and was undone on 31 Dec 99.]

WAIT 0 <modem-signals> skipped getting the modem signals because of a boundary
condition on the loop test.  Fixed in ckuus6.c, 29 Dec 99.

Switching RTS/CTS on and off still didn't work.  I think now I know why.
In tthflow(), we have constructions like this: 

  if ((temp.c_cflag & CRTSCTS) == CRTSCTS) ...

But it turns out that, at least on Linux, CRTSCTS has a definition like:

   020000000000

which is liable to go negative, causing an 'if' condition like the one above
to fail when it should succeed.  Fixed in tthflow() by testing flags & CRTSCTS
for 0 or non-0, rather than any particular value.  ckutio.c, 29 Dec 99.

The iksd log is full of references to a file called "//READ.ME" (two slashes).
A little investigation shows that when C-Kermit is chroot'd (in SunOS), this
is how realpath() returns names of files in the chroot'd root directory.
Added a code snippet to collapse multiple leading /'s to a single one.  Also
noticed many references to a file called "getwd:_can't_open_.." in the log,
also only when chroot'd; couldn't reproduce this but I suspect that realpath()
is storing an error message in the destination buffer.  I changed the code to
zero the buffer if realpath() fails; let's see if this comes out in the log
again after today.  zfnqfp(): ckufio.c, 29 Dec 99.

From Jeff: New ckctel.[ch] ckcnet.c ckcdeb.h more pleasing to DECC.  29 Dec 99.

Added notes to ckermit2.txt about leading 0's in numeric IP addresses.
29 Dec 99.

From Jeff: more X forwarding.  ckcnet.c ckwart.c ckctel.c ckuus5.c ckuus3.c
ckcdeb.h ckctel.h ckucns.c ckuusr.h ckuus4.c, 30 Dec 99.

Removed definition of CK_FORWARD_X for UNIX from ckcdeb.h; we'll save this
for C-Kermit 7.1.  30 Dec 99.

Changed copyright dates to 2000.  All modules, 30 Dec 99.

Inserted the final copyright and permissions notice and disclaimer.  ckcmai.c,
30 Dec 99.

Removed Beta references from NEWS text; updated SUPPORT text.  ckuus6.c,
30 Dec 99.

Checked Lucas's bug (make a connection from CK on DU to IKSD, wait 10 min
until IKSD times out & closes the connection, re-CONNECT, C-Kermit pops back
because connection is closed, and now CBREAK mode is lost).  Can't reproduce
it on DU, SunOS, or anything else.  But for safety's sake, added a new
invisible command, SET COMMAND CBREAK, to force console into CBREAK mode in
case it got lost.  ckuus3.c, 30 Dec 99.

Put the tx_lucidasub() routine in #ifdef OS2..#endif, since this is a fairly
sizeable chunk of code used only by K95, and optimizers always complain about
it.  ckcuni.c, 30 Dec 99.

George Gilmer determined that C-Kermit 7.0 Beta.11 can be built for NCR MP-RAS
2.03 and 3.02 by adding -DNOGETUSERSHLL and -DNO_DNS_SRV to the sys5r4sx[tcpc]
targets, and uploaded the resulting binaries.  Added new build targets and
designer banner for MP-RAS, to be picked up next time around.  makefile,
ckuver.h, 30 Dec 99.

Fixed a bug in UNIX zfnqfp() I introduced yesterday by copying the result
to the wrong buffer, thus breaking file reception whenever backing up was
necessary.

After building on VMS 5.5, found that something had gone wrong with the
"curses" (SMG) support.  The first call worked, subsequent ones didn't.  For
example, Ctrl-L works the first time but not the second; the prompt comes out
in the wrong place after the fullscreen file-transfer display.  The Beta.11
binary, however, works fine.  Comparison of screen-related code in Beta.11
ckuusx.c and in today's copy shows no differences at all.  What happened?  To
make a long story short, I *forced* Ctrl-L to work by always calling initscr()
before clear() and endwin() afterwards (refresh() too, though it doesn't make
a difference).  But SCREEN MOVE (move()) now behaves exactly like SCREEN
CLEAR, and yes, we really are calling the correct SMG$blah routine.  So I
replaced the current ckuusx.c with the one from Beta.11 and rebuilt -- and we
still have the same problems.  As a final experiment, I rebuilt from the
entire Beta.11 source set and guess what: this one has the same problems, even
though the binary I built from exactly the same sources on exactly the same
machine 24 days ago has no problems at all.  Y2K jitters?  It's only 30 hours
away...  Anyway, I changed back to the old, old MYCURSES code, despite the
cautions in the comments.  It works fine on both a fast Alpha and a sloooow
VAXstation 3100 and cuts about 5K off the binary.  ckuusx.c, 30 Dec 99.

Next problem -- C-Kermit is not sending back the full pathname in its ACK when
receiving a file if a file of the same name did not already exist.  Similarly,
\fpathname(foo) no longer works if foo doesn't exist, but it did in Beta.11.
After wasting several hours on this, I rolled back all the zfnqfp() changes
from the past couple days; the only reason for them was to fix some glitches
in the idsd log, which who cares.  ckufio.c, 30 Dec 99.

Next problem -- Unix traverse() really is too slow.  People will hate it.
Changed default value of FASTLOOKUP (variable stathack) to 1.  ckuus7.c,
30 Dec 99.

Added PROTECTION to HELP SET ATTRIBUTES.  ckuus2.c, 30 Dec 99.

Made sure that NOPUTENV was defined for not K95 or UNIX.  ckcdeb.h, 30 Dec 99.

More X forwarding from Jeff.  30 Dec 99.

Trimmed trailing blanks from source files.  30 Dec 99.

Made sure the result builds cleanly on VMS (net and nonet) and SunOS.

Some final X forwarding and IKSD changes from Jeff.  ckctel.c ckcnet.c
ckctel.h ckutio.c, 31 Dec 99.

David Sanderson reported that client commands that got short-form replies
from the server (RCD, FINISH, etc) always failed.  This was caused by the
"Fixed a dangling case in the protocol state table" item from Dec 29; it
wasn't dangling at all; fixed by removing the fix.  ckcpro.w, 31 Dec 99.

At the end of the Beta-test period, our census of binaries stands at:

 Beta 04 binaries:   9
 Beta 05 binaries:  20
 Beta 06 binaries:   6
 Beta 07 binaries:  25
 Beta 08 binaries:  19
 Beta 09 binaries:  21
 Beta 10 binaries:  70
 Beta 11 binaries: 179
 Total:            349

After 2000 came in Russia (Leningrad) I transferred a 1988 file from here
to there; the timestamp was correct.  Then I touched it there to get the
1 Jan 2000 timestamp and transferred it back to NY, and this had the correct
timestamp too.  Later, same deal between here and Amsterdam.  No problems.

The pre-10.00 HP-UX builds were all done on systems that had their dates
set back to 1971, so at midnight they'll turn over 1972, which has the same
calendar as 2000 (and 1944).  HINT: touch all source files after unpacking
the tar archive :-)

A reference to uidbuf[] needed to be #ifdef NOSPL.  ckuus4.c, 31 Dec 99.

DECC on DU 3.2 now dumps core on ckuus6.c with -O.  makefile, 31 Dec 99.

Binaries built 31 Dec 1999 - 1 Jan 2000.

---7.0.196 Released 1 Jan 2000---

Minor fixes applied 2 Jan 2000, after binaries built but before announcements
and final source-code packaging:

 1. WAIT n FILE MODIFICATION did not fail if interrupted from keyboard.
    Interfered with IKSDPY: ckuus6.c.

 2. Fixed NOICP builds by moving declaration of stathack from
    ckuus7.c to ckcmai.c.

 3. Fixed SET FLOW help message when CK_DTRCD and CK_DTRCTS are defined. 
    ckuus3.c.

 4. Some authentication-related HELP messages updated, ckuus2.c.

 5. Minor syntax corrections to telnet.txt, security.txt.

 6. Minor corrections to introductory comments in several modules.

 7. Server's response to GET xxx where xxx doesn't exist was changed from
    "No filespec given" to "File not found".  ckcfns.c.

 8. New makefile targets for NetBSD define DTR/CD and DTR/CTS flow control

 9. Replaced "??-" in comments with "xx-" to shut the compilers up about
    trigraphs.

10. Replaced a missing comment terminator in ckcpro.w.  This one could
    cause the following problem: when sending a file and failing to close
    it, the discard directive would not be sent.  But it's hard to imagine
    a circumstance in which we would fail to close a file we just opened
    and read from successfully.

11. Enclosed an unguarded reference to the sj struct in #ifdef KANJI.
    ckcfns.c.

SHOW VERSIONS of binaries built before these changes give a ckuusr date of
1 Dec 1999; binaries with these fixes show 1 Jan 2000 for ckuusr.

---7.0.196 Announced 3 Jan 2000---

Added sinix541 makefile target for SINIX-L (i386) 5.41, plus designer banner,
and added a couple #ifdefs to allow it to compile (it doesn't like fdopen()).
makefile, ckuver.h, ckufio.c, 6 Jan 2000.

Removed -O2 and added -DNODEBUG -DNOIKSD to the ultrix42c makefile entry;
although it compiled OK, it got bizarre relocation errors at link time and
this was the only (ok, first) way I could find to make them go away.
makefile, 6 Jan 2000.

Updated the ps2aix target for AIX 1.2.1 on the PS/2, and added a new
ps2aixnetc target in the makefile.  Had to put #ifndef PS2AIX10 around
#include <netdb.h> in ckcnet.c, and add a prototype for ttyname() to ckutio.c.
There's a warning about tlog() that's unavoidable (termio.h defines a tlog
macro and we redefine it).  OK, it's not really unavoidable...  6 Jan 2000.

Added a couple new paragraphs to the ckermit2.txt section about coping with
faulty Kermit implmentations.  6 Jan 2000.

Changes for CLIX from Carl Friend.  ckutio.c, ckcnet.c, makefile, 16 Jan 2000.

Changes from Joe Smith for SunOS 4.1 with X.25.  ckutio.c, makefile,
16 Jan 2000.

Changes from David Lane for Stratus VOS: ckcdeb.h, ckcker.h, cklfio.c,
16 Jan 2000.

A couple new variations on the 3B2/3B20 makefile targets from Peter
Mauzey.  makefile, 17 Jan 2000.

Text and binary filename patterns for VOS, and changes to VOS network module
to allow building for X.25 but not TCP/IP, from David Lane.  ckcmai.c,
cklnet.c, 17 Jan 2000.

Some changes to make C-Kermit compile on OSF/1 1.3.  First there is some kind
of foulup in the header files that turns off ANSI prototyping when C-Kermit
thinks it should be doing it, so this had to be undone in ckucmd.c, ckcnet.c,
ckucns.c, ckufio.c, and ckutio.c.  Then in ckuusr2.c there was a string
contstant that contained something like "/usr/share/kermit/*.*", which the
compiler took to be a comment begin and so lost an #ifdef.  This needed
"rewording".  Changed the dec-osf target to skip optimization and force
static linking.  18 Jan 2000.

Building C-Kermit 7.0 for OS-9/68000 on Steve Rance's Solaris 7 system in
Australia using the xcc (Ultra C 2.0) cross-compiler (reportedly, Microware no
longer supports development directly on OS-9, but requires cross-builds).
This needed a new makefile, ck9xcc.mak.  Notes (19-21 Jan 2000):

 . We can build wart but can't run it, so must touch ckcpro.c.
   Later I just took everything to do with wart out of the makefile.
   Later Steve changed the makefile to build wart for Sun and run it.
 . All ckc*.c and ckuus*.c build, and so do ck9con and ck9tio.
 . ck9fio.c blows up because of some inline assembly code.
   This was handled by changing #asm..#endasm to _asm("...");
   But we need to do this with #ifdefs to allow old way too?
 . ck9asm.a just builds, amazing.
 . ck9ren.c had to be removed from the makefile (not needed for this build).
 . References to {me,u}_binary in ck9con.c had to be updated to new macros.
 . Had to add NO_DNS_SRV.
 . Had to change <inet/...> to <INET/...> in ckcnet.h.
   But this was only for the cross compiler so I defined a new
   symbol OSKXXC for this.
 . Link step, libs, etc, needed changing/updating (termlib added).

Steve Rance made various other edits, mostly changing the names of error
symbols from E_blah to EOS_blah (should this be conditionalized? -- will
it break "native" OS-9 builds?)

Finally it built OK and runs on OS-9/68000 3.0.3.  It can make a Telnet
connection, transfer files, produce the fullscreen file-transfer display,
produce file lists and do filename completion, etc; pretty much fully
functional.  I did find one glitch: any reference to the \v(ipaddress)
variable causes a crash, but only before any TCP connections have been made.
I "fixed" this by #ifndef OSK'ing the code in nvlook() that calls
getlocalipaddr().  ckuus4.c, 22 Jan 2000.

To remove voluminous warnings (when -cw added CFLAGS), added CK_STDLIBS to
OS-9 CFLAGS, but then had to put #include <unistd.h> within #ifndef
OSK..#endif.  Now it compiles cleanly except for the usual torrent of
"variable declared (or set) but never used" warnings (because of all the
#ifdefs), plus warnings about implicit declaration of a few functions,
including alarm(), isatty(), getpid(), ustrncmp(), _ev_unlink(), and
_ev_delete(); not sure what to #include to fix these but they should be
harmless anyway.  ckcdeb.h, 22 Jan 2000.

Fixed a bunch of nontrivial warnings in ck9tio.c -- nested comments, use of
uninitialized variables, and int conxxx() routines that did not return a
value.  22 Jan 2000.

The only serious remaining problem that I know about is: even though the
TELNET command works just fine, SET HOST dies immediately with a stack
overflow.  Tried rebuilding ckuus7.c (the module containing the SET HOST
code) without optimization but it made no difference.  Will have to wait for
OS-9 guys to fix this one; some magic incantation to increase the stack
size?  In the meantime we have a binary that's usable for most things (but
unfortunately SET HOST is needed for scripting).

Installed TCPware 5.4 on my Alpha and tried to build C-Kermit 7.0.  Total
disaster, horrible syntax errors in SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 (not
in Kermit code).  Turned it over to Hunter Goatley.  21 Jan 2000.

Steve Rance fixed the OS-9 problem by increasing the stack size.  I cleaned
up the source files to #ifdef all the recent changes that depend on Ultra C.
ck9xcc.mak, ck9[tf]io.c, ck9con.c, 23 Jan 2000.

Worked o