Printers might be connected through a serial port to a host computer. This procedure doesn't cover that case because Sun system documentation covers it adqeuately. However, be aware that serial port connections are very slow as compared to network connections. High serial transmission rates might be 9600 baud or 55 kilobits/sec. On the other hand, AppleTalk runs at 230 kilobits/sec. While you can attach a priter to a serial port, you'll be waiting 4 times longer just to ship the data to the printer.
Few printers (at least inexpensive ones) will comfortably hang on directly on an Ethernet, but many will work on AppleTalk. To bridge these systems, you need either a AppleTalk Ethernet bridge in the form of a Kinetics/Shiva FastPath or the now cheaper printer bridges for AppleTalk legacy hardware such as an Asante MicroPrint.
CAP is the Columbia AppleTalk Protocol public domain software that will run on AppleTalk or EtherTalk systems. This is no longer under development, but provides stable access to all Apple systems I've yet encountered. If you're going to use CAP under EtherTalk, make sure you have it configured properly.
Is the printer a PostScript printer or not? If it is, you can use the off-the-shelf code for papif that comes with CAP. If it isn't, you'll need code that will talk over the AppleTalk/EtherTalk network to the printer using PAP (Apple's Printer Access Protocol) to run the printer. Code to do this is available here, in the form of papif-nops, if you don't have something else to drive the printer over the network. Code papif-nops.c.
At Bristol the CAP run-time code is in /usr/local/lib/cap (on the host called garnet, and the source tree is rooted at /usr/local/src/cap60.
Plug it in and use atlook to discover its name.
atlook will spew out all the devices on the network.
You'll have to wade through the output to locate the printer.
If it is a real PostScript printer, it will have a name like
some name:LaserWriter@*
The name is everything before the colon, and the type of the printer
is everything after it up to the @. If you know in advance it is
a PostScript printer, you can save yourself some effort by using
atlooklws which will filter out everything except the
PostScript printers.
cap.printers is a file that converts between printers that Unix knows about and that the AppleTalk/EtherTalk know about. This is a file that associates the Unix printer name and the network printer name. Dream up a Unix printer name for your new bit of kit and put it in the file along with the network name - complete with the name and type.
At this point, CAP is ready to use the printer.
The spool directory will contain temporary copies of the data destined for the printer. One of these must exist on every machine that intends using the printer, so if you have a lot of machines, you have to do this on each one (or use rdist to spray the new directory throughout your cluster of machines).
The traditional place for spool directories is in /usr/spool/lpd so make a new directory here. Make sure the directory is permissioned rwx to both root and daemon, and rx to everybody else.
On the host running CAP only, also create a log file in the printer's spool directory for CAP to use when printing (because it helps sort out problems when the printer or network malfunctions). This file should be something ending with -log, like deskjet-log so that users can find it and look inside when anything goes wrong with their jobs.
On the host running CAP only, create a file called .banner in the printer's spool directory, and permission it rwx to both root and daemon and r to everybody else. If you don't get daemon's permissions right, the printer won't do anything and your system will spin its wheels trying to print to the printer forever.
/etc/printcap contains all the information the Unix spooling system needs to know to route files to the printer. It has an arcane but forgiving format (see man printcap for details). You need to put the Unix name of the printer here - the one you associated with the printer in cap.printers, above - plus spool directory information, plus routing information in it.
On the host running CAP only, the entry is more involved because you have to tell the spooling system how to print to the printer. The other hosts only need to be told which system has the printer attached to it (or equivalently, will use CAP to send files to it).
On the host running CAP only, the entry will look like this:
pname|PostScript|postscript|flowing prose printer description:\
:lp=/usr/spool/lpd/sdir/pname:sd=/usr/spool/lpd/sdir:\
:lf=/usr/spool/lpd/sdir/pname-log:af=/usr/adm/pname.acct:\
:if=/usr/local/lib/cap/if-filter:\
:of=/usr/local/lib/cap/of-filter:gf=/usr/local/lib/cap/atgf:\
:nf=/usr/local/lib/cap/atnf:tf=/usr/local/lib/cap/attf:\
:rf=/usr/local/lib/cap/atrf:vf=/usr/local/lib/cap/atvf:\
:cf=/usr/local/lib/cap/atcf:df=/usr/local/lib/cap/atdf:
Replace all instances of pname in the above with your
chosen Unix printer name. Replace all instances of sdir
with the name of the spool directory you chose (hopefully in
the directory /usr/spool/lpd as suggested before, or modify
the entries accordingly). The of=, gf=, nf=, tf=, rf=, vf=,
cf=, and df= entries are all standard boilerplate for CAP.
If your printer is PostScript, you'll need to replace
if=if-filter with if=atif and
of=of-filter with of=atof.
If not PostScript, replace
if=if-filter with if=atif-nops and
of=of-filter with either of=atof or a filter of your
own choosing that will generate printer initialization code and/or
a banner page file to be sent to the printer. papif-nops
needs to be explicitly told about a banner file, so if you don't
plan to use one don't worry about getting this right.
Also update your printer description (the flowing prose part) to
describe the printer to humans, e.g. "The DeskJet in Room G5" or
"Sophie's Choice" or whatever.
On hosts not running CAP, the entry, much simpler, will look like this:
pname|PostScript|postscript|flowing prose printer description:\
:lp=:rp=pname:rm=host:\
:sd=/usr/spool/lpd/sdir:\
:lf=/usr/spool/lpd/sdir/pname-log:
Replace all instances of pname in the above with your
chosen Unix printer name. Replace all instances of sdir
with the name of the spool directory you chose (hopefully in
the directory /usr/spool/lpd as suggested before, or modify
the entries accordingly). Finally, replace host with the
name of the Unix host that is running CAP to talk to the printer.
That's how your system knows where to ship off the data for the
printer.
Remember to add the same /etc/printcap entry to the other systems.
Try issuing the command
lpq -Ppname
from every machine. If your /etc/printcap isn't set up
right, you'll get errors reported at this point. If there aren't
any, next try issuing
echo "Hello from `hostname`" | lpr -Ppname
from all the hosts to make sure that the output gets to the printer.
A typical customization is to write an intelligent input filter that
detects alternate-format (or outright aberrant) input and acts
accordingly. For example, a DeskJet printer might well have
PostScript output directed at it. If so, it should run Ghostscript
gs (the PostScript interpreter) to reformat the output to
HP PCL that the DeskJet understands. You can do this by substituting
a program or a shell script for the if= /etc/printcap
entry. Bristol runs its DeskJet with special input and output filters.
The output filter djof emits printer reset commands at the
beginning of each job in case the previous one left the printer in
an unusual state. This writes a file called .banner that
the input filter (papif-nops) will prefix to the output
destined for the printer. djof is,
#!/bin/sh
# Output filter for a DeskJet/LaserJet printer. This only emits a reset
# sequence so the printer isn't left in a bad state when the next job
# appears.
banner=${BANNER:-.banner}
touch $banner && [ ! -w $banner ] && echo "Can't open $banner" && exit 8
sed -e 's/[ ]*%.*$//' -e 's/\\033/^[/g' << EOF | tr -d '\012' > $banner
\033E\033&k2G %reset printer, set CR=CR,LF=CRLF,FF=CRFF */
\033&l6d66p0o0e66f0L %letter size, portrait, no perf skip */
\0339 %reset side margins */
\033&a0r0C %move cursor to 0,0 */
\033(0U %set US ascii font (ron@mlfarm) */
EOF
kill -STOP $$
Note the unusual termination style, suicide. Proper operation of
the spooling system requires this.
djif, the input filter, is a bit subtler. It detects incoming
PostScript and runs Ghostscript on it, as follows:
#!/bin/sh
# Input filter for a DeskJet/LaserJet printer. This checks whether it is
# receiving PostScript and if so runs it through GhostScript to convert
# to DeskJet output. Otherwise, it execs the normal input filter.
args="$@"
read first_line
first_two_chars=`expr "$first_line" : '\(..\)'`
if [ "$first_two_chars" = "%!" ]; then
#
# It's PostScript; use Ghostscript to scan-convert and print it
#
(echo $first_line && cat) |
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=cdjcolor -r300x300 -sOutputF
ile=- - |
/usr/local/lib/cap/atif-nops $args && exit 0
else
#
# Plain text or HP/PCL, so just print it directly; print a form
# at the end to eject the last page.
#
(echo $first_line && cat) | /usr/local/lib/cap/atif-nops $args && exit 0
fi
exit 2