
This chapter describes how the various UUCP protocols work, anddiscusses some other internal UUCP issues.
This chapter is quite technical. You do not need to understand it, oreven read it, in order to use Taylor UUCP. It is intended for peoplewho are interested in how UUCP code works.
This chapter is also, unfortunately, somewhat out of date, although Ibelieve that is incomplete rather than inaccurate. I post thisinformation to the newsgroups`comp.mail.uucp' and`news.answers' each month; if you want to write code based on thisinformation, please get the most recent copy.
Most of the discussion covers the protocols used by all UUCP packages,not just Taylor UUCP. Any information specific to Taylor UUCP isindicated as such. There are some pointers to the actual functions inthe Taylor UUCP source code, for those who are extremely interested inactual UUCP implementation.
Modern UUCP packages support grades for each command. The gradesgenerally range from`A' (the highest) to`Z' followed by`a' to`z'. Taylor UUCP also supports`0' to`9'before`A'. Some UUCP packages may permit any ASCII character as agrade.
On Unix, these grades are encoded in the name of the command file. Acommand file name generally has the form
C.nnnngssss
wherennnn is the remote system name for which the command isqueued,g is a single character grade, andssss is a fourcharacter sequence number. For example, a command file created for thesystem`airs' at grade`Z' might be named
C.airsZ2551
The remote system name will be truncated to seven characters, to ensurethat the command file name will fit in the 14 character file name limitof the traditional Unix file system. UUCP packages which have no othermeans of distinguishing which command files are intended for whichsystems thus require allsystems they connect to to have namesthat are unique in the first seven characters. Some UUCP packages use avariant of this format which truncates the system name to sixcharacters. HDB uses a different spool directory format, which allowsup to fourteen characters to be used for each system name. The TaylorUUCP spool directory format is configurable. The new Taylor spooldirectory format permits system names to be as long as file names; themaximum length of a file name depends on the particular Unix file systembeing used.
The sequence number in the command file name may be a decimal integer,or it may be a hexadecimal integer, or it may contain any alphanumericcharacter. Different UUCP packages are different.
Taylor UUCP creates command files in the functionzsysdep_spool_commands. The file name is constructed by thefunctionzsfile_name, which knows about all the different typesof spool directories supported by Taylor UUCP. The Taylor UUCP sequencenumber can contain any alphanumeric character; the next sequence numberis determined by the functionfscmd_seq.
I do not know how command grades are handled in non-Unix UUCPpackages.
Modern UUCP packages allow you to restrict file transfer by gradedepending on the time of day. Typically this is done with a line inthe`Systems' (or`L.sys') file like this:
airs Any/Z,Any2305-0855 ...
This allows only grades`Z' and above to be transferred at anytime. Lower grades may only be transferred at night. I believe thatthis grade restriction applies to local commands as well as to remotecommands, but I am not sure. It may only apply if the UUCP packageplaces the call, not if it is called by the remote system. Taylor UUCPcan use thetimegrade andcall-timegrade commands(see sectionWhen to Call) to achieve the same effect (and supports theabove format when reading`Systems' or`L.sys').
This sort of grade restriction is most useful if you know what gradesare being used at the remote site. The default grades used depend onthe UUCP package. Generallyuucp anduux have differentdefaults. A particular grade can be specified with the`-g' optiontouucp oruux. For example, to request execution ofrnews on airs with grade`d', you might use something like
uux -gd - airs!rnews <article
`uunet' queues up mail at grade`Z' and news at grade`d'. The example above would allow mail to be received at anytime, but would only permit news to be transferred at night.
This discussion applies only to Unix. I have no idea how UUCP locksports on other systems.
UUCP creates files to lock serial ports and systems. On most (if notall) systems, these same lock files are also used by cu to coordinateaccess to serial ports. On some systems getty also uses these lockfiles.
The lock file normally contains the process ID of the locking process.This makes it easy to determine whether a lock is still valid. Thealgorithm is to create a temporary file and then link it to the namethat must be locked. If the link fails because a file with that namealready exists, the existing file is read to get the process ID. If theprocess still exists, the lock attempt fails. Otherwise the lock fileis deleted and the locking algorithm is retried.
Older UUCP packages put the lock files in the main UUCP spooldirectory, /usr/spool/uucp. HDB UUCP generally puts the lock files ina directory of their own, usually /usr/spool/locks or /etc/locks.
The original UUCP lock file format encoded the process ID as a four bytebinary number. The order of the bytes was host-dependent. HDB UUCPstores the process ID as a ten byte ASCII decimal number, with atrailing newline. For example, if process 1570 holds a lock file, itwould contain the eleven characters space, space, space, space, space,space, one, five, seven, zero, newline. Some versions of UUCP add asecond line indicating which program created the lock (uucp, cu, orgetty). I have also seen a third type of UUCP lock file which did notcontain the process ID at all.
The name of the lock file is generally "LCK.." followed by the base nameof the device. For example, to lock /dev/ttyd0 the file LCK..ttyd0would be created. There are various exceptions. On SCO Unix, the lockfile name is always forced to lower case even if the device name hasupper case letters. System V Release 4 UUCP forms the lock file nameusing the major and minor device numbers rather than the device name(this is pretty sensible if you think about it).
Taylor UUCP can be configured to use various different types of locking.The actual locking code is in the functionfsdo_lock.
The UUCP protocol is a conversation between two UUCP packages. A UUCPconversation consists of three parts: an initial handshake, a seriesof file transfer requests, and a final handshake.
Before the initial handshake, the caller will usually have logged in thecalled machine and somehow started the UUCP package there. On Unix thisis normally done by setting the shell of the login name used to`uucico'.
All messages in the initial handshake begin with a`^P' (a bytewith the octal value \020) and end with a null byte (\000).
Taylor UUCP implements the initial handshake for the calling machine infdo_call, and for the called machine infaccept_call.
The initial handshake goes as follows. It is begun by the calledmachine.
max-remote-debug (see sectionMiscellaneous sys File Commands).ulimit value of the calling UUCP. The limit isspecified as a base 16 number in C notation (e.g.,`-U0x1000000').This number is the number of 512 byte blocks in the largest file whichthe calling UUCP can create. The called UUCP may not transfer a filelarger than this. Supported by System V Release 4 UUCP. Taylor UUCPunderstands this option, but never generates it.Most UUCP packages will consider each locally supported protocol in turnand select the first one supported by the called UUCP. With someversions of HDB UUCP, this can be modified by giving a list of protocolsafter the device name in the Devices file or the`Systems' file.Taylor UUCP provides theprotocol command which may be usedeither for a system (see sectionProtocol Selection) or a port (see sectionThe Port Configuration File).
After the protocol has been selected and the initial handshake has beencompleted, both sides turn on the selected protocol. For some protocols(notably`g') a further handshake is done at this point.
Each protocol supports a method for sending a command to the remotesystem. This method is used to transmit a series of commands betweenthe two UUCP packages. At all times, one package is the master and theother is the slave. Initially, the calling UUCP is the master.
If a protocol error occurs during the exchange of commands, both sidesmove immediately to the final handshake.
The master will send one of four commands:`S',`R',`X'or`H'.
Any file name referred to below is either an absolute pathname beginningwith`/', a public directory pathname beginning with`~/', apathname relative to a user's home directory beginning with`~user/', or a spool directory file name. File names in thespool directory are not pathnames, but instead are converted topathnames within the spool directory by UUCP. They always begin with`C.' (for a command file created byuucp oruux),`D.' (for a data file created byuucp,uux or by anexecution, or received from another system for an execution), or`X.' (for an execution file created byuux or received fromanother system).
Taylor UUCP chooses which request to send next in the functionfuucp. This is also where Taylor UUCP processes incomingcommands from the remote system.
master:`Sfromtouser -optionstempmodenotifysize'
The`S' and the`-' are literal characters. This is a requestby the master to send a file to the slave. Taylor UUCP handles the`S' request in the file`send.c'.
The slave then responds with an S command response.
If the slave responds with`SY', a file transfer begins. When thefile transfer is complete, the slave sends a`C' command response.Taylor UUCP generates this confirmation infprecfile_confirm andchecks it infpsendfile_confirm.
After the`C' command response has been received (in the`SY'case) or immediately (in an`SN' case) the master will send anothercommand.
master:`Rfromtouser -optionssize'
The`R' and the`-' are literal characters. This is a requestby the master to receive a file from the slave. I do not know how SVR4UUCP implements file transfer restart in this case. Taylor UUCPimplements the`R' request in the file`rec.c'.
The slave then responds with an`R' command response.
If the slave responds with`RY', a file transfer begins. When thefile transfer is complete, the master sends a`C' command. Theslave pretty much ignores this, although it may log it. Taylor UUCPsends this confirmation infprecfile_confirm and checks it infpsendfile_confirm.
After the`C' command response has been sent (in the`RY'case) or immediately (in an`RN' case) the master will send anothercommand.
master:`Xfromtouser -options'
The`X' and the`-' are literal characters. This is a requestby the master to, in essence, executeuucp on the slave. Theslave should execute`uucpfromto'. Taylor UUCPhandles the`X' request in the file`xcmd.c'.
The slave then responds with an X command response.
In either case, the master will then send another command.
master:`H'
This is used by the master to hang up the connection. The slave willrespond with an`H' command response.
After the protocol has been shut down, the final handshake isperformed. This handshake has no real purpose, and some UUCP packagessimply drop the connection rather than do it (in fact, some will dropthe connection immediately after both sides agree to hangup, withouteven closing down the protocol).
That is, the calling UUCP sends six letter O's and the called UUCPreplies with seven letter O's. Some UUCP packages always send six O's.
The`g' protocol is a packet based flow controlled error correctingprotocol that requires an eight bit clear connection. It is theoriginal UUCP protocol, and is supported by all UUCP implementations.Many implementations of it are only able to support small window andpacket sizes, specifically a window size of 3 and a packet size of 64bytes, but the protocol itself can support up to a window size of 7 anda packet size of 4096 bytes. Complaints about the inefficiency of the`g' protocol generally refer to specific implementations, ratherthan the correctly implemented protocol.
The`g' protocol was originally designed for general packet drivers,and thus contains some features that are not used by UUCP, includingan alternate data channel and the ability to renegotiate packet andwindow sizes during the communication session.
The`g' protocol is spoofed by many Telebit modems. When spoofing isin effect, each Telebit modem uses the`g' protocol to communicatewith the attached computer, but the data between the modems is sentusing a Telebit proprietary error correcting protocol. This allowsfor very high throughput over the Telebit connection, which, becauseit is half-duplex, would not normally be able to handle the`g'protocol very well at all.
This discussion of the`g' protocol explains how it works, but doesnot discuss useful error handling techniques. Some discussion of thiscan be found in Jamie E. Hanrahan's paper (see sectionDocumentation References). A detailed examination of the source code would also beprofitable.
The Taylor UUCP code to handle the`g' protocol is in the file`protg.c'. There are a number of functions; the most importantones arefgstart,fgsend_control,fgsenddata, andfgprocess_data.
All`g' protocol communication is done with packets. Each packetbegins with a six byte header. Control packets consist only of theheader. Data packets contain additional data.
The header is as follows:
The control byte in the header is composed of three bit fields, referredto here astt (two bits),xxx (three bits) andyyy(three bits). The complete byte isttxxxyyy, or (tt << 6) +(xxx << 3) +yyy.
Thett field takes on the following values:
l. Let the first byte inthe data field beb1. Ifb1 is less than 128 (if the mostsignificant bit ofb1 is 0), then there arel - b1 validbytes of data in the data field, beginning with the second byte. Ifb1 >= 128, letb2 be the second byte in the data field.Then there arel - ((b1 & 0x7f) + (b2 << 7)) valid bytes of datain the data field, beginning with the third byte. In all caseslbytes of data are sent (and all data bytes participate in the checksumcalculation) but some of the trailing bytes may be dropped by thereceiver. Thexxx andyyy fields are described below.In a data packet (short or not) thexxx field gives the sequencenumber of the packet. Thus sequence numbers can range from 0 to 7,inclusive. Theyyy field gives the sequence number of the lastcorrectly received packet.
Each communication direction uses a window which indicates how manyunacknowledged packets may be transmitted before waiting for anacknowledgement. The window may range from 1 to 7 packets, and may bedifferent in each direction. For example, if the window is 3 and thelast packet acknowledged was packet number 6, packet numbers 7, 0 and 1may be sent but the sender must wait for an acknowledgement beforesending packet number 2. This acknowledgement could come as theyyy field of a data packet or as theyyy field of aRJ orRR control packet (described below).
Each packet must be transmitted in order (the sender may not skipsequence numbers). Each packet must be acknowledged, and each packetmust be acknowledged in order.
In a control packet, thexxx field takes on the following values:
CLOSECLOSEpacket is received, aCLOSE packet should be sent in reply andthe`g' protocol should halt, causing UUCP to enter the finalhandshake.RJ orNAKSRJRR orACKINITCINITBINITATo compute the checksum, call the control byte (the fifth byte in theheader)c.
The checksum of a control packet is simply0xaaaa - c.
The checksum of a data packet is0xaaaa - (check ^ c)(^ denotes exclusive or, as in C), andcheck is theresult of the following routine run on the contents of the data field(every byte in the data field participates in the checksum, even for ashort data packet). Below is the routine used by Taylor UUCP; it is aslightly modified version of a routine which John Gilmore patched fromG.L. Chesson's original paper. Thez argument points to thedata and thec argument indicates how much data there is.
intigchecksum (z, c) register const char *z; register int c;{ register unsigned int ichk1, ichk2; ichk1 = 0xffff; ichk2 = 0; do { register unsigned int b; /* Rotate ichk1 left. */ if ((ichk1 & 0x8000) == 0) ichk1 <<= 1; else { ichk1 <<= 1; ++ichk1; } /* Add the next character to ichk1. */ b = *z++ & 0xff; ichk1 += b; /* Add ichk1 xor the character position in the buffer counting from the back to ichk2. */ ichk2 += ichk1 ^ c; /* If the character was zero, or adding it to ichk1 caused an overflow, xor ichk2 to ichk1. */ if (b == 0 || (ichk1 & 0xffff) < b) ichk1 ^= ichk2; } while (--c > 0); return ichk1 & 0xffff;}When the`g' protocol is started, the calling UUCP sends an INITAcontrol packet with the window size it wishes the called UUCP to use.The called UUCP responds with an INITA packet with the window size itwishes the calling UUCP to use. Pairs of INITB and INITC packets arethen similarly exchanged. When these exchanges are completed, theprotocol is considered to have been started. The window size is senttwice, with both the INITA and the INITC packets.
When a UUCP package transmits a command, it sends one or more datapackets. All the data packets will normally be complete, although someUUCP packages may send the last one as a short packet. The commandstring is sent with a trailing null byte, to let the receiving packageknow when the command is finished. Some UUCP packages require the lastbyte of the last packet sent to be null, even if the command endsearlier in the packet. Some packages may require all the trailing bytesin the last packet to be null, but I have not confirmed this.
When a UUCP package sends a file, it will send a sequence of datapackets. The end of the file is signalled by a short data packetcontaining zero valid bytes (it will normally be preceeded by a shortdata packet containing the last few bytes in the file).
Note that the sequence numbers cover the entire communication session,including both command and file data.
When the protocol is shut down, each UUCP package sends aCLOSEcontrol packet.
The`f' protocol is a seven bit protocol which checksums an entirefile at a time. It only uses the characters between \040 and \176(ASCII space and`~') inclusive as well as the carriage returncharacter. It can be very efficient for transferring text only data,but it is very inefficient at transferring eight bit data (such ascompressed news). It is not flow controlled, and the checksum is fairlyinsecure over large files, so using it over a serial connection requireshandshaking (XON/XOFF can be used) and error correctingmodems. Some people think it should not be used even under thosecircumstances.
I believe the`f' protocol originated in BSD versions of UUCP. It wasoriginally intended for transmission over X.25 PAD links.
The Taylor UUCP code for the`f' protocol is in`protf.c'.
The`f' protocol has no startup or finish protocol. However, bothsides typically sleep for a couple of seconds before starting up,because they switch the terminal intoXON/XOFF mode andwant to allow the changes to settle before beginning transmission.
When a UUCP package transmits a command, it simply sends a stringterminated by a carriage return.
When a UUCP package transmits a file, each byte b of the file istranslated according to the following table:
0 <= b <= 037: 0172, b + 0100 (0100 to 0137) 040 <= b <= 0171: b ( 040 to 0171) 0172 <= b <= 0177: 0173, b - 0100 ( 072 to 077) 0200 <= b <= 0237: 0174, b - 0100 (0100 to 0137) 0240 <= b <= 0371: 0175, b - 0200 ( 040 to 0171) 0372 <= b <= 0377: 0176, b - 0300 ( 072 to 077)
That is, a byte between \040 and \171 inclusive is transmitted as is,and all other bytes are prefixed and modified as shown.
When all the file data is sent, a seven byte sequence is sent: two bytesof \176 followed by four ASCII bytes of the checksum as printed in base16 followed by a carriage return. For example, if the checksum was0x1234, this would be sent: "\176\1761234\r".
The checksum is initialized to 0xffff. For each byte that is sent it ismodified as follows (whereb is the byte before it has beentransformed as described above):
/* Rotate the checksum left. */if ((ichk & 0x8000) == 0) ichk <<= 1;else { ichk <<= 1; ++ichk; }/* Add the next byte into the checksum. */ichk += b;When the receiving UUCP sees the checksum, it compares it against itsown calculated checksum and replies with a single character followedby a carriage return.
The sending UUCP checks the returned character and acts accordingly.
The`t' protocol is intended for TCP links. It does no errorchecking or flow control, and requires an eight bit clear channel.
I believe the`t' protocol originated in BSD versions of UUCP.
The Taylor UUCP code for the`t' protocol is in`prott.c'.
When a UUCP package transmits a command, it first gets the length of thecommand string,c. It then sends ((c / 512) + 1) * 512bytes (the smallest multiple of 512 which can holdc bytes plus anull byte) consisting of the command string itself followed by trailingnull bytes.
When a UUCP package sends a file, it sends it in blocks. Each blockcontains at most 1024 bytes of data. Each block consists of four bytescontaining the amount of data in binary (most significant byte first,the same format as used by the Unix functionhtonl) followed bythat amount of data. The end of the file is signalled by a blockcontaining zero bytes of data.
The`e' protocol is similar to the`t' protocol. It does noflow control or error checking and is intended for use over TCP.
The`e' protocol originated in versions of HDB UUCP.
The Taylor UUCP code for the`e' protocol is in`prote.c'.
When a UUCP package transmits a command, it simply sends the command asan ASCII string terminated by a null byte.
When a UUCP package transmits a file, it sends the complete size of thefile as an ASCII decimal number. The ASCII string is padded out to 20bytes with null bytes (i.e., if the file is 1000 bytes long, it sends`1000\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'). It then sends the entirefile.
I believe that the`x' protocol was intended for use over X.25virtual circuits. It relies on a write of zero bytes being read as zerobytes without stopping communication. I have heard that it does notwork correctly. If someone would care to fill this in more, I would begrateful. Taylor UUCP does not implement the`x' protocol.
This is apparently used for DataKit connections, and relies on a writeof zero bytes being read as zero bytes, much as the`x' protocoldoes. I don't really know anything else about it. Taylor UUCP does notimplement the`d' protocol.
The`G' protocol is apparently simply the`g' protocol, exceptthat it is known to support all possible window and packet sizes. Itwas introduced by SVR4 UUCP; the SVR4 implementation of the`g'protocol is apparently fixed at a packet size of 64 and a window size of7. Taylor UUCP does not recognize the`G' protocol. It doessupport all window and packet sizes for the`g' protocol.
I took a lot of the information from Jamie E. Hanrahan's paper in theFall 1990 DECUS Symposium, and from Managing UUCP and Usenet by TimO'Reilly and Grace Todino (with contributions by several other people).The latter includes most of the former, and is published by O'Reilly &Associates, Inc.
Some information is originally due to a Usenet article by Chuck Wegrzyn.The information on the`g' protocol comes partially from a paper byG.L. Chesson of Bell Laboratories, partially from Jamie E. Hanrahan'spaper, and partially from source code by John Gilmore. The informationon the`f' protocol comes from the source code by Piet Berteema.The information on the`t' protocol comes from the source code byRick Adams. The information on the`e' protocol comes from aUsenet article by Matthias Urlichs.