Kermit Project   C-Kermit   C-Kermit Tutorial   Kermit Script Library

C-Kermit Case Study: Logging a session to a serial port

Frank da Cruz
Columbia University
Last update: Mon Oct 26 16:50:44 2009

In Unix, the normal way to record (log) an interactive shell session is with the Unix 'script' command (what the user types is underlined):

$ script filename
Script started, output file is filename
...
$ exit
Script done, file is /dev/ttyS0
$
You can use C-Kermit to log a local session too; here's how:
C-Kermit> log session filename
C-Kermit> set host /pty \$(SHELL)
...
$ exit
C-Kermit>
This main difference from 'script' is that Kermit gives you some recording options:
SET SESSION-LOG BINARY
Every byte that is sent to the screen is recorded in the log.

SET SESSION-LOG TEXT
Strips out carriage returns (in Unix), XON and XOFF, NUL, and in C-Kermit 9.0, also strips out ANSI escape sequences.

SET SESSION-LOG DEBUG
Writes control characters and 8-bit characters in an ASCII format.

SET SESSION-LOG TIMESTAMPS
For text-mode session logs, puts a timestamp on each line (this command implicitly sets SESSION-LOG TEXT).

SET SESSION-LOG NUL-PADDED-LINES
This inserts an ASCII NUL (0) byte after every linefeed that goes into the session log. This feature can be used with both text and binary session logs.
This final option was added for the benefit of the RC Systems DoubleTalk LT speech synthesizer that (reportedly) requires a NUL byte at the end of each line before it will speak the line. This feature is probably not going to be widely useful but if desired it could be expanded to be more flexible as to padding format and syntax.

A more fundamental change to Kermit was required to allow the session log to be sent to a serial port. Previously a command such as:

C-Kermit> log session /dev/ttyS0
would fail with "?Write permission denied - /dev/ttyS0". This would happen even if you actually had write permission to the device. The reason is that Kermit's LOG commands were never designed to use serial ports. Normally when Kermit goes to open a file for write or create access, it first checks to see if it has write access to the containing directory. In this case, it did not (people aren't allowed to write into the /dev directory), so Kermit returned a spurious refusal.

This was cured by having the LOG command check to see if the log file was actually a serial port, and if so to handle it specially. HOWEVER... a further problem remains. Serial ports aren't like other files. They have to be configured (speed, flow control, stop bits, start bits, parity) before you can use them, and in Unix they also are supposed to be guarded by a “lock file” to prevent simultaneous access.

C-Kermit was never designed for any of this. Only the SET LINE (SET PORT) command knows how to fully deal with serial ports, and this is only for the purpose of making connections, not opening log files. Changing the situation would require a massive redesign and rewrite of the code, which probably won't (and shouldn't) happen.

Making this feature generally available as-is would have the bad affect of bypassing the Unix lockfile mechanism, which could result in mangled sessions or log files, or worse. Therefore it is enabled only in C-Kermit versions that have been built with the -DNOUUCP flag, meaning "no lock files"; that is, computers that already have this problem anyway. (For a detailed explanation of lock files and UUCP, READ THIS and THIS.)

Well, it seems that in the 21st Century serial ports are fading from the landscape, and some operating systems, such as Mac OS X have erased the very concept from their toolset, and with it UUCP. Therefore in C-Kermit 9.0, the Mac OS X version ("make macosx") is a -DNOUUCP build by default, and so it has the serial-port logging feature unless you go out of your way to do a UUCP build and configure UUCP and its directories and files and lockfiles and groups and permissions on your Mac, which almost nobody does since, after all, these are usually personal, not shared, machines.

Logging a session to a serial port

HERE is sample script for logging a session to a serial port. As noted, it will work only in C-Kermit 9.0, only on Mac OS X, and then only if you have gone to the trouble to buy a third-party USB serial-port adapter and driver (the Keyspan High Speed USB Serial Adapter USA-19HS is popular and is the one tested here). As noted in the comments, the LOG SESSION command is likely to hang if the serial port is not connected (typically with a null modem cable) to a logging device that is turned on and presenting the required modem signals (or a straight-through cable with a modem eliminator).