Installing a complete printing system with HP DeskJet 640C under Linux
path › xlifecolumns20030315

Installing a complete printing system with HP DeskJet 640C under Linux

Xlife column for March 18, 2003: (Updated June 30, 2003)
Summary:
Learn how to install a full featured printing system based on LPRng, Ghostscript, a2ps and hpijs on your machine and also learn how printing works under Linux. The case subject is a HP DeskJet 640C printer, but the tutorial should be extensible to more HP printers and perhaps other brands as well. No remote printer solution, just some brief pointers for that, sorry.
  1. Introduction
    1. About the working environment used here
    2. Important update about switching from lpdomatic to foomatic-rip [2003-06-30]
      For people who can't find the lpdomatic script or LPD-O-Matic printer description files on linuxprinting.org anymore.
      HECK, EVERYBODY, READ THIS!
      1. Why should I update?
      2. Why did this happen?
      3. OK, what do I do?
      4. I want to do it the old way!
  2. Before we start
    1. Do you really want to do it my way?
    2. Err.. will your printer work under Linux?
    3. Look, it worked for me
  3. Quick download list
  4. How everything works
    1. Quick run-through:
    2. The printing chain
  5. The printer device
    1. Guessing the device
    2. Testing the device
    3. Device support in the kernel
    4. Very short documentary on the device mating habits
  6. The spooler system (LPRng)
    1. What it does
    2. Installation
    3. Installing LPRngTool
    4. Checking the installation
    5. Starting and stopping the printer server
    6. Printer server configuration
    7. Do you need IFHP?
    8. Testing the configuration
    9. Small rant about Postscript
    10. Final note on the LPRng inner workings
  7. The Postscript -> HP converter (hpijs)
  8. a2ps
  9. Ghostscript - the Postscript processor
    1. Installing Ghostscript
    2. Important: get the Ghostscript fonts
  10. Filtering scripts
    1. lpdomatic
    2. The printer description file
      1. Fixing distorted or oversized printing
    3. foomatic.gswrapper
    4. Putting them together
    5. Configuring lpdomatic
      1. filter.conf
      2. lpdomatic itself
  11. Testing the printing chain
    1. Debugging the printing chain
      1. Getting information
      2. Test the chain link by link
  12. Printing from applications
    1. StarOffice and OpenOffice
    2. Gimp
      1. Gimp-print
      2. The Gimp printing dialogue
      3. Setting up printing options
      4. Actually printing
    3. Other applications
    4. Managing the job queues
  13. Miscellannea
    1. Where to get more help
    2. Don't forget the security!
    3. Why not use CUPS?
    4. You read this all the way to the bottom?!

1 Introduction

OK, so you've got a printer on your desktop and some random application running in Linux. And you suddenly feel the need to print the document you were working on. This column will teach you how to set up a full fledged printing system on your Linux box from scratch, while explaining the details on the way so you end up a smarter Linux user.

1.1 About the working environment used here

Throughout the column there will be shell commands examples. The commands prefixed with $ are meant to be run as a non-privileged user, and those marked with # must be run as root.

Please note that I like to install stuff in the /opt directory. Applications may assume that everything gets installed in traditional places under /usr, so please follow my instructions carefully to overcome any problems.

If you're gonna install stuff in /opt too, it's a good idea to save the output from "make install" in a file such as /opt/app-name/install.log. Just in case it makes a boo-boo and you wanna see what went down.

1.2 Important update about switching from lpdomatic to foomatic-rip

Please read this update carefully. Since I first wrote this column, one major change has occured.

1.2.1 Why should I update?

Here are the problems you will encounter if you don't:

  • you won't be able to find the lpdomatic filtering script on linuxprinting.org anymore;
  • you won't be able to find LPD-O-Matic printer description files for your printer on linuxprinting.org anymore.

1.2.2 Why did this happen?

Because instead of lpdomatic you have the foomatic-rip script now, which doesn't need LPD-O-Matic files anymore but uses PPD files instead, which can still be found where they used to be. This is a good thing. Instead of two databases with printer description files and two standards we have only one now.

1.2.3 OK, what do I do?

Simply keep on reading the rest of the column because it applies just the same. The only changes are the following:

  1. Instead of the lpdomatic script download foomatic-rip. It is very similar to lpdomatic, you can just subtitute it while reading this column and everything about lpdomatic should still apply!

  2. You don't need the LPD-O-Matic file anymore, just the PPD file.

  3. The lines in /etc/printcap that look like this:

    :if=/opt/lpdomatic/bin/lpdomatic
    :filter_options= --lprng $Z /etc/lpdomatic/hpdj640c.desc

    Should be changed to look like this:

    :if=/opt/lpdomatic/bin/foomatic-rip
    :filter_options= --lprng $Z /etc/lpdomatic/hpdj640c.ppd

1.2.4 I want to do it the old way!

If you have a HP DeskJet 640C and you really want to go with the old way of doing things, you can get the LPD-O-Matic description file for HPDJ640C here.

2 Before we start

2.1 Do you really want to do it my way?

You may not want to. It's not necessarily the hard way, since I try to explain everything very well, but it's not easy either. You may want to check out your distribution's package manager, install a printing system like CUPS or LPRng and the associated drivers, and from where I'm standing it's a 50-50 chance (perhaps better) you'll get your printer working in just a couple of minutes. It may not make you a better Linux user, but then again you won't end up throwing your printer out the window in frustration either. Linux can be like that.

Consider your options well, and if you're keen on learning something new or if you can't get drivers for your printer straight out of the distro box, you're most welcome to try it my way.

2.2 Err.. will your printer work under Linux?

You must find out what kind of support is there for your printer in Linux! You may find out that it's gonna work perfectly, that you're gonna miss some functionality, or that you can't use it at all.

Why is that, you may ask. Because printer manufacturers are people too. They may have chosen to make a cheaper printer by taking part of the functionality and putting it on a floppy disk or CD-ROM as drivers instead of coding it into hardware chips. And guess what unique operating system they're producing drivers for. No, it's most likely not Linux.

Some printer manufacturers (granted, less and less these days) are not gonna make the source of the drivers public and they won't write drivers for Linux. So maybe some crazy programmer out there is really bored and somehow reverse engineers the inner workings of the same kind of printer you have, or successfully adapts a driver from another. Then again, you may not be so lucky.

So it's very important to know if you're gonna be able to use your printer at all in Linux. If you intend to buy a new printer it's a very good idea to take your wish list and check it against the linuxprinting.org database, or even better against their recommended printer list, to see what's what. It's also a good idea that you read this column for some more printer buying tips and ask around in your local Linux Users Groups or in Linux dedicated forums or mailing lists.

2.3 Look, it worked for me

Please remember that I'm talking about my own experience here. We're talking a HP DeskJet 640C printer and LPRng for a spooler system, with the printer attached locally to the computer (i.e. no network printers). What I offer may or may not work for you. If, for instance, you went to the above database and found out that your printer only works in a setup that's different from my own, I can't help you anymore. If you have a (even slightly) different printer or if the gods hate you, things may go wrong. Live with it.

So what I'm trying to say is that this column may end up not getting you a working printer at all. In any case, it should still give you a good idea about how printing works in Linux.

3 Quick download list

You may want to download everything you need first and get reading after that. This is what you need:

  • LPRng
  • LPRngTool (not crucial, but highly recommended!)
  • Ghostscript (it doesn't matter if it's APFL or GNU as long as it's a recent version)
  • Ghostscript fonts
  • lpdomatic script (it's the same no matter what printer you have); lpdomatic is for LPRng, if you have something else get something else [Read the update!]
  • foomatic-gswrapper script (it's the same no matter what printer you have)
  • hpijs (remember, I own a HP printer!) You can probably skip downloading the PPD description file below if you get this, it has a nice ppd/ directory included.
  • two printer descriptions (for lpdomatic and PPD) from the hpijs driver page on linuxprinting.org; there are some selection forms there, find your printer in the LPD-O-Matic and PPD-O-Matic section respectively and then generate the files [Read the update!]. The hpijs package also comes with a big selection of PPD files included.
  • a2ps
  • gimp-print (if you want to print from Gimp); note that only gimp-print supports the full 600x600 DPI in Grayscale mode for DeskJet 640C

4 How everything works

4.1 Quick run-through:

You connect your printer to your computer. The Linux kernel ensures a "raw" connection to the printer (for any application that wants to use it) in the form of a device.

Technically you could already start printing, but there are two issues: first, you need some common ground, a common language to describe all printing jobs with, and you need the printer to understand that one language (instead of a myriad of languages). Postscript is a very good such description language and many people consider Ghostscript to be an excellent Postscript processor.

Second, you can't just have all applications madly rushing in to use only one device; it's better to have a "middleman" that receives print jobs, organises a queue and makes sure you can quickly tell five applications to print 100 pages overall and then go about your business and come back to a properly filled up exit tray. Such a middleman, namely LPRng, is called a printing spooler and can do the above, share your printer on the network or Internet, filter printing jobs to ensure they are properly understood by the printer, and more.

In filtering, LPRng is aided by a few files you can get from linuxprinting.org as well as by a2ps which is basically a "something else"-to-Postscript converter.

Finally, hpijs is a Ghostscript plug-in that will translate Postscript into the PCL language that my HP DeskJet understands.

4.2 The printing chain

Pay attention, kids, because this is very important. The entire process of printing can roughly be described graphically like this:

application -> lprng -> linuxprinting filters -> a2ps -> ghostscript -> hpijs -> lprng -> device -> printer

In the following I'll tackle the elements in the above chain in seemingly random order. It's not random, it's just right so you can properly understand everything and easily identify causes of failure. Please report back to the chain from time to time and see how everything comes to fit together.

5 The printer device

5.1 Guessing the device

How does your printer connect to the computer? It may use a serial port (although it's unlikely, since it's the slowest choice), a parallel port or an USB port. Serial ports have 9 pins and their corresponding devices in Linux have names such as /dev/ttyS0, /dev/ttyS1... Parallel ports have 25 pins and they're most likely called /dev/lp0, /dev/lp1... Finally, USB port connectors look like a single rectangular sheet of metal and they are most likely to be found under a name such as /dev/usb/lp0.

You must've noticed the numbers that form the device names above. 0 means the first such device, 1 the second, and so on. If you have a parallel or USB printer chances are it's the first such port (unless you have more than one printer). If it has a serial connector you'll have to check whether there are other peripherals that also use serial ports: mice and external modems are the most likely candidates, but other stuff like an infrared receiver may also use a serial port. Figure out which one is your printer.

5.2 Testing the device

OK, so you have made a guess about what device your printer should be accessible through. Turn the printer on, fire up a shell and type the following command:

echo -e "This text should appear on the printer\f" > /dev/usb/lp0

What this does is send the text directly to the device. Please note the "\f", it's a special character and it means "form feed" -- it tells the printer to eject the paper after it's done printing.

/dev/usb/lp0 is my device, replace it with yours. The above may or may not work. If it doesn't you should get a message stating "/dev/usb/lp0: no such device". This may be due to one of the following: either you didn't get the right device, or you don't have support for that kind of device in the kernel you're currently using.

You may also get this message: "/dev/usb/lp0: Permission denied". Make sure the device is readable and writable by the user that you're trying to perform the test as. On my system I have /dev/usb/lp0 owned by user root and group lp, with mode 660. That's because 99 times out of 100 I use LPRng to print, which runs as user lp. Note: it's probably a good idea (security-wise) to use the above permissions and always use 'lpr' to do the printing.

Please note that if you get the right port (and the printer is on, and you have paper in it) you should get that text printed. That would make this test successful.

If you don't get an error message but no printed paper either, it's not a successful result. A successful result means getting the message printed, getting something seemingly random printed, getting the printer to twitch, moan, blink, anything. If it just stays there staring at you with an unmoving green led, you failed.

If you failed, try some more devices. Really only the first two serial devices, the first two parallel devices or the first USB device should be of any use. Go as high as four (4) on all kinds if you feel like it. If you run out of devices and still nothing, it's time to check the kernel.

5.3 Device support in the kernel

Any kernel devised for the desktop user should include support for the serial and parallel ports out of the box. I'm not so sure about the USB ports. Your chances of having proper support for your printer port increase if you're using the kernel that came with your distribution. If you compiled the kernel yourself you may have left it out (you'd be amazed of what people can leave out of their kernel). Let's check.

Here's a quick way to check for USB printer support -- run the following:

dmesg|grep -i usb

The output (if any) should contain stuff about USB and about a printer. Ideally, you'll get to see "usblp" or "USB Printer" somewhere.

I'll also tell you where in the kernel config to look and check if you've got proper support:

  • serial:
    Character devices / Standard/generic (8250/16550 and compatible UARTs) serial support
    (CONFIG_SERIAL in .config)
  • parallel:
    Parallel port support
    (CONFIG_PARPORT in .config)
  • USB:
    USB support and USB Printer support
    (CONFIG_USB and CONFIG_USB_PRINTER in .config)

Please note that generic USB support is not enough, you also need to specify what you're gonna use it for (the printer support).

It should be as easy as grepping your kernel .config file (usually found in /usr/src/linux/ after the configuration stage) for the codes given above in the brackets and see if they're commented out or not. Well, if you're the kind of person who compiled his own kernel you should be able to figure it out.

If the right support is built inside the kernel you should be OK. If it's compiled as modules you should make sure you load the proper modules first. Check the help for each of the above config options (Documentation/Configure.help in the kernel source tree), they'll tell you what the modules should be called.

5.4 Very short documentary on the device mating habits

A device, the printer and the associated kernel support work together. It's a threesome, so to speak. If it's not the right device, you don't have kernel support or the printer is turned off, it won't work. On the bright side, if the support comes as modules and you have loadable module support, the proper modules will be automatically loaded when you try to poke the device. But only if it's the right device.

6 The spooler system (LPRng)

6.1 What it does

LPRng can do a lot of things for you. It works as a server, allowing applications to connect to it over the network and print to your printer. It provides a simple tool for printing almost any kinds of document: the "lpr" command, which in its most basic form only needs the document produced by an application and a printer name and takes care of everything. You'll notice most applications come with "lpr" predefined as their printer command, which goes to prove that this is a very popular printing spooler system. Even other, completely different, spooling systems provide a "fake" lpr command which redirects to their own respective tools.

LPRng will queue print jobs up nicely, ensuring that they don't get mixed up and that applications don't have to fight each other over the use of the printer port. The applications typically put the document you want to print in a temporary file for LPRng to read. LPRng does that, then picks up the document and puts it in its own spool directories. So once you've pressed "print" in your application (well, actually a short time after that), the application is no longer needed for printing. You may very well close it, the printing continues just fine.

In fact, LPRng will remember printing jobs even after reboot! If, say, power went down and your machine with it, as soon as you reboot and lpd (the printer daemon) starts, your printer will happily continue printing where it left off. even better, actually, it re-does the job during which the interruption occurred. However, sometimes such over-pampering from your LPRng can be annoying, you must remember to keep the printer off when you restart in such a situation, and sort through the printing jobs manually.

LPRng will also run the printing document through whatever filters you indicate before pushing it out the printer device. This ensures that no matter what kind of document an application produces, it can be transformed into a format your printer understands. Having "lpr" to rely on as common ground also allows applications to specify often encountered options, such as what paper format to use, what orientation, how many colours, what printing quality and so on.

6.2 Installation

Installing LPRng from source is very simple. It's one of those veteran applications that have pretty much gotten over details such as compilation problems. Here's how to install LPRng:

Attention: you may already have a lpd or lp user:group pair defined on your system. Look in /etc/passwd and /etc/group to find out. If they are there you may as well use them.

$ mkdir ~/tmp; cd ~/tmp
$ tar xvzf lprng-version.tar.gz; cd lprng
$ ./configure --prefix=/opt/lprng --with-userid=lp \
--with-group-id=lp --enable-force_localhost --disable-setuid \
--enable-unixsocket --disable-nls \
--with-libiconv-prefix=/opt/libiconv --with-openssl=/opt/openssl \
--sysconfdir=/etc
$ make
$ su
# groupadd lp
# useradd -g lp -d /var/spool/lpd -s /bin/false -c "printer" lp
# make install

You unpack the source tarball distribution somewhere, then you run configure to, well, configure it. The options above tell the application to install in /opt/lprng; to run as group and user lp; to force binding the server against localhost; to not install executables setuid root; to enable usage of unix socket connections as opposed to network; to not use localised error and info messages (i.e. in another language that English); where libiconv and openssl is located; where to put configuration files.

You may skip --sysconfdir and --prefix and you'll get stuff installed in /usr and /etc, but it's gonna be tough uninstalling it. You only need to indicate where libiconv and openssl are if they are also installed in a non-standard place such as /opt.

Next you "make" aka compile the package, and then switch to root for the actual installation (make install). If you don't already have the user and group that LPRng will run as you should create them before the installation.

More info in the source tarball, in the INSTALL and README files.

Please note that in some older versions of LPRng you needed to edit the Makefile file found in the root dir of the unpacked archive between the configure and make steps and add "DGETENV=0" at the beginning. This disabled the use of the LPD_CONF environment variable for LPRng to find its config file, which is a security risk. You'd better add the option in newer versions as well, just to be safe.

6.3 Installing LPRngTool

If you haven't downloaded LPRngTool too, please reconsider. It was designed to work alongside LPRng and it will provide you with easy configuration and some printer testing facilities. You can do all that by hand, but why not use a nice graphical tool.

Same as above, unpack, run configure, make, make install. No need for any fancy stuff for this one, just the following will do:

$ ./configure --prefix=/opt/lprngtool --sysconfdir=/etc
$ make
$ su
# make install

Add --disable-nls if localised messages piss you off.

6.4 Checking the installation

For both LPRng and LPRngTool to work, you need to add their installation bin/ and sbin/ dirs to the PATH environment variable, their lib/ dirs to /etc/ld.so.conf followed by running ldconfig, and maybe their man/ dirs to /etc/man.conf (or man.config). Here's the rundown:

# echo "PATH=\$PATH:/opt/lprng/bin:/opt/lprng/sbin:/opt/lprngtool/bin" >> /etc/profile
# echo "/opt/lprng/lib" >> /etc/ld.so.conf; ldconfig
# echo -e "MANPATH /opt/lprngtool/man\nMANPATH /opt/lprng/man" >> /etc/man.conf

Since I'm lazy, I won't mention this again in the rest of the column, but you need to do it for every package you install in /opt.

6.5 Starting and stopping the printer server

LPRng is a sweetie and after detecting a Red Hat system it creates the /etc/init.d/lpd script which can be used to start and stop the printer server. Do a chkconfig --list to check if the lpd script appears and a chkconfig --add lpd to enable starting it upon system startup. Starting and stopping LPRng is as simple as calling /etc/init.d/lpd start and /etc/init.d/lpd stop ("restart" and "status" also work).

6.6 Printer server configuration

By long lasting tradition, printer configurations are kept in /etc/printcap. The format is text-only and fairly common, but different printing spooler software will put their own quirks in there. You can have the same keyword, but the associated value may only be meaningful for a certain printing server. That's why we need LPRngTool, so go fire it up.

Important: in addition to editing /etc/printcap, LPRngTool also manages the spool directories (/var/spool/lpd/) for each printer. If you don't use LPRngTool remember to do it by hand! Anyway, it's always a good idea to use LPRngTool to configure /etc/printcap with!

Hint: there are screenshots of LPRngTool on the LPRng homepage, check them out if you can't run LPRngTool right now.

After starting it (as root) press "View Printcaps", then "Add". Choose "Printer Port" when asked. Ignore the error message if it appears next, it only probes parallel ports and you may have an USB or serial printer. OK, now start filling entries as follows; remember to use the help buttons (those with question marks on them) -- they offer very good info.

  1. Erase everything, fill in just the following.
  2. Names = hpdj640c|MyPrinter|alias2|alias3 (just choose some simple to remember words)
  3. Comments = go crazy here
  4. Spool directory = /var/spool/lpd/%P (should've been already filled in)
  5. Printer device = /dev/usb/lp0 (this is mine, use yours)
  6. Check "Open Device Read/Write"; note: your mileage may vary on this one if you're not sure you have a bidirectional printer *and* a bidirectional cable connecting it to the computer; if in doubt, uncheck this and test with it checked [much] later, after everything else has been ironed out.
  7. Check "User specified" Filter
  8. Job options = pagesize=a4 (I only use A4, ever); use the "Select LPR Job and Filter Options" for a helper dialogue which will add more options for you; there are all default options which will be used if the application doesn't specify it's own. Don't go crazy with options if you're not sure what they mean.
  9. Check "Printcap for: Server and Client (BOTH)"
  10. Check "Spool action: Localhost"
  11. Check "Printer type: Device"

OK, now for some Advanced Options:

  1. Erase everything, fill in just the following.
  2. Accounting File = acct
  3. Log File = log
  4. File limit = 0
  5. User specified printcap options (put one per line):
    :if=/opt/lpdomatic/bin/lpdomatic
    :filter_options= --lprng $Z /etc/lpdomatic/hpdj640c.desc
    [Read the update!]

Please note the above two paths. They lead to the filter script and the printer description sheet, which you'll get from linuxprinting.org. What this does is basically tell LPRng to run every printjob through that script, which script will receive the parameters on the second line. If you've read the helpers, you noticed that the "$Z" thing will be expanded to the default job and filter options you specified earlier, if any (pagesize=a4).

Click your way out through OK buttons.

6.7 Do you need IFHP?

You may have noticed that there was an filter called IFHP near the "User specified" one we chose. IFHP is LPRng's own "printer driver" collection. If you select it and then you find your printer under "Select Printer Model and Filter Options", you should download IFHP, install it and use it instead of the linuxprinting.org filtering scripts. Your mileage may vary on its usage. I went with those scripts simply because them plus hpijs meant support for my printer, which IFHP doesn't have to this day AFAIK (or it provides working support for another printer and I wasn't in the mood to experience trial and error). IMHO, hpijs has much more potential, being made by in collaboration with HP themselves.

6.8 Testing the configuration

Now we're cooking. So far, you've got your printcap entry. (Remember, we're still running LPRngTool). Use "File/View Printcap File" or just look at /etc/printcap to see how ugly it looks. Here's mine:

##LPRNGTOOL## DEVICE 
hpdj640c
:force_localhost
:filter_options= --lprng $Z /etc/lpdomatic/hpdj640c.desc
:if=/opt/lpdomatic/bin/lpdomatic
:lf=log
:lp=/dev/usb/lp0
:mx=0
:prefix_z=pagesize=a4
:rw
:sd=/var/spool/lpd/%P
:sh
[Read the update!]

Time to do some tests. Highlight your printer entry and start working with the "Tests" menu.

"Print ASCII directly to port" means basically the same test we did when we were testing the printer device. It will only print a couple of lines. This should work fine.

"Print ASCII test page" is a more elaborate test. It will still only use text, but will test a couple more printer facilities, such as proper alignment. The output page will contain some instructions on what to do if something's wrong. There shouldn't be much wrong.

The final test's outcome depends on whether your printer can "speak" Postscript or not.

6.8.1 Small rant about Postscript

What is Postscript anyway? Postscript is a language used to describe desktop publishing documents. It's not just a descriptive language, it is a full fledged programming language. This allows it to describe documents in a much smarter way that a simple descriptive format could.

Postscript ability is a very nice thing for a printer to have. However, a Postscript enabled printer costs much more. So if you're a regular person in terms of cash you're very likely to own a printer which doesn't know Postscript, but another (often proprietary) language, which is the case with my HP DeskJet 640c which can only "speak" PCL.

So if you have a Postscript enabled printer, the final test (please select whatever page size you want) will either produce a nice colour test page or a piece of junk. But please note that after the entire setup is complete (with filter scripts, Ghostscript and hpijs installed and working) the test page will be converted to HP's language by the filter, so you'll still get the nice page regardless of the fact that your printer may not actually support Postscript.

You may wonder why do we take this detour through Postcript land? Reasons:

  • There are next to none PCL converters out there, while Postscript is very good and many Postscript processors such as Ghostscript and a wad of other Postscript tools are freely available.
  • Most applications will use Postscript as the common ground when describing the documents for printing.
  • There are 99% chances you'll be able to get documents produced by regular Linux applications converted to Postscript.

So the best way to go, really, is to intercept all printing jobs, convert them to Postscript, then convert that to the printer's language. Instead of dealing with PCL many times we work with Postscript instead, and turn to PCL only when it really matters, just before the actual printing.

6.9 Final note on the LPRng inner workings

You may have noticed that LPRng appears twice in the job printing chain above. It's because LPRng is there from the beginning to the end. It doesn't actually do any conversion itself. LPRng is being handed a file from the application. It passes it to the linuxprinting filter, which runs it through a2ps, Ghostscript and hpijs as needed. Then LPRng picks up the resulting stuff and simply pours it down the printer device's throat.

7 The Postscript -> HP converter (hpijs)

Let's get hpijs out of the way so we can concentrate on more important stuff. You just need to download it, unpack it, compile and install it. Much like the LPRngTool installation:

$ ./configure --prefix=/opt/hpijs --sysconfdir=/etc
$ make
$ su
# make install

A few words about hpijs: this is a joint effort from HP and several enthusiasts to provide a Postscript to PCL converter in the form of a plugin which is used by Ghostscript. Do note that you won't need to run hpijs at any time by hand. The linuxprinting.org filter script (lpdomatic) runs Ghostscript, which in turn runs hpijs as needed.

hpijs is constantly improved and you should make sure you have the latest version at all times, because it can add new options and new facilities for a better printer usage. It supports most HP printers out there, even if some of them with limited functionality.

8 a2ps

a2ps started out as an "ASCII to PostScript" utility, but developed into a nice "any to PostScript" utility eventually. It's obvious why we need such a tool in our setup: since print jobs come in all kinds of formats, we first want to transform them into a common one (PostScript) before moving on. This is what a2ps does.

All you need to do is compile and install a2ps. You won't have to bother running it by hand if you don't want to, the filtering script does that for you. However, you may want to check it out in depth, since it can produce beautifully formatted Postscript and PDF.

$ ./configure --prefix=/opt/a2ps --sysconfdir=/etc \
--with-medium=A4 --with-encoding=latin2
$ make
$ su
# make install

The above means: install in /opt/a2ps; use /etc as the dir for config files; default paper size and character set are A4 and latin2, respectively. You may want to leave these out (don't know what the defaults are, sorry) or you can go with your own preferences. Common alternative choices are Letter for paper size and latin1 for encoding (US users, most likely). Of course, these are just defaults, which I've taken the custom of specifying everywhere. A printjob with specific requirements will override them.

9 Ghostscript - the Postscript processor

This thing can take a file written in Postscript and process it -- in other words, it understands the language and renders the document in preparation for display or printing, just like a PHP or Perl engine is used to run PHP or Perl scripts.

In case you're wondering (and because I love to rant), PDF is not PostScript. PDF is a derivative of PostScript made by Adobe, which eventually became very popular among Windows users. You'll be happy to know that under *nix there are a lot of very good free tools for processing and creating PDF and PostScript, unlike Windows where the PDF hype lead to expensive proprietary software being needed for PDF creation. That's part of the reason why a PDF file carries a certain weight: "wow, they had the money to produce PDF's at will" -- please.

I've already covered this, but let's just make sure we got it: why do we need Ghostscript? Because there are a myriad applications out there and they produce print jobs in all kinds of formats. But you only have one printer, which may speak Postscript or that other language that can be used if you have hpijs. So instead of expecting the printer to deal with all kinds of printjob formats we convert all of them to Postscript using a2ps. If the printer knows Postscript, very well. If it doesn't we use hpijs to convert Postscript to the proper language. Just one or two conversion steps, tops, and we've secured an usable printjob regardless which application produced it and how.

9.1 Installing Ghostscript

$ CPPFLAGS="-I/opt/libpng/include -I/opt/zlib/include \
-I/opt/libjpeg/include" LDFLAGS="-L/opt/libpng/lib \
-L/opt/libjpeg/lib -L/opt/zlib/lib" ./configure \
--prefix=/opt/ghostscript --sysconfdir=/etc --with-ijs
$ make
$ su
# make install

Ghostscript needed to be told where to find the PNG, ZLIB and JPEG libraries in my case, because I had them in /opt which is a non-standard place for them. Next I told configure to install in /opt/ghostscript, to put config files in /etc, and finally, to build the IJS plugin interface.

IJS allows Ghostscript to interact with third party software in the form of plugins and thus extend its functionality. As you may have already guessed, this will be needed for using hpijs.

After installation, run Ghostscript and check it's output to make sure you got the IJS interface in there:

$ gs -h

AFPL Ghostscript 8.00 (2002-11-21)
Copyright (C) 2002 artofcode LLC, Benicia, CA.  All rights reserved.
Usage: gs [switches] [file1.ps file2.ps ...]
Most frequently used switches: (you can use # in place of =)
 -dNOPAUSE           no pause after page   | -q       `quiet', fewer messages
 -g<width>x<height>  page size in pixels   | -r<res>  pixels/inch resolution
 -sDEVICE=<devname>  select device         | -dBATCH  exit after last file
 -sOutputFile=<file> select output file: - for stdout, |command for pipe,
                                         embed %d or %ld for page #
Input formats: PostScript PostScriptLevel1 PostScriptLevel2 PostScriptLevel3 PDF
Available devices:
   x11 x11alpha x11cmyk x11gray2 x11gray4 x11mono bmpmono bmpgray bmpsep1
   bmpsep8 bmp16 bmp256 bmp16m bmp32b deskjet djet500 laserjet ljetplus
   ljet2p ljet3 ljet3d ljet4 ljet4d lj5mono lj5gray cdeskjet cdjcolor
   cdjmono cdj550 pj pjxl pjxl300 uniprint ijs bj10e bj200 bjc600 bjc800
   faxg3 faxg32d faxg4 pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk pbm
   pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm
   pksmraw tiffcrle tiffg3 tiffg32d tiffg4 tifflzw tiffpack tiff12nc
   tiff24nc psmono psgray psrgb bit bitrgb bitcmyk jpeg jpeggray pdfwrite
   pswrite epswrite pxlmono pxlcolor bbox cljet5 cljet5c spotrgb spotcmyk
   devicen xcf nullpage
Search path:
   . : /opt/ghostscript/share/ghostscript/8.00/lib :
   /opt/ghostscript/share/ghostscript/fonts
For more information, see /opt/ghostscript/share/ghostscript/8.00/doc/Use.htm.
Report bugs to bug-gs@ghostscript.com, using the form in Bug-form.htm.

9.2 Important: get the Ghostscript fonts

Ghostscript is a complete rendering system, in some ways similar to XFree: while X renders windows on your monitor, Ghostscript renders documents for display or printing. So it needs fonts for that, and it needs its own set, which you should have already downloaded.

After you get them, make sure you put them in {prefix}/share/ghostscript/fonts. What "prefix" is depends on where you installed Ghostscript: if you've put it in /opt then it's /opt/ghostscript, otherwise it may be /usr or /usr/local. They're a bunch of .afm, .pfb and .pfm files. Forgetting to install these fonts and them wondering why printing doesn't work quite right is a very common pitfall.

10 Filtering scripts

10.1 lpdomatic

[Read the update!]

A very important part of the printing chain is a filtering script called lpdomatic that the very nice folks at linuxprinting.org have put together.

As you have noticed above, LPRng will run every print job through this script (it's a Perl script, so you must have Perl installed on your system -- try running 'which perl' to check). The script examines the document, runs it through a2ps, Ghostscript and hpijs as needed, and makes sure all options regarding printing are just right for your printer.

How does lpdomatic know about your printer? Simple: it allows you to specify a printer "description" file as a parameter at run time. Take a look at the LPRng configuration section above and you'll notice that in printcap we tell the script where to find the description file as well as a few other options such as the default preferred page size. And because the description file can be specified per each different printcap printer definition entry, you can very well use two or more printers, each with it's own description file.

Quick note: linuxprinting.org offers a more complex bundle called Foomatic which can make it easier to deal with an environment where you need to use many different printers. But as long as you're just a desktop user limited to one or two printers, lpdomatic will do just fine.

10.2 The printer description file

[Read the update!]

You can get the description file for your particular printer at linuxprinting.org on the hpijs driver page and then requesting the lpdomatic (LPD-O-matic) description for it. Save it in an intuitive place. I've put mine in /etc/lpdomatic along with a couple of other files which we'll discuss soon. I've called it hpdj640c.desc.

10.2.1 Fixing distorted or oversized printing

You may run into a nasty mishap whose cause may be hard to spot for the printing newbie: it may so happen that some of the things you print come out too big on one dimension or both, causing it to look "stretched" horizontally or vertically or both (doubled in size), respectivelly.

It's hard to realize what's going on at first. You may think that the margins are set wrong or that some down-and-to-the-right shifting occurs before realizing that in fact the document is twice as big as it should be.

This has to do with the printing resolution, or the pixel to inch conversion ratio, which is probably set wrong in the description file. A setting of 600 dpi (aka 600x600) for a 300 dpi (aka 300x300) printer will cause "doubling", and a 600x300 or 300x600 setting instead of 300x300 will cause "stretching".

Look for a section called 'Quality' in the description file (it's text, you can edit it). You'll notice several preset settings in the Quality sub-sections, which set various bits for the printer depending on what kind of printjob was requested. The 'driverval' value has a '-r' parameter which uses the wrong value (you can even look for '-r' in the file and jump directly to it).

Why would these settings be wrong? Well, the 'driverval' lines are parameters that get passed down to hpijs. Now would be a good time for you to skim through the HTML documentation that gets installed with hpijs, because it lists supported resolutions for all the printers that hpijs works with. For my printer, the HP DeskJet 640C, hpijs only offers 300dpi, so if the description file came with a '-r600' setting I will get doubling. I need to modify all the lines and set them to '-r300'. Look in the hpijs manual I mentioned, find your printer (or printer class) and see what you should use. If you got a doubling or stretching effect is quite possible that you'll figure out the '-r' parameter was wrong.

10.3 foomatic.gswrapper

foomatic.gswrapper is also a Perl script. It is not a filter itself, it is just called by lpdomatic and it makes sure that Ghostscript "behaves" properly as a filter for the printjob at hand.

A common pitfall is forgetting about foomatic.gswrapper and not installing it. lpdomatic has a fallback mechanism which will allow it to work even without it. A, but some of the printjobs will fail then, and it can be tricky to figure it out.

10.4 Putting them together

I have lpdomatic and foomatic.gswrapper in /opt/lpdomatic/bin and the printer description file as /etc/lpdomatic/hpdj640c.desc. Don't forget to make sure that the printer parameters (in /etc/printcap, or edited with LPRngTool) point to the exact full-path locations of the two files (lpdomatic and hpdj640c.desc).

10.5 Configuring lpdomatic

[Read the update!]

lpdomatic takes it's setting from two places: a file called filter.conf, which I've also put in /etc/lpdomatic; and some variables set inside itself.

10.5.1 filter.conf

textfilter: a2ps
debug: 1

Common pitfall: don't put the full path to a2ps here, use just "a2ps". The "a2ps" you see here is not a program's name, it is a keyword which will tell lpdomatic to use a2ps. If you want to make sure lpdomatic knows where a2ps (or any other program it needs) is, put its path in the $configpath below. Using a full path instead of just "a2ps" (or "enscript", or "mpage" for that matter) will have weird effects, one being that no matter how you modify lpdomatic to run a2ps with your own parameters, it won't work.

If you set debug to '1' you'll get a report log created for every printjob. It's very useful in order to see how the printing goes and to spot any problems, but don't leave it at '1' once everything's OK, because it's a security hole. See below to find out how to set the location of the debug log.

10.5.2 lpdomatic itself

[Read the update!]

You can (should) edit lpdomatic with a text editor and modify a few things.

First of all, the paths in which lpdomatic looks for all its friends. There's gonna be trouble if you put any of the programs needed in the printing chain in some non-standard place and lpdomatic can't find them. It's just gonna quietly work around it and you won't know what went wrong unless you examine the debug log, or not even then.

So look for the $execpath variable and add the paths where all the stuff you need is. Common pitfall: assuming that setting the PATH environment variable (via shell code or via the "filter_path" printcap option) is enough before lpdomatic runs; actually, lpdomatic overrides PATH with the value of $execpath!

my $execpath = "/usr/local/bin:/usr/bin:/bin:\
/opt/lpdomatic/bin:/opt/hpijs/bin:\
/opt/ghostscript/bin:/opt/lprng/bin:/opt/a2ps/bin";

You have to tell it where to find filter.conf:

my $configpath = "/etc/lpdomatic";

You have to specify which PostScript convertor will be used, in my case it's a2ps (if you don't, it will use the setting in filter.conf to determine it). Just like in filter.conf, please note that this is not the name of the program, it's just a keyword, so use exactly "a2ps".

my $enscriptcommand = "a2ps";

You can specify that you want a debugging log to be created (again, the option in filter.conf is also checked if this one's missing):

my $debug = 1;

Where should the debug log be placed:

my $logfile = "/tmp/prnlog";

Finally, some customization of a2ps. By default, a2ps produces two normal pages squeezed side by side on a landscape page, with borders, header, footer and aditional information. I for one don't like that. When I print text I want to get the raw text, not a fancy printout. Thus, I've located the place where lpdomatic keeps the parameters for a2ps and changed it to suit me.

This was the original. I only care about the line containing a2ps:

my @enscriptcommands = 
  ('a2ps -1 @@--medium=@@PAGESIZE@@ @@--center-title=@@JOBTITLE@@ -o - 2>/dev/null',
   'enscript -G @@-M @@PAGESIZE@@ @@-b "Page $%|@@JOBTITLE@@ --margins=36:36:36:36 -p- 2>/dev/null',
   'mpage -o -1 @@-b @@PAGESIZE@@ @@-H -h @@JOBTITLE@@ -m36l36b36t36r -P- -');

...which line I've changed to look as follows. Please do not remove the parameters enclosed in @@ marks, lpdomatic will put the actual page size and job title there:

('a2ps -1 --margin=10 -X iso-8859-2 --borders no -B -f10\
-R --columns 1 @@--medium=@@PAGESIZE@@ @@--center-title=@@JOBTITLE@@ -o - 2>/dev/null',

What my parameters do: add a nice margin; specify my own character set (the one I use most often); remove borders; remove headers; use a font size of 10 points; print in portrait mode; and print one page/column per page, like one would expect.

11 Testing the printing chain

The chain is pretty much in place by now and you should test it. Just grab some application (not Gimp or Star/OpenOffice, see below why not) and try printing.

If things don't work quite right go over things and think about what you may have missed. One faulty piece of the chain can result in faulty printing, but sometimes the problem appears only in some cases or for some kinds of documents, so it may be tricky to isolate.

11.1 Debugging the printing chain

11.1.1 Getting information

When troubleshooting your printing setup, you need information about what's going on. Here are some of the ways to get it:

  • Activate the lpdomatic logging and check the log.

  • Examine the output from 'lpq' before, during and after the print attempt. Use extra -v parameters to make it more verbose.

  • Check out the output from 'ps -u lp' during printing. This will list all active processes owned by the printer user, lp. Go over the list and look for the elements of the printing chain. See who's missing. Note: if you're just printing text or if you're not using a printer definition that goes through you may not see a2ps, ghostscript or hpijs. You may not get to see a2ps regardless, because it may not be needed if the document was already Postscript. Here's what I got during a regular printing operation:

     PID TTY TIME CMD
    3251 ?   0:00 lpd (Server) 'hpdj640c'
    3252 ?   0:00 lpd (Worker - Print) 'hpdj640c'
    3253 ?   0:00 /usr/bin/perl /opt/lpdomatic/bin/lpdomatic --lprng -Zpagesize=a4 /etc
    3254 ?   0:00 sh -c gs '-dBATCH' '-dSAFER' '-dQUIET' '-dNOPAUSE' '-sDEVICE=ijs' '-s
    3255 ?   0:03 gs -dBATCH -dSAFER -dQUIET -dNOPAUSE -sDEVICE=ijs -sIjsServer=/opt/hp
    3256 ?   0:00 sh -c  cat >&3
    3257 ?   0:00 cat
    3258 ?   0:06 /opt/hpijs/bin/hpijs

    What you see above is:

    • The lpd (LPRng) server.
    • A "child" of lpd created for the sole purpose of handling the current printing task. That's how LPRng, and many daemons in general, separate the job of waiting for new tasks from actually dealing with them.
    • lpdomatic, running through Perl, with the expected parameters.
    • Ghostscript. There seem to be two instances of Ghostscript, but it's actuall a shell (sh) and Ghostscript itself (gs). This happens if you've set up foomatic-gswrapper correctly -- lpdomatic will use it to "format" the gs call and make sure all parameters are nicely wrapper in quote marks, then use sh to run it. This helps to deal with parameters containing spaces and other weird characters.
    • Two instances of 'cat' which lpdomatic uses to move the document around as it is formatted.
    • Finally, hpijs, which makes its worthy contribution.

    Note how the process ID's (PID) follow right through one after another, which is to be expected on a desktop machine without much load, because all the involved programs start very close together.

11.1.2 Test the chain link by link

Still no clue? Here's an alternative approach: test parts of the printing chain to rule out the ones that work and close down on the culprit. The following list has various ideas you can use:

  • [Read the update!]

  • Did you install the GS fonts?

  • Is every part of the chain installed? Does ldpomatic know where everything is (i.e. did you tell it all the relevant paths?)

  • Warning: after any modification of /etc/printcap or with LPRngTool you must restart LPRng!

  • Test just Ghostscript and the printer alone. Run this:

    gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD \
    -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="DESKJET 640" -r300 \
    -dNOPAUSE -dSAFER -sOutputFile="/dev/usb/lp0" \
    /opt/lprngtool/libexec/filters/testpage-a4.ps -c quit

    This will take a test page (testpage-a4.ps) found in the LPRngTool installation and will send it directly to the printer device. Note that you have to use the right parameters for your printer (look in the debug log, the printer description file and the hpijs manual for hints). If this works and you get a nice test page printed you can be sure that Ghostscript and hpijs work OK.

  • Take the GS testing call above and put it in a shell script which you'll be using as a filter instead of lpdomatic; modify it to look like this:

    #!/bin/sh
    gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD \
    -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="DESKJET 640" -r300 \
    -dNOPAUSE -dSAFER -sOutputFile="/dev/usb/lp0" \
    -sOutputFile=- - 2>/tmp/testlog

    It's the last line that was modified. This will make GS read the printjob from standard input, as passed from lprng, and output it to the standard output; but put error messages in /tmp/testlog. Using this script as the filter in printcap will test LPRng and Ghostscript.

  • Circumvent LPRng and run lpdomatic directly.

  • Upgrade hpijs to the latest version. Older versions (like 1.0.x) were buggy. Regardless, the latest version is the best to have at all times.

  • Temporarily replace lpdomatic with the following shell script to act as filter:

    #!/bin/sh
    cat $* >/tmp/print-parameters
    cat <&0 >/tmp/print-job

    This will: (a) output the parameters it receives to /tmp/print-parameters; (b) dump the raw printing job, as received from the application, to /tmp/print-job. You can call 'lpr' from the command line with a text file or something and if you find the exact same file in /tmp/print-job it means that LPRng is doing it's job.

  • Do you have more than one printer installed? In that case you should make sure that the right jobs go the right printer -- use 'lpr' with the '-P' parameter. Running 'lpr' without it will probably make it use the first printer defined in /etc/printcap.

  • Does ijs appear in the output from 'gs -h'?

  • Test what a2ps is doing (read 'man a2ps' and experiment!). Here's an example that will take a regular text file and convert it to Postscript, then view the result with GhostView:

    $ a2ps file.txt -o list.ps
    $ gv list.ps
  • Does printing work as root but not as another (lesser) user? You've obviously got a permission/ownership problem. Check installed programs, configuration scripts and devices, as well as the paths that lead to them.

    Remember that programs use 'lpr' to print, which in turn runs as the printer user (lp or lpr) and group daemon (at least on my system). You've created the lp user and group as part of the LPRng installation, and LPRng was told about them, so you should assume that this happens. Examples of troublesome permissions would be a printer device (/dev/usb/lp0) or a filter script which are not accesible to lp.daemon.

12 Printing from applications

12.1 StarOffice and OpenOffice

In order to print from these Office applications you need to define the printer in the spadmin utility.

You're going to need a PPD description file, which you can get from linuxprinting.org (PPD-O-matic) from the same place you got the lpdomatic printer description file -- the hpijs driver page.

I've called my PPD file hpdj640c.ppd and I've placed it in /etc/lpdomatic/.

The setup is very easy: run spadmin, choose "Printers", create a new printer, load the PPD file, adjust a few of the options if you want and that's it. Remember to use 'lpr' as the printing command.

Please note that you can either do this once by running spadmin as root, or you can do it for each lesser user separately, in which case only that user will be able to use the printer.

12.2 Gimp

12.2.1 Gimp-print

Gimp already has a printing interface, but you will require the gimp-print package in order to make the best out of this. Download gimp-print and install it as follows. Please note that gimp-print (4.2.x) only works with Gimp 1.2.x-. If you have Gimp 1.3+ you can still use the default printing dialogue, without the gimp-print enhancements, but your mileage may vary.

$ ./configure --prefix=/opt/gimp-print --disable-nls \
--sysconfdir=/etc --with-gimp --disable-escputil \
--with-libiconv-prefix=/opt/libiconv --with-gtk-prefix=/opt/gtk+ \
--with-glib-prefix=/opt/glib --with-gimp-prefix=/opt/gimp
$ make
$ su
# make install

This will specify the installation directory; disable localised interface; indicate /etc as the system config directory; mention that we want to build the Gimp plugin; disable escputil (which is only useful for Epson Stilus printers); specify where various packages are installed on my system.

Gimp-print offers more that just a plugin for Gimp; it has grown into a standalone printing solution, like IFHP for example, and it even offers a Ghostscript plugin based on IJS. That's why, above, I had to mention I want the Gimp plugin built.

The installation process will install gimp-print as well as a plugin in Gimp's plugins directory. Remember to run ldconfig so that gimp-print's libraries can be integrated into the system.

Once you've done all this you can fire up Gimp.

12.2.2 The Gimp printing dialogue

Open an image file, right-click on it and choose "File/Print". The printing dialogue appears. If you've seen it before installing gimp-print you'll notice it was cleaned-up a bit.

Gimp (and gimp-print) don't actually care much about the whole printing setup you've just put together. Gimp produces printing jobs based on gimp-print's and it's own printer driver collection, and the jobs it makes are ready to be dumped to the printer device.

This means that you're either going to have to send the document directly to the device, or create a printcap entry that does the very same thing, with the added benefit of LPRng's spooling and queueing services.

12.2.3 Setting up printing options

First of all, tell Gimp about the printer. The printing dialogue does have those "Setup Printer" and "New printer" buttons, but they don't actually refer to printers at least not to the printers you've defined in LPRng! "Printer" in this context means more like "set of options that are going to be used to print this image". It's a bit confusing at first.

So as you start you only have "File" as the "Printer Name" at the top of the printing window. Start thinking of those "Printer Name" entries as sets of options: we're now using the set of options called "File" (as you add more sets you'll notice how each of them remembers it's own settings from around the window, including the position of the image on the paper and so on).

(Another unpleasant thing: you can't remove there "printers", not from this dialogue anyway. You have to manually edit ~/.gimp-1.2/printrc to remove them.)

OK, so back to "File": it has the special property of saving output printing jobs to a file of your choice (the moment you press "Print"). Other than that, it's just like any other set of options.

You can create new sets of options by simply pushing "New Printer" and offering a name for it. That's all.

Of particular interest is the "Setup printer" button. It opens a dialogue which will set two things: the printer driver which will be used to create (or "encode" if you want) the printing job, and a printing command which will take the job to the printer. Using the wrong driver will produce a job which may not print correctly on your printer (I used "HP DeskJet 600 series"). The driver selection will also affect the options directly below in the printing window (like "Ink type" and "Resolution"). And, obviously, the "File" set doesn't have a printing command under the "Setup Printer" dialogue.

12.2.4 Actually printing

You've chosen a set of options, you've tweaked all the quality and positioning options for the image around, and you're ready to produce a print job. If you go with "File" you'll be prompted for a file name as soon as you hit "Print" and that's it. Careful, it doesn't ask if you want to overwrite!

The files produced in this manner can be printed by simply dumping them into the printer device in various manners. They are "raw" printer feed data, so you can't do anything else with them, like convert them to something else.

If you go with any other set of options, the "printer command" under "Setup Printer" will be run and it will receive the printing job. Let's see what we can do with it.

One option is to simply dump the job to the device, like this:

cat > /dev/usb/lp0

OK, it wasn't such a great option. It works, but just barely. What if the printer is not local, like a network printer? You can't use cat anymore, but luckily lpr allows itself to be used as a "smarter" cat (printing-wise). Consider this:

lpr -Y -P /dev/usb/lp0
...or...
lpr -Y -P host%port

This is slightly better. We are using lpr in its "lightweight mode" (-Y) and we can reach more than just local devices (see 'man lpr' for more).

But it's still not good enough. You're not using LPRng's full power. You don't have any collision protection, for instance, and if the printer is busy printing right at that moment your job will silently fail. You have all kinds of additional problems, because you're trying to access the printer device as a regular user, and please remember that it's supposed to be used only by the lp user. So to get rid of all these problems, add the following entry in your /etc/printcap:

hpdirect
:force_localhost
:if=/bin/cat >/dev/usb/lp0
:sd=/var/spool/lpd/%P
:rw@
:sh

To use it, restart lpd and use this as the printing command:

lpr -P hpdirect

This is basically the first example all over again, but with added benefits: it runs as the proper user (lp.daemon), and if the printer is busy LPRng will queue the job into the associated spool directory (/var/spool/lpd/hpdirect) and wait until the right time. (You may have to create the spool dir by hand, and mind the ownership and permission!)

See 'man lpr' and 'man 5 printcap' if you want to tweak this setup even further.

12.3 Other applications

Regular applications won't need so much trouble. Once you have the setup in place you can at any time call lpr -P myprinter file and it will get printed, even if you do it from the console or from any application. I've tried it from browsers such as Opera or Galeon, from text processors such as Lyx, editors like nedit or email clients like Sylpheed-claws. It works.

12.4 Managing the job queues

You may ask, "how do I see what's going on in my printer's queue at any given moment?" Simple: if you're in X use LPRngTool. If you're at the console use lpq. They both can list, kill, pause and reorder the jobs in the queue.

13 Miscellannea

13.1 Where to get more help

linuxprinting.org has TONS of documentation. All the software I mentioned here comes with TONS of documentation. There are at least two full HOWTO's over at The Linux Documentation Project (Printing and Printing-Usage).

If all else fails, ask your local Linux Users Group for help or join one of the discussion lists from linuxprinting.org, like lp.hp or inkjet-list.

13.2 Don't forget the security!

It's a drag, but we live in a dangerous world. So mind the following:

  • Start lpd with the script it provided. Compile it with the options I mentioned, and read the INSTALL file to find out how to make it even more security aware. (Hint: it doesn't get compiled with OpenSSL for nothing, you know...)
  • Turn off the debugging option in lpdomatic! You forgot about it, didn't you?
  • Restrict the access to the printer daemon and to the printer devices. Use the unpriviledged user lp to run the daemon and as owner of the device. Don't make the device world accessible.
  • Bind the lpd daemon against localhost if you don't need to use it on a LAN, and add rules in your firewall that prevent unwanted people from using it.

Please do these things. You most likely don't want to discover one day that *someone* on the Internet just printed 1000 pages on *your* printer or that he broke into your printer daemon and got access to your entire machine because you were running it the wrong way.

13.3 Why not use CUPS?

You want to give CUPS a try, please do. It's very user-friendly (it even has a builtin Web-server providing a configuration interface you can access with your browser).

I'm not very keen on using CUPS due to various issues. It's too complex for it's own good and newbies have been known to get hopelessly lost in it. It has bothersome issues, like not being able to detect USB printers if they weren't on at the time the CUPS service started; that's right -- it started when you started your computer, and how many times do you have the printer on at that time?

It may just be a pet-peeve of mine. Please do try it, it's a good piece of software and people have worked on it a lot. If you like it, use it, it's your choice after all.

13.4 You read this all the way to the bottom?!

You must really like my ranting. :) Well, I hope you got the help you needed. This is my first column of such size and there may by wrong things in it. If you have suggestions for improvement please contact me.

< Back to the top | Read other columns | Choose what column I should write next! >