| 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 
ftp.columbia.edu. 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 lees@cps.msu.edu;
http://www.cps.msu.edu/~lees. 
 
 
 |