This document describes what I did to get printing working under netatalk on my MkLinux machine.
Much of the procedure I describe below was deduced from information found in Werner Eugster's Linux printing page at http://www.giub.unibe.ch/~eugster/appleprint.html. However, some of the pathnames and so forth in that document seem more appropriate to PC Linux machines, so be sure to compare the information there with where files are actually located under MkLinux.
Some of the printing services you can set up with netatalk are:
My printer is an HP LaserJet 4MP. One complication I had to address before trying to set up netatalk for printing is that this printer has a LocalTalk interface rather than an ethernet interface. For the printer to to be visible on the ethernet (and thus to MkLinux, which has no LocalTalk support currently), it has to be bridged onto the ethernet using a microPrint-like device, or with LaserWriter Bridge running on an ethernetted Macintosh running MacOS. (See the description of my network for details on what I do on my network.) If you have an ethernetted printer, that shouldn't be necessary.
On my network, the printer has its default AppleTalk name of "HP LaserJet 4MP"; substitute your printer's AppleTalk name in the examples shown below.
I wanted to call my printer lp in /etc/printcap on MkLinux, since lp is the default printer name. That way lpr, lpq, lprm, etc., can be used without any -P arguments, which simplifies printing. That is, I can print to the HP 4MP like this:
% some-command ... | lpr
And check the print queue like this:
% lpq
Below are the steps I followed to make the printer accessible from MkLinux. Note that you must become root to do most of this stuff.
Create an /etc/printcap entry for the printer. Mine looks like this:
lp|HP LaserJet 4MP:\
:sd=/var/spool/lp:\
:lp=/dev/atalk/lp:\
:lf=/var/log/lpd-errs:\
:if=/usr/local/atalk/lib/atalk-filters/ifpap:\
:mx#0:sh:sf:
There are several directories and files named by this entry that you must make sure exist: the "line printer" device file (lp=), the spool directory (sd=), the log file (lf=), and the input filter (if=).
Create the spool directory:
# cd /var/spool
# mkdir lp
# chown root.lp lp
# chmod 775 lp
A "line printer" device file (lp=) must be specified in the printcap entry because the lpd system will try to open it for output. (For printing to an AppleTalk printer, we don't want to actually connect to a device file; the input filter will connect on the network to the printer. Nevertheless, a file must still be listed.) The file listed in the entry above (/dev/atalk/lp) is simply a fake file to satisfy the lpd system. Create it as follows:
# cd /dev
# mkdir atalk (if it doesn't exist)
# chown root.lp atalk
# chmod 775 atalk
# touch atalk/lp
# chown root.lp atalk/lp
# chmod 664 atalk/lp
It's best to have a separate device file for each printer. You'll get locking problems if you have multiple printers and the system is trying to print to more than one of them at once, because spool processes for each printer will contend with each other trying to lock the same file.
Note: Some of the documents I read (including the psf manual page) stated that if you create a fake device file, you need to use mknod to create it. I don't believe mknod is necessary. You just need to create a file that will be used for only one printer; touch is sufficient for that purpose.
Create the lpd-errs file if it doesn't already exist:
# cd /var/log
# touch lpd-errs
# chown root.lp lpd-errs
# chmod 664 lpd-errs
If things don't work later on when you try to print, lpd-errs is the file to look in, along with /var/log/messages.
You might also want to set up a cron job that rolls over the lpd-errs file periodically, so that it doesn't grow without bound. A sample script is available here.
The input filter /usr/local/atalk/lib/atalk-filters/ifpap is a link to psf. It should already exist, so it's not necessary to create it.
The "if" and "pap" in the input filter's name are both significant here. When psf is invoked with a name beginning "if", it knows it's an input filter. When the name contains "pap", psf knows that it should use the pap program to talk to an AppleTalk printer. That leaves out one detail: how does pap know which printer? You specify the printer name by creating a file .paprc in the printer spool directory (/var/spool/lp) that contains the printer name. This works because when lpd starts up an input filter, it sets the current directory to the corresponding printer's spool directory. Thus, by reading .paprc in the current directory, pap can be sure of getting the correct printer name.
My /var/spool/lp/.paprc file looks like this:
HP LaserJet 4MP:LaserWriter@*
In the printer name, I specified the zone as "*" because my network has no zones. If you were in a network with named zones, you'd replace the "*" with the zone name.
Note: My input filter assumes its input is already in PostScript format. If you want to send text files to the printer, you'll either need to run them through a PostScript converter or arrange to use some sort of filter that does this for you.
The mx, sh, and sf settings allow print jobs of any size, and suppress header pages and form feeds. These are not strictly necessary, but I prefer to have them present. See the printcap manual page for more information.
Before you can print anything, you must make sure lpd is running. You can start it manually like this:
# /usr/sbin/lpd
However, it's better to make sure lpd starts at boot time. I do so like this (assuming normal multiuser runlevel is 3):
# cd /etc/rc.d/rc3.d
# ln -s ../init.d/lpd.init S40lpd
This makes a link S40lpd in the runlevel 3 startup directory to the standard lpd initialization script.
Now you can try to print something. A command to generate a blank page is shown below:
# echo "" | lpr
If nothing comes out, check the printer queue:
# lpq
Also, look in /var/log/lpd-errs and in
/var/log/messages for clues.
You can try stopping and restarting the printer daemon:
# lpc abort lp
# lpc start lp
Read the lpc manual page for more details about ways you can poke and prod the printing system.
If you have MkLinux printing working as described in the previous section, the lpd system can also handle print job requests from MacOS Macintosh clients, assuming the clients are using the LaserWriter 8 printer driver. This can be useful because you'll typically get the print job off the MacOS machine faster when sending it to a MkLinux host than when sending it directly to the printer.
To set up this kind of print spooling, create a file papd.conf in /usr/local/atalk/etc that specifies the printer name you want MacOS clients to see in the Chooser. My MkLinux host name is grey, so I wanted to make the network name of the MkLinux print spooler be lpr-grey to make it clear that print jobs would be going to lpr on grey. My papd.conf file looks like this:
lpr-grey:\
:pr=lp:\
:pd=/usr/local/atalk/etc/HPLJ_4M.PPD:\
:op=netatalk:
The pr value is the /etc/printcap printer name to associate with lpr-grey.
The pd (PostScript printer description file) value is the pathname of a PPD file like those you find in the Printer Descriptions folder in the Extensions folder as used by the MacOS LaserWriter 8 driver. To get it, just copy the appropriate file from a MacOS machine to the pathname named in the pd field of the papd.conf file. (You can also get PPD files from the Adobe FTP site.)
The PPD file should be installed on the MkLinux host in the location specified in the papd.conf file, as well as on each MacOS client machine (in the System Folder:Extensions:Printer Descriptions folder). Otherwise, the LaserWriter 8 driver won't be able to determine the printer type properly.
When papd starts up at MkLinux boot time and reads the papd.conf file shown above, the name lpr-grey is advertised on the AppleTalk network, and MacOS clients are able to see that name in the Chooser. You should also see the name if you run nbplkup.
If you don't create the papd.conf file, the name that appears in the Chooser is the MkLinux machine's host name, and it might not be obvious to clients that the name represents a printer. This will also be a problem if you decide to make more than one printer available from the MkLinux host.
You can use netatalk to make AppleTalk printers visible to other UNIX machines that aren't running netatalk. To do so, use the remote printing capabilities of the printing system on those machines. (This assumes they can communicate with the MkLinux host over TCP/IP.)
(A caveat: I have not actually tested the instructions in this section. If you try 'em and find out that they don't work -- or that they do -- please let me know.)
First, you must set up MkLinux printing as described in the section Printing from MkLinux above. You may also need to add the names of the client machines to /etc/hosts.lpd or to /etc/hosts.equiv (run man lpd for details). It might be a good idea to add both the unqualified and fully-qualified forms of the client machine name.
BSD Client Setup
For a UNIX client running a BSD-style printing system, you need to create an /etc/printcap entry and a spool directory, much like you do on the MkLinux machine itself. However, the form of the printcap entry is a little different than for a local printer. It might look something like this:
lpr-grey|HP LaserJet 4MP, remotely on grey:\
:lp=:\
:rm=grey.primate.wisc.edu:\
:rp=lp:\
:sd=/var/spool/lpr-grey:\
:mx#0:sh:sf:
lpr-grey is the name by which the printer will be known on the client machine. The rm value is the machine to connect to when sending print jobs, and the rp (remote printer) value is the name by which the printer is known on the remote machine.
Then create the spool directory. This will be similar to the way you created the directory on the MkLinux host.
To print from the client machine, you'll need to use the -P flag to specify the printer name:
% some-command ... | lpr -P lpr-grey
If you don't already have a printcap entry named lp on the client machine, you could use lp instead of lpr-grey. Then you wouldn't need the -P flag.
When you print from the client, the print job initially is stored in the spool directory on the client machine. Then the lpd system takes the job and sends it over the network to the MkLinux machine, which spools it there and eventually sends it to the printer.
System V Client Setup
For a UNIX client running a System V-style printing system, tell the printing admininstration tool what machine the printer is on, what its name is, and (possibly) that BSD-style protocols should be used to communicate with the MkLinux host. (This is vague because I haven't used these kinds of printing systems much.)
To print from the client machine, you'll need to use the -d flag to specify the printer name:
% some-command ... | lp -dlpr-grey
4 July 1996
27 June 1996