Cover V04, I02
Listing 1
Listing 2
Listing 3
Listing 4
Sidebar 1
Table 1


Printing: BSD or System V?

John Lees

Everyone wants to print. Predictions of the paperless office aside, generating paper seems to be the primary use of computers.

On today's UNIX systems you may well have a choice between using the System V spooling system (lp and lpsched) and the BSD spooling system (lpr and lpd). System V derivatives such as Sun Solaris 2 and Hewlett-Packard HP-UX come with the System V spooler. Apple A/UX comes with both spoolers. Linux and OSF/1 have the BSD spooler. Most flavors of UNIX offer both the BSD and System V user commands, regardless of the underlying spooler.

If your system comes with only the System V spooler, you still have the option of installing the BSD spooler. Source code for the BSD spooler is readily available -- for example, in the BSD4.4-Lite source distribution. If you converted from SunOS 4.1 to Solaris 2, the binaries from the former run just fine under the latter (see the sidebar, "Using the SunOS 4.1.2 Spooler under Solaris 2.3").

The Spooler System

A spooler consists of three main parts: the commands used by normal users and by system administrators during normal spooler operation; the commands and procedures used by system administrators to install the spooler and configure printers; and the spooler guts (daemon, spool queues, configuration files).

The User Interface

The user needs to spool the job, check on its status, and perhaps cancel the job. System administrators need to be able to start and stop the spooling system, cancel jobs, and perhaps reroute already spooled jobs to a different printer. Table 1 shows the commands for these tasks in the two systems. As the table shows, both systems have much the same capability. Shell scripts are often written to translate the options so that both sets of commands are available, because some programs have lp or lpr hardwired into them.

The lp and lpr commands both have many anachronistic options for doing things like setting margins or selecting the print wheel and forms to be used. Today such functions are usually done in the PostScript files sent to the printer. For that matter, printing is often done by clicking an icon in total ignorance of the underlying UNIX commands.

Spooler Administration

At the system administration level, the System V spooler has more commands, more separate configuration files, and is basically a more complex system. The BSD spooler, on the other hand, depends on the arcane syntax and semantics of the /etc/printcap file. Both require the system administrator to take some action to complete the basic OS installation.

The System V spooler can be configured (under Solaris) either via a GUI front end, or by using a collection of commands and editing a number of files. The latter approach is complicated and messy, but if you really have to maintain and understand the spooler, I encourage you to do this at least once so you can see what is going on under the covers. An appendix in the appropriate manual leads you through most of this process.

Installing the BSD spooler consists of editing the ASCII file /etc/printcap to identify the printers, their capabilities, log and accounting files, and filters used to convert print jobs. The spooler need not be shut down while you edit this file, since it reads the file every time a job is printed. (Of course it would be prudent to shut down the spooler, just in case you make mistakes while editing. But when you want to experiment, it's useful to be able to do it "live".)

Guts: The Print Client

In the world of workstations, most computers are print clients. They must send spooled jobs elsewhere for printing. Each print client runs a daemon (lpd for BSD, lpsched for System V) that handles the transmission of the print job to the remote printer host. These daemons also handle the communication required to check remote spool queues and cancel jobs on the printer hosts.

The /etc/printcap file tells BSD systems where the remote printer is located (or at least where to send the print job for further handling). System V systems have a set of configuration files for each printer that hold the same information.

The BSD spooler system runs a master lpd daemon that uses a socket for local and remote requests. The master daemon forks lpd daemons to handle each request. Print jobs are spooled in /usr/spool directories for each printer. Each job consists of at least a cf* control file and a df* data file. Print job format conversions, accounting, and logging are always done on the printer host. Most fields in the /etc/printcap entry are ignored on a print client.

The System V spooler under Sun Solaris 2 can be set up to communicate with BSD spooler daemons (or printers masquerading as such). The entries in the /etc/lp/Systems file define whether to use the System V or the BSD protocol when communicating with a printer host. Because the spooler does understand the BSD lpd protocol, you can configure all your print clients and hosts to use the BSD protocol for communication if you find this to be more reliable. To communicate with BSD spoolers, the Service Access Facility listen daemon must be configured to listen for both S5 and BSD requests. The SAF makes these requests available to the lpsched daemon through named pipes.

Guts: The Printer Host

Jobs originating locally or received from print clients are handled in essentially the same way on the printer host. Both the lp and the lpr commands have options to print a file without making a copy in the spool queue, but that applies only to jobs actually spooled on the print host. Jobs from clients are always copied to the spool space on the host, so this space needs to be large enough to hold all queued jobs. PostScript files containing bitmap graphics, especially color graphics, can be very large. For this reason I set several hundred megabytes aside as spool space.

A major complication of printing is that the print job may not be in the "language" the printer speaks. Send an ASCII file to a PostScript printer and nothing will print. Send a PostScript file to a printer expecting the HP PCL language and the file will print as an ASCII file showing the PostScript language and bitmaps. Send a binary file to a lineprinter and you may get thousands of pages of garbage. Appropriate filters need to be installed and configured on the printer host to translate print jobs into the printer language.

The Adobe TranScript package is often used to convert files to PostScript. Some conversions are automatic, such as text to PostScript, while some must be explicitly requested by the user. There may be a command outside the spooling system for doing the file conversion -- for example, using dvips to do the conversion from TEX dvi to PostScript. Users of graphics packages generally can select PostScript as an output format.

Printer accounting and logging is done on the BSD printer host, if enabled in the /etc/printcap file and supported by one of the printing filters. Out of the box, the System V spooler does not implement printer accounting, but it does keep several log files in the /var/lp/logs directory.

Note that accounting is not a simple task. Often only the printer knows for certain how many pages or sheets were printed, so a dialog with the printer is needed after the job has been printed to recover accounting information. Even then it may be impossible to tell if the user printed on, say, expensive overhead transparency film instead of on recycled paper.

Guts: The Printer

Finally there is the task of sending the print job to the printer hardware. This may involve using a serial or parallel connection, or forwarding the job on to a printer sitting on the network. Although a printer may itself be quite a smart box, the dialog between the printer host and the printer is usually quite stupid. The printer host cannot determine what the printer is really doing and has a limited set of commands for controlling the printer. Because the same connection is used to send the data and the commands, the host may not be able to get the printer's attention when something goes wrong.

Using Both Spoolers

Given that you have solved the separate problems of making your BSD systems work well on their own and your System V systems work well on their own, exchanging print jobs is easy to do. Most System V spoolers know how to talk to BSD spoolers, so this is just a matter of configuration.

Printer accounting is done by the BSD printer host. If you hang a printer on a System V machine, don't expect to be able to recover accounting information.

Conversion of a print file to PostScript is generally done on the printer host if it is not done explicitly by the user. Make sure all your printer hosts are capable of the same set of conversions.

Techniques, Tricks, Problems

A number of vendors sell printers that sit directly on the network and speak the BSD spooler protocol. There are boxes you can buy for $1K or less that have a network connection on one side, a parallel port on the other side, and speak the BSD spooler protocol. This improves throughput and isolates the printer from whatever is happening on a particular UNIX machine, but may make it difficult to talk directly to the printer to recover accounting information.

CAP (Columbia AppleTalk Package) is available by anonymous FTP from The package is a general solution for letting a UNIX machine interact with an Apple Macintosh, but a small part of it makes it possible for a UNIX machine to talk to a printer that is on an AppleTalk network. I've used the package with SunOS and it is reported to work with Solaris. Be warned, though, that CAP can be difficult to install if you know nothing about AppleTalk and that you may need additional network hardware to do the routing between your TCP/IP on Ethernet and your AppleTalk-on-Ethernet.

When setting up multiple network printers accessed from a BSD host, be careful with the printer locking. The capability in printcap usually specified as ":lp=/dev/null:" explicitly locks the device while data is being transferred to the printer. A hung printer can cause /dev/null to be inaccessible, with strange results. If you specify two printers with the same entry in that field, only one of them at a time will receive data. So create some other object, like /usr/spool/lp1/lockobj, for each network printer.

It is common to hang printers on workstations to get them out of the machine room. You may need to use NFS-mounted spool space to do this. Watch out for the root-over-NFS access problem and make certain the spool space is mounted as writable by root. Also watch out for problems with the GID used to access some of the files. The GID is different between BSD and System V spoolers.

Printer and spooler log files can mushroom in the blink of an eye when something goes wrong. Use cron jobs to frequently clean out these files. You rarely need to keep log information for very long unless you're using the log to recover accounting information.

When printers or printer hosts are down, spooled jobs can quickly build up on workstations and exhaust the queue space. When you bring the printer or host back online, these jobs may all print, even though users in the interim printed their jobs elsewhere. It is a serious deficiency of both spoolers that there is no way to manage the log files and spool space distributed on machines around the network.

Practical Examples

Listing 1, a user command I call lptek, is a perl script to control the options on a Tektronix Phaser III PXi printer by prepending PostScript control code to the job sent to the printer. (The control code is supplied with the printer and is not included in the source listing.) This general approach can be used to set options on many PostScript printers. The script also writes an accounting record compatible with the BSD pac accounting command.

Listing 2, a perl script I call mypac, is a replacement for the BSD pac command. This is not an exact replacement, but does only what I want in terms of printer accounting. You can use this script with either the BSD or the System V spooler, as long as you are writing pac-style accounting records. See the comments in the script for the simple format of these records.

The sidebar ("Using the SunOS 4.1.2 Spooler under Solaris 2.3") and Listing 3 and Listing 4 describe how I have installed the SunOS 4.1.2 BSD spooler binaries on many of my workstations running Solaris 2.3. We had a number of problems with the spooler under Solaris, at least through patch level 9. Eventually I gave up on it, installed the BSD-style binaries, and moved my heavily used printers to network or BSD hosts.

Which Should You Use?

After all I've said, is there a good reason to choose one spooler over the other, if you have a choice? My experience has been that the BSD spooler works better and interoperates better with other spoolers and network printers. It has the hooks built in to do simple accounting and a program (pac) to generate reports. The availability of source code is a big plus for me.

The System V spooler holds promise, if you are willing to put some effort into making it work. It supports classes of printers, forms management, flexible specification of printer filters and interfaces, and has a richer set of system administration commands and capabilities, such as redirecting jobs already spooled. It has a more "commercial" feel to it. Out of the box it does not provide printer accounting, but this is relatively easy to add yourself.

Printing, as represented by the BSD and System V spooling systems, is still in the dark ages of one or two slow lineprinters attached to a big computer. Printers themselves have grown quite reliable (Apple LaserWriters run for years, printing over 100,000 pages before they need an overhaul), but neither spooler is really what we need in today's world of workstations and network printers. Better things are, I hope, coming.

Author's Note: I wish to acknowledge my fellow system administrators at MSU and on the net. I would not know what I know or be able to do what I do without the help, information, and tools freely shared in this community.

About the Author

John Lees has an M.S. in computer science and has worked during the past twenty years as a teacher, technical writer, programmer, and system administrator. His computer experience began in the days of front panels and paper tape, and he doesn't have enough fingers and toes to count the operating systems he has used. His love/hate relationship with UNIX dates to early 1985. Currently Mr. Lees is a systems analyst with the Department of Computer Science and manager of the Pattern Recognition and Image Processing Laboratory at Michigan State University. He is a member of ACM, TUG, and the USENIX System Administrators Guild. You can reach him at;