Cover V02, I03
Figure 1
Figure 2
Figure 3
Figure 4
Listing 1
Sidebar 1
Table 1


Configuring UUCP: Version 2

Chris Hare

This article discusses issues involved in configuring Version 2 UUCP. Although this version has been largely superseded by BNU (Basic Networking Utilities, also known as HoneyDanBer, or HDB) UUCP, it is still found on some older versions of UNIX.

I should point out that I've written this article using experience, personal notes, and the relevant documentation for reference, as I no longer have access to a system which runs Version 2 UUCP. Also, I refer occasionally to the article "UUCP: Administering BNU" in the March/April 1993 issue of Sys Admin.

What Is Version 2 UUCP?

Version 2 UUCP was the first commercial release of UUCP included in UNIX. To find out which UUCP release you have, look in /usr/lib/uucp. If you find a file called L.sys, then you have Version 2 and this article is for you. If you find Systems, then you'll want to refer to "UUCP: Administering BNU."

This discussion assumes the presence of two machines connected through a working modem or serial connection.

File Layout

Version 2 UUCP's directory structure is similar to that of HDB UUCP, with most of the differences occurring at the file level. Figure 1 shows the file layout, while Figure 2 lists the files and gives a brief description of the files' contents.

Naming Your Host

If your system consists only of a UUCP connection between a couple of machines, the names of the machines are of interest only to the system administrators involved. However, if you plan to join Usenet, you should contact the system administrator of your Usenet feed so that you can find out if your chosen system name has already been used. (For more information on naming the host, see the March/April issue of Sys Admin.)

Configuring UUCP

To use Version 2 UUCP (hereafter referred to as V2), you must configure the following files to allow for a minimal UUCP network, i.e., one that allows you to initiate a call to a remote system using either cu, or uucico.


The L-devices File

The L-devices file contains descriptions for the devices V2 uses to make connections to remote systems. An L-devices entry look like this:

type	device	call-unit	speed
ACU	tty000	-		1200

The type field consists the type of link typically used for this device. ACU (automatic call unit or modem) and DIR (direct) are usually the only types supported, but other types may be supported, depending upon the operating system version. For example, BSD UNIX supports types like TCP (TCP/IP) and PAD (X.25). Such cases are rare, however, as very few implementations of V2 support device types other than ACU and DIR. Multiple entries of the same type may be listed in the file.

The device field holds the name of the physical device used to establish the link.

The call-unit field is used only on systems with a Bell 801 dialer and separate modem. In this case, you would enter the device for the data line in the device field and enter the name of the device as the dialer. Because dialers are not commonly used now, having been replaced with the "smart" modem, the hyphen serves as a place holder.

The speed field contains the connect speed for this device.

Testing the Connection

At this point in the configuration, it's a good idea to evaluate the continuity of the connection between your systems. To do this, use the cu command (located in /bin in V2). The syntax is as follows:

cu -l tty01

(substitute the appropriate device name in the command line). If you get a connected message, then you can attempt to log in to the remote system. If, on the other hand, you get an error message such as "NO DEVICE AVAILABLE," or "REQUESTED DEVICE NAME UNKOWN," then you must reconfigure the L-devices file. Figure 3 shows a sample cu connection.

The L.sys File

The L.sys file is essentially the same as the Systems file in HDB UUCP. The format of each entry in the file is

system	schedule  device  speed
phone  chat-script

as in

xray	Wk0800-1700  ACU  1200  5551234
ogin: anon

The system field identifies the system this entry is used to contact. Values entered in this field must be unique to seven characters.

schedule defines calling times for the remote system, by means of a series of times and related keywords. This field can be used to control calling costs if the link is expensive. For example, the contents of this field may include:

Start-end -- The starting hour and the ending hour using the 24-hour clock (0800 being 8:00 A.M., and 2000 being 8:00 P.M.).

Any -- No limit on calling.

Never -- No calling permitted.

Wk -- Calling restricted to weekdays (Monday through Friday).

Mo,Tu,We,Th,Fr,Sa,Su -- Calling allowed on specific days of the week.

You can combine these components to build a very restrictive definition. For example, to allow calling only between 8:00 A.M. and 11:00 A.M. on Saturday and Sunday, then the appropriate entry would be:


An optional retry subfield can be included after the schedule field by adding a comma and a time period in seconds. uucico doesn't restart automatically after this time elapses; instead, this is the delay period used after an unsuccessful call.

As noted earlier, the device type in V2 is restricted to one of the device types allowed in L-devices: ACU or DIR. When a call is made to the remote system, the device entry is checked against device entries in the L-devices file. If there are multiple entries for a device, the first available device is used.

The speed field contains the baud rate to be used when calling the remote system. A corresponding entry for this speed must exist in the L-devices file.

The phone number field holds the number to be dialed when calling the remote system. If this entry is for a direct link to a remote system, this field contains a hyphen.

The balance of the entry consists of the chat script, which is used to negotiate the login to the remote system. The script consists of a series of expect-send sequences that define the login sequence required for access to the remote computer. The expect-send pairs are separated by spaces; optional subexpect-subsend pairs, by hyphens.

Consider the following example:

login:-BREAK-login: nuucp word: loginAok

In this example, uucico expects the remote system to print login:. If this doesn't occur within a predefined period of time, the local system sends a BREAK signal and expects login:. The BREAK signal is a modem break, which may wake up a getty running on the remote system, or cause that getty to switch to another speed. Once login: appears, the local system sends nuucp, and waits for the word: string. When word: appears, the system sends loginAok, which is the system password. When the script succeeds, the local system has logged into the remote system.

The subexpect-subsend pairs, such as

login: nuucp word: loginAok

enable the local system to log in if the remote system answers at a different speed from that used by the local modem. For example, if the local system is calling at 1200 baud and the remote system answers at 2400 baud, it would be necessary to send a BREAK twice, assuming that the related gettydefs entry says "go from 2400->300->1200." Therefore, the chat script would look like

login:-BREAK-login:-BREAK-login: nuucp word: loginAok

The difference to note between the primary expect-send and the subexpect-subsend is that the subexepect-subsend will be used only if the expect string is not received.

uucico stops looking at the incoming characters once a match is found for the expect text. However, it is commonplace to use the last text expected to ensure that the send sequence isn't sent to the remote system too soon.

Testing the Connection with uucico

Once the L-devices and L.sys files have been configured, use the debug option on uucico to test communications.

uucico works essentially the same way for both Version 2 and HDB. Once the call is initiated, uucico keeps track of the process by creating a status file for the machine in the /usr/spool/uucp directory. The status file -- called STST. followed by the name of the machine -- contains the details of the last connection. If the status file is present when the remote system calls in, the remote is notified that there is a LOCK file and the connection is dropped. If the status file is there when the local system tries to call out, the call is blocked, and a message is logged noting that a status file has prevented the call. The contents of a status file are shown in Figure 4.

The status part of the entry typically explains the error code.

With a status file present, other jobs queued for the affected system can't make a call until the retry time period has expired. To circumvent this, you can remove the status file.

Version 2 Permissions

In HDB UUCP one file essentially controls access to commands and to files on your system. With V2, there are as many as five files, with three being the typical configuration. These files are USERFILE, L.cmds, SQFILE.


USERFILE controls access to the files on your system for both remote and local users. A variety of sources recommend strongly that for each entry in your /etc/passwd file, you create an entry in your USERFILE. Listing 1(a) shows a Bourne shell script to accomplish this, while Listing 1(b) shows the output of the script. Like the entries in the HDB Permissions files, each USERFILE entry defines a number of constraints for file transfer, including:

  • which files on the system can be accessed for UUCP by a local user. Both USERFILE and UNIX file permissions must be satisfied for the request to succeed.

  • which files can be accessed by a remote system.

  • the login name the remote system must use when calling in.

  • callback configuration (the local machine calls the remote back to confirm the remote's identity).

    Not all constraints must be configured, but the fewer implemented, the greater the risk of a security violation.

    USERFILE entries consist of

    username,system [c] pathname(s)

    such as

    uu101,thumper /usr/spool/uucppublic /usr/tmp
    uu102,bugs c /u/tmp

    The username (uu101, uu102) defines the name which must be used to log in to the local system. This name must be configured in the /etc.passwd file, using a shell of /usr/lib/uucp/uucico.

    system defines the name of the remote system.

    The callback flag, shown as a single c with spaces on either side, is similar to the CALLBACK option in HDB UUCP. If c appears after the system name, the local system must respond to a call from the remote system by hanging up the phone and calling the remote system back. This allows the local system to validate the identity of the remote system.

    The pathname component is a space-delimited absolute-pathname list of the directories accessible by the remote machine.

    Unfortunately for the system administrator, USERFILE is a complicated beast, capable of causing many long nights in the office (I know -- I've been there). A further complication is that the same entry may behave a little differently on different systems. Again unfortunately, the only symptom of the problem is a loss of security, which usually isn't visible until you've already lost data on your system!

    The following are aspects of UUCP's use of the USERFILE

  • when uucp and uux are run by users or when uucico runs in Master mode, only the username portion of the USERFILE entry is used.

  • when uucico runs in Slave mode, only the systemname section of the entry is used (in the course of any conversation, uucico can switch between Slave and Master any number of times).

  • in any USERFILE for systems other than BSD 4.2, and BSD 4.3, there must be one entry that doesn't have a system name, and one entry that doesn't have a username. In BSD 4.2 and 4.3, these entries can be one and the same. The empty system name entry is used when uucico is in Slave mode and has already searched the USERFILE and cannot find a matching entry. The empty username entry is used by uucp, uux, uuxqt, and uucico when in Master mode, in the case where there is no matching username in /etc/passwd.

    The exact operation and use of USERFILE differs between versions of UUCP, so you must examine carefully the documentation shipped with your operating system.

    Special USERFILE Entries

    If no username is specified in the entry, as in

    ,xray	/

    any user on the system may request outbound transfer of any file on your system. If you prefer not to use an entry like this, then you must create an entry for every user on your system.

    To allow uuxqt file access while uucico is in Slave mode, USERFILE must include an entry which has no system name, as in

    nuucp,       /usr/spool/uucppublic

    This entry is used even when uuxqt is started on your local system! Based on what I've said thus far, you might expect that this entry would mean that any system logging in with a username of nuucp will have access to /usr/spool/uucppublic. In fact, this isn't exactly true, because only the system name is used to validate file transfers requests when the local uucico is in Slave mode.

    You can also grant individual users special access permissions for certain systems. You can then combine the system name and username entry in the USERFILE file, but you should also have the remote system call in with its own login name and password, as, for example,

    uu101,thumper /usr/spool/uucppublic/ /usr/tmp /u/src

    It is not uncommon to see entries that look like this:

    nuucp,			/usr/spool/uucppublic
    nuucp,thumper	/usr/spool/uucppublic
    nuucp,bugs		/usr/spool/uucppublic

    With this arrangement, however, there is nothing to prevent someone from changing the name of their remote system and then calling yours. This problem arises because uucico doesn't use the login name when in Slave mode. The best way to limit this possibility is to set up individual UUCP login names for each of the systems that will be calling you.

    The L.cmds File

    The next component in the issue of security is remote commnd execution, which is defined in the file L.cmds. Typically, the administrator restricts the commands that can be run by a remote system. If the command in question is not listed in the L.cmds file, then execution of it via uux is denied. Usually, L.cmds contains only one command: rmail.

    The L.cmds on my system contains the following entries:


    which indicate that both the rmail and uucico commands may be executed by uux. Be careful about which commands you add to this file. Even some seemingly innocuous commands, like cat, can be dangerous to your system.


    Finally, there is SQFILE, which is used to keep track of the conversations that have taken place between your machines. This is an optional file, so if you want to use conversation counts, you must create it in /usr/lib/uucp. SQFILE must be owned by uucp, and must have a file mode of 400. SQFILE must contain an entry for each file for which you want conversations checked. The remote system must also be configured to use SQFILE.

    Once the file is created, edit it to include the names of the files you want to monitor, one system per line. After the first call, uucico adds the the number of conversations, and the date and time of the last contact.

    When one system calls the other, uucico compares the SQFILE information on the two systems; if they don't agree, then the login fails. The log files on the calling system contain a message indicating that there is a SEQ number problem. To correct this, the two system administrators must edit the files manually.

    Log Files

    The log files for V2 are quite different from those of HDB. Unlike HDB, V2 places all of the log entries in a single file, named LOGFILE, in /usr/spool/uucp. A second file, called SYSLOG, records the actual amount of data transferred and the time it took to do it. LOGFILE will grow continously, so if you are running short of disk space, this is the first place you should look.

    An entry from LOGFILE looks like

    user system		date/time 		comment
    root unilabs		(2/12-5:42)		NO (AVAILABLE DEVICE)
    root unilabs		(2/12-5:42) 		FAILED (call to unilabs)
    root unilabs		(2/12-5:59) 		QUEUED (C.unilabsn0297)
    root unilabs		(2/12-5:59) 		QUEUED (C.unilabsn0298)
    root unilabs		(2/12-5:59) 		SUCCEEDED (call to unilabs)
    root unilabs		(2/12-5:59) 		HANDSHAKE FAILED (LOGIN)
    unilabs unilabs 	(2/12-18:35) 		OK (startup)

    The next few entries show that the files /tmp/spool and /tmp/sys were S (sent) to unilabs:

    root unilabs (2/12-18:35) REQUEST (S /tmp/spool ~ root)
    root unilabs (2/12-18:35) REQUEST (SUCCEEDED)
    root unilabs (2/12-18:35) REQUEST (S /tmp/sys ~ root)
    root unilabs (2/12-18:35) REQUEST (SUCCEEDED)
    root unilabs (2/12-18:35) OK (conversation complete)

    These log entries don't contain the same information as those in HDB, but the second log file, SYSLOG, provides the remaining information. SYSLOG contains information about the actual transfer. The first examples here show that this machine received the data from the remote machine, unilabs.

    user	system	 date/time	secs         comments
    chare 	unilabs  (11/21-22:56)	(722404580)  received data \ 148 bytes 2 secs
    chare 	unilabs  (11/21-22:56)	(722404593)  received data \ 1197 bytes 6 secs
    chare 	unilabs	 (11/21-22:56)	(722404601)  received data \  148 bytes 1 secs

    The next entries relate to the two files shown as transfered in the LOGFILE: /tmp/sys, and /tmp/spool. These two files were sent from bugs to unilabs.

    root unilabs (2/12-18:35) (729560123) sent data 97
    bytes 0 secs
    root unilabs (2/12-18:35) (729560125) sent data 115
    bytes 0 secs


    Maintenance for Version 2 is simplified somewhat through the use of the uuclean command, which operates quite similarly to HDB's.

    uuclean is used to clean up the UUCP spool directory (/usr/spool/uucp, typically) in a somewhat intelligent way. For systems that cannot be reached, uuclean sends a mail message back to the originator, deletes locally created rnews files, executes remotely created rnews files, and removes everything which shouldn't be there.

    The main additional maintenance required is to periodically remove the logfiles, so that they won't consume your available disk space with redundant UUCP log information.


    V2 UUCP is no longer in wide use, as it has been superseded by the more easily configured, maintained, and modified HDB UUCP. If you do use it, however, be sure to refer to your system documentation, as each vendor does things a bit differently. In addition, I strongly recommend that you add one or more books (such as those listed below) on the configuration and administration of UUCP.


    For more reading on UUCP, I suggest the following books, some of which were used as references for this series.

    Todino, Grace. Using UUCP and USENET. Sebastopol, CA: O'Reilly and Associates, 1989.

    Todino, Grace, and Tim O'Reilly. Managing UUCP and USENET. Sebastopol, CA: O'Reilly and Associates, 1989.

    Anderson, Costales, Henderson. UNIX Communications. Corte Madera, CA: The Waite Group, 1988.

    Thomas, Rebecca, and Rik Farrow. UNIX Administration Guide for System V. Englewood Cliffs, NJ: Prentice-Hall, 1989.

    Farrow, Rik. UNIX System Security. Reading, MA: Addison-Wesley, 1991.

    About the Author

    Chris Hare is Ottawa Technical Services Manager for Choreo Systems, Inc. He has worked in the UNIX environment since 1986 and in 1988 became one of the first SCO authorized instructors in Canada. He teaches UNIX introductory, system administration, and programming classes. His current focus is on networking, Perl, and X. Chris can be reached at, or, which is his home.