Icon The Kermit Project   |   Now hosted by Panix.com
New York City USA   •   kermit@kermitproject.org
since 1981

Kermit file-transfer packet reference

Frank da Cruz
The Kermit Project, Bronx NY.
7 September 2022
Last update: Mon Jan 29 12:35:41 2024

This is a supplement to the information found in the Kermit Protocol Manual (1986) and the book Kermit, a File Transfer Protocol (1987). Both of those documents were written in the pre-WWW days in a markup language called Scribe that no longer exists and therefore those sources can't be easily updated. This page does not explain the Kermit protocol, only what is in the packets.

Fundamental rules Block checks Negotiations Capabilities mask S-Packet examples Empty directories Transfer encodings References

Kermit packet exchange - stop and wait Over the decades many backwards-compatible improvements have been made to the Kermit file transfer protocol, and these resulted in a variety of new packet formats, types, and contents. Until now this information was never collected into a single reference.

Kermit file transfers occur when two Kermit programs — the file sender and the file receiver — exchange a well-defined sequence of packets. The file sender initiates the transfer by sending a packet to the file receiver. The receiver sends a short acknowledgement packet back (or in case the packet was damaged in transit, a negative acknowledgement). The process repeats until the the task is done. There can also be a client/server relationship, in which the client sends not only files to the server, but also commands (for example, to "get" a file or other information from the server or perform file-management tasks in the server side.

Fundamental rules

Kermit packet exchange - sliding windows Kermit protocol was designed in 1981 to accommodate a variety of platforms and communication methods and hosts that were sensitive to long bursts of input, control characters, and/or 8-bit characters (bytes with their high-order bit set to 1). Thus the default mode of operation is, and must remain, to exchange short packets that consist of only printable ASCII characters — lines of text — with each packet acknowledged before the next one can be sent. That's the lowest common denominator.

The use of longer packets, sliding windows (right), streaming, compression, transmission of bare control or 8-bit characters, and all the other performance improvements made since the original protocol — which was designed to interoperate among IBM mainframes, the DECSYSTEM-20 mainframe, and 8-bit CP/M microcomputers — can be used only if both Kermit programs implement them and agree to use them in the feature-negotiation phase at the beginning of the file transfer.

Functions referenced in this document (see ASCII table):
tochar(x)
Converts an integer x (0-94) to a printable ASCII character (space through tilde) by adding 32, so 0 (zero) becomes space, 1 (one) becomes exclamation mark, (etc...), and 95 becomes circumflex/caret (^).
unchar(x)
Converts a tochar()-encoded integer x back to its numeric value.
ctl(x)
Converts a C1 (7-bit) control character x (ASCII 0-31) to a printable character or vice-versa by toggling its bit number six (i.e. 7th bit from the "right").

All numbers used in this document are decimal (base 10). All characters used in Kermit packets to implement the protocol are 7-bit ASCII printable characters (strictly speaking, the Mark and End control characters are outside the packet). Of course any kind of data — binary, 8-bit, text in any language (e.g. Japanese) — can be included in the packet Data field but it is almost always encoded to some degree for transparency and/or efficiency using methods described in this document such as single and locking shifts.

Kermit packet types

In the "Sent by" column, Sender means the Kermit program that is sending a file; Receiver means the Kermit program that is receiving a file; Client means the Kermit program that is acting as a client to a Kermit server; Server indicates a Kermit server. Of course a server can also be a file sender or a file receiver. In the Status column, "required" indicates a packet type that all Kermit protocol implementations must support; "optional" packets are extras whose use must be be negotiated.

Type Name Status Sent by Description
Y ACK Required Receiver Acknowledgment. Indication that a sender's packet was received successfully
N NAK Required Receiver Negative Acknowledgment. Indication that a sender's packet was not received successfully and needs to be retransmitted. Never carries data.
S SINIT Required Sender Send Initiation. Tells the receiver to expect one or more files. The Data field contains the sender's initialization parameters. The ACK to this packet contains the receiving Kermit's initialization parameters.
I INIT Optional Client Initialize. Data field contains initialization string. Sent to server to set parameters prior to a command other than SEND. ACK to this packet contains the server's initialization string.
F FILE Required Sender File Header. Data field contains the name of the file being sent. ACK to this packet may contain the name receiver will store file under.
X TEXT Optional Server Text Header. Indicates the incoming data is to be displayed on the screen rather than being stored in a file. The X-packet's Data field can contain a heading for the display.
A ATTR Optional Sender File Attributes. Data field contains attributes of the file about to be sent. ACK may contain corresponding agreement or refusal, per attribute.
D DATA Required Sender Data Packet. File or screen data. ACK may contain X to interrupt sending this file or Z to interrupt entire transaction (if multiple files are being sent).
Z EOF Required Sender End of file. Data field may contain D for Discard (in case the transfer was interrupted by the user).
B BREAK Required Sender Break: End of transmission.
E ERROR Required Any/All Error. Cancels any file transfer in progress. Data field contains error message.
R GET Optional Client Sends to a Kermit server the name of a file to send to the client. The Data field contains the name of the desired file. The server responds by starting a new transfer with an S packet.
C CMD Optional Client Host Command. Data field contains a command for other Kermit's host command processor, with the results to be sent back as screen text.
K KCMD Optional Client Kermit command. Data field contains command for Kermit command processor to execute; any results are sent back as screen text.
T TIMO N/A N/A Timeout psuedopacket (not an actual packet), for internal use in the state machine.
Q CHKERR N/A N/A Block check error psuedopacket (not an actual packet), for internal use.
G GENERIC Optional Client Generic Kermit Command. Data field contains a single character subcommand, followed by zero or more length-encoded operands. Typical examples are CD (which tells the server to change to another directory), report disk usage, delete a file, copy a file, run an external program, etc. The subcommands are listed here.
H MOVE Optional Client GET /DELETE: Asks server to send one or more files and if delivered successfully, to delete the original afterwards.
V RGET Optional Client GET /RECURSIVE: Asks the server to send all matching files not only from its current directory but also from all its subdirectories (and all their subdirectories, etc).
W RMOVE Optional Client GET /DELETE /RECURSIVE: Asks the server to send all matching files not only from its current directory but also from all its subdirectories (and all of their subdirectories, etc) and delete each source file after it is succefully delivered.
O XGET Optional Client Extended GET: For adding new GET options without having to add new packet types by specifying desired actions (delete, recurse, recover, execute a command, etc). For example, GET /DELETE, GET /RECURSIVE, GET /RECOVER, GET /COMMAND, etc, could all be done using the O packet, and other actions could be easily defined without exhausting the precious packet-type space (traditionally, but not necessarily always, the uppercase ASCII letters). Described here.
Basic Kermit packet
Mark  Len Seq Type Data.... Check End

Packet fields
Name Format Description
Mark  Control character, normally Ctrl-A Signals beginning of packet
Len Single byte: tochar(len) Number of characters that follow, 3-95
Seq Single byte: tochar(seq) Packet sequence number, 0-63
Type Single byte: ASCII uppercase letter Type of packet (S, F, D, Z, B, etc)
Data Partially encoded character stream Depends on packet type
Check Single byte: tochar(check) Len-through-Data six-bit checksum
End Control character, normally CR (Ctrl-M) Signals end of packet

Here's an example:

🇦+!Ftest.txtC🇲
in which 🇦 represents Ctrl-A (Mark) and 🇲 represents Ctrl-M (carriage return, End) and:

The maximum length for a basic Kermit packet (not counting Mark and End, which are outside the packet) is 96, so the maximum length of the Data field is 92 to 94, depending on the type of block check. This is the basic and required packet format for all implementations of the Kermit protocol. In the Data field, "sensitive" items such control characters are encoded printably, for example #M#J is Control-M followed by Control-J, i.e. carriage return and linefeed.

For increased efficiency and reliability an optional format allows packets up to about 9K long. A long packet has a blank Len field (blank = space = ASCII 32 - 32 = 0). This tells the receiver to take the length from the two bytes after the Type field.

Extended Kermit packet
Mark  (blank) Seq Type MaxLx1 MaxLx2 Hcheck Data.... Check End

Packet fields
Name Format Description
Mark Control character, normally Ctrl-A Signals beginning of packet
Len Blank (space, ASCII 32) Indicates extended length given in bytes 5 and 6
Seq Single byte: tochar(seq) Packet sequence number, 0-63
MaxLx1 tochar(length / 95) High-order byte of packet length
MaxLx2 tochar(length MOD 95) Low-order byte of packet length
Hcheck tochar(checksum) 6-bit header checksum of Len through MaxLx2
Data Partially encoded character string Depends on packet type, variable length
Check Single byte: tochar(check) Len-through-Data six-bit checksum
End Control character, normally CR (Ctrl-M) Signals end of packet

Like the basic packet format except Len is blank (Space, ASCII character 32), an impossible value for a basic-format packet, which denotes this as a "long packet" with its length appearing after the Type and before Data field:

References

If long packets are negotiated, any packet can be sent in either short or long format, since the Len field always identifies the format.

Block checks

The packet block check comes after the Data field and before the End character. It can be one, two, or three bytes long. All Kermit implementations are required to support the single-byte block check. The others are optional and used only if negotiated. The S-Packet and I-packet if any and their ACKs always use the 1-byte block check, and the the protocol switches to the negotiated type for subsequent packets.

For all packets, the Packet checksum is based on the sum, s, of the ASCII numeric code values of all the bytes in the packet starting with the Len field up to the last byte of the Data field. The Header checksum (used only in long packets) is based on the arithmetic sum, s, of the code values of Len, Seq, Type, MaxLx1, and MaxLx2. In both cases the single-byte 6-bit block check is calculated by this formula:

checksum = tochar((s + ((s & 192)/64)) & 63;
where '&' is the bitwise logical AND operator. In long packets, the header checksum is always Type 1.

Kermit protocol packet block check types
Type Command Bytes Status Explanation
1 SET BLOCK 1 1 Required, negotiated 6-bit checksum
2 SET BLOCK 2 2 Optional, negotiated 12-bit checksum
3 SET BLOCK 3 3 Optional, negotiated 16-bit CRC
BLANK-FREE-2 SET BLOCK 4 2 Optional, negotiated 12-bit checksum with no blanks
FORCE-3* SET BLOCK 5 3 Optional, set manually 16-bit CRC forced for all packets
* Explained here.

The 2-byte block check is the low-order 12 bits of the sum of all the characters divided into two bytes, each made printable by tochar(). It is 64 times stronger than type 1.

The two-byte "blank-free" 12-bit block check, for use on communication paths (such as IBM 370 protocol converters) that discard trailing blanks, is the same, but if a result byte is blank (ASCII 32), it is converted to '!' (ASCII 33).

The 3-byte block check is the international standard CRC-16-CCITT cyclic redundancy check (as used in X.25) encoded as three printable characters. It detects all single- and double-bit errors, all messages with an odd number of bits in error, all error bursts shorter than 16 bits, and over 99.99% of longer error bursts.

The original protocol had only one kind of block check so its location and length were always known. When higher-order block checks were introduced some years later a minor weakness was that you could no longer tell by looking at a packet where the block check started or how long it was. Kermit programs that support the newer block checks have to rely on the state established by the negotiations at the beginning of the transfer: the length of the Data field is indicated in the packet, so the block check is the final 1, 2, or 3 characters depending on the block-check type previously negotiated. If the block check were clearly marked in the packet itself, then every packet would be "self-parsing" and could have any kind of block check. In 40 years of practice, however, no ill effects have been noted with over 300 different versions of Kermit created in nearly 40 different programming languages (see list).

Reference: Kermit, A File Transfer Protocol: Block check options.

Feature negotiation

A normal file transfer begins when the file sender sends an 'S' (Send-init) packet to the file receiver. The S-packet Data field contains a number of parameters encoded as printable characters. The file receiver, if it received the S-packet successfuly, responds with an Acknowledgment (ACK) packet of type Y (for Yes) containing its own parameters. The same applies to client-server transactions, which begin with an I-packet (Information packet).

The parameters are encoded in various ways, some of which are not comprehensible by the human reader. In retrospect, a better design might have conveyed parameters in tag=value format but in the early 1980s bandwidth was extremely limited (imagine transferring even a modest-size a file over a noisy 300 bit-per-second dialup modem connection, which was the norm 1n 1981, the year Kermit was born).

The Data field of the S-packet, I-packet, and their ACKs can contain the following fields (where "I" am the file sender and "you" are the receiver):

Protocol initialization parameters
Pos Name Type Format Description
1 MAXL Int 0-94 tochar() The maximum-length basic-format packet I can receive, The file receiver replies with the maximum-length basic-format packet it can receive. Neither side may exceed the given maximums unless sebsequent parameters announce long-packet capability.
2 TIMO Int 0-94 tochar() The number of seconds you should wait for a packet from me before timing out and requesting (by sending a NAK - Negative Acknowledgment for the missing packet).
3 NPAD Int 0-94 tochar() The number of padding characters I need you to precede each packet you send me with. Normally zero.
4 PADC Int 0-31 ctl() the control character I need for padding, transformed by ctl() (not tochar()) to make it printable). Normally zero.
5 EOL Int 0-31 ctl() End Of Lline, the control character I need incoming packets to be terminated with, normally carriage return.
6 QCTL Printable ASCII character verbatim The control-character prefix (verbatim) that I will use for encoding control characters in the file I will send to you, normally '#', so (for example), #M#J is Carriage-return (M) and Linefeed (J). If the control prefix character itself is present in the data, it is prefixed by the control prefix, e.g. '#' becomes '##'.

All Kermit programs must implement the six parameters above; the first one, MAXL, is fundamental to the procotol (each Kermit program tells the other one the maximum-length packet it can receive). Parameters 2-6 rarely need to be adjusted in modern times. Over the years more parameters were added, which are optional. These are described in assorted documents found in this directory, and listed below.

Pos Name Type Format Description
7 EBQ Printable ASCII character verbatim What to do about 8-bit data characters on a 7-bit communication channel. For the sender '&' means I will do 8th-bit quoting with '&' as the quote character, and 'N' means I will not do 8th-bit quoting. For the receiver 'Y' means yes, please do 8th-bit quoting and 'N' (or the absense of this field) means, don't do it (and therefore transfers might fail on 7-bit connections). None of the following fields are required and if they are missing, the corresponding features do not exist or are not used.
8 BCT Int 1-5 tochar() Block-check type:
  1. single-byte 6-bit checksum;
  2. two-byte 12-bit checksum;
  3. three-byte 16-bit CRC;
  4. two-byte 12-bit checksum containing no blanks;
  5. three-byte 16-bit CRC even on the first packet (explained here).
If this field is not present, the Type 1 block check is used.
9 RPT Printable ASCII character verbatim Prefix to be used to indicate a span of repeated characters like 'xxxxxxxxxxxxxx'; for most Kermit programs the default repeat prefix is '~' (tilde). If the receiver answers with 'Y' it its RPT field, repeated-character compression will be done, with the repeat-count prefix followed by the tochar()-encoded count byte and then one copy of the repeated character; e.g. 'xxxxxxxxxxxxxx' would be sent as '~,x' (3 bytes). Otherwise repeated characters won't be compressed for transmission.
10 CAPAS Bitmask tochar() Capabilities bitmask. A bit mask, in which each bit position corresponds to a capability of the Kermit program that is creating this packet. A bit is set to 1 if that capability is present, or 0 if it is not. A CAPAS field contains a 6-bit quantity (transformed by tochar()), whose low order bit is set to 1 if another capability byte follows (it doesn't, and never will). The meanings of each bit are listed below this table.
11 Wslots Int 1-31 tochar() Number of sliding window slots, normally 1 (windows don't slide). For a number greater than 1, that many packets may be sent be sent before an acknowledgement is required, which makes the file transfer go faster.
12 MaxLx1 Int 0-94 tochar() First of two characters representing the high-order and low-order parts of the maximum long-packet length.
13 MaxLx2 Int 0-94 tochar() Second byte of maximum long-packet length length = (unchar(MaxLx1) * 95) + unchar(MaxLx2), which can go as high as 9024 bytes
14 CHKPNT 0 Verbatim A checkpoint-restart feature was designed in 1993 but never implemented, documented here. The CHKPNT field negotiates whether both sides agree to use it. Since it was never implemented, it should be 0 (zero).
15 CHKINF1 _ N/A Not used: First byte of a 3-byte field reserved for checkpoint/restart. For the present (and probably forever) each of the three CHKINF bytes is set to '_' (underscore, ASCII 95)
16 CHKINF2 _ N/A Not used: Second byte of a 3-byte field reserved for checkpoint/restart
17 CHKINF3 _ N/A Not used: Third byte of a 3-byte field reserved for checkpoint/restart
18 WHATAMI Bitmask tochar() Whether I am a server, my prevailing transfer mode (text, binary), my filename-conversion setting, whether I want to stream*, whether I believe we have a clear (i.e. transparent) channel*.
19 SYSIDL Small digit tochar() Length of System ID that is to follow (always " = 2)
20 SYSID1 Printable ASCII character verbatim First byte of my system ID code (e.g. U = portable OS's)
21 SYSID2 Printable ASCII character verbatim Second byte of system ID (e.g. 1 = Unix and derivatives). If the two Kermit partners' SYSIDs match, they can (normally) transfer all files in binary mode.
22 WHATAMI2 Bitmask tochar() For client control of server's transfer mode, charset conversion, and recursion.
* Streaming means to send Data packets in a stream without requiring ACKs, explained here.
** Clear channel means it passes all byte values through. Explained in the same document.

Clearly, the initialization string must be at least 12 characters long in order for long packets to be used; long packets are documented in the Kermit Protocol Manual and in Chapter 12 of the Kermit book. SYSIDs are listed starting on page 275 (scroll down to "(ASCII 46)"), reproduced in part here with slightly updated terminology:

A1 Apple II
A3 Apple Mac OS X, macOS
D1 DECsystem-10 TOPS-10
D2 DECSYSTEM-20 TOPS-20
D7 DEC (now HP) VMS, OpenVMS
DA DEC RSTS/E
DB DEC RT11
F3 Data General AOS/VS
I1 IBM VM/CMS
I2 IBM MVS/TSO
I4 McGill University MUSIC for IBM mainframes
I7 IBM CICS
I9 IBM MVS/ROSCOE
K2 Atari ST
L3 Commodore Amiga
MV Stratus VOS
N3 Apollo Aegis
U1 UNIX (Bell Labs, BSD, Linux, etc)
U8 MS-DOS
UD Microware OS-9
UN Microsoft Windows (including NT)
UO IBM OS/2

The SYSID can be used by the file sender to choose a transfer character-set for text files that is appropriate for the file receiver. Conceivably a SYSID could be longer than 2 characters, but the great proliferation of computer system types in the 1980s has dwindled down to just Windows, macOS, Unix, and (Open)VMS in the 21st Century.

The capabilities mask

A series of bytes starting at position 10 of the data field of an S or I packet or its Ack, in this format:
    bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
   +----+----+----+----+----+----+----+----+
   |  X |  X |  1 |  2 |  3 |  4 |  5 |  Z |
   +----+----+----+----+----+----+----+----+
where:
   X   = Must always be 0
   1-5 = Bits indicating specific capabilities
   Z = Capability Mask Extension Bit (1 = end; 0 = more to follow)
Capabilities:
    lpcapb = 2,                         /* Long Packet capability */
    swcapb = 4,                         /* Sliding Window capability */
    atcapb = 8,                         /* Attribute-packet capability */
    rscapb = 16,                        /* RESEND capability */
    lscapb = 32,                        /* Locking Shift capability */
Although the capabilites mask was designed to be extensible, it has never been extended, and it can be safely assumed that, if present, it is always one byte long and Z is always zero (but see this section below).

S-Packet examples

Here's a C-Kermit S-packet that includes all the fields that have been defined:

🇦9 S~/ @-#Y3~^>J)0___J"U1@C🇲

Packet header and block check
Character Pos Description
9 1 Length of this packet (ASCII '9' = 57 - 32 = 25); 25 characters starting with sequence number
(space) 2 Sequence number (ASCII ' ' = 32 - 32 = 0); the S-packet is always packet mumber 0
S 3 Type S (Send-init)
~ 4 Data field, variable length, first character = '~'... see next table
C 24 One-byte 6-bit block check*
* The first packet always has the single-byte block check; subsequent packets have the block-check negotiated in the S-packet/ACK exchange.

S-packet Data field   (Pos is the position within Data field (1-based), not the whole packet)
Character Pos Format Description
~ 1 tochar() MAXL (ASCII '~' = 126 - 32 = 94) (max packet length = 94)
/ 2 tochar() TIMO (ASCII '/' = 47 - 32 = 15) timeout = 15 sec
  3 tochar() NPAD (ASCII ' ' = 32 = 32 = 0) no padding requested
@ 4 ctl() PADC (ASCII '&' = 64 & 64 = 0) pad character would be ASCII 0 (NUL)
- 5 tochar() EOL (ASCII 45 - 32 = 13) Carriage Return packet terminator
# 6 verbatim QCTL (ASCII 35 = '#') Printable encoding prefix for control characters
Y 7 verbatim EBQ: Yes, I will do 8th-bit quoting if requested
3 8 verbatim BCT: digit 1-5 denoting block-check type
~ 9 verbatim RPT: repeat count prefix
^ 10 tochar() CAPAS, capabilities mask (^ = ASCII 94)
> 11 tochar() WSLOTS, number of sliding-window slots (62 - 32 = 30)
J 12 tochar() MaxLx1, Long packet length byte #1 (value 62)
) 13 tochar() MaxLx2, Long packet length byte #2 (value 74): total = 5964
0 14 verbatim CHKPNT, 0 = Won't checkpoint
_ 15 verbatim CHKINF1, checkpoint info (not used; underscore is a place-holder)
_ 16 verbatim CHKINF2, checkpoint info (ditto)
_ 17 verbatim CHKINF3, checkpoint info (ditto)
J 18 tochar() WHATAMI, whether I am a server, whether I believe we have a clear channel, etc.
" 19 tochar() SYSIDL, length field for following data (tochar(") = 2)
U 20 verbatim SYSID1, First byte of my system ID code (U = portable OS's)
1 21 verbatim SYSID2, Second byte of system ID (1 = Unix and derivatives)
@ 22 tochar() WHATAMI2, for client control of server's transfer mode, charset conversion, and recursion.

🇦9 S~/ @-#Y3~^>J)0___J"U1@C🇲
     1234567890123456789012

Here's an ACK to C-Kermit's S-packet from a bare-bones Kermit implementation:

🇦^A, Y~* @-#N1~]🇲

ACK to S-packet Data field
Character Pos Format Description
~ 1 unchar() MAXL (ASCII '~' = 127 - 32 = 95) (max packet length = 95)
* 2 unchar() TIMO (ASCII '/' = 42 - 32 = 10) timeout = 10 sec
  3 unchar() NPAD (ASCII ' ' = 32 = 32 = 0) no padding requested
@ 4 ctl() PADC (ASCII 64 & 64 = 0) pad character would be ASCII 0 (NUL)
- 5 unchar() EOL (ASCII 45 - 32 = 13) Carriage Return packet terminator
# 6 verbatim QCTL (ASCII 35 = '#') Printable encoding prefix for control characters
N 7 verbatim EBQ: I do NOT support 8th-bit quoting
1 8 verbatim BCT: I can handle only Type 1 block checks
~ 9 verbatim Repeat counts: I can do them and accept prefix '~'

Since fields 10-21 are not present, the capabilities and features they represent are not used. This allows the newest and most advanced Kermit implementation to interoperate with oldest and least capable one, provided it follows the rules.

File header packet

After the S-packet is sent and ack'd, the next packet sent by the file sender is the File header, packet type F, which simply contains the name of the file that is about to arrive. There is exactly one F-packet for each file, which abides by the parameters that have been agreed upon in the negotiation phase: prefixing, maximum length, etc. The ACK to the F-packet may, but need not, contain the name or the full path of the file on the receiving computer.

There is no provision for very long or non-ASCII filenames. In retrospect, it would have been better to allow multiple F packets for a file whose name is longer than the negotiated maximum length; these would work just like Data packets, but there would also need to be some kind of "end of filename" signal.

Another issue with F-packets is that the receiver has no way of knowing the filename's character-set because A packets come after the F packet. For example, the filename might be German "Grüße" in UTF-8 or ISO-8859-1, or even some proprietary character set the receiver never heard of. Until such time (if ever) as the protocol is improved to handle these issues, the best policy is to keep filenames shorter than about 80 characters, spell them with ASCII letters and digits and a few other characters like "-" (hyphen), "_" (underscore), and of course "." (period); almost anything else can cause confusion or conflict. And avoid including spaces in filenames even if it's legal on your computer, because it isn't on others. And for that matter don't assume that capital and small letters are equivalent in filenames; they are in most operating systems but not others.

Attribute packets

One or more File Attribute packets, packet type A, may follow the F packet if the A-packet capability has been agreed upon in the negotiation phase. A-packets contain information about the file. The attribute codes are printable ASCII characters; for details about each attribute see Transmitted File Attributes in the Kermit Protocol Manual; many of these are no longer relevant to today's computer operating and file systems.

Kermit file attribute codes
Code Description
! Approximate length of file as a printable number in Kbytes.
" File type A (text) or B (binary) e.g. AMJ means text with carriage-return and linefeed (CRLF), B8 is 8-bit binary.
# Creation date.
$ File creator's or owner's user ID.
% Account to which the file is charged.
& Area in which to store the file.
' Access password for area to store the file.
( Block size (e.g. on IBM mainframe or VMS operating systems)
) Access: N=new, S=Supersede (overwrite), A=Append
* Transfer encoding (ASCII, ISO 8859-1, UTF-8, etc)
+ Disposition: save on disk, print, type, mail, etc.
, System-dependent file protection/permissions
- System-dependent file protection/permissions (tochar(bitmask))
. ID of system of origin.
/ Record format of data within packets.
0 System-dependent parameters.
@ End of attributes.

Each attribute consists of a 1-byte length field, which is a small integer (up to 95) encoded by encoded by tochar(). Then the attribute code as a 7-bit ASCII character, then the value of the attribute. Here is a typical A packet:

🇦U"A."UN"#AMJ*'CI6/100#120181209 09:44:49!!31$2763@ '.]🇲
  000000000011111111112222222222333333333344444444445555
  123456789012345678901234567890123456789012345678901234

U (at position 06) is the packet length (85 - 32 = 53), " is the packet sequence number (2), and A is the packet type (Attribute). The attributes start at 04. The first attribute is . (period), meaning system ID; it is " (doublequote) bytes long (meaning 2), and the ID is UN. The next attribute starts at 08, type " = File type, Length # = 3, value AMJ meaning text with CRLF line terminator. Next comes attribute * at 13, the transfer encoding, length 7, value I6/100, which denotes ISO 8859-1 Latin Alphabet 1. Next at 22: Creation date, length 1 = 49 - 32 = 17, "20181209 09:44:49". Next, !!3 says the file is about 3k bytes long. Finally, 2763 says the exact file length is 2763 bytes in the sender's file system. The @-sign at 40 means "end of attributes", i.e, no more attribute packets follow this one and the next packet will be file data. The A-packet ends with a 3-byte block check.

Here's the same packet with each field separated by spaces for easier reading:

🇦U"A ."UN "#AMJ *'CI6/100 #120181209 09:44:49 !!3 1$2763 @ '.]🇲
  000 0000 00011 111111112 2222222223333333333 444 444444 4 555
  123 4567 89012 345678901 2345678901234567890 123 456789 0 123
  hdr sid  ftype charset   creation date-time  kb  bytes  @ chk

Empty directories

As noted, the file type attribute can be A (text) or B (binary), with optional modifiers. The file name in the F packet can include a a directory or path; normally if you tell Kermit to "send somedirectory/somefile.txt", the sender uses the path part to find the file but does not put it in the F packet. In recursive transfers, however, the path is included so the receiver can mirror the sender's directory tree. But in every case, the F packet includes the name of a file. Concievably the protocol could be extended to add a D file type, indicating a directory, which would simply instruct the file receiver to create a new directory with the name given. The issue arises in recursive transfers where the file sender encounters an empty directory; presently it is simply skipped and it never appears on the receiver. A 'D' attribute would allow the empty directory to mirrored at the receiver. Clearly, use of the D attribute would have to be negotiated and this would require extension of the capabilities mask into a never-before-seen second byte, which would confuse file receivers that did not follow the specifiction.

Generic server commands

In a client/server connection, the client can ask the server to execute a "generic" command by sending a G packet. This happens when you give a REMOTE command to the client; for example here's the packet log for "remote pwd", which asks the server to report its current working directory:
[C:\Users\fdc\tmp\] CKW> log packets
[C:\Users\fdc\tmp\] CKW> remote pwd
/hmt/sirius1/prv0/kd/fdc/tmp
[C:\Users\fdc\tmp\] CKW> close packet-log
[C:\Users\fdc\tmp\] CKW> type packet.log
s-00-00-^A9 I~/ @-#Y3~^>J)0___Z"UN@'
r-00-00-^A9 Y~/ @-#Y3~^>J)0____"U1@^
s-00-00-^A$ GA/
r-00-00-^A? Y/hmt/sirius1/prv0/kd/fdc/tmp#
[C:\Users\fdc\tmp\] CKW>
The generic command is specified by a single letter following the 'G' in the G-packet as shown in line 8 above, where the second character in the Data field is A, the function code for Report Working directory. If the command had arguments, e.g. "remote directory zeroking.txt", they would follow the function code in the G packet. Here is the list of currently defined generic commands with their one-letter codes; alphabetic case is significant. The examples show how (in C-Kermit at least) most REMOTE commands can be shortened; for example, REMOTE DIRECTORY can be entered as REMOTE DIREC, REMO DIR, REM DIR, (etc), or simply RDIR.

Code Function Client command Examples
A Report Working Directory REMOTE PWD remote pwd,  rpwd
B (free)
C Change Working Directory REMOTE CD remote cd ~/tmp,  rcd ~/tmp
D Directory (list files) REMOTE DIRECTORY remote dir ck*.[ch],  rdir ck*.[ch]
E Delete (Erase) File(s) REMOTE DELETE remo del *.tmp,  rdel *.tmp
F Finish (quit server mode) FINISH fin
G (free)
H Help REMOTE HELP rem help,  rhelp
I Login/Logout* REMOTE LOGIN / LOGOUT remote login (but not RLOGIN*)
J (free)
K Copy REMOTE COPY rem copy foo.txt foo.tmp
L Bye (tells server to exit and logout) BYE bye
M Message REMOTE MESSAGE rmsg this is some text
N (free)
O (free)
P (free)
Q Server Status Query REMOTE STATUS rem stat,  rstat
R Rename REMOTE RENAME remo ren names.txt names.save
S Set Parameter REMOTE SET rset file type binary, rset window 12
T Type REMOTE TYPE remote type info.txt,  rtype info.txt
U Report Disk Usage REMOTE SPACE remote space   rem sp,  rsp
V Issues a Kermit SET command to the server REMOTE SET rem set file character-set utf-8
W Who ("Finger", list logged-in users) REMOTE WHO remote who, rwho, rwho fred
X Tells Kermit server to exit (e.g. to shell)  REMOTE EXIT rem exit,  rexit
Y (free)
Z (free)
d Remove Directory REMOTE RMDIR rem rmdir tmp2,  rrmdir tmp3
m Create (make) Directory REMOTE MKDIR rem mkdir newdir,  rmkdir another
q Interruption (pseudopacket) Server interrupted or connection lost
u Server CD to superior directory REMOTE CDUP rem cdup,  rcdup (new Jan 2024)
z Reserved as escape when we run out
0-9 Reserved

* REMOTE LOGIN / LOGOUT is used only with Internet Kermit Servers. RLOGIN can't be used as a short form of REMOTE LOGIN because RLOGIN is a separate command, that makes Internet connections via the IETF RLOGIN (Remote Login) protocol.

Transfer encodings

Kermit protocol specializes in transferring files between unlike computer platforms and therefore must often convert platform-specific or proprietary text character encodings to standard ones "on the wire". Here, for example, are the character sets used on the file systems where C-Kermit can be built (Unix, VMS, Windows, AOS/VS, VOS, OS-9, etc etc):
(~/) C-Kermit>set file character-set ? One of the following:
 ascii               cp866-cyrillic      german              latin9-iso
 british             cp869-greek         greek-iso           macintosh-latin
 bulgaria-pc         cyrillic-iso        hebrew-7            mazovia-pc
 canadian-french     danish              hebrew-iso          next-multinational
 cp1250              dec-kanji           hp-roman8           norwegian
 cp1251-cyrillic     dec-multinational   hungarian           portuguese
 cp1252              dg-international    jis7-kanji          shift-jis-kanji
 cp437               dutch               koi7                short-koi
 cp850               elot927-greek       koi8                spanish
 cp852               elot928-greek       koi8r               swedish
 cp855-cyrillic      euc-jp              koi8u               swiss
 cp858               finnish             latin1-iso          ucs2
 cp862-hebrew        french              latin2-iso          utf8
(~/) C-Kermit>
See this table for details. And here are the transfer character sets, the ones used on the wire:
(~/) C-Kermit>set transfer character-set ? One of the following:
 ascii         greek-iso     latin2-iso    ucs2
 cyrillic-iso  hebrew-iso    latin9-iso    utf8
 euc-jp        latin1-iso    transparent
(~/) C-Kermit>
Kermit transfer character sets
Code Character set
(none) US ASCII ANSI X3.4-1986
I6/100 ISO 8859-1 Latin Alphabet 1
I6/101 ISO 8859-2 Latin Alphabet 2
I6/144 ISO 8859-5 Latin/Cyrillic Alphabet
I6/126 ISO 8859-7 Latin/Greek Alphabet
I6/138 ISO 8859-8 Latin/Hebrew Alphabet
I6/203 ISO 8859-15 Latin Alphabet 9
I14/87/37 Japanese Extended Unix Code
I162 ISO 10646 Unicode UCS-2
I190 ISO 10646 Unicode UTF-8
The table lists the character sets used by Kermit for transfer of text text files; the Code column shows the codes (derived from the corresponding ISO registration number) used in Kermit protocol to identify each set. These are all national or international standards so that text can be exchanged between computers that use different (and sometimes unique and proprietary) text character sets, without Kermit software having to know the details of file systems of platforms other than its own. It's the responsibility of each Kermit partner to convert proprietary or nonstandard encodings (like IBM code pages, DOS code pages, Windows code pages, DEC multinational, USSR Short KOI, etc) into the appropriate standard set from the list.

Kermit's text-character conversion features were designed and implemented before Unicode appeared. If Kermit had come later we might have used UTF-8 as the the one-and-only transfer character set. But as matters stand, there are still a lot old Kermit implementations out there, and if we did that now they couldn't transfer files with modern Kermits.

References: