Eric Radman : a Journal

BSD Printing Primer

CUPS is for ConfUsing Print System

From what I understand, cups is supposed to solve the deficiencies of the traditional printing systems, but I've always found the operation of CUPS to be confusing, and hard to troubleshoot. BSD's lpr is not a marvel of human ingenuity, but I think it does follow methodology that is comprehensible>

All of the printers on a BSD system are listed in /etc/printcap, and follow an unusual, but comprehensible format. The following is the line that defines a simple line printer, which is simply a device that prints characters that are streamed to it:

lp|dot-matrix:sh:lp=/dev/lpt0:sd=/var/spool/output/lp:lf=/var/log/lpd-errs

The first part of this line is the printer name. lp is the default printer, and here one of two aliases for the printer. Pipes (|) can be used to create expanded or simplified names for each device. Each collen (:) separates one parameter from another, and in most cases the second paramerter is going to be sh which prevents lpd from printing a header page. By default FreeBSD does not print a header page any more; a change that is definately overdue.

Now to illustrate my initial assertion that lpd/lpr is not a new paradyme, only new information I'll show you how to change the name of my default printer:

lp|epson:sh:lp=/dev/lpt0:sd=/var/spool/output/lp:lf=/var/log/lpd-errs

Restart lpd to read the new configuration and you can now print a test page like this:

 lptest 40 5 | lpr -P epson

Try changing a printer name set up with CUPS...I presume that it can be done, but I sure havn't figured it out.

Network PostScript Printers

PostScript is a page description language that PDF's are based on that has long been the standard format for printing documents in BSD and Linux. If you're printer understands PostScript then no translation is required to output office documents. Here is how I configured our HP LaserJet 4650N:

hp4650|4650|hp4650ps:mx#0:sh:rm=192.168.168.190:rp=RAW1: \
  sd=/var/spool/output/4650:lf=/var/log/lpd-errs:

rm can be a hostname or an IP address of the print server, and rp is the name of the printer. HP's network printers use the same interface that the JetDirrect print servers use, which usually means the printers RAW1, RAW2, RAW3, TEXT1, TEXT2, TEXT3. The RAW printer names simply pass the incoming data stream to the printer, but the TEXT ports translate ASCII input to PCL.

If you want to pipe the output of commands to a printer like this another entry can be added that defines the text port:

hp4650txt|4650txt:mx#0:sh:rm=192.168.168.190:rp=TEXT1: \
  sd=/var/spool/output/4650:lf=/var/log/lpd-errs:

The Magic of Ghostscript

The first mental leap that a person striving to understand UNIX printing must make is that one printer driver or interpreter can drive many different printer models. Just like the chipset on many network cards printers use similar instructions sets. The basic function of Ghostscript is to transform an input (for printing, PostScript) to another output format (like PCL).

Setting up a filter for non-PostScript printers is a three-step process. First, find out what gs device will work with your printer. Second, define an printer filter, third, assign that filter to you're printer in /etc/printcap. My Canon printer is not supported specifically by Ghostscript, by I picked a similar printer.

# /etc/printcap
bjc8200|8200:sh:lp=/dev/lpt0:sd=/var/spool/output/bjc8200:\
  lf=/var/log/lpd-errs:if=/usr/local/libexec/filters/bjc8200
# /usr/local/libexec/filters/bjc8200
#!/bin/sh
# Treat LF as CR+LF
printf "\033&k2G" || exit 2
# Print the postscript file
/usr/local/bin/gs -dSAFER -dBATCH -dQUIET -dNOPAUSE -q -sDEVICE=bjc800 \
  -sModel=bjc-8200 -sOutputFile=- -sPAPERSIZE=letter - && exit 0
exit 2

The BJC-8200 is only partially supported, and the quality of the output of photos is really poor. In order to leverage some of the advanced features in gimp-print I defined another printer without the input filter. When I fire up the GIMP to print an image I select this new raw printer and than use a specific printer instead of Level 1 or 2.

bjc8200-raw|8200raw:sh:/dev/lpt0:sd=/var/spool/output/bjc8200-raw: \
  lf=/var/log/lpd-errs:

This entry is nothing more than a reference to the printer without an input filter: gimp-print does the translation.

References

NetBSD Guide - Printing

FreeBSD Handbook - Printing

An introduction to Linux printing systems