@Comment(-*-SCRIBE-*-) @Comment(SCRIBE 3C Text Formatter Input for the KERMIT Protocol Manual) @Make @Comment(Use /draft:F on command line to produce .LPT file w/cc in column 1) @Style @PageHeading
@Modify @Comment(Set desired spacing around various environments) @Modify @Modify @Modify @Modify @Modify @Modify @Comment(Printing Device Dependencies) @Define @Case @Comment(Set spacing and paging requirements for chapter & section headings) @Modify(Hdx,Above 2,Below 1,Need 8) @Modify(Hd0,Above 2,Below 1,Need 8) @Modify(Hd2,Above 2,Below 1,Need 8) @Modify(Hd3,Above 2,Below 1,Need 8) @Modify(Hd4,Above 2,Below 1,Need 8) @Modify @Modify @Comment(Start the document off with a titlepage) @Begin(TitlePage,Initialize "@BlankSpace(2.5inches)",sink 0) @MajorHeading(KERMIT PROTOCOL MANUAL) @i Frank da Cruz Columbia University Center for Computing Activities New York, New York 10027 @value Copyright (C) 1981,1982,1983,1984 Trustees of Columbia University in the City of New York @i @case[device, x9700 "@blankpage(1)"]@Comment{Duplex Kludge} @case[device, imprint10 "@blankpage(1)"]@Comment{Duplex Kludge} @end @set(page=1) @PageHeading(Even,Left="Page @ref(page)",Right="@b") @PageHeading(Odd,Left="@b<@Title[Chapter]>",Right="Page @ref(page)") @PrefaceSection The fourth edition (November 1983) of the KERMIT Protocol Manual incorporates some new ideas that grew from our experience in attempting to implement some of the features described in earlier editions, particularly user/@|server functions. These include a mechanism to allow batch transfers to be interrupted gracefully for either the current file or the entire batch of files; a "capability mask"; a protocol extension for passing file attributes. In addition, numbers are now written in decimal notation rather than octal, which was confusing to many readers. Also, several incompatible changes were made in minor areas where no attempts at an implementation had yet been made; these include: @Begin(Itemize,spread 0.5) The format and interpretation of the operands to the server commands. Usurpation of the reserved fields 10-11 of the Send-Init packet, and addition of new reserved fields. @End(Itemize) Most of the remaining material has been rewritten and reorganized, and much new material added, including a section on the recommended vocabulary for documentation and commands. The previous edition of the Protocol Manual attempted to define "protocol version 3"; this edition abandons that concept. Since KERMIT development is an unorganized, disorderly, distributed enterprise, no requirement can be imposed on KERMIT implementors to include a certain set of capabilities in their implementations. Rather, in this edition we attempt to define the basic functionality of KERMIT, and then describe various optional functions. The key principle is that any implementation of KERMIT should work with any other, no matter how advanced the one or how primitive the other. The capabily mask and other Send-Init fields attempt to promote this principle. @Heading The fifth edition (March 1984) attempts to clarify some fine points that had been left ambiguous in the 4th edition, particularly with respect to when and how prefix encoding is done, and when it is not, and about switching between block check types. A mechanism is suggested (in the Attributes section) for file archiving, and several attributes have been rearranged and some others added (this should do no harm, since no one to date has attempted to implement the attributes packet). A more complete protocol state table is provided, a few minor additions are made to the collection of packet types. @heading Before deciding to write a new version of KERMIT, please bear in mind that the philosophy of KERMIT has always been that is not, and never should become, a commercial product, sold for profit. Its goal is to promote communication and sharing, and KERMIT itself should be freely shared, and not sold. Media and reproduction costs may be recouped if desired, but profit should not be the motive. Vendors of commercial software, however, may request permission to include KERMIT with, or in, their programs provided certain conditions are met, including that credit for the protocol be given to Columbia and that the price of the product not be raised substantially beyond media and reproduction costs for inclusion of KERMIT. Contact the KERMIT group at Columbia if you have any questions about this. Prospective KERMIT implementors should check with us in any case, to be sure that someone else has not already done, or started to do, the same thing you propose to do. KERMIT is distributed from Columbia University on magnetic tape. Complete ordering instructions can be found in the @i. Direct inquiries about KERMIT to: @begin KERMIT Distribution Columbia University Center for Computing Activities 7th Floor, Watson Laboratory 612 West 115th Street New York, NY 10025 @end @Heading Bill Catchings and I designed the basic KERMIT protocol at Columbia University in 1981. For ideas, we looked at some of the ANSI models (X3.57, X3.66), the ISO OSI model, some real-@|world "asynchronous protocols" (including the Stanford Dialnet and TTYFTP projects, the University of Utah Small FTP project), as well as at file transfer on full-@|blown networks like DECnet and ARPAnet. Bill wrote the first two programs to implement the protocol, one for the DEC-20, one for a CP/M-80 microcomputer, and in the process worked out most of the details and heuristics required for basic file transfer. Meanwhile, Daphne Tzoar and Vace Kundakci, also of Columbia, worked out the additional details necessary for IBM mainframe communication. Much credit should also go to Bernie Eiben of Digital Equipment Corporation for promoting widespread use of KERMIT and for adding many insights into how it should operate, and to Nick Bush and Bob McQueen of Stevens Institute of Technology, for many contributions to the "advanced" parts of the protocol, and for several major KERMIT implementations. Thanks to the many people all over the world who have contributed new KERMIT implementations, who have helped with KERMIT distribution through various user groups, and who have contributed to the quality of the protocol and its many implementations by reporting or fixing problems, criticizing the design, or suggesting new features. @Heading @i @Chapter This manual describes the @Index[KERMIT] KERMIT @Index[Protocol] protocol. It is assumed that you understand the purpose and operation of the Kermit file transfer facility, described in the @i, and basic terminology of data communications and computer programming. @Section The KERMIT file transfer protocol is intended for use in an environment where there may be a diverse mixture of computers -- micros, personal computers, workstations, laboratory computers, timesharing systems -- from a variety of manufacturers. All these systems need have in common is the ability to communicate in ASCII over ordinary serial telecommunication lines. KERMIT was originally designed at Columbia University to meet the need for file transfer between our DECSYSTEM-20 and IBM 370-@|series mainframes and various microcomputers. It turned out that the diverse characteristics of these three kinds of systems resulted in a design that was general enough to fit almost any system. The IBM mainframe, in particular, strains most common assumptions about how computers communicate. @Section The KERMIT protocol is specifically designed for character-@|oriented transmission over serial telecommunication lines. The design allows for the restrictions and peculiarities of the medium and the requirements of diverse operating environments -- buffering, duplex, parity, character set, file organization, etc. The protocol is carried out by KERMIT programs on each end of the serial connection sending "packets" back and forth; the sender sends file names, file contents, and control information; the receiver acknowledges (positively or negatively) each packet. The packets have a layered design, more or less in keeping with the ANSI and ISO philosophies, with the outermost fields used by the data link layer to verify data integrity, the next by the session layer to verify continuity, and the data itself at the application level. Connections between systems are established by the ordinary user. In a typical case, the user runs KERMIT on a microcomputer, enters terminal emulation, connects to a remote host computer (perhaps by dialing up), logs in, runs KERMIT on the remote host, and then issues commands to that KERMIT to start a file transfer, "escapes" back to the micro, and issues commands to that KERMIT to start its side of the file transfer. Files may be transferred singly or in groups. Basic KERMIT provides only file transfer, and that is provided for @i@index(Sequential Files), though the protocol attempts to allow for various types of sequential files. Microcomputer implementations of KERMIT are also expected to provide terminal emulation, to facilitate the initial connection. More advanced implementations simplify the "user interface" somewhat by allowing the KERMIT on the remote host to run as a "server", which can transfer files in either direction upon command from the local "user" Kermit. The server can also provide additional functionality, such as file management, messages, mail, and so forth. Other optional features also exist, including a variety of block check types, a mechanism for passing 8-bit data through a 7-bit communication link, a way to compressing a repeated sequence of characters, and so forth. As local area networks become more popular, inexpensive, and standardized, the demand for KERMIT and similar protocols may dwindle, but will never wither away entirely. Unlike hardwired networks, KERMIT gives the ordinary user the power to establish reliable error-@|free connections between @i computers; this may always be necessary for one-@|shot or long-@|haul connections. @Chapter @Section @Index @u: This is the term commonly used for a device which is connected to a computer over an EIA RS-232 serial telecommunication line. This device is most commonly an ASCII terminal, but it may be a microcomputer or even a large multi-@|user computer emulating an ASCII terminal. Most computers provide hardware (RS-232 connectors and UARTs) and software (device drivers) to support TTY connections; this is what makes TTY-@|oriented file transfer protocols like KERMIT possible on almost any system at little or no cost. @Index[Local] @u: When two machines are connected, the LOCAL machine is the one which you interact with directly, and which is in control of the terminal. The "local Kermit" is the one that runs on the local machine. A local Kermit always communicates over an external device (the micro's communication port, an assigned TTY line, etc). @index @u: The REMOTE machine is the one on the far side of the connection, which you must interact with "through" the local machine. The "remote Kermit" runs on the remote machine. A remote Kermit usually communicates over its own "console", "controlling terminal", or "standard i/o" device. @index @u: Another word for "computer", usually meaning a computer that can provide a home for multiple users or applications. This term should be avoided in KERMIT lore, unless preceded immediately by LOCAL or REMOTE, to denote which host is meant. @index @u: An implementation of remote Kermit that can accept commands in packet form from a local Kermit program, instead of directly from the user. @index @u: In addition to its usual use to denote the person using a system or program, "user" will also be used refer to the local Kermit program, when the remote Kermit is a server. @Section All @u in the following text are expressed in decimal (base 10) notation unless otherwise specified. @Index Numbers are also referred to in terms of their bit positions in a computer word. Since KERMIT may be implemented on computers with various word sizes, we start numbering the bits from the "right" -- bit 0 is the least significant. Bits 0-5 are the 6 least significant bits; if they were all set to one, the value would be 63. @Index<8th Bit> A special quirk in terminology, however, refers to the high order bit of a character as it is transmitted on the communication line, as the "8th bit". More properly, it is bit 7, since we start counting from 0. References to the "8th bit" generally are with regard to that bit which ASCII transmission sets aside for use as a parity bit. KERMIT concerns itself with whether this bit can be usurped for the transmission of data, and if not, it may resort to "8th-bit prefixing". @Section All @u are in ASCII @index (American national Standard Code for Information Interchange) representation, ANSI standard X3.4-1968. All implementations of KERMIT transmit and receive characters only in ASCII. The ASCII character set is listed in Appendix @ref<-ascii>. @ux @Begin NUL@\Null, idle, ASCII character 0. SOH@\Start-of-header, ASCII character 1 (Control-A). SP@\Space, blank, ASCII 32. CR@\Carriage return, ASCII 13 (Control-M). LF@\Linefeed, ASCII 10 (Control-J). CRLF@\A carriage-@|return linefeed sequence. DEL@\Delete, rubout, ASCII 127. @end @Index A @ux is considered to be any byte whose low order 7 bits are in the range 0 through 31, or equal to 127. In this document, control characters are written in several ways: @Begin(Description,leftmargin +8,indent -8) Control-A@\This denotes ASCII character 1, commonly referred to as "Control-A". Control-B is ASCII character 2, and so forth. CTRL-A@\This is a common abbreviation for "Control-A". A control character is generally typed at a computer terminal by holding down the key marked CTRL and pressing the corresponding alphabetic character, in this case "A". @q<^A>@\"Uparrow" notation for CTRL-A. Many computer systems "echo" control characters in this fashion. @End(Description) A @ux is considered to be any character in the range 32 (SP) through 126 (tilde). @Section Several conversion functions are useful in the description of the protocol and in the program example. The machine that Kermit runs on need operate only on integer data; these are functions that operate upon the numeric value of single ASCII characters. @begin @Index[char(x)] @q@\Transforms the integer @i, which is assumed to lie in the range 0 to 94, into a printable ASCII character; 0 becomes SP, 1 becomes "@q", 3 becomes "@q<#>", etc. @Index[unchar(x)] @q@\Transforms the character @i, which is assumed to be in the printable range (SP through tilde), into an integer in the range 0 to 94. @Index[ctl(x)] @q@\Maps between control characters and their printable representations, preserving the high-@|order bit. If @i is a control character, then @example that is, the same function is used to controllify and uncontrollify. The argument is assumed to be a true control character (0 to 31, or 127), or the result of applying @c to a true control character (i.e. 63 to 95). The transformation is a mnemonic one -- @q(^A) becomes A and vice versa. @end @Section @Index[Packet] A @u is a clearly delimited string of characters, comprised of "control fields" nested around data; the control fields allow a KERMIT program to determine whether the data has been transmitted correctly and completely. A packet is the unit of transmission in the KERMIT protocol. @Index[ACK] @u stands for "Acknowledge". An ACK is a packet that is sent to acknowledge receipt of another packet. Not to be confused with the ASCII character ACK. @Index[NAK] @u stands for "Negative Acknowledge". A NAK is a packet sent to say that a corrupted or incomplete packet was received, the wrong packet was received, or an expected packet was not received. Not to be confused with the ASCII character NAK. @Index A @u is an event that can occur if expected data does not arrive within a specified amount of time. The program generating the input request can set a "timer interrupt" to break it out of a nonresponsive read, so that recovery procedures may be activated. @Chapter The KERMIT protocol requires that@q<:> @begin The host can send and receive characters using 7- or 8-bit ASCII encoding over an EIA RS-232 physical connection, either hardwired or dialup. All printable ASCII characters are acceptable as input to the host and will not be transformed in any way@foot. Similarly, any intervening network or communications equipment ("smart modems", TELENET, terminal concentrators, port selectors, etc) must not transform or swallow any printable ASCII characters. @index A single ASCII @i can pass from one system to the other without transformation. This character is used for packet synchronization. The character is normally Control-A (SOH, ASCII 1), but can be redefined. @IndexEntry[Key="Line Terminator (see End-Of-Line)", Text="Line Terminator (see End-Of-Line)"] @Index[End-Of-Line (EOL)] If a host requires a line terminator for terminal input, that terminator must be a single ASCII control character, such as CR or LF, distinct from the packet synchronization character. @Index[Remote]@Index[Binary Mode]@Index[Raw Mode] When using a job's controlling terminal for file transfer, the system must allow the KERMIT program to set the terminal to no echo, infinite width (no "wraparound" or CRLF insertion by the operating system), and no "formatting" of incoming or outgoing characters (for instance, raising lowercase letters to uppercase, transforming control characters to printable sequences, etc). In short, the terminal must be put in "binary" or "raw" mode, and, hopefully, restored afterwards to normal operation. The host's terminal input processor should be capable of receiving a single burst of 40 to 100 characters at normal transmission speeds. This is the typical size of packet. @end Note that most of these requirements rule out the use of KERMIT through IBM 3270 / ASCII protocol converters. KERMIT does @i require: @begin @Index That the connection run at any particular baud rate. @index That the system can do @Index[XON/XOFF] XON/XOFF or any other kind of flow control. System- or hardware-@|level flow control can help, but it's not necessary. See section @ref<-flow>. @Index[Duplex]@Index[Full Duplex]@Index[Half Duplex] That the system is capable of full duplex operation. Any mixture of half and full duplex systems is supported. @Index That the system can transmit or receive 8-bit bytes. KERMIT will take advantage of 8-bit connections to send binary files; if an 8-bit connection is not possible, then binary files may be sent using an optional prefix encoding. @end @Chapter @Index[Records]@Index[Logical Records] @Index[Printable Files] @Index[Binary Files] @Index[Text Files] For transmission between unlike systems, files must be assigned to either of two catagories: @i or @i. A printable text file is one that can make sense on an unlike system -- a document, program source, textual data, etc. A binary file is one that will not (and probably can not) make sense on an unlike system -- an executable program, numbers stored in internal format, etc. On systems with 8-bit bytes, printable ASCII files will have the high order bit of each byte set to zero@foot (since ASCII is a 7-bit code) whereas binary files will use the high order bit of each byte for data, in which case its value can vary from byte to byte. Many computers have no way to distinguish a printable file from a binary file -- especially one originating from an unlike system -- so the user may have to give an explicit command to Kermit to tell it whether to perform these conversions. @Section @index@index@index@index A primary goal of KERMIT is for printable text files to be useful on the target system after transfer. This requires a standard representation for text during transmission. KERMIT's standard is simple: 7-bit ASCII characters, with "logical records" (lines) delimited by CRLFs. It is the responsibility of systems that do not store printable files in this fashion to perform the necessary conversions upon input and output. For instance, IBM mainframes might strip trailing blanks on output and add them back on input; UNIX would prepend a CR to its normal record terminator, LF, upon output and discard it upon input. In addition, IBM mainframes must do EBCDIC/@|ASCII translation for text files. @index No other conversions (e.g. tab expansion) are performed upon text files. This representation is chosen because it corresponds to the way text files are stored on most microcomputers and on many other systems. In many common cases, no transformations are necessary at all. @Section @index Binary files are transmitted as though they were a sequence of characters. The difference from printable files is that the status of the "8th bit" must be preserved. When binary files are transmitted to an unlike system, the main objective is that they can be brought back to the original system (or one like it) intact; no special conversions should be done during transmission, except to make the data fit the transmission medium. For binary files, eight bit character transmission is permissible as long as the two Kermit programs involved can control the value of the parity bit, and no intervening communications equipment will change its value. In that case, the 8th bit of a transmitted character will match that of the original data byte, after any control-@|prefixing has been done. When one or both sides cannot control the parity bit, a special prefix character may be inserted, as described below. Systems that do not store binary data in 8-bit bytes, or whose word size is not a multiple of 8, may make special provisions for "image mode" transfer of binary files. This may be done within the basic protocol by having the two sides implicitly agree upon a scheme for packing the data into 7- or 8-bit ASCII characters, or else the more flexible (but optional) file attributes feature may be used. The former method is used on PDP-10 36-bit word machines, in which text is stored five 7-bit bytes per word; the value of the "odd bit" is sent as the parity bit of every 5th word. @Chapter @Index The file transfer protocol takes place over a @i. A transaction@index is an exchange of packets beginning with a Send-Init (S) packet, and ending with a Break Transmission (B) or Error (E) packet@foot, and may include the transfer of one or more files, all in the same direction. In order to minimize the unforseen, KERMIT packets do not contain any control characters except one specially designated to mark the beginning of a packet. Except for the packet marker, only printable characters are transmitted. The following sequence characterizes basic Kermit operation; the @i is the machine that is sending files; the @i is the machine receiving the files. @Begin(Enumerate) The sender transmits a Send-@|Initiate (S) packet to specify its parameters (packet length, timeout, etc; these are explained below). The receiver sends an ACK (Y) packet, with its own parameters in the data field. The sender transmits a File-Header (F) packet, which contains the file's name in the data field. The receiver ACKs the F packet, with no data in the data field of the ACK (optionally, it may contain the name under which the receiver will store the file). @tag(-fpacket) The sender sends the contents of the file, in Data (D) packets. Any data not in the printable range is prefixed and replaced by a printable equivalent. Each D packet is acknowledged before the next one is sent. When all the file data has been sent, the sender sends an End-@|Of-@|File (Z) packet. The receiver ACKs it. If there is another file to send, the process is repeated beginning at step @ref<-fpacket>. When no more files remain to be sent, the sender transmits an End-@|Of-@|Transmission (B) packet. The receiver ACKs it. This ends the transaction, and closes the logical connection (the physical connection remains open). @end @index Each packet has a @i, starting with 0 for the Send Init. The acknowledgment (ACK or NAK) for a packet has the same packet number as the packet being acknowledged. Once an acknowledgment is successfully received the packet number is increased by one, modulo 64. If the sender is remote, it waits for a certain amount of time (somewhere in the 5-30 second range) before transmitting the Send-Init, to give the user time to escape back to the local KERMIT and tell it to receive files. @section KERMIT is most commonly run with the user sitting at a microcomputer, connected through a communications port to a remote timesharing system. The remote KERMIT is using its job's own "controlling terminal" for file transfer. While the microcomputer's port is an ordinary device, a timesharing job's controlling terminal is a special one, and often performs many services that would interfere with normal operation of KERMIT. Such services include echoing (on full duplex systems), wrapping lines by inserting carriage return linefeed sequences at the terminal width, pausing at the end of a screen or page full of text, displaying system messages, alphabetic case conversion, control character intepretation, and so forth. Mainframe KERMIT programs should be prepared to disable as many of these services as possible before packet communication begins, and to restore them to their original condition at the end of a transaction. Disabling these services is usually known as "putting the terminal in binary mode." KERMIT's use of printable control character equivalents, variable packet lengths, redefinable markers and prefixes, and allowance for any characters at all to appear between packets with no adverse effects provide a great deal of adaptability for those systems that do not allow certain (or any) of these features to be disabled. @Section If a KERMIT program is capable of setting a timer interrupt, or setting a time limit on an input request, it should do so whenever attempting to read a packet from the communication line, whether sending or receiving files. Having read a packet, it should turn off the timer. If the sender times out waiting for an acknowledgement, it should send the same packet again, repeating the process a certain number of times up to a retry limit, or until an acknowledgement is received. If the receiver times out waiting for a packet, it can send either a NAK packet for the expected packet or another ACK for the last packet it got. If a packet from the sender is garbled or lost in transmission (the latter is detected when the sequence number increases by more than 1, modulo 64, the former by a bad checksum), the receiver sends a NAK for the garbled or missing packet. If an ACK or a NAK from the receiver is garbled or lost, the sender ignores it; in that case, one side or the other will time out and retransmit. A retry count is maintained, and there is a retry threshold, normally set around 5. Whenever a packet is resent -- because of a timeout, or because it was NAK'd -- the counter is incremented. When it reaches the threshold, the transaction is terminated and the counter reset. If neither side is capable of timing out, a facility for manual intervention must be available on the local KERMIT. Typically, this will work by sampling the keyboard (console) periodically; if input, such as a CR, appears, then the same action is taken as if a timeout had occurred. The local KERMIT keeps a running display of the packet number or byte count on the screen to allow the user to detect when traffic has stopped. At this point, manual intervention should break the deadlock. Shared systems which can become sluggish when heavily used should adjust their own timeout intervals on a per-@|packet basis, based on the system load, so that file transfers won't fail simply because the system was too slow. Normally, only one side should be doing timeouts, preferably the side with the greatest knowledge of the "environment" -- system load, baud rate, and so forth, so as to optimally adjust the timeout interval for each packet. If both sides are timing out, their intervals should differ sufficiently to prevent collisions. @section @Index@Index During file transfer, the sender may encounter an i/o error on the disk, or the receiver may attempt to write to a full or write-@|protected device. Any condition that will prevent successful transmission of the file is called a "fatal error". Fatal errors should be detected, and the transfer shut down gracefully, with the pertinent information provided to the user. Error packets provide a mechanism to do this. If a fatal error takes place on either the sending or receiving side, the side which encountered the error should send an Error (E) packet. The E packet contains a brief textual error message in the data field. Both the sender and receiver should be prepared to receive an Error packet at any time during the transaction. Both the sender and receiver of the Error packet should halt, or go back into into user command mode (a server should return to server command wait). The side that is local should print the error message on the screen. There is no provision for sending nonfatal error messages, warnings, or information messages during a transaction. It would be possible to add such a feature, but this would require both sides agree to use it through setting of a bit in the capability mask, since older KERMITs that did not know about such a feature would encounter an unexpected packet type and would enter the fatal error state. In any case, the utility of such a feature is questionable, since there is no guarantee that the user will be present to see such messages at the time they are sent; even if they are saved up for later perusal in a "message box", their significance may be long past by the time the user reads them. See the section on Robustness, below. @section During any transaction, several heuristics are useful: @begin A NAK for the current packet is equivalent to an ACK for the previous packet (modulo 64). This handles the common situation in which a packet is successfully received, and then ACK'd, but the ACK is lost. The ACKing side then times out waiting for the next packet and NAKs it. The side that receives a NAK for packet @i while waiting for an ACK for packet @i simply sends packet @i. If packet @i arrives more than once, simply ACK it and discard it. This can happen when the first ACK was lost. Resending the ACK is necessary @i sufficient -- don't write the packet out to the file again! When opening a connection, discard the contents of the line's input buffer before reading or sending the first packet. This is especially important if the other side is in receive mode (or acting as a server), in which case it may have been sending out periodic NAKs for your expected SEND-@|INIT or command packet. If you don't do this, you may find that there are sufficient NAKs to prevent the transfer -- you send a Send-Init, read the response, which is an old NAK, so you send another Send-Init, read the next old NAK, and so forth, up to the retransmission limit, and give up before getting to the ACKs that are waiting in line behind all the old NAKs. If the number of NAKs is below the cutoff, then each packet may be transmitted multiply. Similarly, before sending a packet, you should clear the input buffer (after looking for any required handshake character). Failure to clear the buffer could result in propogation of the repetition of a packet caused by stacked-up NAKs. @end @Section @Index The syntax for file names can vary widely from system to system. To avoid problems, it is suggested that filenames be represented in the File Header (F) packet in a "normal form", by default (that is, there should be an option to override such conversions). @Begin(Enumerate) @Index Delete all pathnames and attributes from the file specification. The file header packet should not contain directory or device names; if it does, it may cause the recipient to try to store the file in an inaccessible or nonexistent area, or it may result in a very strange filename. After stripping any pathname, convert the remainder of the file specification to the form "@i@q<.>@i", with no restriction on length (except that it fit in the data field of the F packet), and: @Begin(Enumerate, spread 0) Include no more than one dot. Use digits, uppercase letters only in @i"name" and @i"type". @End(Enumerate) @End(Enumerate) Special characters like @q<"$">, @q<"_">, @q<"-">, @q<"&">, and so forth should be disallowed, since they're sure to cause problems on one system or another. The recipient, of course, cannot depend upon the sender to follow this convention, and should still take precautions. However, since most file systems embody the notion of a file name and a file type, this convention will allow these items to be expressed in a way that an unlike system can understand. The particular notation is chosen simply because it is the most common. The recipient must worry about the length of the name and type fields of the file name. If either is too long, they must be truncated. If the result (whether truncated or not) is the same as the name of a file that already exists in the same area, the recipient should have the ability to take some special action to avoid writing over the original file. KERMIT implementations that convert file specifications to normal form by default should have an option to override this feature. This would be most useful when transferring files between like systems, perhaps used in conjunction with "image mode" file transfer. This could allow, for instance, one UNIX system to send an entire directory tree to another UNIX system. @Section A major feature of the KERMIT protocol is the ability to transfer multiple files. Whether a particular KERMIT program can actually send multiple files depends on the capabilities of the program and the host operating system (any KERMIT program can receive multiple files). If a KERMIT program can send multiple files, it should make every attempt to send the entire group specified. If it fails to send a particular file, it should not terminate the entire batch, but should go on the the next one, and proceed until an attempt has been made to send each file in the group. Operating in this robust manner, however, gives rise to a problem: the user must be notified of a failure to send any particular file. Unfortunately, it is not sufficient to print a message to the screen since the user may not be physically present. A better solution would be to have the sender optionally keep a log of the @Index transaction, giving the name of each file for which an attempt was made, and stating whether the attempt was successful, and if not, the reason. Additional aids to robustness are described in the Optional Features section, below. @Section @label<-flow> @Index@Index On full duplex connections, XON/XOFF flow control can generally be used in conjunction with KERMIT file transfer with no ill effects. This is because XOFFs are sent in the opposite direction of packet flow, so they will not interfere with the packets themselves. XON/XOFF, therefore, need not be implemented by the KERMIT program, but can done by the host system. If the host system provides this capability, it should be used -- if both sides can respond XON/XOFF signals, then buffer overruns and the resulting costly packet retransmissions can be avoided. Beware, however, of the following situation: remote Kermit is sending periodic NAKs, local system is buffering them on the operating system level (because the user has not started the local end of the file transfer yet); local line buffer becomes full, local systems sends XOFF, remote starts buffering them up on its end, user finally starts file transfer on local end, clears buffer, local operating system sends XON, and then all the remotely buffered NAKs show up, causing the packet echoing problem described above, despite the buffer clearing. Flow control via modem signals can also be used when available. Note that flow control should not be confused with "handshake" or "line turnaround" techniques that are used on simplex or half-@|duplex communication lines. @Section The KERMIT protocol can be described as a set of states and transitions, and rules for what to do when changing from one state to another. State changes occur based on the type of packets that are sent or received, or errors that may occur. Packets always go back and forth; the sender of a file always sends data packets of some kind (init, header, data) and the receiver always returns ACK or NAK packets. Upon entering a given state, a certain kind of packet is either being sent or is expected to arrive -- this is shown on top of the description of that state. As a result of the action, various responses may occur; these are shown in the EVENT column. For each event, an appropriate ACTION is taken, and the protocol enters a NEW STATE. The following table specifies basic KERMIT operation. Timeouts and error conditions have been omitted from the following table for simplicity, but the action is as described above. Server operation and some of the advanced features are also omitted. A full-@|blown state table is given subsequently. @newpage() @begin @u@ux @i(@ @ @ @ @ -- SEND STATES --) @!@i(Send Send-Init Packet)@/@&_@\ S Get NAK,bad ACK (None) S Get good ACK Set remote's params, open file SF (Other) (None) A @i(Send File-Header Packet)@/@&_@\ SF Get NAK,bad ACK (None) SF Get good ACK Get bufferful of file data SD (Other) (None) A @i(Send File-Data Packet)@/@&_@\ SD Get NAK,bad ACK (None) SD Get good ACK Get bufferful of file data SD (End of file) (None) SZ (Other) (None) A @i(Send EOF Packet)@/@&_@\ SZ Get NAK,bad ACK (None) SZ Get good ACK Get next file to send SF (No more files) (None) SB (Other) (None) A @i@/@&_@\ SB Get NAK,bad ACK (None) SB Get good ACK (None) C (Other) (None) A @i<@ @ @ @ @ -- RECEIVE STATES --> @i(Wait for Send-Init Packet)@/@&_@\ R Get Send-Init ACK w/local params RF (Other) (None) A @i(Wait for File-Header Packet)@/@&_@\ RF Get Send-Init ACK w/local params (previous ACK was lost) RF Get Send-EOF ACK (prev ACK lost) RF Get Break ACK C Get File-Header Open file, ACK RD (Other) (None) A @i(Wait for File-Data Packet)@/@&_@\ RD Get previous packet(D,F) ACK it again RD Get EOF ACK it, close the file RF Get good data Write to file, ACK RD (Other) (None) A @i<@ @ @ @ @ -- STATES COMMON TO SENDING AND RECEIVING --> C (Send Complete) start A ("Abort") start @end @Chapter @section @Index[Packet] The KERMIT protocol is built around exchange of packets of the following format: @begin +------+-----------+-----------+------+------------+-------+ | MARK | char(LEN) | char(SEQ) | TYPE | DATA | CHECK | +------+-----------+-----------+------+------------+-------+ @end where all fields consist of ASCII characters. The fields are: @begin @u@\The synchronization character that marks the beginning of the packet. This should normally be CTRL-A, but may be redefined. @u@\The number of ASCII characters within the packet that follow this field, in other words the packet length minus two. Since this number is transformed to a single character via the @q function, packet character counts of 0 to 94 (decimal) are permitted, and 96 (decimal) is the maximum total packet length. The length does not include end-@|of-@|line or padding characters, which are outside the packet and are strictly for the benefit of the operating system or communications equipment, but it does include the block check characters. @u@\The packet sequence number, modulo 64, ranging from 0 to 63. Sequence numbers "wrap around" to 0 after each group of 64 packets. @u@\The packet type, a single ASCII character. The following packet types are required: @begin D@\Data packet Y@\Acknowledge (ACK) N@\Negative acknowledge (NAK) S@\Send initiate (exchange parameters) B@\Break transmission (EOT) F@\File header Z@\End of file (EOF) E@\Error T@\@i @end The NAK packet is used only to indicate that the expected packet was not received correctly, never to supply other kinds of information, such as refusal to perform a requested service. The NAK packet @i has an empty data field. The T "packet" is used internally by many KERMIT programs to indicate that a timeout occurred. @Index[Control Characters] @u@\The "contents" of the packet, if any contents are required in the given type of packet, interpreted according to the packet type. Control characters (bytes whose low order 7 bits are in the ASCII control range 0-31, or 127) are preceded by a special prefix character, normally "@q<#>", and "uncontrollified" via @q. A prefixed sequence may not be broken across packets. Logical records in printable files are delimited with CRLFs, suitably prefixed (e.g. "@q<#M#J>"). Logical records need not correspond to packets. Any prefix characters are included in the count. Optional encoding for 8-bit data and repeated characters is described later. @begin[multiple] @u@\@Index[Checksum]@IndexA block check on the characters in the packet between, but not including, the mark and the block check itself. The check for each packet is computed by both hosts, and must agree if a packet is to be accepted. A single-@|character arithmetic checksum is the normal and required block check. Only six bits of the arithmetic sum are included. In order that all the bits of each data character contribute to this quantity, bits 6 and 7 of the final value are added to the quantity formed by bits 0-5. Thus if @i is the arithmetic sum of the ASCII characters, then @example[@i = char((@i + ((@i AND 192)/64)) AND 63)] This is the default block check, and all Kermits must be capable of performing it. Other optional block check types are described later. The block check is based on the ASCII values of all the characters in the packet, including control fields and prefix characters. Non-@|ASCII systems must translate to ASCII before performing the block check calculation. @end[multiple] @end @section @Index[End-Of-Line (EOL)] @index Any line terminator that is required by the system may be appended to the packet; this is carriage return (ASCII 15) by default. Line terminators are not considered part of the packet, and are included for in the count or checksum. Terminators are not necessary to the protocol, and are invisible to it, as are any characters that may appear between packets. If a host cannot do single character input from a TTY line, then a terminator will be required when sending to that host. The terminator can be specified in the initial connection exchange. Some KERMIT implementations also use the terminator for another reason -- speed. Some systems are not fast enough to take in a packet and decode it character by character at high baud rates; by blindly reading and storing all characters between the MARK and the EOL, they are able to absorb the incoming characters at full speed and then process them at their own rate. @section The space between packets may be used for any desired purpose. Handshaking characters may be necessary on certain connections, others may require screen control or other sequences to keep the packets flowing. @section @index MARK, LEN, SEQ, TYPE, and CHECK are @i. Control fields are always literal single-@|character fields, except that the CHECK field may be extended by one or two additional check characters. Each control field is encoded by @q or taken literally, but never prefixed. The control fields never contain 8-bit data. @index The DATA field contains a string of data characters in which any control characters are encoded printably and preceded with the control prefix. The decision to prefix a character in this way depends upon whether its low order 7 bits are in the ASCII control range, i.e. 0-31 or 127. Prefix characters that appear in the data must themselves be prefixed by the control prefix, but unlike control characters, these retain their literal value in the packet. The treatment of the high order ("8th") bit of a data byte is as follows: @begin @index If the communication channel allows 8 data bits per character, then the original value of the 8th bit is retained in the prefixed character. For instance, a data byte corresponding to a Control-A with the 8th bit set would be send as a control prefix, normally "@q<#>", without the 8th bit set, followed by @q @i the 8th bit set. In binary notation, this would be @example<00100011 10000001> In this case, the 8th bit is figured into all block check calculations. @Index If the communication channel or one of the hosts required parity on each character, and both sides were capable of 8th-@|bit prefixing, then the 8th bit will be used for parity, and must not be included in the block check. 8th bit prefixing is an option feature described in greater detail in Section @ref<-optional>, below. If parity is being used but 8th-@|bit prefixing is @i being done, then the value of the 8th bit of each data byte will be lost and binary files will not be transmitted correctly. Again, the 8th bit does not figure into the block check. @end The data fields of all packets are subject to prefix encoding, @i S, I, and A packets, and their ACKs (see below). @Chapter @Index[Initial Connection]@Index Initial connection occurs when the user has started up a Kermit program on both ends of the physical connection. One Kermit has been directed (in one way or another) to send a file, and the other to receive it. The receiving Kermit waits for a "Send-Init" packet from the sending Kermit. It doesn't matter whether the sending Kermit is started before or after the receiving Kermit (if before, the Send-Init packet should be retransmitted periodically until the receiving Kermit acknowledges it). The data field of the Send-Init packet is optional; trailing fields can be omitted (or left blank, i.e. contain a space) to accept or specify default values. The Send-Init packet contains a string of configuration information in its data field. The receiver sends an ACK for the Send-Init, whose data field contains its own configuration parameters. The data field of the Send-Init and the ACK to the Send-Init are @i, that is, there is no prefix encoding. This is because the two parties will not know @i to do prefix encoding until @i the configuration data is exchanged. It is important to note that newly invented fields are added at the right, so that old KERMIT programs that do not have code to handle the new fields will act as if they were not there. For this reason, the default value for any field, indicated by blank, should result in the behavior that occurred before the new field was defined or added. @begin 1 2 3 4 5 6 7 8 9 10... +------+------+------+------+------+------+------+------+------+------- | MAXL | TIME | NPAD | PADC | EOL | QCTL | QBIN | CHKT | REPT | CAPAS +------+------+------+------+------+------+------+------+------+------- @end The fields are as follows (the first and second person "I" and "you" are used to distinguish the two sides). Fields are encoded printably using the @q function unless indicated otherwise. @begin 1. @u@\The maximum length packet I want to receive, a number up to 94 (decimal). You respond with the maximum you want me to send. This allows systems to adjust to each other's buffer sizes, or to the condition of the transmission medium. 2. @u represents any printable character, @q<^A> represents any control character, @q<'x> represents any character with the 8th bit set. The @q<#> character is used for control-@|character quoting, and the @q<&> character for 8-bit quoting. The repeat count must always precede any other prefix character. The repeat count is taken literally (after transformation by @q; for instance "@q<#>" and "@q<&>" immediately following a "@q<~>" denote repeat counts, not control characters or 8-bit characters. The control quote character "@q<#>" is most closely bound to the data character, then the 8-bit prefix, then the repeat count; in other words, the order is: repeat prefix and count, 8-bit quote, control quote, and the data character itself. To illustrate, note that @q<&#A> is @i equivalent to @q<#&A>. When the parity bit is available for data, then 8th-bit quoting should not be done, and the 8th bit of the prefixed character will have the same value as the 8th bit of the original data byte. In that case, the table looks like this: @begin Quoted With @u @ux 'A 'A ~('A '^A #'A ~(#'A '# #'# ~(#'# '& '& ~('& '~ #'~ ~(#'~ @end Note that since 8th bit quoting is not being done, "@q<&>" is not being used as an 8th bit prefix character, so it does not need to be quoted with "@q<#>". Also, note that the 8th bit is set on the final argument of the repeat sequence, no matter how long, and not on any of the prefix characters. Finally, remember the following rules: @Begin(Itemize,spread 0.5) @i @i @i @End(Itemize) In the first rule above, note that a prefixed sequence means a single character @index and all its prefixes, like @q<~%&#X>, @i a sequence like @q<#M#J>, which is @i prefixed sequences. @Section @index A KERMIT server is a KERMIT program running remotely with no "user interface". All commands to the server arrive in packets from the local KERMIT. SERVER operation is much more convenient than basic operation, since the user need never again interact directly with the remote KERMIT program after once starting it up in server mode, and therefore need not issue complementary SEND and RECEIVE commands on the two sides to get a file transfer started; rather, a single command (such as SEND or GET) to the local KERMIT suffices. KERMIT servers can also provide services beyond file transfer. Between transactions, a Kermit server waits for packets containing server commands. The packet sequence number is always set back to 0 after a transaction. A Kermit server in command wait should be looking for packet 0, and command packets sent to servers should also be packet 0. Certain server commands will result in the exchange of multiple packets. Those operations proceed exactly like file transfer. @index A KERMIT server program waiting for a command packet is said to be in "server command wait". Once put into server command wait, the server should never leave it until it gets a command packet telling it to do so. This means that after any transaction is terminated, either normally or by any kind of error, the server must go back into command wait. While in command wait, a server may elect to send out periodic NAKs for packet 0, the expected command packet. Since the user may be disconnected from the server for long periods of time (hours), the interval between these NAKs should be significantly longer than the normal timeout interval (say, 30-60 seconds, rather than 5-10). The periodic NAKs are useful for breaking the deadlock that would occur if a local program was unable to time out, and sent a command that was lost. On the other hand, they can cause problems for local KERMIT programs that cannot clear their input buffers, or for systems that do XON/XOFF blindly, causing the NAKs to buffered in the server's host system output buffer, to be suddenly released en masse when an XON appears. For this reason, servers should have an option to set the command-@|wait wakeup interval, or to disable it altogher. Server operation must be implemented in two places: in the server itself, and in any KERMIT program that will be communicating with a server. The server must have code to read the server commands from packets and respond to them. The user KERMIT must have code to parse the user's server-@|related commands, to form the server command packets, and to handle the responses to those server commands. @subsection Server commands are listed below. Not all of them have been implemented, and some may never be, but their use should be reserved. Although server-@|mode operation is optional, certain commands should be implemented in every server. These include Send-Init (S), Receive-Init (R), and the Generic Logout (GL) and/or Finish (GF) commands. If the server receives a command it does not understand, or cannot execute, it should respond with an Error (E) packet containing a message like "Unimplemented Server Command" and both sides should set the packet sequence number back to 0, and the server should remain in server command wait. Only a GL or GF command should terminate server operation. Server commands are as follows: @begin S@\Send Initiate (exchange parameters, server waits for a file). R@\Receive Initiate (ask the server to send the specified files). I@\Initialize (exchange parameters). X@\Text header. Allows transfer of text to the user's screen in response to a generic or host command. This works just like file transfer except that the destination "device" is the screen rather than a file. Data field may contain a filename, title, or other heading. C@\Host Command. The data field contains a string to be executed as a command by the host system command processor. K@\KERMIT Command. The data field contains a string in the interactive command language of the KERMIT server (normally a SET command) to be executed as if it were typed in at command level. G@\Generic Kermit Command. Single character in data field (possibly followed by operands, shown in {braces}, optional fields in [brackets]) specifies the command: @begin I@\Login [{*user[*password[*account]]}] C@\CWD, Change Working Directory [{*directory[*password]}] L@\Logout, Bye F@\Finish (Shut down the server, but don't logout). D@\Directory [{*filespec}] U@\Disk Usage Query [{*area}] E@\Erase (delete) {*filespec} T@\Type {*filespec} R@\Rename {*oldname*newname} K@\Copy {*source*destination} W@\Who's logged in? (Finger) [{*user ID or network host[*options]}] M@\Send a short Message {*destination*text} H@\Help [{*topic}] Q@\Server Status Query P@\Program {*[program-filespec][*program-commands]} J@\Journal {*command[*argument]} V@\Variable {*command[*argument[*argument]]} @end Note that field length encoding is used within the data field of all Generic command packets, but not within the data fields of the other packets, such as S, I, R, X, K, and C. @end Asterisk as used above ("@q<*>") represents a single-@|character length field, encoded using @q, for the operand that follows it; thus lengths from 0 to 94 may be specified. This allows multiple operands to be clearly delimited regardless of their contents. @index@index All server commands that send arguments in their data fields should pass through the prefix encoding mechanism. Thus if a data character or length field happens to correspond to an active prefix character, it must itself be prefixed. The field length denotes the length of the field @i prefix encoding and (hopefully) @i prefix decoding. For example, to send a generic command with two fields, "ABC" and "ZZZZZZZZ", first each field would be prefixed by @q of its length, in this case @q and @q, giving "@q<#ABC(ZZZZZZZZ>". But "@q<#>" is the normal control prefix character so it must be prefixed itself, and the eight Z's can be condensed to 3 characters using a repeat prefix (if repeat counts are in effect), so the result after encoding would be "@q<##ABC(~(Z>" (assuming the repeat prefix is tilde ("@q<~>"). The recipient would decode this back into the original "@q<#ABC(ZZZZZZZZ>" before attempting to extract the two fields. Since a generic command must fit into a single packet, the program sending the command should ensure that the command actually fits, and should not include length fields that point beyond the end of the packet. Servers, however, should be defensive and not attempt to process any characters beyond the end of the data field, even if the argument length field would lead them to do so. @subsection KERMIT does not provide a mechanism for suspending and continuing a transaction. This means that text sent to the user's screen should not be frozen for long periods (i.e.@ not longer than the timeout period times the retry threshold). Between transactions, when the server has no tasks pending, it may send out periodic NAKs (always with type 1 checksums) to prevent a deadlock in case a command was sent to it but was lost. These NAKs can pile up in the local "user" Kermit's input buffer (if it has one), so the user Kermit should be prepared to clear its input buffer before sending a command to a server. Meanwhile, servers should recognize that some systems provide no function to do this (or even when they do, the process can be foiled by system flow control firmware) and should therefore provide a way turn off or slow down the command-@|wait NAKs. @SubSection @index The R packet, generally sent by a local Kermit program whose user typed a GET command, tells the server to send the files specified by the name in the data field of the R packet. Since we can't assume that the two Kermits are running on like systems, the local (user) Kermit must parse the file specification as a character string and let the server to check it. If the server can open and read the specified file, it sends a Send-Init (S) packet -- @i -- to the user, and then completes the file-@|sending transaction, as described above. If the server cannot send the file, it should respond with an error (E) packet containing a reason, like "File not found" or "Read access required". @SubSection The K packet can contain a character string which the server interprets as a command in its own interactive command language. This facility is useful for achieving the same effect as a direct command without having to shut down the server, connect back to the remote system, continue it (or start a new one), and issue the desired commands. The server responds with an ACK if the command was executed successfully, or an error packet otherwise. The most likely use for the K packet might be for transmitting SET commands, e.g. for switching between text and binary file modes. @SubSection @index@index Any request made of a server may be answered in either of two ways, and any User Kermit that makes such a request should be prepared for either kind of reply: @Begin(itemize) @i. This consists of a single ACK packet, which may contain text in its data field. For instance, the user might send a disk space query to the server, and the server might ACK the request with a short character string in the data field, such as "12K bytes free". The user KERMIT should display this text on the screen. @i. This proceeds exactly like a file transfer (and in some cases it may be a file transfer). It begins with one of the following: @begin A File-Header (F) packet (optionally followed by one or more Attributes packets; these are discussed later); A Text-Header (X) packet. A Send-Init (S) Packet, followed by an X or F packet. @end After the X or F packet comes an arbitrary number of Data (D) packets, then an End-Of-File (Z) packet, and finally a Break-Transmission (B) packet, as for ordinary file transfer. @End(itemize) A long reply should begin with an S packet unless an I-packet exchange has already taken place, @i the type 1 (single-@|character) block check is being used. @SubSection @index The following server commands request the server to perform tasks other than sending or receiving files. Almost any of these can have either short or long replies. For instance, the Generic Erase (GE) command may elicit a simple ACK, or a stream of packets containing the names of all the files it erased (or didn't erase). These commands are now described in more detail; arguments are as provided in commands typed to the user KERMIT (subject to prefix encoding); no transformations to any kind of normal or canonic form are done -- filenames and other operands are in the syntax of the server's host system. @begin I@\Login. For use when a KERMIT server is kept perpetually running on a dedicated line. This lets a new user obtain an identity on the server's host system. If the data field is empty, this removes the user's identity, so that the next user does not get access to it. L@\Logout, Bye. This shuts down the server entirely, causing the server itself to log out its own job. This is for use when the server has been started up manually by the user, who then wishes to shut it down remotely. For a perpetual, dedicated server, this command simply removes the server's access rights to the current user's files, and leaves the server waiting for a new login command. F@\Finish. This is to allow the user to shut down the server, putting its terminal back into normal (as opposed to binary or raw) mode, and putting the server's job back at system command level, still logged in, so that the user can connect back to the job. For a perpetual, dedicated server, this command behaves as the L (BYE) command. C@\CWD. Change Working Directory. This sets the default directory or area for file transfer on the server's host. With no operands, this command sets the default area to be the user's own default area. D@\Directory. Send a directory listing to the user. The user program can display it on the terminal or store it in a file, as it chooses. The directory listing should contain file sizes and creation dates as well as file names, if possible. A wildcard or other file-@|group designator may be specified to ask the server list only those files that match. If no operand is given, all files in the current area should be shown. U@\Disk Usage Query. The server responds with the amount of space used and the amount left free to use, in K bytes (or other units, which should be specified). E@\Erase (delete). Delete the specified file or file group. T@\Type. Send the specified file or file group, indicating (by starting with an X packet rather than an F packet, or else by using the Type attribute) that the file is to be displayed on the screen, rather than stored. R@\Rename. Change the name of the file or files as indicated. The string indicating the new name may contain other attributes, such as protection code, permitted in file specifications by the host. K@\Copy. Produce a new copy of the file or file group, as indicated, leaving the source file(s) unmodified. W@\Who's logged in? (Finger). With no arguments, list all the users who are logged in on the server's host system. If an argument is specified, provide more detailed information on the specified user or network host. M@\Short Message. Send the given short (single-packet) message to the indicated user's screen. P@\Program. This command has two arguments, program name (filespec), and command(s) for the program. The first field is required, but may be left null (i.e. zero length). If it is null, the currently loaded program is "fed" the specified command. If not null, the specified program is loaded and started; if a program command is given it is fed to the program as an initial command (for instance, as a command line argument on systems that support that concept). In any case, the output of the program is sent back in packets as either a long or short reply, as described above. J@\Journal. This command controls server transaction logging. The data field contains one of the following: @begin @q<+>@\Begin/resume logging transactions. If a filename is given, close any currently open transaction and then open the specified file as the new transaction log. If no name given, but a log file was already open, resume logging to that file. If no filename was given and no log was open, the server should open a log with a default name, like @q. @q<->@\Stop logging transactions, but don't close the current transaction log file. @q@\Stop logging and close the current log. @q@\Send the transaction log as a file. If it was open, close it first. @end Transaction logging is the recording of the progress of file transfers. It should contain entries showing the name of each file transferred, when the transfer began and ended, whether it completed successfully, and if not, why. @q@\Set or Query a variable. The @i can be S or Q. The first argument is the variable name. The second argument, if any, is the value. @begin S@\Set the specified variable to the specified value. If the value is null, then undefine the variable. If the variable is null then do nothing. If the variable did not exist before, create it. The server should respond with an ACK if successful, and Error packet otherwise. Q@\Query the value of the named variable. If no variable is supplied, display the value of all active variables. The server responds with either a short or long reply, as described above. If a queried variable does not exist, a null value is returned. @end Variables are named by character strings, and have character string values, which may be static or dynamic. For instance, a server might have built-@|in variables like "system name" which never changes, or others like "mail status" which, when queried, cause the server to check to see if the user has any new mail. @end @SubSection Host commands are conceptually simple, but may be hard to implement on some systems. The C packet contains a text string in its data field which is simply fed to the server's host system command processor; any output from the processor is sent back to the user in KERMIT packets, as either a short or long reply. Implementation of this facility under UNIX, with its forking process structure and i/o redirection via pipes, is quite natural. On other systems, it could be virtually impossible. @SubSection In basic KERMIT, the Send-Init exchange is always sufficient to configure the two sides to each other. During server operation, on the other hand, some transactions may not begin with a Send-Init packet. For instance, when the user sends an R packet to ask the server to send a file, the server chooses what block check option to use. Or if the user requests a directory listing, the server does not know what packet length to use. The solution to this problem is the "I" (Init-Info) packet. It is exactly like a Send-Init packet, and the ACK works the same way too. However, receipt of an I packet does not cause transition to file-send state. The I-packet exchange simply allows the two sides to set their parameters, in preparation for the next transaction. Servers should be able to receive and ACK "I" packets when in server command wait. User KERMITs need not send "I" packets, however; in that case, the server will assume all the defaults for the user listed on page @pageref<-defaults>, or whatever parameters have been set by other means (e.g. SET commands typed to the server before it was put in server mode). User Kermits which send I packets should be prepared to receive and ignore an Error packet in response. This could happen if the server has not implemented I packets. @section There are two optional kinds of block checks: @begin @ux@\ A two-@|character checksum based on the low order 12 bits of the arithmetic sum of the characters in the packet (from the LEN field through the last data character, inclusive) as follows: @begin 1 2 --------+--------------+-------------+ ...data | char(b6-b11) | char(b0-b5) | --------+--------------+-------------+ @End(Example) For instance, if the 16-bit result is 154321 (octal), then the 2 character block check would be "@q". @ux@\ Three-@|character 16-bit CRC-CCITT. The CRC calculation treats the data it operates upon as a string of bits with the low order bit of the first character first and the high order bit of the last character last. The initial value of the CRC is taken as 0; the 16-bit CRC is the remainder after dividing the data bit string by the polynomial @i@+(16)+@i@+(12)+@i@+(5)+1 (this calculation can actually be done a character at a time, using a simple table lookup algorithm). The result is represented as three printable characters at the end of the packet, as follows: @begin 1 2 3 --------+---------------+--------------+-------------+ ...data | char(b12-b15) | char(b6-b11) | char(b0-b5) | --------+---------------+--------------+-------------+ @End(Example) For instance, if the 16-bit result is 154321 (octal), then the 3 character block check would be "@q<-C1>". The CRC technique chosen here agrees with many hardware implementations (e.g. the VAX CRC instruction). A useful reference on table-@|driven CRC calculations can be found in "Byte-wise CRC Calculations" by Aram Perez in @i, June 1983, p.40. @End(Description) The single-character checksum has proven quite adequate in practice. The other options can be used only if both sides agree to do so via Init packet (S or I) exchange. The 2 and 3 character block checks should only be used under conditions of severe line noise and packet corruption. Since type 2 and 3 block checks are optional, not all KERMITs can be expected to understand them. Therefore, during initial connection, communication must begin using the type 1 block check. If type 2 or 3 block checks are agreed to during the "I" or "S" packet exchange, the switch will occur @i the Send-Init has been sent and ACK'd with a type 1 block check. This means that the first packet with a type 2 or 3 block check must always be an "F" or "X" packet. Upon completion of a transaction, both sides must switch back to type 1 (to allow for the fact that neither side has any way of knowing when the other side has been stopped and restarted). The transaction is over @i a "B" or "E" packet has been sent and ACK'd, or after any error that terminates the transaction prematurely or abnormally. A consequence of the foregoing rule is that if a type 2 or 3 block check is to be used, a long reply sent by the server @i begin with a Send-Init (S) packet, even if an I packet exchange had already occurred. If type 1 block checks are being used, the S packet can be skipped and the transfer can start with an X or F packet. A server that has completed a transaction and is awaiting a new command may send out periodic NAKs for that command (packet 0). Those NAKs must have type 1 block checks. The use of alternate block check types can cause certain complications. For instance, if the server gets a horrible error (so bad that it doesn't even send an error packet) and reverts to command wait, sending NAKs for packet 0 using a type 1 block check, while a transfer using type 2 or 3 block checks was in progress, neither side will be able to read the other's packets. Communication can also grind to a halt if A sends a Send-Init requesting, say, type 3 block checks, B ACKs the request, switches to type 3 and waits for the X or F packet with a type 3 block check, but the ACK was lost, so A resends the S packet with a type 1 block check. Situations like this will ultimately resolve themselves after the two sides retransmit up to their retry threshhold, but can be rectified earlier by the use of two heuristics: @begin The packet reader can assume that if the packet type is "S", the block check type is 1. @indexA NAK packet never has anything in its data field. Therefore, the block check type can always be deduced by the packet reader from the length field of a NAK. In fact, it is the value of the length field minus 2. A NAK can therefore be thought of as a kind of "universal synchronizer". @end These heuristics tend violate the layered nature of the protocol, since the packet reader should normally be totally unconcerned with the packet type (which is of interest to the application level which invokes the packet reader). A better design would have had each packet include an indicator of the type of its own block check; this would have allowed the block check type to be changed dynamically during a transaction to adapt to changing conditions. But it's too late for that now... @section This section describes an optional feature of the KERMIT protocol to allow graceful interruption of file transfer. This feature is unrelated to server operation. To interrupt sending a file, send an EOF ("Z") packet in place of the next data packet, including a "D" (for Discard) in the data field. The recipient ACKs the Z packet normally, but does not retain the file. This does not interfere with older Kermits on the receiving end; they will not inspect the data field and will close the file normally. The mechanism can be triggered by typing an interrupt character at the console of the sending KERMIT program. If a (wildcard) file group is being sent, it is possible to skip to the next file or to terminate the entire batch; the protocol is the same in either case, but the desired action could be selected by different interrupt characters, e.g. CTRL-X to skip the current file, CTRL-Z to skip the rest of the batch. To interrupt receiving a file, put an "X" in the data field of an ACK for a data packet. To interrupt receiving an entire file group, use a "Z". The user could trigger this mechanism by typing an interrupt character by typing, say, CTRL-X and CTRL-Z, respectively, at the receiving KERMIT's console. A sender that was aware of the new feature, upon finding one of these codes, would act as described above, i.e. send a "Z" packet with a "D" code; a sender that did not implement this feature would simply ignore the codes and continue sending. In this case, and if the user wanted the whole batch to be cancelled (or only one file was being sent), the receiving KERMIT program, after determining that the sender had ignored the "X" or "Z" code, could send an Error (E) packet to stop the transfer. The sender may also choose to send a Z packet containing the D code when it detects that the file it is sending cannot be sent correctly and completely -- for instance, after sending some packets correctly, it gets an i/o error reading the file. Or, it notices that the "8th bit" of a file byte is set when the file is being sent as a text file and no provision has been made for transmitting the 8th bit. @Section @label<-attributes> The optional Attributes (A) packet provides a mechanism for the sender of a file to provide additional information about it. This packet can be sent if the receiver has indicated its ability to process it by setting the Attributes bit in the capability mask. If both sides set this bit in the Kermit capability mask, then the sender, after sending the filename in the "F" packet and receiving an acknowledgement, may (but does not have to) send an "A" packet to provide file attribute information. Setting the Attributes bit in the capability mask does @i indicate support for any particular attributes, only that the receiver is prepared to accept the "A" packet. The attributes are given in the data field of the "A" packet. The data field consists of 0 or more subfields, which may occur in any order. Each subfield is of the following form: @Begin(Example) +-----------+--------------+------+ | ATTRIBUTE | char(LENGTH) | DATA | +-----------+--------------+------+ @End(Example) where @Begin(Description, leftmargin +10, indent -10) ATTRIBUTE@\is a single printable character other than space, LENGTH@\is the length of the data characters (0 to 94), with 32 added to produce a single printable character, and DATA@\is @i characters worth of data, all printable characters. @End(Description) No quoting or prefixing is done on any of this data. More than one attribute packet may be sent. The only requirement is that all the A packets for a file must immediately follow its File header (or X) packet, and precede the first Data packet. There may be 93 different attributes, one for each of the 93 printable ASCII characters other than space. These are assigned in ASCII order. @Begin(Description, leftmargin +10, indent -10) @q (ASCII 33)@\Length. The data field gives the length in K (1024) bytes, as a printable decimal number, e.g. "!#109". This will allow the receiver to determine in advance whether there is sufficient room for the file, and/or how long the transfer will take. @q<"> (ASCII 34)@\Type. The data field can contain some indicator of the nature of the file. Operands are enclosed in {braces}, optional items in [brackets]. @Begin(Description,leftmargin +8, indent -8) A[{xx}]@\ASCII text, containing no 8-bit quantities, logical records (lines) delimited by the (quoted) control character sequence {xx}, represented here by its printable counterpart (MJ = CRLF, J = LF, etc). For instance AMJ means that the appearance of @q<#M#J> (the normal prefixed CRLF sequence) in a file data packet indicates the end of a record, assuming the current control prefix is "@q<#>". If {xx} is omitted, MJ will be assumed. B[{xx}]@\Binary. {xx} indicates in what manner the file is binary: @Begin(Description,leftmargin +4, indent -4) 8@\(default) The file is a sequence of 8-bit bytes, which must be saved as is. The 8th bit may be sent "bare", or prefixed according to the Send-Init negotiation about 8th-bit prefixing. 36@\The file is a PDP-10 format binary file, in which five 7-bit bytes are fit into one 36-bit word, with the final bit of each word being represented as the "parity bit" of every 5th character (perhaps prefixed). @End(Description) D{x}@\@i F{x}@\@i I[{x}]@\Image. The file is being sent exactly as it is represented on the system of origin. For use between like systems. There are {x} usable bits per character, before prefixing. For instance, to send binary data from a system with 9-bit bytes, it might be convenient to send three 6-bit characters for every two 9-bit bytes. Default {x} is 8. @End(Description) @q<#> (ASCII 35)@\Creation Date, expressed as "@q<[yy]yymmdd[ hh:mm[:ss]]>" (ISO standard julian format), e.g. @q<831009@ 23:59>. The time is optional; if given, it should be in 24-hour format, and the seconds may be omitted, and a single space should separate the time from the date. @q<$> (ASCII 36)@\Creator's ID, expressed as a character string of the given length. @q<%> (ASCII 37)@\Account to charge the file to, character string. @q<&> (ASCII 38)@\Area in which to store the file, character string. @q<'> (ASCII 39)@\Password for above, character string. @q<(> (ASCII 40)@\Block Size. The file has, or is to be stored with, the given block size. @q<)> (ASCII 41)@\Access: @Begin(Description,leftmargin +4, indent -4,spread 0) N@\New, the normal case -- create a new file of the given name. S@\Supersede (overwrite) any file of the same name. A@\Append to file of the given name. @End(Description) @q<*> (ASCII 42)@\Encoding: @Begin(Description,leftmargin +4, indent -4,spread 0) A@\ASCII, normal ASCII encoding with any necessary prefixing, etc. H@\Hexidecimal "nibble" encoding. E@\EBCDIC (sent as if it were a binary file). X@\Encrypted. Q{x}@\Huffman Encoded for compression. First @i bytes of the file are the key. @End(Description) @q<#> (ASCII 43)@\Disposition (operands are specified in the syntax of the receiver's host system): @Begin(Description) M{user(s)}@\Send the file as Mail to the specified user(s). O{destination}@\Send the file as a lOng terminal message to the specified destination (terminal, job, or user). S[{options}]@\Submit the file as a batch job, with any specified options. P[{options}]@\Print the file on a system printer, with any specified options, which may specify a particular printer, forms, etc. T@\Type the file on the screen. L[{aaa}]@\Load the file into memory at the given address, if any. X[{aaa}]@\Load the file into memory at the given address and eXecute it. A@\Archive the file; save the file together with the attribute packets that preceded it, so that it can be sent back to the system of origin with all its attributes intact. A file stored in this way should be specially marked so that the KERMIT that sends it back will recognize the attribute information as distinct from the file data. @End(Description) , (ASCII 44)@\Protection. Protection code for the file, in the syntax of the receiver's host file system. With no operand, store according to the system's default protection for the destination area. - (ASCII 45)@\Protection. Protection code for the file with respect to the "public" or "world", expressed generically in a 6-bit quantity (made printable by @q), in which the bits have the following meaning: @Begin(Description,leftmargin +4,indent -4,spread 0) b0:@\Read Access b1:@\Write Access b2:@\Execute Access b3:@\Append Access b4:@\Delete Access b5:@\Directory Listing @End(Description) A one in the bit position means allow the corresponding type of access, a zero means prohibit it. For example, the letter "E" in this field would allow read, execute, and directory listing access (@q binary). . (ASCII 46)@\Machine and operating system of origin. This is useful in conjunction with the archive disposition attribute. It allows a file, once archived, to be transferred among different types of systems, retaining its archive status, until it finds its way to a machine with the right characteristics to de-archive it. The systems are denoted by codes; the first character is the major system designator, the second designates the specific model or operating system. A third character may be added to make further distinctions, for instance operating system version. The systems below do not form a complete collection; many more can and probably will be added. @begin A@\Apple microcomputers @begin 1@\Apple II, DOS 2@\Apple III 3@\Macintosh 4@\Lisa @end B@\Sperry (Univac) mainframes @begin 1@\1100 series, EXEC @end C@\CDC mainframes @begin 1@\Cyber series, NOS @end D@\DEC Systems @begin 1@\DECsystem-10/20, TOPS-10 2@\DECsystem-10/20, TOPS-20 3@\DECsystem-10/20, TENEX 4@\DECsystem-10/20, ITS 5@\DECsystem-10/20, WAITS 6@\DECsystem-10/20, MAXC 7@\VAX-11, VMS 8@\PDP-11, RSX-11 9@\PDP-11, IAS A@\PDP-11, RSTS/E B@\PDP-11, RT-11 C@\Professional-300, P/OS D@\Word Processor (WPS or DECmate), WPS @end D@\Honeywell mainframes @begin 1@\MULTICS systems 2@\DPS series, running CP-6 @end F@\Data General machines @begin 1@\RDOS 2@\AOS @end G@\PR1ME machines, PRIMOS H@\Hewlett-Packard machines @begin 1@\HP-1000, RTE 2@\HP-3000, MPE @end I@\IBM 370-series and compatible mainframes @begin 1@\VM/CMS 2@\MVS/TSO 3@\DOS 4@\MUSIC 5@\GUTS 6@\MTS @end J@\Tandy microcomputers, TRSDOS K@\Atari micros, DOS L-T@\@i(Reserved) U@\Portable Operating or File Systems @begin 1@\UNIX 2@\Software Tools 3@\CP/M-80 4@\CP/M-86 5@\CP/M-68K 6@\MP/M 7@\Concurrent CP/M 8@\MS-DOS 9@\UCSD p-System A@\MUMPS @end @end / (ASCII 47)@\Format of the data within the packets. @begin A{xx}@\Variable length delimited records, terminated by the character sequence {xx}, where xx is a string of one or more control characters, represented here by their unprefixed printable equivalents, e.g. @q for @q<^M^J> (CRLF). D{x}@\Variable length undelimited records. Each logical record begins with an {x}-character ASCII decimal length field (similar to ANSI tape format "D"). For example, "@q" would indicate 4-digit length fields, like "0132". F{xxxx}@\Fixed-length undelimited records. Each logical record is {xxxx} bytes long. R{x}@\For record-@|oriented transfers, to be used in combination with one of the formats given above. Each record begins (in the case of D format, after the length field) with an x-character long position field indicating the byte position within the file at which this record is to be stored. M{x}@\For record-@|oriented transfers, to be used in combination with one of the formats given above. Maximum record length for a variable-@|length record. @end 0 (ASCII 48)@\Special system-dependent parameters for storing the file on the system of origin, for specification of exotic attributes not covered explicitly by any of the KERMIT attribute descriptors. These are given as a character string in the system's own language, for example a list of DCB parameters in IBM Job Control Language. 1-@@ (ASCII 49-64)@\@i @End(Description) Other attributes can be imagined, and can be added later if needed. However, two important points should be noted: @Begin(Itemize) The receiver may have absolutely no way of honoring, or even recording, a given attribute. For instance, CP/M-80 has no slot for creation date or creator's ID in its FCB; the DEC-20 has no concept of block size, etc. The sender may have no way of determining the correct values of any of the attributes. This is particularly true when sending files of foreign origin. @End(Itemize) The "A" packet mechanism only provides a way to send certain information about a file to the receiver, with no provision or guarantee about what the receiver may do with it. That information may be obtained directly from the file's directory entry (FCB, FDB, @q<...>), or specified via user command. The ACK to the "A" packet may in turn have information in its data field. However, no complicated negotiations about file attributes may take place, so the net result is that the receiver may either refuse the file or accept it. The receiver may reply to the "A" packet with any of the following codes in the data field of the ACK packet: @Begin(Description,leftmargin +8, indent -8) @\(empty data field) I accept the file, go ahead and send it. N[{xxx}]@\I refuse the file as specified, don't send it; {xxx} is a string of zero or more of the attribute characters listed above, to specify what attributes I object to (e.g. "@q" means it's too long, "@q<&>" means I don't have write access to the specified area, etc). Y[{xxx}]@\I agree to receive the file, but I cannot honor attributes {xxx}, so I will store the file according to my own defaults. Y@\(degenerate case of Y{xxx}, equivalent to , above) @End(Description) How the receiver actually replies is an implementation decision. A NAK in response to the "A" packet means, of course, that the receiver did not receive the "A" correctly, not that it refuses to receive the file. @Section The simple table presented previously is sufficient for a basic KERMIT implementation. The following is a state table for the full Kermit protocol, including both server mode and sending commands to a server Kermit. It does not include handling of the file attributes packet (A). Note that states whose names start with "Send" always send a packet each time they are entered (even when the previous state was the same). States whose name starts with "Rec", always wait for a packet to be received (up to the timeout value), and process the received packet. States whose names do not include either send or receive do not process packets directly. These are states which perform some local operation and then change to another state. The initial state is determined by the user's command. A "server" command enters at @q. A "send" command enters at @q. A "receive" command (the old non-@|server version, not a "get" command) enters at @q. Any generic command, the "get" command, and the "host" command enter at either @q or @q, depending upon the expected response. Under "Rec'd Msg", the packet type of the incoming message is shown, followed by the packet number in parentheses; (n) means the current packet number, (n-1) and (n+1) mean the previous and next packet numbers (modulo 64), (0) means packet number zero. Following the packet number may be slash and a letter, indicating some special signal in the data field. For instance @t indicates a Z (EOF) packet, sequence number @i, with a "D" in the data field. Under "Action", "@t" means that the retry count is incremented and compared with a threshhold; if the threshhold is exceeded, an Error packet is sent and the state changes to "Abort". "@t" means that the packet number is incremented, modulo 64, and the retry count, @i, is set back to zero. @begin @u @ux @u @ux Rec_Server_Idle -- @i Set n and r to 0 I(0) Send ACK Rec_Server_Idle S(0) Process params, ACK with params, n+ Rec_File R(0) Save file name Send_Init K, C or G(0) Short reply: ACK(0)/reply Rec_Server_Idle Long reply: init needed Send_Init init not needed, n+ Open_File Timeout Send NAK(0) Rec_Server_Idle Other Error Rec_Server_Idle @hinge Rec_Init -- @i Set n and r to 0 S(0) Process params, send ACK with params, n+ Rec_File Timeout Send NAK(0), r+ Rec_Init Other NAK Abort @hinge Rec_File -- @i F(n) Open file, ACK, n+ Rec_Data X(n) Prepare to type on screen, ACK, n+ Rec_Data B(n) ACK Complete S(n-1) ACK with params, r+ Rec_File Z(n-1) ACK, r+ Rec_File Timeout NAK, r+ Rec_File Other NAK Abort @hinge Rec_Data -- @i D(n) Store data, ACK, n+; If interruption wanted include X or Z in ACK Rec_Data D(n-1) Send ACK, r+ Rec-Data Z(n) Close file, ACK, n+ Rec_File Z(n)/D Discard file, ACK, n+ Rec_File F(n-1) Send ACK, r+ Rec_Data X(n-1) Send ACK, r+ Rec_Data Timeout Send NAK, r+ Rec_Data Other Send E Abort @hinge Send_Init -- @i Set n and r to 0, send S(0) with parameters Y(0) Process params, n+ Open_File N, Timeout r+ Send_Init Other r+ Send_Init @hinge Open_File -- @i Send_File @hinge Send_File -- @i Send F or X(n) Y(n), N(n+1) Get first buffer of Send_Data or Send_Eof if data, n+ empty file or text N, Timeout r+ Send_File Other Abort @hinge Send_Data -- @i Send D(n) with current buffer Y(n), N(n+1) n+, Get next buffer Send_Data or Send_Eof if at end of file or text Y(n)/X or Z n+ Send_Eof N, Timeout r+ Send_Data Other Abort @hinge Send_Eof -- @i Send Z(n); if interrupting send Z(n)/D Y(n), N(n+1) Open next file, n+ Send_File if more, or Send_Break if no more or if interrupt "Z". N, Timeout r+ Send_Eof Other Abort @hinge Send_Break -- @i Send B(n) Y(n), N(0) Complete N(n), Timeout Send_Break Other Abort @hinge Send_Server_Init - @i Send I(0) with parameters Y(0) Process params Send_Gen_Cmd N, Timeout r+ Send_Server_Init E Use default params Send_Gen_Cmd Other Abort @hinge Send_Gen_Cmd - @i Send G, R or C(0) S(0) Process params, ACK with params, n+ Rec_File X(1) Setup to type on terminal, n+ Rec_Data Y(0) Type data on TTY Complete N, Timeout r+ Send_Gen_Cmd Other Abort @hinge Complete -- @i Set n and r to 0; If server, reset params, enter Rec_Server_Idle otherwise exit @hinge Abort -- @i Reset any open file, set n and r to 0 If server, reset params, enter Rec_Server_Idle otherwise exit @hinge Exit, Logout states Exit or Logout @hinge @end Note that the generic commands determine the next state as follows: @begin If the command is not supported, an error packet is sent and the next state is "Abort". If the command generates a response which can be fit into the data portion of an ACK, an ACK is sent with the text (quoted as necessary) in the data portion. If the command generates a large response or must send a file, nothing is sent from the @q state, and the next state is either @q (if either no I message was received or if alternate block check types are to be used), or @q (if an I message was received and the single character block check is to be used). If the command is Logout, an ACK is sent and the new state is Logout. If the command is Exit, an ACK is sent and the new state is Exit. @end @Chapter The following list of KERMIT commands and terms is suggested. It is not intended to recommend a particular style of command parsing, only to promote a consistent vocabulary, both in documentation and in choosing the names for commands. @Section @Begin(Description,leftmargin +8,indent -8) SEND@\This verb tells a Kermit program to send one or more files from its own file structure. RECEIVE@\This verb should tell a Kermit program to expect one or more files to arrive. GET@\This verb should tell a user Kermit to send one or more files. Some Kermit implementations have separate RECEIVE and GET commands; others use RECEIVE for both purposes, which creates confusion. @End(Description) Since it can be useful, even necessary, to specify different names for source and destination files, these commands should take operands as follows (optional operands in [brackets]): @Begin(Description,leftmargin +8,indent -8) SEND local-source-filespec [remote-destination-filespec]@\ If the destination file specification is included, this will go in the file header packet, instead of the file's local name. RECEIVE [local-destination-filespec]@\ If the destination filespec is given, the incoming file will be stored under that name, rather than the one in the file header pakcet. GET remote-source-filespec [local-destination-filespec]@\ If the destination filespec is given, the incoming file will be stored under that name, rather than the one in the file header packet. @End(Description) If a file group is being sent or received, alternate names should @i be used. @Section @Begin(Description,leftmargin +8,indent -8) EXIT@\Leave the KERMIT program, doing whatever cleaning up must be done -- deassigning of devices, closing of files, etc. QUIT@\Leave the KERMIT program without cleaning up, in such a manner as to allow further manipulation of the files and devices. PUSH@\Preserve the current KERMIT environment and enter the system command processor. TAKE@\Read and execute KERMIT program commands from a local file. LOG@\Specify a log for file transfer transactions, or for terminal session loggin. @End(Description) @Section @label<-emulation> @Begin(Description,leftmargin +8,indent -8) CONNECT@\This verb, valid only for a local Kermit, means to go into terminal emulation mode; present the illusion of being directly connected as a terminal to the remote system. Provide an "escape character" to allow the user to "get back" to the local system. The escape character, when typed, should take a single-@|character argument; the following are suggested: @Begin(Description,leftmargin +8,indent -4,spread 0) 0@\(zero) Transmit a NUL B@\Transmit a BREAK C@\Close the connection, return to local KERMIT command level P@\Push to system command processor Q@\Quit logging (if logging is being done) R@\Resume logging S@\Show status of connection ?@\Show the available arguments to the escape character @i<(a second copy of the escape character)>:@ @ Transmit the escape character itself @End(Description) Lower case equivalents should be accepted. If any invalid argument is typed, issue a beep. @End(Description) Also see the SET command. @Section These commands are used only by Users of Servers. @Begin(Description,leftmargin +8,indent -8) BYE@\This command sends a message to the remote server to log itself out, and upon successful completion, terminate the local Kermit program. FINISH@\This command causes the remote server to shut itself down gracefully without logging out its job, leaving the local KERMIT at KERMIT command level, allowing the user to re-CONNECT to the remote job. @End(Description) @Section Some Kermit implementations include various local file management services and commands to invoke them. For instance, an implementation might have commands to let you get directory listings, delete files, switch disks, and inquire about free disk space without having to exit and restart the program. In addition, remote servers may also provide such services. A user Kermit must be able to distinguish between commands aimed at its own system and those aimed at the remote one. When any confusion is possible, such a command may be prefixed by one of the following "object prefixes": @Begin(Description,leftmargin +8,indent -8) REMOTE@\Ask the remote Kermit server to provide this service. LOCAL@\Perform the service locally. @End(Description) If the "object prefix" is omitted, the command should be executed locally. The services include: @Begin(Description,leftmargin +8,indent -8) LOGIN@\This should be used in its timesharing sense, to create an identity ("job", "session", "access", "account") on the system. LOGOUT@\To terminate a session that was initiated by LOGIN. COPY@\Make a new copy of the specified file with the specified name. CWD@\Change Working Directory. This is ugly, but more natural verbs like CONNECT and ATTACH are too imprecise. CWD is the ARPAnet file transfer standard command to invoke this function. DIRECTORY@\Provide a list of the names, and possibly other attributes, of the files in the current working directory (or the specified directory). DELETE@\Delete the specified files. ERASE@\This could be a synomym for DELETE, since its meaning is clear. @Begin(Quotation) (It doesn't seem wise to include UNDELETE or UNERASE in the standard list; most systems don't support such a function, and users' expectations should not be toyed with...) @End(Quotation) KERMIT@\Send a command to the remote KERMIT server in its own interactive command syntax. RENAME@\Change the name of the specified file. TYPE@\Display the contents of the specified file(s) at the terminal. SPACE@\Tell how much space is used and available for storing files in the current working directory (or the specified directory). SUBMIT@\Submit the specified file(s) for background (batch) processing. PRINT@\Print the specified file(s) on a printer. MOUNT@\Request a mount of the specified tape, disk, or other removable storage medium. WHO@\Show who is logged in (e.g. to a timesharing system), or give information about a specified user or network host. MAIL@\Send electronic mail to the specified user(s). MESSAGE@\Send a terminal message (on a network or timesharing system). HELP@\Give brief information about how to use KERMIT. SET@\Set various parameters relating to debugging, transmission, file mode, and so forth. SHOW@\Display settings of SET parameters, capabilities in force, etc. STATISTICS@\Give information about the performance of the most recent file transfer -- elapsed time, effective baud rate, various counts, etc. HOST@\Pass the given command string to the specified (i.e. remote or local) host for execution in its own command language. LOGGING@\Open or close a remote transaction or debugging log. @End(Description) @section A SET command should be provided to allow the user to tailor a connection to the peculiarities of the communication path, the local or remote file system, etc. Here are some parameters that should be SET-able: @Begin(Description,leftmargin +8,indent -8) BLOCK-CHECK@\Specify the type of block check to be used: single character checksum, two-@|character checksum, 3-@|character CRC. DEBUGGING@\Display or log the packet traffic, packet numbers, and/or program states. Useful for debugging new versions of KERMIT, novel combinations of KERMIT programs, etc. DELAY@\How many seconds a remote (non-server) KERMIT should wait before sending the Send-Init packet, to give the user time to escape back to the local KERMIT and type a RECEIVE command. DUPLEX@\For terminal emulation, specify FULL or HALF duplex echoing. EIGHT-BIT-PREFIXING@\Specify that "8th bit" prefixing must be done; normally it will not be done. END-OF-LINE@\Specify any line terminator that must be used after a packet. ESCAPE@\Specify the escape character for terminal emulation. FILE attributes@\ Almost any of the attributes listed above in the Attributes section (@ref<-attributes>). The most common need is to tell the KERMIT program whether an incoming or outbound file is text or binary. FLOW-CONTROL@\Specify the flow control mechanism for the line, such as XON/XOFF, DTR/CTS, etc. Allow flow control to be turned off as well as on. Flow control is done only on full-@|duplex connections. HANDSHAKE@\Specify any line-@|access negotiation that must be used or simulated during file transfer. For instance, a half duplex system will often need to "turn the line around" after sending a packet, in order to give you permission to reply. A common handshake is XON (@q<^Q>); the current user of the line transmits an XON when done transmitting data. LINE@\Specify the line or device designator for the connection. This is for use in a KERMIT program that can run in either remote or local mode; the default line is the controlling terminal (for remote operation). If an external device is used, local operation is presumed. LOG@\Specify a local file in which to keep a log of the transaction. There may be logs for debugging purposes (packet traffic, state transitions, etc) and for auditing purposes (to record the name and disposition of each file transferred). MARKER@\Change the start-of-packet marker from the default of SOH (CTRL-A) to some other control character, in case one or both systems has problems using CTRL-A for this purpose. PACKET-LENGTH@\The maximum length for a packet. This should normally be no less than 30 or 40, and can never be greater than 96. Short packets can be an advantage on noisy lines; they reduce the probabily of a particular packet being corrupted, as well as the retransmission overhead when corruption does occur. PADDING@\The number of padding characters that should be sent before each packet, and what the padding character should be. Rarely necessary. PARITY@\Specify the parity (ODD, EVEN, MARK, SPACE, NONE) of the physical connection. If other than none, the "8th bit" cannot be used to transmit data and must not be used by either side in block check computation. PAUSE@\How many seconds to pause after receiving a packet before sending the next packet. Normally 0, but when a system communication processor or front end has trouble keeping up with the traffic, a short pause between packets may allow it to recover its wits; hopefully, something under a second will suffice. PREFIX@\Change the default prefix for control characters, 8-bit characters, or repeated quantities. PROMPT@\Change the program's prompt. This is useful when running KERMIT between two systems whose prompt is the same, to eliminate confusion about which KERMIT you are talking to. REPEAT-COUNT-PROCESSING@\Change the default for repeat count processing. Normally, it will be done if both KERMIT programs agree to do it. RETRY@\The maximum number of times to attempt to send or receive a packet before giving up. The normal number is about 5, but the user should be able to adjust it according to the condition of the line, the load on the systems, etc. TIMEOUT@\Specify the length of the timer to set when waiting for a packet to arrive. @End(Description) @Section @index In addition to the individual set commands, a "macro" facility is recommended to allow users to combine the characteristics of specific systems into a single SET option. For example: @begin[example] DEFINE IBM = PARITY ODD, DUPLEX HALF, HANDSHAKE XON DEFINE UNIX = PARITY NONE, DUPLEX FULL DEFINE TELENET = PARITY MARK @end[example] This could be done by providing a fancy runtime parser for commands like this (which could be automatically TAKEn from the user's KERMIT initialization file upon program startup), or simply hardwired into the SET command table. With these definitions in place, the user would simply type "SET IBM", "SET UNIX", and so forth, to set up the program to communication to the remote system. @chapter The local system must be able to act as a terminal so that the user can connect to the remote system, log in, and start up the remote KERMIT. Terminal emulation should be provided by any KERMIT program that runs locally, so that the user need not exit and restart the local KERMIT program in order to switch between terminal and protocol operation. On smaller systems, this is particularly important for various reasons -- restarting the program and typing in all the necessary SET commands is too inconvenient and time-@|consuming; in some micros, switching in and out of terminal emulation may cause carrier to drop, etc. Only bare-bones terminal emulation need be supplied by KERMIT; there is no need to emulate any particular kind of "smart" terminal. Simple "dumb" terminal emulation is sufficient to do the job. Emulation of fancier terminals is nice to have, however, to take advantage of the remote system's editing and display capabilities. In some cases, microcomputer firmware will take care of this. To build emulation for a particular type of terminal into the program, you must interpret and act upon escape sequences as they arrive at the port. No error checking is done during terminal emulation. It is "outside the protocol"; characters go back and forth "bare". In this sense, terminal emulation through KERMIT is no better than actually using a real terminal. Some KERMIT implementations may allow logging of the terminal emulation session to a local file. Such a facility allows "capture" of remote typescripts and files, again with no error checking or correction. When this facility is provided, it is also desirable to have a convenient way of "toggling" the logging on and off. If the local system does not provide system- or firmware-@|level flow control, like XON/XOFF, the terminal emulation program should attempt to simulate it, especially if logging is being done. The terminal emulation facility should be able to handle either remote or local echoing (full or half duplex), any required handshake, and it should be able to transmit any parity required by the remote side or the communication medium. A terminal emulator works by continuously sampling both console input from the local terminal and input from the communication line. Simple input and output functions will not suffice, however, since if you ask for input from a certain device and there is none available, you will generally block until input @i become available, during which time you will be missing input from the other device. Thus you must have a way to bounce back and forth regardless of whether input is available. Several mechanisms are commonly used: @Begin(Itemize) Continuously jump back and forth between the port status register and the console status register, checking the status bits for input available. This is only practical on single-@|user, single-@|process systems, where the CPU has nothing else to do. Issue an ordinary blocking input request for the port, but enable interrupts on console input, or vice versa. Handle port input in one process and console input in another, parallel process. The UNIX KERMIT program listed in this manual uses this method. @End(Itemize) Any input at the port should be displayed immediately on the screen. Any input from the console should be output immediately to the port. In addition, if the connection is half duplex, console input should also be sent immediately to the screen. The terminal emulation code must examine each console character to determine whether it is the "escape character". If so, it should take the next character as a special command, which it executes. These commands are described above, in section @ref<-emulation>. @index The terminal emulator should be able to send every ASCII character, NUL through DEL, and it should also be able to transmit a BREAK signal (BREAK is not a character, but an "escape" from ASCII transmission in which a 0 is put on the line for about a quarter of a second, regardless of the baud rate, with no framing bits). BREAK is important when communicating with various systems, such as IBM mainframes. Finally, it is sometimes necessary to perform certain transformations on the CR character that is normally typed to end a line of input. Some systems use LF, EOT, or other characters for this function. To complicate matters, intervening communications equipment (particularly the public packet-@|switched networks) may have their own independent requirements. Thus if using KERMIT to communicate over, say, TRANSPAC with a system that uses LF for end-@|of-@|line, it may be necessary to transform CR into LFCR (linefeed first -- the CR tells the network to send the packet, which will contain the LF, and the host uses the LF for termination). The user should be provided with a mechanism for specifying this transformation, a command like "SET CR @i". @Chapter @Index Before writing a new implementation of KERMIT or modifying an old one, first be sure to contact the KERMIT Distribution center at Columbia University to make sure that you're not duplicating someone else's effort, and that you have all the latest material to work from. If you do write or significantly modify (or document) a KERMIT program, please send it back to Columbia so that it can be included in the standard KERMIT distribution and others can benifit from it. It is only through this kind of sharing that KERMIT has grown from its modest beginnings to its present scale. The following sections provide some hints on KERMIT programming. @section A basic KERMIT implementation can usually be written as a relatively small program, self-contained in a single source file. However, it is often the case that a program written to run on one system will be adapted to run on other systems as well. In that case, it is best to avoid having totally divergent sources, because when new features are added to (or bugs fixed in) the system-@|independent parts of the program -- i.e. to the protocol itself -- only one implementation will reap the benefits initially, and the other will require painful, error-@|prone "retrofitting" to bring it up to the same level. Thus, if there is any chance that a KERMIT program will run on more than one machine, or under more than one operating system, or support more than one kind of port or modem, etc, it is desirable to isolate the system-@|dependent parts in a way that makes the common parts usable by the various implementations. There are several approaches: @Begin(Enumerate) Runtime support. If possible, the program can inspect the hardware or inquire of the system about relevant parameters, and configure itself dynamically at startup time. This is hardly ever possible. Conditional compilation (or assembly). If the number of systems or options to be supported is small, the system dependent code can be enclosed in conditional compilation brackets (like @q). An example is provided in UNIX KERMIT listing included with this manual. However, as the number of system dependencies to be supported grows, this method becomes unwieldy and error-@|prone -- installing support for system X tends to break the pre-existing support for system Y. Modular composition. When there is a potentially large number of options a program should support, it should be broken up into separate modules (source files), with clearly specified, simple calling conventions. This allows people with new options to provide their own support for them in an easy way, without endangering any existing support. Suggested modules for a KERMIT program are: @Begin(Itemize) System-Indendent protocol handling: state switching, packet formation, encoding (prefixing) and decoding, etc. User Interface: the command parser. Putting this in a separate module allows plug-in of command parsers to suit the user's taste, to mimic the style of the host system command parser or some popular application, etc. Screen i/o: This module would contain the screen control codes, cursor positioning routines, etc. Port i/o: Allows support of various port hardware. This module can define the port status register location, the status bits, and so forth, and can implement the functions to read and write characters at the port. Modem control: This module would support any kind of "intelligent" modem, which is not simply a transparent extension of the communications port. Such modems may accept special commands to perform functions like dialing out, redialing a recent number, hanging up, etc., and may need special initialization (for instance, setting modem signals like DTR). Console input: This module would supply the function to get characters from the console; it would know about the status register locations and bits, interrupt structure, key-to-@|character mappings, etc., and could also implement key redefinitions, keystroke macros, programmable function keys, expanded control and meta functions, etc. Terminal Emulation: This module would interpret escape sequences in the incoming character stream (obtained from the port i/o module) for the particular type of terminal being emulated and interpret them by making appropriate calls the the screen i/o module, and it would send user typein (obtained from the console input module) out the serial port (again using the port i/o module). Ideally, this module could be replacable by other modules to emulate different kinds of terminals (e.g. ANSI, VT52, ADM3A, etc). File i/o: This module contains all the knowledge about the host system's file structure; how to open and close files, perform "get next file" operations, read and write files, determine and set their attributes, detect the end of a file, and so forth, and provides the functions, including buffering, to get a character from a file and put a character to a file. This module may also provide file management services for local files -- directory listings, deleting, renaming, copying, and so forth. Definitions and Data: Separate modules might also be kept for compile-@|time parameter definitions and for global runtime data. @End(Itemize) @End(Enumerate) @section @Index The language to be used in writing a KERMIT program is more than a matter of taste. The primary consideration is that the language provide the necessary functionality and speed. For instance, a microcomputer implementation of BASIC may not allow the kind of low-@|level access to device registers needed to do terminal emulation, or to detect console input during file transfer, or even if it can do these things, it might not be able to run fast enough do drive the communication line at the desired baud rate. The second consideration in choosing a language is portability. This is used in two senses: (1) whether the language is in the public domain (or, equivalently, provided "free" as part of the basic system), and (2) whether it is well standardized and in wide use on a variety of systems. A language that is portable in both senses is to be preferred. Whatever programming language is selected, it is important that all lines in the program source be kept to 80 characters or less (after expansion of tabs). This is because KERMIT material must often be shipped over RJE and other card-@|format communication links. In addition, it is important that the names of all files used in creating and supporting a particular KERMIT implementation be (possibly a subset) of the form @q, where NAME is limited to six characters, and TYPE is limited to three, and where the NAME of each file begin with a common 2 or 3 character prefix. This is so that all related files will be grouped together in an alphabetic directory listing, and so when all of the hundreds of KERMIT related files are placed together on a tape, all names will be both legal and unique, especially on systems (like PDP-11 operating systems) with restrictive file naming conventions. @section A new KERMIT program should be thoroughly documented; one of the hallmarks of KERMIT is its documentation. The documentation should be at both the user level (how to use the program, what the commands are, etc, similar to the documentation presently found in the @i), and the implementation level (describe system dependencies, give pointers for adapting to new systems, and so forth). In addition, programs themselves should contain copious commentary. Like program source, documentation should be kept within 80-@|character lines. If possible, a section for the implementation should be written for the KERMIT User Guide using the UNILOGIC Scribe formatting language (subsets of which are also to be found in some microcomputer text processing software such as Perfect Writer or Final Word), using the same general conventions as the existic Scribe-@|format implementation sections. @index KERMIT programs should also contain a revision history, in which each change is briefly explained, assigned an "edit number", and the programmer and site are identified. The lines or sections comprising the edit should be marked with the corresponding edit number, and the KERMIT program, upon startup, should announce its version and edit numbers, so that when users complain of problems we will know what version of the program is in question. The version number changes when the functionality has been changed sufficiently to require major revisions of user documentation. The edit number should increase (monotonically, irrespective of version number) whenever a change is made to the program. The edit numbers are very important for program management; after shipping out a version of, say, CP/M KERMIT-80, we often receive many copies of it, each containing its own set of changes, which we must reconcile in some manner. Edit numbers help a great deal here. @section @Index Finally, a bootstrap procedure should be provided. KERMIT is generally distributed on magnetic tape to large central sites; the users at those sites need ways of "downloading" the various implementations to their micros and other local systems. A simple bootstrap procedure would consist of precise instructions on how to accomplish an "unguarded" capture of the program. Perhaps a simple, short program can be written for each each end that will do the job; listings and instructions can be provided for the user to type in and run these programs. @appendix @b @begin +------+-----+-----+------+------------+-------+ | MARK | LEN | SEQ | TYPE | DATA | CHECK | +------+-----+-----+------+------------+-------+ @end @b @begin 1 2 3 4 5 6 7 8 9 10... +------+------+------+------+------+------+------+------+------+------- | MAXL | TIME | NPAD | PADC | EOL | QCTL | QBIN | CHKT | REPT | CAPAS +------+------+------+------+------+------+------+------+------+------- @end KERMIT packet types and subtypes; required types are marked with an asterisk (*): @begin Y*@\Acknowledge (ACK) N*@\Negative acknowledge (NAK) S*@\Send initiate (exchange parameters) I@\Initialize (exchange parameters) F*@\File header A@\File attributes D*@\Data packet Z*@\End of file (EOF) B*@\Break transmission (EOT) E*@\Error R@\Receive Initiate (ask the server to send the specified files) C@\Host Command K@\KERMIT Command T@\@i G@\Generic Kermit Command; @i@q<:> @begin I@\Login (or logout) C@\CWD, Change Working Directory L@\Bye F@\Finish D@\Directory U@\Disk Usage Query E@\Erase, Delete T@\Type R@\Rename K@\Copy W@\Who's logged in? M@\Short Message H@\Help Q@\Server Status Query P@\Program Invocation J@\Journal Control V@\Variable Set/Query @end @end @appendix There's no true linear scale along which to rate Kermit implementations. A basic, minimal implementation provides file transfer in both directions, and, for microcomputers (PC's, workstations, other single user systems), terminal emulation. Even within this framework, there can be variations. For instance, can the program send a @i in a single command, or must a command be issued for each file? Can it time out? Here is a list of features that may be present; for any KERMIT implementation, the documentation should show whether these features exist, and how to invoke them. @Begin(Itemize) File groups. Can it send a group of files with a single command, using "wildcard", pattern, or list notation? Can it successfully send or receive a group of files of mixed types? Can it recover from an error on a particular file and go on to the next one? Can it keep a log of the files involved showing the disposition of each? Filenames. Can it take action to avoid overwriting a local file when a new file of the same name arrives? Can it convert filenames to and from legal or "normal form"? File types. Can binary as well as text files be transmitted? 8th-Bit prefixing. Can it send and receive 8-bit data through a 7-bit channel using the prefixing mechanism? Repeat-Count processing. Can it send and receive data with repeated characters replaced by a prefix sequence? Terminal Emulation. Does it have a terminal emulation facility? Does it provide various communication options, such as duplex, parity, and handshake selection? Can it transmit all ASCII characters? Can it transmit BREAK? Can it log the remote session locally, to provide unguarded file capture? Communications Options. Can duplex, parity, handshake, and line terminator be specified for file transfer? Block Check Options. In addition to the basic single-@|character checksum, can the two-@|character checksum and the three-@|character CRC be selected? Basic Server. Can it run in server mode, accepting commands to send or receive files, and to shut itself down? Advanced Server. Can it accept server commands to delete files, provide directory listings, send messages, and forth? Issue Commands to Server. Can it send commands to a server, and handle all possible responses? Host Commands. Can it parse and send remote "host commands"? If it is a server, can it pass these commands to the host system command processor and return the results to the local user Kermit? Interrupt File Transfers. Can it interrupt sending or receiving a file? Can it respond to interrupt requests from the other side? Local File Management Services. Are there commands to get local directory directory listings, delete local files, and so forth? File Attributes. Can it send file attribute information about local files, and can deal with incoming file attribute information? Can alternate dispositions be specified. Can files be archived? Debugging Capability. Can packet traffic be logged, examined, single-@|stepped? @end @Appendix KERMIT doesn't do everything. Here is a short list of things it doesn't do, or could do better. @begin KERMIT cannot be used through IBM 3270 protocol emulators. These are devices that allow asynchronous ASCII terminals or PCs to communicate with IBM mainframes as though they were synchronous full-@|screen displays. The problems include: (a) the protocol converter translates from EBCDIC to ASCII -- that is, it assumes it is receiving EBCDIC when KERMIT is supposed to be sending ASCII -- according to its own translate table, which may vary from site to site, and is not a 1-to-1 mapping in any case; (b) non-@|printing control characters (like SOH) cannot be sent at all; (c) the protocol converter looks for 3270 formatting commands and translates them to escape sequences for the ASCII terminal, possibly modifying packet data; (d) the IBM system automatically pauses at the end of each screenful; (e) the protocol converter thinks it knows what is "on the screen" and may attempt to optimize. In general, one never knows exactly how a particular protocol converter will work, or how it may differ from another one. Still, it may be possible to work around these problems if the Kermits on either end are put into a special "3270 mode", "clear the screen" between each packet, and agree on some special convention for packet delimitation and data translation. Control character prefixing. This can get pretty expensive for binary files or other files that contain lots of control characters. Since most hosts won't choke on every single control character, it might be a good idea for each host to inform the other of what control characters it can receive "bare". On the other hand, this could backfire when the two hosts are connected by a network or device that chokes on control characters that neither of the hosts choke on. For hardwired connections with no unknown factors, however, many control characters could be sent "bare". When long sequences of characters in the control range are being sent, individually prefixing each character is costly. Shift-in/@|shift-out codes might be used more effectively here. Same for long strings of characters with the parity bit on, when 8th-bit prefixing is being done. The cost would be yet another set of prefix characters, and the associated complexity of packet formation and decoding. In some situations, certain printable characters can't get through a communication link. For instance, a network terminal server might reserve "@@" as its attention character. Should the protocol allow some way to encode such characters for translation? A set of user-@|definable escape sequences could be useful here. Ironically, some systems do not fare well with KERMIT's small packet sizes. These are typically big mainframes that expect to communicate with block mode terminals, receiving thousands of characters at a time. Such systems find that KERMIT is simply too expensive to run. Meanwhile, other systems that can run KERMIT with no difficulty find the performance disappointing (the efficiency generally works out somewhere between 50 and 80 percent, i.e. data characters divided by the speed of the the transmission line, in characters per second). These two problems could be solved in either of two ways: allow longer packets, or allow multiple data packets to be sent end to end. @begin Without changing the format or encoding of the packet control fields, it might be possible to have longer packets by reserving packet lengths of 0, 1, 2, 3 to be codes for bigger numbers like 200, 500, 1000, 2000. However, the longer the packet, the greater the probability of corruption, and the longer to retransmit once corrupted. In addition, the adequacy of the single-@|character block check would be much reduced for long packets; long packets should therefore be sent with type 2 or 3 block checks. It would be possible to extend the protocol to allow transmission of data packets while ACKs were still outstanding, and any ACK would be taken as an ACK for the specified packet and all previous ones. A limit on the number of outstanding ACKs could be agreed upon; the maximum size of this "floating window" would have to be less than 64, which is where KERMIT packet numbers wrap around, and the window could not extend over a wraparound or else KERMIT would have no way of knowing whether @i times 64 packets had been skipped. A floating window of 8 and a packet size of 95 would give about the same effect as 700-@|character packets. A NAK would require the sender to back up all the way to the NAK'd packet. A future edition of the Protocol Manual might include a specification for floating windows. @end @end @Appendix @label<-KProg> @Index[Program, Kermit] What follows is a listing of a real production version of KERMIT, written in the C language@foot[Kernighan & Ritchie, @ux: Prentice-@|Hall (1978)]. It is designed to run under various versions of the UNIX operating system. The basic KERMIT functionality is present, but very little in the way of optional features. Only the most rudimentary (UNIX-@|style) command parser is provided. The program illustrates many of the considerations described in this manual, with respect to the protocol, the program design, and so forth. It must be emphasized that this is a bare minimum implementation of Kermit. Anyone writing a new Kermit from scratch is encouraged to look at the source for one of the more advanced implementations as a model (check the @i for a list of KERMIT implementations and their features). Although you may not understand the language it's written in, there should be profuse comments that can be useful. The following program uses decimal notation for numbers, and @q rather than @q for integer-@|to-@|character conversion. @Begin @Include @End @Include @Case(Device,x9700="@Comment @SendEnd(#Index `@begin@end') @Comment")