Cover V04, I05
Article
Figure 1
Figure 2
Listing 1
Listing 2
Listing 3
Listing 4
Listing 5
Sidebar 1
Sidebar 2

sep95.tar


A UNIX Print Server for UNIX Workstations, PCs, and Macs

David Leibfritz

Note: This article was written by a contractor for the U.S. Government (U.S. Dept. of Energy, Office of Basic Energy Sciences, contract No. W-31-109-ENG-38). The U.S. Government retains a nonexclusive, royalty-free license to publish or reproduce the published form of this contribution, or allow others to do so, for U.S. Government purposes.

Introduction

Configuring a UNIX print server to host jobs from Macs, PCs, and UNIX workstations is a difficult task. The Macs want to prepend a LaserPrep file to the beginning of every print job, which may reconfigure the printer and render it useless for the next non-Mac print job. Print jobs from Microsoft Windows try to prepend a Control-D, which most filters will interpret as a binary file. The queue must determine if the print job is ASCII or PostScript and execute the appropriate filter. Moreover, users want the capability to select different paper trays on a printer; the printer names and spools must be updated on all the machines when a new printer is added; and a default printer must be created for each user and machine.

A Sun workstation set up as a print server running the BSD spooling system and TranScript 4.0, a suite of UNIX programs from Adobe that transform print files into PostScript format, can create queues for all types of PostScript printers. The Columbia AppleTalk Package (CAP) can be used to host AppleTalk printers and to queue UNIX-based printers to the AppleTalk community. Printers with either serial, parallel, or network interfaces can be queued from a UNIX print server on an Ethernet network running TCP/IP and AppleTalk protocols. All printers can be set up in a similar environment, which simplifies administration of the printers.

In a pure UNIX environment, TranScript supplies almost everything you need to support PostScript printing. It does not, however, solve the problems created by Macs and MS Windows. This article presents listings for filters that remove a Mac LaserPrep file and the Windows Control-D character and shows how to reconfigure the spooler to install the filter. I'll also show some configuration tricks that let programs that assume the printer is always lw or lp use a shared printer more effectivly.

Filtering the Print Job

The first requirement is to make sure the printer supports PostScript. The second is to aquire the TranScript software (see the sidebar "For TranScript Information). Using TranScript with print jobs from UNIX systems should work most of the time without any errors. As noted earlier, print jobs from Macs will prepend a LaserPrep file to each job. The LaserPrep file may attempt to load certain fonts into the printer or select a different paper tray. These settings remain resident in the printer until they are reset by another print job or cleared by power cycling the printer. A print job with a LaserPrep file may render a printer useless for the next print job. This occurs frequently when Mac and non-Mac jobs are sent to the same printer. To avoid this problem, it's necessary to strip off the LaserPrep file from each print job. The C program in Listing 1 (rmprep.c) does just that; it is reproduced here with permission from the author, Vui Le from Qualix.

A problem specific to Microsoft Windows is print jobs that start with a Control-D character. The TranScript filters will see the Control-D as the first character and treat the file as a binary graphics file. When the printer receives this Control-D as the first character, it may interpret this as the end-of-file character and flush the rest of the job, so that nothing gets printed. To solve this problem, the C program in Listing 2 (ctrldrm.c) strips out the first Control-D character in the print job. ctrldrm.c also removes any leading spaces before the %! PostScript designator on the first line of a print file.

To incorporate these filters into TranScript, modify the script psint.sh which is supplied with the code. Use pipes to insert the rmprep and ctrldrm filters before each occurrence of $dman.

Creating a Master printcap File

For locations with numerous workstations and printers, the most efficient way of maintaining a current /etc/printcap file is to create one master /etc/printcap file which all machines will reference. You can accomplish this by creating two queues for each printer. The first queue is a pseudo queue that users reference for printing. The pseudo queue points to the real queue for that printer, which is on a remote machine with a different queue name. An example of such a printcap entry is shown in Figure 1.

Using printer ps1 sends the print job to printer ps1_2 on the machine sleepy. This setup also requires two spools, named /var/spool/ps1 and /var/spool/ps1_lp. The spool /var/spool/ps1_lp only has to be created on the machine sleepy. The spool /var/spool/ps1 must be created on every machine -- you can do this with a simple script.

The other issue that arises with creating a single /etc/printcap file for all machines is how to set up the default printers lw and lp. Various applications use these printer names and do not necessarily provide a means of changing the printer specification. The script in Listing 3 finds a user's PRINTER variable in his/her .login file and allows you to route the print job to that printer.

lw_msg, referenced in Listing 3, is simply a text file explaining that the PRINTER variable in the user's .login file needs to be defined. With PRINTER defined, you can modify /etc/printcap for the lw and lp printers as in the following example:

# This entry will reroute jobs to the appropriate
# printer defined in the user's .login file.
lw|lp|ps|postscript|PostScript:\
:lp=/dev/lwlp:sd=/var/spool/lw_lp:\
:lf=/var/adm/lw-log:\
:sh:mx#0:\
:if=/usr/local/lib/ts/print_route.sh:\
:nf=/usr/local/lib/ts/print_route.sh:\
:tf=/usr/local/lib/ts/print_route.sh:\
:rf=/usr/local/lib/ts/print_route.sh:\
:vf=/usr/local/lib/ts/print_route.sh:\
:cf=/usr/local/lib/ts/print_route.sh:\
:df=/usr/local/lib/ts/print_route.sh:

The files /dev/lwlp, /var/adm/lw-log, as well as the spool directory /var/spool/lw_lp, must be created on every machine. Use the UNIX touch command to create these files.

Adding the Spool

To add a spool for a serial printer attached to a workstation, use the printcap entry shown in Figure 1. Make sure that the device name field (lp=/dev/ttya) matches the serial port on the workstation to which the printer is attached. Also match the baud rate to that of the printer for the parameter br#38400 (38400 baud). Remember that the spool directory /var/spool/ps1 must be created on every machine, and the spool directory /var/spool/ps1_2 must be created on the workstation to which the printer is attached, with owner and group set to daemon. The /var/spool/ps1_2 directory must contain a file called .options, which allows TranScript to communicate with the printer. The contents of this file are shown below:

PSCOMM=$PSLIBDIR/pscomm
export PSCOMM

You must also create /var/adm/ps1-log and /var/adm/ps1.acct files on the workstation to which the printer is attached, with the owner of the /var/adm/ps1.acct set to daemon. These files will maintain a log of all printing for that printer. The log file is a good place to search for printer errors.

Adding a spool for a printer attached to a MiLan Fastport requires assigning an IP number to the print server. You can accomplish this either by using a rarp server or by attaching a serial line to the MiLan Fastport and hardcoding the IP number into nvram (refer to the MiLan Fastport manual for details on setting the IP address). The /etc/printcap entry for a printer attached to a MiLan Fastport is similar to the entry in Figure 1, with a few modifications. The device field must be changed to a pseudo device (e.g., /dev/ps1) -- you can use touch to create the empty file. The spool directory name should match the name of the MiLan Fastport (e.g., /var/spool/milan5), with owner and group set to daemon. The .options file in the spool directory must include the following:

PSCOMM=$PSLIBDIR/fpcomm
export PSCOMM

To set the parameters that configure the MiLan Fastport, create a file called .fpconfig in the spool directory. The contents of .fpconfig for a printer attached to the parallel port are shown below:

parallel
hostname milan5
ctrld

These parameters configure the MiLan Fastport to use the parallel port for communicating with the printer, specify the IP name of the MiLan FastPort, and send a Control-D before and after every print job. For a printer attached to the serial port, modify the contents of .fpconfig by changing parallel to serial. Make sure that serial is the first line of .fpconfig.

To add a spool for a printer with a HP JetDirect network interface card, follow the directions in the manual for assigning an IP number using bootp. Once everything is configured properly, the printer should respond to a ping. The /etc/printcap entry is similar to that in Figure 1, with a few modifications. The device field must be changed to a pseudo device (e.g., /dev/ps1). The spool name must match the name of the printer. The output filter field must be changed to use the HP filter (e.g., of=/usr/lib/hpnp/hplj.of.sh); the remaining print filters still use the TranScript filters. The .options file in the spool directory must include the following in order to communicate with the HP JetDirect network interface:

PSCOMM=/usr/lib/hpnp/hplj.if.sh
export PSCOMM

Finally, create a file called .params in the spool directory to set parameters that configure the HP printer. You can generate this file with the HP configuration scripts supplied with the software.

For printers connected via EtherTalk, use the Columbia AppleTalk Package (CAP) software, which is available on the net. Find the AppleTalk name of the printer using either a Mac Chooser or the atlooklws UNIX program supplied with CAP (the AppleTalk name should also be displayed on a configuration page from the printer). Then map the AppleTalk name to the UNIX queue name by adding the following line to the /etc/cap.printers file on the UNIX CAP server:

ps1=AppleTalk_Name:LaserWriter@*

The /etc/printcap entry is similar to that in Figure 1, with one modification: the device field must be changed to a pseudo device (e.g., /dev/ps1). Include the following in the .options file in the spool directory:

PSCOMM=$PSLIBDIR/capcomm
export PSCOMM

Support for Additional Printer Trays

To allow users to access additional paper trays on printers, create an additional queue to represent each tray. Each additional queue is a pseudo queue that massages the PostScript file to select the appropriate tray and then sends the print job to the real queue for printing. This The script in Listing 4 makes sure that the file is a PostScript file, then calls tray2 -- shown in Listing 5 -- to select the second tray.

Figure 2 shows how to incorporate the tray script into the queue entry of the /etc/printcap file.

Remember to create the spool device /dev/ps1b as an empty file, and the spool directories and the log file, to record errors.

Defining UNIX Queues to the Mac Environment

Sites with a mix of UNIX workstations and Macintoshes find it convenient to use the same printers for both types of machines. The CAP (Columbia AppleTalk Package) software includes a program, lwsrv, that provides a mapping between a UNIX print queue and an AppleTalk print queue. Follow the instructions for using lwsrv that are supplied with CAP to create this mapping. (The CAP documentation is well written and provides examples which makes it easy to get started.)

Defining UNIX Queues to the PC Environment

To allow PCs to print on a UNIX queue, use pcnfsd, which is freely redistributable. pcnfsd supports a print model based on NFS to transfer the print job from the client to the server. The pcnfsd server must export the /var/spool/pcnfs directory to all the PCs. In addition, the print server must permit the PC to print by including its name in the /etc/hosts.lpd file. A mapping must exist between the IP address and the PC name, either via a hosts file or a nameserver.

About the Author

David Leibfritz has an M.S. in computer science and is currently employed at Argonne National Laboratory as a network operations specialist. He started his computer science career providing consulting assistance for various types of operating systems, and has worked on UNIX systems and taught UNIX and C classes since 1988. For the past three years he has been the UNIX network administrator for over 150 Sun Workstations and has provided support for over 100 printers of various types on a network consisting of nearly 700 machines, including PCs and Macs.