return to first page linux journal archive
keywordscontents

Setting Up UUCP

Does setting up UUCP scare the hell out of you? No more! Read on.

by Jim Hill

Discovering the Internet in a college environment, I was always very casual about the time I spent on-line. Since I didn't get a direct bill from the university, there was no reason to keep track of it. All that changed when I left the college world and got a commercial Internet service provider (ISP). As I read news and mail on-line, I realized the vast majority of my on-line time was spent not in transferring data, but in moving my eyes back and forth across the screen. From that simple observation began my long, strange journey into UUCP. Despite the fancy hardware and software in use today, UUCP remains an ideal way for those of us in the backwaters of the Internet to be connected. This article is

This article covers the simple setup: one computer, one phone line, one ISP, and calls originating only from the reader's machine. Those with more complicated setups are referred to The Linux Network Administrator's Guide by Olaf Kirch; Vince Skahan's excellent FAQs (see http://www.ssc.com/linux/howto.html) on UUCP, Mail, and News; Managing UUCP and Usenet by Tim O'Reilly and Grace Todino; and a competent psychiatrist.

A Brief History of UUCP

Dating back to the late 70s, UUCP (Unix-to-Unix CoPy) was developed at AT&T Bell Labs to provide them with simple dial-up networking capabilities. As is typical with such software, improvements and enhancements were quickly implemented so that, today, several distinct ``flavors'' of UUCP exist. The most noticeable difference to the user is in the names and locations of the various configuration files UUCP uses. The original style, Version 2, is mostly defunct and is mentioned only for completeness. The HoneyDanBer (HDB) implementation, developed in 1983, uses rather hard-to-understand configuration files, but by virtue of its age, it is in fairly heavy use. Increased flexibility and ease of use are provided by Ian Taylor's Taylor UUCP package. As an added bonus, Taylor UUCP is capable of understanding HDB configuration files. Most, if not all, Linux distributions are released with Taylor UUCP; the current release is v1.06.

Installing UUCP

I run Red Hat Linux, but I prefer to compile my own packages, so installing UUCP was as simple as installing the SRPM file and compiling:

rpm -i uucp-1.06.1-4.src.rpm
To compile, edit the top-level Makefile.in to define your installation directories. Run sh configure to produce the Makefile and the configuration header, config.h. Browse through these files to make sure they say what you expected them to say. Edit the policy.h header file to customize it to your system; this is heavily commented, so the only thing to look out for is the default to HDB-style configuration files. I'd suggest changing these to Taylor format. Type make to build the software, then uuchk to verify your configuration file formats. make install installs the software, and now you're ready to begin configuration.

Configuring UUCP

Taylor UUCP uses a handful of interdependent configuration files which I chose to put in /etc/uucp. The first configuration file, called config, sets the most general properties:

# /etc/uucp/config -- UUCP main
# configuration file

hostname perrin
The hostname is the UUCP name you and your ISP agree upon--mine is perrin. If this entry is absent, UUCP will attempt to obtain it via hostname(), but if your UUCP name and your system name are different, you will be unable to log in to your ISP. Once you have UUCP set up, don't change this arbitrarily, as your ISP will have entries in his config files which correspond to this name. A change will prevent you from accessing his machine. Other parameters in this file can be set to override compiled defaults, but I recommend specifying the defaults in the UUCP Makefile when you compile.

The next required file is sys, which contains information about the systems to which perrin can connect. There will be only one entry in this file, since perrin will be connecting only to my ISP's machine. Its UUCP name, by the way, is sloth. Here's my sys file:

# /etc/uucp/sys - name UUCP neighbors
#  system:  sloth

remote-send ~
remote-receive ~
local-send ~
local-receive ~
command-path /usr/sbin
commands rmail rnews

system   sloth
time     any
phone    123-4567
port     serial1
speed    38400
chat     ogin:  UUCP_LOGIN_NAME \
ssword:  UUCP_LOGIN_PASSWORD
alternate
phone    123-6789
The remote-send, remote-receive, local-send, and local-receive entries specify the directories in which UUCP expects to find the files it will be manipulating. By default, this is /var/spool/uucp for a Taylor UUCP configuration.

The command-path and commands entries specify what programs uuxqt is allowed to execute and where to look for them. I spent two days trying to figure out why my ISP couldn't feed me news articles before noticing I hadn't put rnews in a directory in the command-path, so look out for this item. If you want uuxqt to be able to execute other programs, you must include entries for them. For example, to allow Fred in Pittsburgh to use your expensive color laser printer, add lpr to the list of commands.

The system entry must be the UUCP name of the system you're calling, because HDB and Taylor UUCP check system names. Ask your ISP what his UUCP name is for this entry.

The time entry is used to specify times when connections to sloth are permitted. I don't know about the average Linux user, but when I think of running specific jobs at specific times, my thoughts turn naturally to cron. By specifying any time in the config file, I can initiate a UUCP connection via a crontab entry and not worry about UUCP quibbling over the time of the call.

The phone entry, unsurprisingly, specifies the ISP's phone number. If your ISP has several access numbers, they can be specified with the alternate field. In the above example, if a call to 123-4567 fails for any reason, UUCP will attempt to place a call to 123-6789, with all other configuration data remaining unchanged.

The port entry is not the port to use, but an entry in a file named port which specifies the port to use. For single-modem machines like mine, the port file will contain a single entry, which we'll look at in a moment.

The speed entry is the speed at which the port will be transferring data.

The chat entry contains a brief chat script used for logging in, which should be familiar to anyone who has used SLIP or PPP. The space-separated fields represent messages which are alternately sent and received. In most cases, the only essential data which must be transferred are the login name and password. If you want a more detailed look at the messages sent out by the ISP's machine, check with your ISP.

Now the port file:

#  /etc/uucp/port  -  UUCP ports

port     serial1
type     modem
device   /dev/modem
speed    38400
dialer   generic
The port entry here must correspond to the port entry in config. The type, device, and speed entries let UUCP know the device file and speed to use. UUCP will create a lockfile based on the device name, so you should use the same device your other communication software specifies. This way, you will avoid having one process disrupt another. (If you are running UUCP via cron jobs, it's extremely likely the time to connect will come around at least once while you are already using your modem, such as for web browsing.) The last entry, dialer, specifies an entry in the last configuration file, called dial.

#  /etc/uucp/dial  --  per-dialer info
#  My modem

dialer     generic
chat       "" ATZ OK ATM0DT\T CONNECT
chat-fail  BUSY
chat-fail  ERROR
chat-fail  VOICE
chat-fail  NO\sCARRIER
chat-fail  NO\sANSWER
chat-fail  NO\sDIALTONE
The dialer entry again matches that in port. The chat entry specifies a chat script which initializes the modem and places the actual call. When this entry is read, \T is replaced by the phone entry in sys. The chat-fail entries provide a list of conditions under which the connection fails and the whole process aborts, or tries an alternate phone number if one is provided.

I've had a problem using the phone line for voice conversation--when cron tells the system to call, the modem will dial, producing the touch tones and interrupting my conversation. Only after dialing does it check for any of the chat-fail conditions and abort. If you know of a way to make the call abort as soon as the modem activates and doesn't ``hear'' a dial tone, please let me know. My friends and family are growing tired of my automated machine. [I think checking for dial tone is a configurable option on most modern modems.--Ed.]

Running UUCP

UUCP is actually a suite of programs to do very specific tasks. For example, uucp itself is used for copying files between nodes (the machines connected via UUCP) and uux is used for executing programs on another node. Programs exist for all kinds of maintenance, like logfile-trimming and spool-checking. For my purposes (and the purposes of this article), the most important programs are uucico and uuxqt. uucico actually places the phone call and sets up file transfers, while uuxqt tells the other machine what program needs to be run for proper handling of the files.

The following sequence of events is typical:

Typing uucico -s sloth causes uucico to look up sloth in config. Seeing it should use serial1 to connect to sloth, it looks in port and sees that serial1 is the modem, which is activated by the dialer entry. Peeking at this entry in dial, uucico initializes the modem and calls the number specified in sys. When the CONNECT string is received, it executes the chat script from sys and logs into sloth.

When the login procedure is complete, perrin is in ``master'' mode and sloth is in ``slave'' mode. Files to be uploaded will be in the spool directory /var/spool/uucp/sloth/D./filename. If these files exist, perrin will upload them with instructions for the slave. The instruction files will be in /var/spool/news/uucp/sloth/C./filename. When the transfer is complete, the master and slave exchange roles, with perrin now receiving any files spooled on sloth, as well as execution instructions. When both sides have transferred all the necessary files, the connection is terminated. Logging is done in /var/log/uucp, so take a look in there for an exhaustive roster of an average session's work.

When the connection is broken, the second important UUCP program is fired up: uuxqt. uuxqt looks in the UUCP spool directory for execution requests and (if permitted) executes them. For example, files consisting of mail messages must be delivered and news postings must be moved into the news spool. By default, UUCP permits only two local programs, rmail and rnews, to be executed, which not-so-coincidentally accomplish the tasks just mentioned.

With UUCP configured and tested, it's now time to set up the transfer of mail and news.

Mail via UUCP

For mail transport and delivery, the two most obvious choices are sendmail and smail. I have read that for small sites the two are roughly equivalent in configuration difficulty, but I've also seen O'Reilly's sendmail book. Nothing that massive could possibly be required for my little project. Accordingly, I chose smail. The current release is v3.1.29--while not part of Red Hat's distribution, some kindly soul has made an RPM available in the /pub/contrib directory at ftp.redhat.com.

Installing smail

After looking at a full source tree for smail, I chickened out and grabbed a precompiled rpm from Red Hat's /pub/contrib directory, then installed it:

rpm -i smail-3.1.29.1-6.i386.rpm

Configuring smail

Two links to smail are needed: usr/bin/rmail and /usr/sbin/sendmail. The former is invoked when mail comes in for delivery via UUCP; the latter is often hardcoded into mail user agents, such as elm. To create these links, use the following commands:

ln -s /path_to_smail/smail  /usr/bin/rmail
ln -s /path_to_smail/smail  /usr/sbin/sendmail
Note that rmail, or a link to it, must be placed in the command-path specified in etc/uucp/sys or this will fail. Your ISP might have permission to run rmail, but if he can't find it then he'll get all sorts of error messages in his UUCP logs and might just send you a nasty e-mail message. Of course, if you've already arranged for mail to be sent via UUCP, this will backfire on the ISP, and you will quickly find yourself less than popular. Or so I hear.

The main configuration file for smail is etc/smail/config. For a site which will be doing all its mailing through a UUCP link, this is a remarkably simple file, especially since the smail package comes with very nice sample files in etc/smail/config.linux. Of the four files smail will use, I had to modify only config for my particular setup:

#  /etc/smail/config

smart_path=sloth
smart_transport=uux
visible_name=swcp.com
uucp_name=perrin.swcp.com
The smart_path entry is the UUCP name of your ISP's machine. This will match the system name in /etc/uucp/sys. Any non-local mail address will be shipped off to this machine for DNS resolution and delivery. Specifying uux as the transport agent will cause any outgoing mail messages to be queued in the UUCP spool to await the next UUCP connection. I will return to this when I discuss the other configuration files for smail.

The visible_name entry identifies your smail domain. If you have registered your UUCP name, append :uucp to this entry. In many cases, this is unnecessary. Using my system as an example, the .swcp.com portion is guaranteed by the InterNIC (and my ISP's hard-earned dollars) to be unique. Therefore, the only machines which could have already taken perrin would be connected to my ISP, who would notify me of a conflict.

The uucp_name entry is (surprise) your system's UUCP name. By default, smail will generate return paths from the hostname command, in my case perrin. Since I have not registered perrin, someone else might. Without this entry, any mail returned to perrin will go to that other machine. By specifying a fully qualified domain name, I am guaranteed (because of the way DNS and UUCP addressing are resolved) the message will go first to swcp.com, which will recognize perrin as my UUCP account. For a machine named ``perrin'', this is a negligible concern, but a more common name, e.g., ``darkstar'', might cause problems.

Running smail

For the stand-alone system under discussion, smail is best run as a daemon all by itself. Make sure this entry appears in etc/services:

smtp 25/tcp #Simple Mail Transfer Protocol
This will specify port 25 for SMTP connections, which the mail transport agent (MTA) will use for delivery.

Run smail as a daemon by having a system startup script run the following:

/path_to_smail/smail -bd -q10m
The -bd option causes smail to run as a daemon; -q10m tells it to process the message queue every 10 minutes. If you do light mailing (or do a lot during a solid block of time), consider increasing this, perhaps to two hours or more with a command line option like -q2h. When a connection to the SMTP port is detected (such as when UUCP hands off the latest batch of local mail), smail will fork and handle the SMTP connection.

When smail gets a wake-up call from a mailer (like rmail, for incoming UUCP deliveries, or elm, for outgoing messages), it looks in the file /etc/smail/routers to see what to do with the message. Here's my file:

# /etc/smail/routers

smart_host:
driver=smarthost,#What do I do with nonlocal mail?
transport=uux; # Deliver it via UUCP-path
               # to the machine specified with the
               # smart_path option in ./config
Upon receiving a message intended for a non-local address, smail checks this file. It sees it is to use the smart_host, which is defined in /etc/smail/config as sloth, the ISP's machine. The message is to be forwarded to sloth using the transport option, which is set to uux. uux is another program in the UUCP suite that queues the message with instructions to run mail in the UUCP spool to await the next UUCP connection.

Local mail is handled partially by an entry in the /etc/smail/directors file. The purpose of the directors file is to tell smail about some of the special options available locally, such as aliasing, forwarding to another user or to a pipe, or just about anything else you could set up. (Mailing lists on a two-user machine, anyone?) I've cut all but the entries which handle .forward files and the generic ``What to do if we have a user who just wants his mail spooled?'' scenario. Read the /etc/smail/config.linux/directors file for full gory detail:

# /etc/smail/directors

dotforward:
# general-purpose forwarding director
driver = forwardfile,	
# problems go to the site mail admin
owner = Postmaster,
nobody,
# sender never removed from expansion
sender_okay;
# .forward file in home directories
file = ~/.forward,
# the user can own this file
checkowner,	
# or root can own the file
owners = root,	
# it should not be globally writable
modemask = 002,		
# don't run things as root or daemon
caution = daemon:root,		
# be extra careful of remotely accessible home
# directories
unsecure = "~uucp:~nuucp:/tmp:/usr/tmp"
# user - match users on the local host with
# delivery to their mailboxes
user:
# driver to match usernames
driver = user;
# local transport goes to mailboxes
transport = local
Once a delivery option is matched in directors, the transports file is searched to see what, if any, special options that particular delivery mode requires. For the trimmed directors file above, the corresponding transports file would be:

# /etc/smail/transports

# append message to a file
local:	driver=appendfile,	
# include a Return-Path: field
return_path,		
# supply a From_ envelope line
from,			
# insert > before From in body
unix_from_hack,	
# comment out the above line for
# MMDF mailbox format and for
# use with the Content-Length
# header fields.
# use local forms for delivery
local;				
# location of mailbox files
file=/var/spool/mail/${lc:user},
# group to own file for System V
group=mail,			
# For BSD: only the user can
# read and write file
mode=0600,			
# append an extra newline
suffix="\n",			
# notify comsat daemon of delivery
notify_comsat,
Note that there is no transport for the forwarding option. This is compiled into smail to send the message on to the forwarding address, with a few extra headers. Forwarding to a non-local address would send the message off to the UUCP queue for the next phone call.

Using UUCP to Transfer Files

Now that you've set up smail to wait for UUCP to deliver mail from the outside world and to send mail to UUCP for transfer from your machine, you need to tell UUCP when to transfer files. This is most easily done via a crontab entry. Create it by typing su uucp, then typing crontab -e. The resulting file should look something like this:

# Call for transfers
25 0,9,11,13,15,17,18-23 * * * \
/usr/sbin/uucico -s sloth

# Trim logfile
35 03 * * * find /var/log/uucp \
-size +16k -exec cp /dev/null {} \;
The first line calls sloth every few hours during the day and hourly through prime time. Every afternoon it trims UUCP's logfile, which can grow spectacularly with frequent transfers.

News via UUCP

Setting up mail didn't take much time, and I was feeling pretty smug when I got my first e-mail from ``the outside''. Humility came back with a vengeance when I turned my attention to setting up news.

News Transport Agents

Like mail, a variety of software packages are available for getting news on and off a local machine. Again like mail, the best known is big and intimidating. Unlike mail, the lesser known is also big and intimidating. The ``big boy'' in news transport is InterNet News (INN). A close second is the C News package. I took a look at the documentation available for these two packages before deciding which to try. INN runs as a daemon and can be a disk and memory hog. While it can be configured to operate in a situation such as mine, it really is intended to be run on dedicated news servers with high-speed connections and many users. C News is a collection of binaries and scripts that are executed by cron and consumes minimal disk resources. While there's more documentation available for INN, I decided that C News was the way to go. Besides, I just wouldn't feel right as a Linux user if I could just follow directions and have a working system.

Installing and Configuring C News

C News is sufficiently system-dependent that compiling from a source distribution is the only logical thing to do. The current release of C News can be found at ftp.cs.toronto.edu in /pub/c-news/c-news.tar.Z. After uncompressing and extracting the source tree, take a moment to read through the files in the docs/ subdirectory; there's some interesting material in there.

To configure C News for your system, follow the instructions in the file README.install. Before getting started, edit the file conf/update.ran. It lacks an initial line of #!/bin/sh and will cause the Makefile to exit with an error. After reading through the documentation, begin installing.

  1. Run ``quiz''. This brief interactive script sets up the defaults for C News based on your answers. In most circumstances, either the default is fine or you will have an intuitive grasp of a preferred alternative (such as deciding to store articles in /var/spool/news instead of /usr/spool/news). However, there are a few things to look out for:
  2. Run make to build the software, then make r to run some regression tests to check out the build.
  3. Create the directories you specified in quiz for the article tree, the overview tree, the binaries, and the control programs. C News calls these NEWSARTS, NEWSOV, NEWSBIN and NEWSCTL, respectively. I put the articles and the overviews in /var/spool/news, the binaries in /usr/lib/news, and the control programs in etc/news. The ownership of /NEWSBIN is largely arbitrary, but the other three should be owned by the /news administrator. I made that user news, group news. If you don't have a news user, create one with adduser or whatever tool you prefer. Some newsreaders look for news in usr/spool/news, so you might need to create a symbolic link in /usr/spool to your NEWSARTS directory.
  4. Use su to log in as the news owner and run make install. You might have a permissions problem trying to write the binaries to NEWSBIN. I got around that by switching virtual consoles, giving everyone write permission to that directory, running make install as news, then restoring the original restrictive permissions. Run make setup next as news.
  5. As the owner of NEWSBIN, run make ui.
  6. C News comes with a news reader, poster and checker which can be best described as functional. You will not want to use these beyond testing your setup, but it's worth installing them for that purpose. Do this by running make readpostcheck.
  7. Make sure NEWSBIN/input/newsspool is owned by news and in the news group. Change its permissions to rwsr-sr-x.
  8. As news, change directories to NEWSCTL and configure the important control files for your particular setup:
  9. Return to the C News source directory and make cmp to see that everything is correctly installed and configured. You'll undoubtedly want to pause briefly, get up from your computer, and do a little dance when you see the message ``no worrisome differences'', for the end is near.
  10. Time to automate! As news, create/edit a crontab with crontab -e. The entries here will set up a schedule of housekeeping tasks and transfers. Here's mine:
    #/var/spool/cron/news
    09  * * * *	/usr/lib/news/input/newsrun
    22  * * * *	/usr/lib/news/batch/sendbatches
    59  0 * * *	/usr/lib/news/expire/doexpire
    17  8 * * *	/usr/lib/news/maint/newsdaily
    05  * * * *     /usr/lib/news/maint/newswatch
    3000 300 100
    
    At 9 minutes past the hour, newsrun takes the batched articles delivered by UUCP, unpacks them, and stores them into the news spool.

    At 22 minutes past every hour, sendbatches takes the outgoing articles, batches and compresses them, and delivers them to the UUCP spool for uploading. These files will be transferred whenever the next UUCP connection takes place, so su to uucp and edit the crontab, as you did with mail.

    At 12:59 AM, doexpire takes care of expiring old articles.

    Every morning at 8:17, newsdaily tidies up some of the various log files and sends mail to the news admin if something is amiss.

    At 5 minutes past the hour, newswatch takes a look at the system to see if there are any problems. Stale locks, full disks, and the like are reported to the newsadmin.

  11. You need to have newsboot run at system bootup to clean up any messes left over after a potential crash. To preserve permissions, it needs to be run as user news. I tacked the line:

    su news -c "/usr/lib/news/maint/newsboot"
    
    onto the end of my rc.sysinit file.

  12. Installing the man pages. Due to wild system variations, your best bet is just to change into the C News doc/ directory and copy them manually into your man page subdirectories.
  13. Create a local test group by:

    cnewsdo addgroup my-site.test y
    
    and post to it. If you made readpostcheck you can do this with the postnews package. Look in NEWSARTS/in.coming and you should see the article, with header information thoughtfully provided by postnews. Leave the computer room and share some time with your family until after newsrun executes again. Now, your article should have appeared in NEWSARTS/my-site/test and should also have entries in the history and log files in NEWSCTL. If you installed readpostcheck, use readnews -n my-site.test and you should see your message. Pat yourself on the back; you've got yourself a Netnews site.
  14. Stop patting yourself on the back. Unless you plan to spend your time sending messages to my-site.test and reading them a bit later, you'll want newsgroups from the Outer World. The installation directions that come with C News cover this step with ``Get a feed from somebody, somehow.'' That's best handled by sending your ISP a list of newsgroups you want to receive and asking for e-mail when it's set up.
  15. As news, edit the files NEWSBIN/active and NEWSBIN/newsgroups. They should both have permission modes 644.
  16. Final Step: do include a local test group in your feed--your ISP probably has one. Post a message to it, wait for batching and UUCP to do their things, then see if it shows up. If so, post a test message to one of the ``real'' newsgroups. Disguise the fact that it's a test message by making it relevant and on topic. If it shows up, you're in business. Sit back, relax, have a Coke and smile.

Jim Hill is a graduate assistant at Los Alamos National Lab who has been playing with Linux since somewhere in the .99 kernel series. Armed with total ignorance of the topic of this article, he set out to learn a little something and maybe help somebody else. Thanks to Mark Costlow at Southwest Cyberport (cheeks@swcp.com), without whose help and patience this article would have read ``It doesn't work; it can't be done.''