AppleTalk, AppleShare and Linux: Printing


How to setup the printer using AppleTalk


As a Linux user, you want to get access to a Mac printer like a LaserWriter sitting with its EtherTalk adapter on the network. As a Mac user, you want to get acces to any printer accessible from Linux. To set up such a service under Linux, you have to follow the same procedure in both cases. After having compiled and installed the AppleTalk software netatalk (if you did not do that read Anders Brownworth's atalk installation guide first!), you probably already started all the daemons using rc.atalk in your /etc directory. However, make sure, the AppleTalk service is really working before trying to configure your printer. The version of netatalk I'm using is 1.3.3 with all patches described in Anders Brownworth's installation guide. I've been told that the path to the netatalk filters has changed in newer versions.

1. Get my AppleTalk zone

Type /usr/local/atalk/bin/getzones to see whether all the AppleTalk zones are visible to your Linux box. You should see at least one name which is your local zone, otherwise it is very likely that your AppleTalk services are not working propperly. I get something like this (only the first few lines shown):
        Pingo$ /usr/local/atalk/bin/getzones | more
        VLSB
        LSB-Integrative Biology
        LSB-Biology Library
        LSB-Herbaria
        LSB-UCMP
        LSB-MVZ
        Vanishing Packets
        MIP
        Barker Hall
With the command line option you find out which is your zone:
        Pingo$ /usr/local/atalk/bin/getzones -m
        VLSB
        Pingo$
So my local zone is VLSB, the complete list of all local zones can be obtained using the -l option (in case your printer is not in your zone, you need to know the exact name of the zone).

2. Find out the name of the printer

If you only want to make a local UNIX printer available to AppleShare clients, skip this step and go directly to step 3. First we have to know how names are defined under AppleTalk Internet. This is very similar to what you know from your Linux box. The names are composed in the form object:type@zone. If you do not care about the name of your local zone, use @*. So, to find all objects in your zone, type /usr/local/atalk/bin/nbplkup, which will yield a huge list containing entries like the following example:
Pingo$ /usr/local/atalk/bin/nbplkup |more
         Sun ValleyUs Macintosh:Macintosh IIsi           12398.245:253
         Sun ValleyUs Macintosh:Workstation              12398.245:4
       IB Instructional Support:  Power Macintosh        12398.196:253
       IB Instructional Support:Workstation              12398.196:4
                  centris 660AV:  Macintosh              12398.51:253
                  centris 660AV:Workstation              12398.51:4
           Chapin Lab vx - JoeC:Macintosh IIvx           12398.101:253
           Chapin Lab vx - JoeC:Workstation              12398.101:4
              Pingo Mac Printer:LaserWriter              12398.164:129
          Pingo Default Printer:LaserWriter              12398.164:128
                          Pingo:AFPServer                12398.164:130
                          Pingo:netatalk                 12398.164:4
                          Pingo:Workstation              12398.164:4
                      Lucicutia:AFPServer                12398.123:248
           Theobald Chapin, III:LaserWriter              12398.73:191
If you only want to know specific object types, like LaserWriters, you have to use /usr/local/atalk/bin/nbplkup :LaserWriter. Make sure you include the colon to indicate that you are looking for a type called LaserWriter. The word need not include capital letters, but you are not allowed to omit the spaces. Thus, e.g. to look for Macintosh IIvx you need to put the type name into quotes:
Pingo$ /usr/local/atalk/bin/nbplkup  :"Macintosh IIvx"
           Chapin Lab vx - JoeC:Macintosh IIvx           12398.101:253
Pingo$
Ok. To make it short: I want to print from my Linux box to the LaserWriter named Theobald Chapin, III. Before you try to set up printcap for your printspooler, rather make a first check, whether the printer is accessible and your printing comes out as you expect.
Type /usr/local/atalk/bin/papstatus -p "Theobald Chapin, III" (note that the quotes only are needed to tell your Unix shell that Theobald Chapin, III is actually only one argument, not three), and you should get something like
status: idle
If not, go back and see whether your AppleTalk really works (maybe the daemon was not started? Check with ps -xa | grep atalkd and ps -xa | grep afpd whether those daemons are present). Since the LaserWriter is expecting PostScript files, you should have a PostScript file handy for a short test. My file's name is test.eps, and I can send it directly to Theobald Chapin, III by invoking the AppleShare print client directly:
/usr/local/atalk/bin/pap -p "Theobald Chapin, III":LaserWriter@VLSB test.eps
Note that I included the zone name just to make sure everything is working fine. If your print job comes out (you will get a status message every second or so if somebody else is using the printer at the same moment. Watch how the response comes from your printer and what it does when it starts printing your file). If you encounter any trouble, use aecho to find out about AppleTalk objects in the same way you would do using ping over TCP/IP (hit Ctrl-C to stop aecho):
/usr/local/atalk/bin/aecho "Theobald Chapin, III":LaserWriter@VLSB
14 bytes from 12398.73: aep_seq=0. time=15. ms
14 bytes from 12398.73: aep_seq=1. time=14. ms
14 bytes from 12398.73: aep_seq=2. time=14. ms
14 bytes from 12398.73: aep_seq=3. time=14. ms

----12398.73 AEP Statistics----
5 packets sent, 4 packets received, 20% packet loss
round-trip (ms)  min/avg/max = 14/14/15
Pingo$
You should only have lost the last packet when you hit Ctrl-C, otherwise something's wrong with your connection.

3. Setting up your Linux print service

There will be two steps. First, you make sure you can print from Linux to your printer, and second, you make sure this printer is available for AppleShare clients.

 Thus, to be more clear: you will first set up your printer as a Unix printer accessible for the lpd printer daemon (sections 3.1 through 3.2) and then you make it available for other users in the AppleTalk zone (section 3.3), which is optional, of course.

 Many people are confused about the setup for two reasons:
(1) If an AppleTalk printer is already available in the AppleTalk zone, Mac users can directly connect to it. Thus, there is no need for a print spooler on a Linux box. However, I am a Linux user and want to have access to this AppleTalk printer, and thus my description given here does exactly that: allow Linux users to print on an AppleTalk printer.
(2) If your printer is a local printer attached to the parallel port of the Linux box (eg. to /dev/lp1), there are some changes for the printcap file. I will give you an example of a setup with a local printer which I have not tested myself but was sent to me by another user. See section 3.4 for this and check out the detailed information given by Mike Pearson and Bill McGonigle on using Ghostscript together with Netatalk.

3.1 Configuring your /etc/printcap

If your printer already is capable of printing a file using a command like
Pingo$ lpr -P lp test.eps
then you can skip this first part of step 3. Otherwise, be root and go into your /etc directory to edit printcap. Use the man page of printcap for all details. I will only describe how to set up the LaserWriter so that it works together with the Linux lpr command. Add an entry for your printer to the printcap file. I have only the LaserWriter defined, and my entry looks like this:
lp|Pingo LaserWriter|Theobald Chapin, III:\
        :sd=/usr/spool/theobald:\
        :lp=/dev/null:\
        :pl#63:pw#85:\
        :mx#0:\
        :sh:sf:\
        :lf=/usr/adm/lpd-errs:\
        :if=/usr/local/bin/myif:\
        :of=/usr/local/atalk/etc/ofpap:

3.1.1 Name of the printer for Linux users

The first line defines three logical names for this printer which do not need to have any similarity to the name you want to give this printer for AppleShare clients. Thus, I included lp in this line, since lp is the default for most UNIX users. The other names I only used to make sure I remember which printer lp actually was.

3.1.2 Spool directory

Then you need to have a spool directory where the print spooler can store the print jobs in the printer queue. I named my spool directory /usr/spool/theobald on the same hierarchy level as the mail spool directory:
Pingo$ ls -l
drwxrwxr-x   2 root     mail         1024 Feb  8 08:46 mail
drwxr-xr-x   2 root     mail         2048 Feb  8 17:23 mqueue
drwxrwxr-x   5 news     news         1024 Sep  1  1994 news
drwxrwxr-x   2 root     lp           1024 Feb  9 13:15 theobald
Create this directory using mkdir and then set ownership to root and group lp, using
Pingo$ chown root.lp theobald
Then make sure you have the propper privileges using
Pingo$ chmod 775 theobald
Then I created the two files lock and status in this directory:
Pingo$ cd theobald
Pingo$ touch lock; chown root.root lock; chmod 004 lock
Pingo$ touch status; chown root.root status; chmod 664 status
Now you can define this directory as the spool directory as I did in line 2.

3.1.3 The printer device

If your printer is a local printer attached to a device like /dev/lp1, this is the device you need. You will use mknod to make this device if it does not already exist. For a printer in the AppleTalk zone, you actually don't want to print to any device, but send your print job to this printer using the pap program sitting in /usr/local/atalk/bin. This will be done by using the psf filter which will invoke the pap program to access the printer. Thus, after your job has been sent to the LaserWriter, it is still present on your local Linux box, since the printer daemon lpd is supposed to send your job to a device at the very end. Therefore we define /dev/null as the printer device which will forward your job to outer space (you only want to keep the copy which came out on the LaserWriter). So we put :lp=/dev/null:\ for that in the third line. Read the manual pages of psf, if you have more than one AppleTalk printer and if there is a problem with using /dev/null as the printer device.

3.1.4 Page size, maximum file size and header

Use the printcap entries pl and pw for page lenth (lines) and page width (characters), respectively. With the printcap entry mx you can define the maximum size of printfile which should be accepted. If your file is larger, the printer daemon will truncate the file or refuse printing at all. If you set the value to zero (mx#0), this means unlimited printing. Be aware that in an accident your printer tray may be emptied until the last sheet if nobody takes any action before this happens! And your starving printer will request for more paper! So my advice is, to omit the mx#0 entry until your testing is done and you are sure everything works ok. With the sh entry we suppress output of a header page or header line (which would include the information on the origin of your print job). With the sf option we suppress output of form feeds.

3.1.5 Error logging

I defined the file /usr/adm/lpd-errs to be used to store error messages. You will have to create this file yourself (just say touch /usr/adm/lpd-errs)!

3.1.6 The filters

Now, this is important. As already discribed, your print job will be sent to the AppleTalk zone only if you install the appropriate filter which will invoke pap. The netatalk distribution uses a hacker-style concept using the filter psf, but with different links to it. psf then analyses the name of that link to find out, that it has to start pap if this substring is in the name of the link, and reverse the order of printing, if rev is in the name. Look at this by typing
Pingo$ ls -l /usr/local/atalk/etc
lrwxrwxrwx   1 root     root            3 Feb  8 14:44 ifpap -> psf
lrwxrwxrwx   1 root     root            3 Feb  8 14:44 ifpaprev -> psf
lrwxrwxrwx   1 root     root            3 Feb  8 14:44 ofpap -> psf
-rwxr-xr-x   1 root     root        49299 Feb  8 14:44 papd
-rw-r--r--   1 root     root           35 Feb  9 13:48 papd.conf
-rwxr-xr-x   1 root     root        11395 Feb  8 14:44 psf
lrwxrwxrwx   1 root     root            3 Feb  8 14:44 tfpap -> psf
lrwxrwxrwx   1 root     root            3 Feb  8 14:44 tfpaprev -> psf
Pingo$
So a filter named ifpap will invoke pap, one named ifpaprev will reverse the order of pages and invoke pap. It converts plain text to postscript, so that you do not end up getting an error message. The only filter you really need to install is the of filter:
        :of=/usr/local/atalk/etc/ofpap:
All other filters are optional (see man psf). However, I left a filter name for plain text,
        :if=/usr/local/bin/myif:\
where /usr/local/bin/myif is a simple shell script which allows me to make linebreaks in texts, which were written with a program that does line wrapping automatically (e.g. textedit). The psf filter unfortunately does not do any line breaking and ignors the setting for the paper width. I wrote my own filter, linebreak.c which does the job, and put the following two lines in myif (make it executable with chown 755 myif):
#!/bin/sh
/usr/local/bin/linebreak $* | /usr/local/atalk/etc/ifpap $*
If you set up your text filter in this way, linebreak will only look at the width of your printer (set with pw), while ifpap (psf) only looks at the length. It seems that psf assumes 0 being the first line, so set pl#63 if you want to have 64 lines per page in your output.

 If you don't need any line breaking, simply put

        :if=/usr/local/atalk/etc/ifpap:\
into your printcap file.

Now save your new printcap. If you try to print now, you will find out that it does not work, so read the following paragraph. As I mentioned before, the Unix name of the printer in the printcap file has no relation to the name the printer has in the AppleTalk zone. You need to create a file called .paprc in your printer's spool directory which contains the AppleTalk address of your printer! This is only one line. Note that in this file I did not need to put the printer's name in quotes, but other people report that it only worked with quotes on their system, and others report that it did not work at all with quotes. Thus try it without quotes first:

Pingo$ cat /usr/spool/theobald/.paprc
Theobald Chapin, III:LaserWriter@VLSB
Pingo$
So, now you're ready to go.

If you get an error message like "Turing:LaserWriter@Tech Support": NBP then try it without quotes. It might also be that you only have to put the name before the colon in quotes, like "Theobald Chapin, III":LaserWriter@VLSB in my case. Be creative and try all combinations if you have troubles. I don't know the universial answer to this problem.

For some additional hacks and workarounds with filters see also section 4.3 (known problems).

3.2 Test the printer

First check whether your printer daemon (lpd) is really present:
Pingo$ ps -xa | grep lpd
   45  ?  SW    0:00 (lpd)
  346 pp0 D     0:00 grep lpd
Pingo$
Try to print a PostScript file and a plain text file to make sure everything works. Probably you have to restart the printer daemon using lpc with the command restart lp, down lp and up lp. Then check the status
lpc> status
lp:
        queuing is enabled
        printing is enabled
        no entries
        no daemon present
lpc> 
lpc> quit
Now print your files using
Pingo$ lpr -P lp filename
If everything is all right, the status file in your spool directory should now contain the most recent status information of your printer :
Pingo$ cat /usr/spool/theobald/status
job: Paul; status: busy; source: LocalTalk
Pingo$

3.3 Assign this printer a name for AppleShare clients

If you now go to a Mac and try to select your "new" printer you will find out that it shows up with the hostname of your Linux box. This might not be very satisfactory, therefore you need to create or edit the papd.conf file in the etc directory of AppleTalk, /usr/local/atalk/etc/papd.conf (read man papd for details). The minimum you would do is putting the name you want to give your printer into this file, followed by :\ like in a printcap entry. On the second line you specify the name this printer has under Linux with the pr option. My entry looks like this:
Pingo$ cat /usr/local/atalk/etc/papd.conf
Pingo Mac LaserWriter:\
        :pr=lp:
Pingo$
This means that the (default) printer variable lp is given the name Pingo Mac LaserWriter for AppleShare clients. You will realize that a Mac user now has access to printer Theobald Chapin, III directly and via my Linux box, where the printer's name is Pingo Mac LaserWriter. For me it's important to be able to print directly to this printer, and when working on the Mac the printing via my Linux box seems much faster, since Linux will do the spooling and the printjob disappears almost instantly from my Mac desktop.

 If you want to register your printer in a specific zone (not the default zone), you just specify this zone with an @zonename extension in your papd.conf file:

MotorsLab@EEAP:\
        :pr=ee3rd:

3.4 What's the difference with a local printer attached to a Linux box?

The major difference between a local printer attached to a Linux box and an Appletalk printer is that you just specify your printer in a standard way in your /etc/printcap, with lp= set to the propper printer device (e.g. /dev/lp1 for the first parallel port), and you don't need to install the ifpap and ofpap printer which DIRECTLY print to an Appletalk printer. This is an example of such a /etc/printcap file:
/etc/princap:
lp:lp=/dev/lp1:sd=/usr/spool/lp1:sh
And then in your papd.conf you can define this printer to be available to Mac users:
/usr/local/atalk/etc/papd.conf:
HP LJIIIp:\
        :pr=lp:\
        :pd=/usr/local/atalk/etc/HP_LaserJet_IIIP.ppd:
Check out the detailed information given by Mike Pearson and Bill McGonigle on using Ghostscript together with Netatalk if your local printer is not a PostScript printer.

3.5 What's different for a non-local non-Appletalk Ethernet printer?

See also the man printcap manual page to solve this problem. The key is to specify the remote-queue machine with the rm= option and specify the printer name on the remote machine with the rp= option. As an example:

Your Linux box is named castor and you want to print to an ethernet printer whose IP address is named POLLUX. If you do not know the internal name the POLLUX printer knows for itself, it is very likely that it is called lp like a standard printer. Then your /etc/printcap would look like this:

lp|Pollux printer:\
        :sd=/usr/spool/pollux:\
        :rm=pollux:\
        :rp=lp:\
        :pl#63:pw#85:\
        :mx#0:\
        :sh:sf:\
        :lf=/usr/adm/lpd-errs:
 

4. Troubleshooting

4.1 General Strategy

If you have trouble printing to your printer, even though it worked fine when you set up everything as I just described, look into your /usr/adm/messages and /usr/adm/syslog files. As soon as you try to print using the psf filter, you will find an entry in /usr/adm/messages. See an example of how it looks when everything is fine:
Feb 12 17:47:52 Pingo ofpap[1443]: starting for ?
Feb 12 17:47:52 Pingo ofpap[1443]: sending to pap[1444]
Feb 12 17:47:52 Pingo ofpap[1443]: straight text
Feb 12 17:47:59 Pingo ofpap[1443]: 1444 done
Feb 12 17:47:59 Pingo ofpap[1443]: pausing
Feb 12 17:48:01 Pingo ifpap[1447]: starting for ?
Feb 12 17:48:01 Pingo ifpap[1447]: sending to pap[1448]
Feb 12 17:48:01 Pingo ifpap[1447]: straight text
Feb 12 17:48:09 Pingo ifpap[1447]: 1448 done
Feb 12 17:48:09 Pingo ofpap[1443]: restarting
Feb 12 17:48:09 Pingo ifpap[1447]: done
Feb 12 17:48:09 Pingo ofpap[1443]: done
Feb 12 18:00:46 Pingo ofpap[1481]: starting for ?
Feb 12 18:00:46 Pingo ofpap[1481]: sending to pap[1482]
Feb 12 18:00:46 Pingo ofpap[1481]: straight text
Feb 12 18:00:51 Pingo ofpap[1481]: 1482 done
Feb 12 18:00:51 Pingo ofpap[1481]: pausing
Feb 12 18:00:52 Pingo ifpap[1485]: starting for ?
Feb 12 18:00:52 Pingo ifpap[1485]: sending to pap[1486]
Feb 12 18:00:52 Pingo ifpap[1485]: straight text
Feb 12 18:00:57 Pingo ifpap[1485]: 1486 done
Feb 12 18:00:57 Pingo ofpap[1481]: restarting
Feb 12 18:00:57 Pingo ofpap[1481]: done
Feb 12 18:00:57 Pingo ifpap[1485]: done
If something is wrong, you get a message in /usr/adm/syslog like:
Feb 12 10:04:59 Pingo papd[70]: No such printer: "lp"
Feb 12 10:04:59 Pingo papd[70]: printcap problem: "lp"
(your default printer variable lp is not defined)
Feb 12 17:02:21 Pingo ofpap[1149]: 1150 died with 1
Feb 12 17:02:21 Pingo lpd[1148]: lp: output filter died (1)
Feb 12 17:02:26 Pingo lpd[1148]: lp: Daemon filter 'f' terminated (11)
Feb 12 17:04:48 Pingo lpd[1195]: lp: Daemon filter 'f' terminated (11)
Feb 12 17:08:03 Pingo lpd[1216]: lp: Daemon filter 'f' terminated (11)
Feb 12 17:10:00 Pingo lpd[1228]: cannot execv /usr/local/bin/linebreak|/usr/local/atalk/ifpap
Feb 12 17:11:51 Pingo lpd[1244]: /usr/adm/lpd-errs: No such file or directory
(/etc/printcap does not accept a pipeline in the definition of if; that's the reason why I used a script file /usr/local/bin/myif. Also I had forgotten to create the file /usr/adm/lpd-errs, which I defined in /etc/printcap.)

4.2 Unknown Problems

First read through Section 4.3 with the known problems. If you do not get any helpful information send me an e-mail and attach your /etc/printcap and your /usr/local/atalk/etc/papd.conf files with it!

nbplkup shows the printer's name and address, but I do not get any response with papstatus from that printer.

Is there a way to keep a printing quota for each Mac user printing via my Linux box?

4.3 Known Problems

I get a lot of feedback from people who have trouble, so I'd like to make some of the information available for everybody. This will be a growing list of unsorted items. Just check out whether your problem is described below.

4.3.1 No output from plain textfile

Check your /usr/adm/lpd-errs file for an entry like
unprintable character (0x9a)!
This is a problem with psf, the filter used to print. Locate the file psf.c in your netatalk distribution, make it writeable (chmod 644 psf.c). Locate the second line where unprintable character is found. The first occurence (out of 2) should be in line 402 and the second in 496 or so. The second is probably the cause of your problem. Replace the part which reads
  if ( !isascii( *p ) || !isprint( *p )) {
      if ( !literal ) {
          fprintf( stderr, "unprintable character (0x%x)!\n",
                  (unsigned char)*p );
          return( 2 );  /* Toss job */
      }
      printf( "\\%o", (unsigned)*p );
with
  if ( !isascii( *p ) || !isprint( *p )) {
      if ( !literal ) {
          fprintf( stderr,
                  "unprintable character (0x%x) converted to ?!\n",
                  (unsigned char)*p );
          /* return( 2 );*/     /* Toss job */
          putchar( '?' );       /* Don't toss job!      */
      }
      else{
        printf( "\\%o", (unsigned)*p );
      }
Now you type make at the prompt in the netatalk directory (not in the directory where psf.c sits, because make will not know the path to pap in this case!). Then copy the new psf to its propper location (/usr/local/atalk/etc). What this does is only the following: it replaces the unprintable character by an interrogation mark and goes on without tossing the job. Maybe someone has the motivation to write a better psf which converts "unprintable" characters to their printable PostScript equivalent? But pay attention to the copyright of psf, if you do so!

4.3.2 No umlauts and national characters

As mentioned just above, the psf filters do not support extended character sets. However, nenscript does. But since this is not a filter of the type which could be directly used in the printcap setup, you will have to make a workaround. My setup defines an additional printer which deals with plain text, using nenscript. /etc/printcap looks like this:
#
# Apple LaserPrinter Select 360 on AppleTalk:
#
lp|Pingo LaserWriter|Theobald Chapin, III:\
        :sd=/usr/spool/theobald:\
        :lp=/dev/null:\
        :pl#61:\
        :pw#80:\
        :mx#0:\
        :sh:\
        :sf:\
        :lf=/var/adm/lpd-errs:\
        :if=/usr/local/bin/myif:\
        :of=/usr/local/atalk/etc/ofpap:
#
# Special setup for plain text files, to convert to PostScript using nenscript
# instead of psf (which doesn't process the whole ISO characterset)
#
text:\
        :sd=/usr/spool/textprinter:\
        :lp=/dev/null:\
        :mx#0:\
        :sh:\
        :sf:\
        :lf=/var/adm/lpd-errs:\
        :of=/usr/local/bin/textfilter:
The file /usr/local/bin/textfilter is a shell script containing the following lines:
#!/bin/sh
/usr/bin/nenscript -P lp -2 -r -T US -i "Werner Eugster"
Unfortunately I didn't find a way to preserve the name of the file to be printed, therefore I used the -i option with my name to label the output. You may find more sophisticated setups, using the user name from the Unix environment variable.

 In this setup, I get plain text printed on landscape paper (option -r) in two columns (-2) sent to the standard printer lp. To print plain text, I use the command

lpr -P text plain.txt
So, first of all, the printer defined as text converts plain text to PostScript using nenscript (which processes the full ISO character set) and hands it over to the printer defined as lp. Thus, using lpq will show you that the print job turns up in the default (lp) printer queue saying it's coming from stdin, which is ok.

 If anyone has some idea how to set things up such that the filename is printed in the header line, I would appreciate this feedback!

4.3.3 My setting of page length and page width is ignored

That was my bug. Check the part where I described myif above. You have to add $* twice in the second line in the file, which now reads
#!/bin/sh
/usr/local/bin/linebreak $* | /usr/local/atalk/etc/ifpap $*

4.3.4 Print job is sent to printer but is never printed

There are many such problems. One which was reported to me by Paolo Supino is the following:

 "At a quick inspection of the output of nbplkup (to see if there are strange sniffers, viruses lurking around), I saw that the printers on the network have the same node number as our NT SERVER (which spools the Windows PCs). This was wrong.
1. NT SERVER is a very bad spooler.
2. It's supposed only to spool the Windows Machines.
3. Even though not instructed to capture all the incoming traffic to the printers on the network it did.
Solution: Disabled totally the print server for Macintosh on the NT server. Edited the .paprc file in the spool directory so it points directly to the printer. Restarted the computer so it will have a fresh memory."

 

4.3.5 My printer doesn't take the paper from the tray I want

With the default setup, everything will be printed on paper from the standard printer tray. If you want to setup your printer in such a way that it takes paper from another tray than the default one, try the following:

Modify your /usr/local/bin/myif and pipe everything through awk or any other filter program, that can write an additional line into the pipe after the header line. E.g. I tried the following in my /usr/local/bin/myif:

#!/bin/sh
/usr/local/bin/linebreak $* | awk '{if(NR==1&&$1~"%!"){print;print "statusdict begin /manualfeed true store end\n";}else{print}}' | /usr/local/atalk/etc/ifpap $*

(make sure there are no physical linebrakes in line number 2). What this does is: it tells your printer to take the paper from the manual tray. For other trays replace the text in the quotes ("statusdict begin /manualfeed true store end\n") by the appropriate command from the following list.
Tray PostScript command
Front paper tray "statusdict begin 0 setpapertray end"
Rear paper tray "statusdict begin 1 setpapertray end"
Manual paper tray "statusdict begin /manualfeed true store end"
The PostScript commands to define the output trays are
Tray PostScript command
Upper output tray  "0 statusdict /setoutputtray get exec" 
Lower output tray  "1 statusdict /setoutputtray get exec" 
Of course, if you want to define input AND output tray, you must have two lines inserted into your postscript file.

However, this only works for input which is already PostScript. If you want the same for text input which is first converted to PostScript, you need to modify the psf.c file and produce a new psf filter (don't forget to really install it in your /usr/local/atalk/etc directory!). What you have to do is find the line where %%!PS-Adobe-2.0 is printed (approximately line 379, it must be in function textps()). Add a new program line below this line which says
printf( "statusdict begin /manualfeed true store end\n" );
(again, you may want to replace the text within the quotes with what is appropriate for your system). Then recompile psf and install it.

Davis Goodman ended up with the following myif script which finds out whether you want to print to letter size or legal size paper. If it's legal, the PostScript command to select the rear tray is issued, otherwise the default tray is used to take the paper from.

#!/bin/sh
bounding=`grep BoundingBox $8 | cut -d" " -f5 `
if [ "$bounding" = "" ]; then
  /usr/bin/awk '{if(NR==1&&$1~"%!"){print;print "statusdict begin 1 setpapertray end\n";}else{print}}' | /usr/local/atalk/etc/ifpap $*
else
  /usr/local/atalk/etc/ifpap $*
fi
This works with Netscape and your own software might produce different values for the BoundingBox. I just included this example by Davis to give you a hint where to start if you want to do similar hacks.

 An example comes from Tomas Pospisek who defined a printer name for each tray of the same printer in /etc/printcap. Thus, in any application or in the shell you specify the respective printer name to get stuff printed to paper from a specific tray. Tomas' /etc/printcap looks like this:

# LaserWriter Pro 630 (Default Tray)
lp:\
        :sd=/usr/spool/lp1:\
        :lp=/dev/null:\
        :pl#63:pw#85:\
        :mx#0:\
        :sh:sf:\
        :lf=/var/log/lp-errs:\
        :if=/usr/lib/atalk/filters/myif:\
        :of=/usr/lib/atalk/filters/ofpap:
#
# LaserWriter Pro 630 (Manual Tray)
lpm:\
        :sd=/usr/spool/lpm:\
        :lp=/dev/null:\
        :pl#63:pw#85:\
        :mx#0:\
        :sh:sf:\
        :lf=/var/log/lp-errs:\
        :if=/usr/lib/atalk/filters/myif_manual:\
        :of=/usr/lib/atalk/filters/ofpap:
and the myif_manual filter looks like this:
#!/bin/sh
/usr/bin/awk '{if(NR==1&&$1~"%!"){print;print "statusdict begin
/manualfeed true store end\n";}else{print}}' |
/usr/lib/atalk/filters/ifpap $*

4.3.6 Sending binary Postscript data via pap does not work

Christof Warlich writes: In psf.c, I simply replaced textps by copyio, which solved the problem perfectly for me, since I never need to print plain text. In magic.c, I only commented out the two occurences of the line "*stop = '\n';". That solved the problem for me, although the very first occurence of a carriage return is still replaced by line feed if the file starts with %!PS-Adobe-3.0.

4.3.7 Problems with the MacIntosh printer driver

This is a feedback from Antonio Vieiro Varela antonio@faraday.usc.es: I've been trying to print on some of our Linux boxes from our Macintosh unsuccessfully for a long time.

 The problem was in our Macintosh's printer driver. A LaserWriter version 7-something. We upgraded it to version 8 (8.3.something) and everything works now. We are printing.

 It was hard to detect, because we did all you said in your pages without success, and we thought the problem was in the Linux side, not in the Macintosh one.

 I am a Linux system administrator, and know _nothing_ about Mac's. I've also learnt that there are available printer drivers in the www.apple.com page (well, that's not surprising) and if you want to install them you need a program called Installer. This program is withing the printer driver disks, which you have to translate with a program called Disk copy.

 I didn't know about the disk-copy program. I just got the drivers and fighted the Mac trying to install them. No way. With the Disk Copy program everything was easiest.

4.3.8 Local printer prints from Linux, but not from Mac via papd

Edan Idzerda has a web page (http://www.cec.mtu.edu/Doc/FAQ/netatalk.html) which actually solved the problem for me. Instead of setting pr: to the printer name in papd.conf, he suggests piping it to lpr -Pprinter_name. As I mentioned to him, it's not very elegant, but since it works, why knock it?
 

4.3.9 My Mac LaserWriter is not hooked up directly to the Ethernet but to a local Mac box

This requires additional software to be installed on the Mac: "LaserWriter Bridge" (as I was told by Tony Sneyd). Ask your Mac gurus where to get this puppy, I do not have it.
 

4.3.10 Problems printing from Macs with OS 8.1

Richard writes that printing locally from Linux worked, but when printing from a Mac with OS 8.1 unknown spooler errors were produced. His solution: use piping to lpr instead of directly specifying a printer, and use a LaserWriter driver with version number 8.4.1 instead of 8.5.1. Version 8.4.1 is the one from OS8 and can be gotten from the Apple Tech Support Site.


Up to now (15.07.98) I got constructive feedback and questions from people in
COM domain              34
EDU (USA)               30
US domain (USA)         3
GOV domain USA          5
NET domain              5
ORG domain              1
Australia               2
Austria                 5
Belgium                 1
Canada                  2
France                  4
Germany                 10
Hongkong                1
Iceland                 1
Italy                   5
Japan                   2
Namibia                 1
Netherlands             2
Poland                  2
Portugal                2
United Kingdom          2
Spain                   2
Switzerland             4

© 2 October 1998 by Werner Eugster (eugster@giub.unibe.ch)