Printing

CUPS Usage

CUPS manages all aspects of printing under Fedora—queues, drivers, scheduling, data filtering, and device communication. By and large, the function of CUPS is to usher print-jobs from applications to the requested printer. Along the way, CUPS orchestrates conversion of the data from the format provided by the submitting application to the format required by the printer. For example, a PNG image must be converted to the PCL or PostScript spoken by an HP LaserJet 1320 printer; even a simple text file typically needs conversion. CUPS also arranges for job options external to the data, like duplex printing, n-up printing, and tray selection. In this, CUPS uses several helpers to work its magic. Ghostscript, in particular, plays a star role. PostScript still reigns under the hood for Fedora printing, and Ghostscript renders PostScript data and printing options into the raster format of the selected printer. In supporting thousands of printers, CUPS also draws drivers and data-conversion filters from Foomatic, Gutenprint, HPIJS, and HPLIP.

You can use system-config-printer to configure CUPS. Alternatively, use the CUPS web interface by opening URL http://localhost:631 in a web browser. For HP printers, also consider the HP Device Manager from HPLIP.

CUPS provides command-line utilities as well. Use cupsctl to configure the CUPS manager and scheduler, the cupsd daemon, and use lpstat to monitor status. Use lpadmin, lpinfo, and lpoptions to add and configure print queues. For printing from a shell or script, use lp or lpr, lpq, cancel or lprm, and lpmove.

The CUPS web site provides documentation, including manpages for command-line tools, various usage guides, and references for configuration files.

Several packages contribute to an aggregate CUPS system: cups, cups-libs, foomatic, foomatic-db-ppds, foomatic-filters, ghostscript, ghostscript-cups, gutenprint, gutenprint-cups, hpijs, hplip.

Printer Drivers

CUPS requires a driver for each printer it manages a queue for. Basically, a driver is a PPD file describing the capabilities and features for a given manufacturer (or "make") and model of printer. The PPD file also lists and filters CUPS should use in preparing data for the printer. It contains any code snippets (e.g. PostScript, PCL, etc.) that implement certain features, like duplex, resolution, or tray selection. For each queue, CUPS stores a private copy of the printer's PPD file in /etc/cups/ppd under the name of the queue. For example, /etc/cups/ppd/Draft.ppd would represent a queue named "Draft." Since each queue has a private PPD file, its editable settings persist even if another queue uses the same original PPD file. In this way, different queues can specify different default options for the same physical printer. For example, a "Draft" queue might specify low resolution and toner, while a "Quality" queue specifies high resolution and toner.

Several projects supply PPD files, including CUPS itself, Foomatic, Gutenprint, and HPIJS. CUPS aggregates these into a single database transparently supporting thousands of printers from several dozen manufacturers. When adding a print queue, you must select a suitable driver from this database. To aid selection, the administration GUIs provide menus of drivers sorted first by manufacturer and then by model. Projects' offerings may overlap, so that some printers have multiple drivers available. These drivers differ in what printer capabilities they support, what CUPS filters they call for, and perhaps in how they affect performance. Experiment by adding queues with different drivers for the same printer; then examine the queue's job options and print some files.

Use lpinfo with its -m switch to probe the CUPS database of drivers. For example, lpinfo reports many drivers for an HP LaserJet 1320:

-> lpinfo -m | grep -i 1320 | grep -v -P "1320(n|tn)" | sort
drv:///hp/hpcups.drv/hp-laserjet_1320.ppd HP LaserJet 1320, hpcups 3.10.9
drv:///hp/hpcups.drv/hp-laserjet_1320_series-pcl3.ppd HP LaserJet 1320 Series pcl3, hpcups 3.10.9
foomatic:HP-LaserJet_1320-hpijs.ppd HP LaserJet 1320 Foomatic/hpijs
foomatic:HP-LaserJet_1320-Postscript.ppd HP LaserJet 1320 Foomatic/Postscript
foomatic:HP-LaserJet_1320-pxlmono.ppd HP LaserJet 1320 Foomatic/pxlmono
gutenprint.5.2://hp-lj_1320/expert HP LaserJet 1320 - CUPS+Gutenprint v5.2.6
gutenprint.5.2://hp-lj_1320/simple HP LaserJet 1320 - CUPS+Gutenprint v5.2.6 Simplified
lsb/usr/HP/hp-laserjet_1320-ps.ppd.gz HP LaserJet 1320 series Postscript
lsb/usr/HP/hp-laserjet_1320_series-ps.ppd.gz HP LaserJet 1320 series Postscript

Foomatic, Gutenprint, and HJIS ("drv:" and "lsb/usr") all happen to provide drivers for this printer and together support both its PCL and PostScript personalities. As another example, here's a quick tally of the driver database:

-> lpinfo -m | wc -l
10791

The CUPS database also includes generic drivers based on printer languages, like PCL, PostScript, ESC/P. For example:

-> lpinfo --make-and-model "Generic" -m  | grep -i PostScript | sort
drv:///sample.drv/generic.ppd Generic PostScript Printer
foomatic:Generic-PostScript_Level_1_Printer-Postscript1.ppd Generic PostScript Level 1 Printer Foomatic/Postscript1
foomatic:Generic-PostScript_Printer-Postscript.ppd Generic PostScript Printer Foomatic/Postscript

Generic drivers offer a fallback for printers not otherwise supported.

Network Printer

CUPS can manage a network printer as if connected directly by USB or such. For this, CUPS needs the printer's IP address and network-printing protocol. The printer's capabilities determine what protocol(s) it accepts. CUPS supports three such protocols: AppSocket (HP's JetDirect protocol), IPP (rising star Internet Printing Protocol), and LPD (old-school Line Printer Daemon). The printer's URI embeds the protocol; CUPS' article "Using Network Printers" gives details. Here is a comparison of valid URIs for an HP LaserJet p4515 network printer, which offers multiple protocols:

http://192.168.1.103
ipp://192.168.1.103/printers
lpd://192.168.1.103
socket://192.168.1.103:9100

For adding a network printer, system-config-printer is perhaps more convenient than the CUPS interface or the command-line tools. Given the IP address and protocol, it constructs the correct URI.

Use nmap to quickly identity a printer's supported protocols. The well-known ports for network-printing protocols are 515 for LPD, 631 for IPP, and 9100 for AppSocket. The following example shows that the LaserJet p4515 at 192.168.1.103 offers all three:

-> nmap 192.168.1.103
...
PORT      STATE SERVICE
...
515/tcp   open  printer
631/tcp   open  ipp
9100/tcp  open  jetdirect
...

Alternatively, muddle through the printer's documentation.

Printer Sharing

CUPS can act as a print server on its host computer by sharing queues for printers connected to its host. In turn, CUPS can act as a client of a CUPS print server hosted by another computer. A CUPS client automatically discovers shared queues.

To configure a CUPS print server: First, adjust the host's firewall to permit the "Network Printing Server (IPP)" service (system-config-firewall). Then, tell CUPS to share:

-> cupsctl --share-printers BrowseLocalProtocols=CUPS

Individual queues may be shared or kept private:

-> lpadmin -p Draft   -o printer-is-shared=true
-> lpadmin -p Quality -o printer-is-shared=false

CUPS now automatically broadcasts the availability of shared queues. By default, these broadcasts recur every 30 seconds.

To configure a CUPS client: First, adjust the firewall on the client's host to permit the "Network Printing Client (IPP)" service. Then, tell cups to browse for shared queues:

-> cupsctl --remote-printers BrowseRemoteProtocols=CUPS

CUPS now automatically discovers any queues shared by remote CUPS servers. Discovery includes any print-time options offered by the queue. The client does not require an further configuration of the queue or its underlying printer.

For a GUI interface, use system-config-printers. Navigate to Server/Settings to permit sharing as either a server or a client. For a CUPS print server, use Properties menu of a queue to toggle sharing for that queue. On a CUPS client, system-config-printers displays both local and remote queues by default. To hide discovered printers, deselect Discovered Printers under the View menu. Alternatively, use the CUPS web interface to configure sharing; go to the Administration tab.

A small distinction: CUPS shares printer queues but not printer devices. A CUPS print server shares queues for its local printers. Here, "local printer" means both a printer attached to the CUPS server's host computer by a cable (USB, SCSI, parallel-port) and a printer reached over ethernet (wired or wireless). CUPS must be configured specifically for each local printer it supports. In particular, each local printer has an entry in the file /etc/cups/printers.conf and a PPD file under the directory /etc/cups/ppd. A CUPS client accesses a remote printer indirectly through the graces of a shared queue tied to the printer, and thus the client does not specify a driver for a remote printer. In particular, a CUPS client does not list remote queues in its /etc/cups/printers.conf, nor does it have PPD files for remote printers.

Printer sharing uses IPP. For example, here is the URI for the Draft queue on a server (192.168.1.100) with an HP LaserJet 1320 attached by USB:

   -> lpstat -v draft
   -> device for Draft: hp:/usb/hp_LaserJet_1320_series?serial=0C1BNC494C5R

A CUPS client sees the shared Draft queue as an IPP printer:

   -> lpstat -v draft
   device for Draft: ipp://192.168.1.100:631/printers/Draft

CUPS supports additional protocols for sharing, and it offers many options to tune sharing. The documentation has the details: Printer Sharing. cupsctl. cupsd.conf.

Adding a queue using lpadmin, lpinfo, and lpoptions

This example demonstrates how to add a print queue using lpadmin. The printer is an HP LaserJet 1320 attached by a USB cable.

   -> lpadmin -p Test -D "HP LaserJet 1320" -L "Home"
   -> lpadmin -p Test -v hp:/usb/hp_LaserJet_1320_series?serial=5C0BNC4G409R
   -> lpadmin -p Test -m lsb/usr/HP/hp-laserjet_1320-ps.ppd.gz
   -> lpadmin -p Test -o InstalledMemory=144MB
   -> lpadmin -p Test -o Duplex=DuplexNoTumble
   -> lpadmin -p Test -o Resolution=600x600dpi -o Smoothing=off -o HPEconoMode=True
   -> lpadmin -p Test -E

Use options -p, -D, and -L, to specify the strings of choice for the name, description, and location.

Use lpinfo to determine the device URI of the printer, which feeds switch -v above:

   -> lpinfo -v | grep LaserJet
   direct usb://HP/LaserJet%201320%20series
   direct hp:/usb/hp_LaserJet_1320_series?serial=00CNBC4C940R

Here, either URI works. The first instructs CUPS to use the USB backend supplied by CUPS, and the second specifies the HP backend supplied by HPLIP.

Use lpinfo also to determine the printer's PPD file (or model) to feed switch -m above:

    -> lpinfo --make-and-model "LaserJet 1320" -m
    gutenprint.5.2://hp-lj_1320/expert HP LaserJet 1320 - CUPS+Gutenprint v5.2.6
    ...
    foomatic:HP-LaserJet_1320-pxlmono.ppd HP LaserJet 1320 Foomatic/pxlmono
    ...
    lsb/usr/HP/hp-laserjet_1320-ps.ppd.gz HP LaserJet 1320 series Postscript
    ...

This LaserJet has a dozen suitable PPD files describing it. These differ in what printer capabilities they support, what CUPS filters they call for, and perhaps in how the affect performance. Experiment by adding queues with different PPD files (-m) for the same printer (-v). Getting the correct string for the PPD file may take some tinkering. For example:

   -> lpadmin -p Test -m "gutenprint.5.2://hp-lj_1320/expert HP LaserJet 1320 - CUPS+Gutenprint v5.2.6"
   -> lpadmin -p Test -m foomatic:HP-LaserJet_1320-hpijs.ppd
   -> lpadmin -p Test -m lsb/usr/HP/hp-laserjet_1320-ps.ppd.gz

Choosing a good string for switch --make-and-model may also take some tinkering. Simply run lpinfo -v (without --make-and-model) for a full list of available PPD files, and pipe its output into grep.

Use switch -o repeatedly to set printer options. The manpage for lpadmin lists options for the printer's state, policies, access control, banner, etc. Use lpoptions to see what additional options the printer's PPD file offers:

   -> lpoptions -p Test -l
   ...
   Duplex/Duplex: None *DuplexNoTumble DuplexTumble
   Resolution/Printer Resolution: 1200x1200dpi 1200dpi *600x600dpi
   Smoothing/Resolution Enhancement: PrinterDefault On *Off
   HPEconoMode/EconoMode: PrinterDefault *True False

Finally, use option -E to enable the printer and let it accept jobs.

See also: lpadmin. lpinfo. lpoptions. cupsenable/cupsdisbale. cupsaccept/cupsreject.

Raw Printer

Normally, CUPS applies one or more filters to convert a print job from the submitted format into the printer's required format. For debugging or just plain tinkering, it's handy at times to print a file without any intervening filtering. This assumes the raw data have a format that the printer understands; a PostScript file to PostScript printer, for example. To print a file from a shell without conversion, use lp or lpr with option -o raw (or lpr with equivalent -l):

-> lp  -d Queue -o raw file.txt
-> lpr -P Queue -o raw file.txt
-> lpr -P Queue -l     file.txt

To accommodate raw printing directly from applications, add a queue without specifying a driver (make and model). This does the trick because CUPS determines a filter chain from the queue's PPD file; no file, no filtering, no problem. Here's an example using lpadmin to create the queue:

-> lpadmin -p raw -E -v hp:/usb/hp_LaserJet_1320_series?serial=00CNBC4C940R \
   -o printer-is-shared=false -o printer-error-policy="abort-job" -u allow:ray
-> lpr -P raw hello.ps 
-> lp -d raw hello.ps 

File-Device Printer

CUPS can send the output of its filter chain to a designated file rather than to a physical printer. The filtered print job can then be examined in a text editor or displayed on screen, for example. A queue for capturing this output has a file-device URI, which consists of the prefix file: followed by the file path; e.g. file:/tmp/cups.ps. This facility supports debugging, testing, and tinkering. It is not intended to provide a "save-to-file" service and thus has two salient limitations: User root owns the output file, and each print job quietly overwrites the fixed output file. The following example uses lpadmin to create a queue named "File" that directs the output of a its PostScript driver to file /tmp/cups.ps. For security, CUPS disables addition of a file-device queue by default, and so a call to cupsctl first reverses this restriction.

-> cupsctl FileDevice=yes
-> lpadmin -p File -E -v file:/tmp/cups.ps -m foomatic:Generic-PostScript_Printer-Postscript.ppd \
   -u allow:ray -o printer-is-shared=false
-> cupsctl -o FileDevice=no

Because the target file is fixed, the queue is here made private to a single user. Even so, only root can read /tmp/cups.ps. For example:

-> ls -l /tmp/cups.ps 
-rw-------. 1 root root 132415 May 27 12:02 /tmp/cups.ps
-> su -c 'evince /tmp/cups.ps' -

CUPS Internals

CUPS Design Description gives a synopsis of CUPS organization.

Files

Each local printer (or queue) on the system has its own entry in /etc/cups/printers.conf and has its own PPD file in directory /etc/cups/ppd. In printers.conf, the CUPS schema uses <DefaultPrinter> for the default printer and <Printer> for each other printer. When a printer is added, CUPS inserts the entry into printers.conf and creates the PPD file. When a printer is deleted, CUPS removes the entry from printers.conf and deletes the PPD file.

Filters

These examples demonstrate how to see what filter(s) and backend CUPS used to process particular print jobs. Job 205 consists of a text file, a Gutenprint driver, and an HP printer over USB:

-> cupsctl LogLevel=debug
-> grep -P '.*Job 205.* Started' /var/log/cups/error_log
I [13/May/2011:16:35:07 -0400] [Job 205] Started filter /usr/lib/cups/filter/texttops (PID 3259)
I [13/May/2011:16:35:07 -0400] [Job 205] Started filter /usr/lib/cups/filter/pstops (PID 3260)
I [13/May/2011:16:35:07 -0400] [Job 205] Started filter /usr/lib/cups/filter/pstoraster (PID 3261)
I [13/May/2011:16:35:07 -0400] [Job 205] Started filter /usr/lib/cups/filter/rastertogutenprint.5.2 (PID 3262)
I [13/May/2011:16:35:07 -0400] [Job 205] Started backend /usr/lib/cups/backend/hp (PID 3263)

Job 209 has a postscript file and driver:

-> grep -P '.*Job 209.* Started' /var/log/cups/error_log
I [13/May/2011:17:00:58 -0400] [Job 209] Started filter /usr/lib/cups/filter/pstops (PID 3620)
I [13/May/2011:17:00:58 -0400] [Job 209] Started backend /usr/lib/cups/backend/hp (PID 3621)

Job 220 has a JPG file (printed via lpr) and again a postscript driver:

-> grep -P '.*Job 220.* Started' /var/log/cups/error_log
I [14/May/2011:15:49:46 -0400] [Job 220] Started filter /usr/lib/cups/filter/imagetops (PID 2964)
I [14/May/2011:15:49:46 -0400] [Job 220] Started backend /usr/lib/cups/backend/hp (PID 2965)

This example uses a Foomatic driver:

-> grep -P '.*Job 213.* Started' /var/log/cups/error_log
I [13/May/2011:21:33:06 -0400] [Job 213] Started filter /usr/lib/cups/filter/pstops (PID 4556)
I [13/May/2011:21:33:06 -0400] [Job 213] Started filter /usr/lib/cups/filter/foomatic-rip (PID 4557)
I [13/May/2011:21:33:06 -0400] [Job 213] Started backend /usr/lib/cups/backend/hp (PID 4558)

This example uses the hpcups driver from HPLIP:

-> grep -P '.*Job 216.* Started' /var/log/cups/error_log
I [14/May/2011:15:34:08 -0400] [Job 216] Started filter /usr/lib/cups/filter/pstops (PID 2747)
I [14/May/2011:15:34:08 -0400] [Job 216] Started filter /usr/lib/cups/filter/pstoraster (PID 2748)
I [14/May/2011:15:34:08 -0400] [Job 216] Started filter /usr/lib/cups/filter/hpcups (PID 2749)
I [14/May/2011:15:34:08 -0400] [Job 216] Started backend /usr/lib/cups/backend/hp (PID 2750)

To disable debugging messages in the log file:

-> cupsctl LogLevel=none

See also: SDB:Using Your Own Filters to Print with CUPS

Backends

See also: SDB:Using Your Own Backends to Print with CUPS

See also: CUPS Printing Tutorial. Printer Driver Basics. Tutorial on CUPS and Foomatic OpenPrinting CUPS Quick Start. Backend Error Handler. SDB:CUPS in a Nutshell.

Foomatic

-> yum install foomatic foomatic-db foomatic-db-filesystem foomatic-dp-ppds foomatic-filters
-> lpinfo -m  | grep foomatic | wc -l
6839
-> rpm -q --list foomatic | grep cups
/usr/lib/cups/backend/beh
/usr/lib/cups/driver/foomatic
(1040) ~/scratch -> rpm -q --list foomatic-filters | grep cups
/usr/lib/cups/filter/foomatic-rip
> rpm -q --list foomatic-db-ppds | grep cups
/usr/share/cups/model/foomatic-db-ppds

See also:

Ghostscript

See also:

Gutenprint

-> yum install gutenprint gutenprint-cups
rpm -q --list gutenprint-cups | grep /usr/lib/cups
/usr/lib/cups/driver/gutenprint.5.2
/usr/lib/cups/filter/commandtocanon
/usr/lib/cups/filter/commandtoepson
/usr/lib/cups/filter/rastertogutenprint.5.2

For a description of what the various printer options mean, see section 8 "List of Supported Options" of the user's manual.

See also:

HPIJSL—HP Inkjet Server

Package hpijs (HP Inkjet Server) provides CUPS with several files, and it also includes almost 200 PPD files for HP printers:

   -> rpm -q --list hpijs | grep -v ppd
   /usr/bin/hpijs
   /usr/lib/cups/filter/hpcups
   /usr/lib/cups/filter/hpcupsfax
   /usr/lib/cups/filter/hplipjs
   /usr/share/cups/drv/hp
   /usr/share/cups/drv/hp/hpcups.drv
   -> rpm -q --list hpijs | grep "/usr/share/ppd/HP/.*\.ppd\.gz" | wc -l
   199

See also:

HPLIPL—HP Linux Imaging and Printing

HP Linux Imaging and Printing provides drivers and utilities for using HP printers, scanners, and faxes under GNU/Linux systems. In addition to a suite of commands for managing HP devices (/usr/bin/hp-*), HPLIP provides drivers to CUPS for a seamless integration.

To use HP printers, first install HPLIP:

   -> yum install hplip hplip-gui hplip-common hplip-libs hpijs

(HPLIP requires lm_sensors-libs, net-snmp, and net-snmp-libs, among other packages.) The HPLIP command-line utilities do not come with separate manpages; run each utility with the --help option instead. Alternatively, see the online manpages.

Use /usr/bin/hp-toolbox [System/Administration/HP Device Manager] for an HP-tuned alternative to the usual system-config-printer. It is an aggregate GUI for the individual CLI utilities (hp-*). Network (JetDirect) printers additionally provide a complete configuration interface via an embedded web server (EWS) available to any computer on the home network. To use it, enter the printer's IP address in a web browser.

HP network printers use AppSocket/JetDirect on port 9100. It is (apparently) unnecessary to open the host computer's firewall to Multicast DNS (mDNS) or Internet Printing Protocol (IPP).

-> hp-probe --bus usb
...
Device URI                                           Model                  
---------------------------------------------------  -----------------------
hp:/usb/hp_LaserJet_1320_series?serial=123456789012  HP LaserJet 1320 series
...
-> hp-probe --bus net
...

HP Printers

These are short notes on HP printers I've used under CUPS or elsewhere.

HP support pages

Deskjet 6980

LaserJet 1320

Officejet Pro L7680

Officejet Pro 8500 (A910)

Photosmart Premium 410a

LaserJet M9050 MFP

Short Glossary of Printer Acronyms

Direct PDF
See also: v1.4
ESC/P: Epson Standard Code for Printers
A older Epson-printer language, supplanted by PCL and PostScript. See also: Wikipedia.
IPP—Internet Printing Protocol
See also: Home. RFC 2910. RFC 2911.
PCL—Printer Standard Code for Printers
A page description language used in HP and other printers. See also: manual. Wikipedia.
PJL—Printer Job Language
Provides commands to switch printer languages (e.g. PCL versus PostScriupt), get printer status and configuration, and modify control panel settings. See also: manual. Wikipedia.
PML—Printer Management Language
XHTML-Print
See also: W3. An Introduction to XHTML Print.

Paper

See also:

PPD Files

PPD: PostScript Printer Description

See also: OpenPrinting manual. CUPS PPD extensions. Wikipedia