SDB:CUPS in a Nutshell

Şuraya atla: kullan, ara

This article addresses experienced Linux users. It does not provide detailed explanations. All important issues in connection with CUPS are presented in a concise form.

Overview of the CUPS Printing System

A general overview is available in the following text in the CUPS documentation: "An Overview of the Common UNIX Printing System" http://localhost:631/overview.html or [file:///usr/share/doc/packages/cups/overview.html file:///usr/share/doc/packages/cups/overview.html].

CUPS home page:

Processing stages of a print job:

  • This step takes place both on client and on server systems. This is the only step on clients. No queues exist on clients.
A command-line tool or an application generates a print job and passes it to the spooler. Applications start a command-line tool (e.g., Mozilla) or use the CUPS library functions directly (e.g., kprinter). A print job consists of information for the spooler, the print data, and optional information for the filter.
Example for a command-line tool:
  lp -d queue -t title -o option1=value1 -o option2=value2 file1 file2
"queue" and "title" are information for the spooler.
"option1=value1" and "option2=value2" are information for the filter.
"file1" and "file2" are the print data.
  • The following steps only take place on a CUPS server. A host on which the following steps take place is a server. A host on which a queue exists is a server. The spooler (cupsd) does:
    1. Saving the print job in the spool directory:
      • Saving the information for the spooler and the filter in /var/spool/cups/c<job-number>
      • Saving the data from the files to print in /var/spool/cups/d<job-number-file-number>
    2. Filtering of the print data and sending the printer-specific data to the printer:
      • Starting the filter system:
        1. Determining which filters are needed for generating the printer-specific data and establishment of the so called "filter chain" or "filter pipe".
        2. Starting the programs of the filter chain with suitable parameters.
      • Starting the backend for sending the printer-specific data from the filter pipe to the printer.
    3. Completing the print job:
      1. Waiting until the backend is finished.
      2. Deleting the respective files from the spool directory.

The Spooler

Function of the spooler:

The main purpose of the spooler system is to move data from the sender to the recipient.

  1. Accepting data (only from authorized senders).
  2. Buffering data (until the recipient is ready to accept them).
  3. Sending data to authorized recipients (after implementing suitable filters, if necessary).
  4. Providing information about the status of the data (e.g., for "lpstat -W completed -o").


  • /usr/sbin/cupsd
    • cupsd is the server for the IPP protocol.
    • The IPP protocol can be regarded as an extension of the HTTP protocol. Details on the IPP protocol are available in RFC-2910 and RFC-2911.
    • cupsd listens on TCP port 631 for IPP tasks like "lp -d queue file" or "lpstat -t".
    • cupsd listens on TCP port 631 for HTTP tasks like http://localhost:631/printers/.
    • cupsd uses UDP port 631 for sending and receiving "IPP browsing" information. Use commands like "netcat -u -l -p 631" to pick up such information (provided UDP port 631 is not yet occupied by cupsd).
    • Configuration file for cupsd: /etc/cups/cupsd.conf
  • /usr/lib/cups/daemon/cups-lpd
    • cups-lpd is the server for the LPD protocol (RFC 1179).
    • cups-lpd accepts print jobs that come in on TCP port 515 via the LPD protocol.
    • xinetd or inetd is used as wrapper for cups-lpd.
    • Configuration files: Either /etc/xinetd.d/cups-lpd or the "cups-lpd" line in /etc/inetd.conf.
  • Documentation:
    • "CUPS Software Administrators Manual": http://localhost:631/sam.html or [file:///usr/share/doc/packages/cups/sam.html file:///usr/share/doc/packages/cups/sam.html])

PPD Files

What is a PPD file and how does it work?

A PPD file contains the printer-specific options (and nothing else) together with the corresponding PostScript code snippets that must be sent to the PostScript interpreter in order to activate a certain option.

Depending on the printer-specific options set for a certain print job (e.g., "-o PageSize=A4"), the filter system reads the suitable PostScript code snippets (the so called "PostScript invocation values") from the PPD file and inserts them in the PostScript data stream.

The syntax for an option entry in the PPD file with two example entries is as follows:

* Main keyword Option keyword/translation string " PostScript invocation value "
*PageSize Letter/letter paper: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
*PageSize A4/A4 paper: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"

More information is available in the "Adobe PostScript Printer Description File Format Specification, Version 4.3".


  • /etc/cups/ppd/
    • This directory contains the PPD files that cupsd actually makes use of.
    • The entries (especially the "*Default..." entries) in a PPD file in /etc/cups/ppd/ can vary from the entries in the original PPD file that was specified when the queue was configured.
  • /usr/share/cups/model/
    • This directory contains the original PPD files from the packages:
      • cups: CUPS PPD files
      • cups-drivers: ic ( PPD files
      • cups-drivers-stp: Gimp-Print PPD files
      • manufacturer-PPDs: manufacturer PPD files with free licenses
    • Additional PPD files (e.g., PPD files from printer manufacturers) can be copied to this directory in order to make them available for the printer configuration tools.
  • The printer database

The Filter

What does the filter system do and how does it work?

  • The main purpose of the filter system is to convert the original data of the print job (ASCII, PostScript, PDF) to printer-specific data (PostScript, PCL, ESC/P).
  • Normally, the filtering takes place by means of the following steps:
    1. Determination of the MIME type of the original data according to /etc/cups/mime.types. If it is not "application/postscript", then conversion to PostScript according to /etc/cups/mime.convs. For example, "text/plain" is converted to PostScript with /usr/lib/cups/filter/texttops.
    2. Inserting the PostScript invocation values in the PostScript data stream according to the following line in /etc/cups/mime.convs:
Input MIME type Output MIME type Costs Filter
application/postscript application/vnd.cups-postscript 66 pstops
    1. If a non-PostScript printer is used with a Foomatic PPD file, the PostScript data are converted to printer-specific data according to the following line in every Foomatic (version 3.x) PPD file:
Main keyword Input MIME type Costs Filter
*cupsFilter: "application/vnd.cups-postscript foomatic-rip"

If a non-PostScript printer is used with a Foomatic PPD file, then foomatic-rip together with Ghostscript serve as the PostScript interpreter. foomatic-rip proceeds as follows to convert the PostScript data to printer-specific data:

      1. Building of a Ghostscript command with the needed Ghostscript parameters according to the printer-specific options set for the respective print job.
      2. In some cases, a postfilter is introduced after the Ghostscript command (via pipe):
        • For PCL printers:
          Certain options are realized by means of changes in the PCL data stream (e.g., paper tray selection via "perl -e").
        • For some GDI printers:
          Conversion of the Ghostscript output to printer-specific data (e.g., with pnm2ppa for HP PPA printers).
      3. Execution of the Ghostscript command (or pipe).
  • If a non-Foomatic PPD file (e.g., a Gimp-Print PPD file from /usr/share/cups/model/stp/) is used for a non-PostScript printer, the "*cupsFilter" entries in the PPD file may look as follows:
  *cupsFilter: "application/vnd.cups-raster 100 rastertoprinter"
  *cupsFilter: "application/vnd.cups-command 33 commandtoepson"

With the matching entries in /etc/cups/mime.convs the result is a different filtering procedure. More information on filtering is available in the Support Database article "Using Your Own Filters to Print with CUPS": SDB:Using Your Own Filters to Print with CUPS.


  • /usr/lib/cups/filter/

This directory contains the various filter programs used by the CUPS filter system if a PPD file was specified when the respective queue was configured.

    1. /usr/lib/cups/filter/*tops (e.g., /usr/lib/cups/filter/texttops) for converting the original data (e.g., "text/plain") to PostScript.
    2. /usr/lib/cups/filter/pstops for inserting the PostScript invocation values and, if necessary, for reformatting the PostScript data (e.g., to downsize and print two pages on one sheet).
    3. /usr/lib/cups/filter/foomatic-rip for converting PostScript data to printer-specific data (e.g., PCL or ESC/P).
  • /etc/cups/interfaces/

This directory contains the filter used by CUPS if a "System V style Interface Script" was specified instead of a PPD file when the respective queue was configured. A "System V style Interface Script" is a single filter program or filter script that produces the printer-specific data for all data formats in which the original print data may be sent. More information about the "System V style Interface Script" is available in the Support Database article "Using Your Own Filters to Print with CUPS": SDB:Using Your Own Filters to Print with CUPS.

  • "raw"

If neither a PPD file nor a "System V style Interface Script" was specified when the respective queue was configured, no filtering will take place. The original print data will be sent directly from the backend to the recipient (normally the printer) as they are (in "raw" form). It is not possible to convert the line break (e.g., LF -> CR+LF) or append a form feed. A "System V style Interface Script" can be used for this purpose.

The Backends

What is a CUPS backend and how does it work?

Normally, the backend receives the printer-specific data from the filter and forwards them to the printer or another recipient.

The differences between the backend and the filter are as follows:

  • One backend but usually several filters (a filter chain) are activated to process a print job. Exceptions: "System V style Interface Script" (one filter) and "raw" printing (no filter).
  • In the processing chain, the backend is always the last program executed for processing a print job.

The print system considers the print job as completed when the backend is finished. The backend is finished when the transmission to the recipient is completed. If the further processing at the recipient fails (e.g., if the printer is not able to print the printer-specific data), this will go unnoticed by the print system.

If the data transmission to the recipient fails (usually after several attempts by the backend), the backend will report an error to the print system (more precisely, to cupsd). The backend decides if and how many attempts make sense before it reports that the data transmission has failed. As further attempts would be futile, cupsd disables printing on the affected queue. After eliminating the cause of the problem, the system administrator must reenable printing with /usr/bin/enable.

More information on backends is available in the "CUPS Software Programmers Manual": http://localhost:631/spm.html or [file:///usr/share/doc/packages/cups/spm.html file:///usr/share/doc/packages/cups/spm.html].


This directory contains the various backends.

A suitable backend must be employed under consideration of how the printer can be accessed from the host running the CUPS system and the type of recipient.

The destination to which a backend can send the data can be any URI (Uniform Resource Identifier) for which a suitable backend is available. The first part of the "DeviceURI" entry in /etc/cups/printers.conf determines the backend, the other entries serve as parameters for the backend.

Backend URI syntax Example URI
parallel parallel:/dev/lp* parallel:/dev/lp0
usb (traditional) usb:/dev/usb/lp* usb:/dev/usb/lp0
usb (new) usb://<make>/<model>?serial=<number> usb://ACME/FunPrinter%201000?serial=A1B2C3
ipp ipp://<ipp-server.domain>/printers/<queue> ipp://cups-server.domain/printers/funprinter1000
lpd lpd://<lpd-server.domain>/<queue> lpd://
socket socket://<host.domain>:<port> socket://
smb see the man page smbspool(8) smb://user:password@workgroup/smb-server/share

If "user" and "password" are needed for the smb backend, the owner, group, and access permissions for the file /etc/cups/printers.conf must be sufficiently restrictive. The specifications "user" and "password" are not displayed with the command "lpstat -v".

Every backend can also be addressed directly. For example, the "parallel" and "usb" backends return the IEEE-1284 identification of connected printers.

root@host# /usr/lib/cups/backend/parallel
direct parallel:/dev/lp0 "ACME FunPrinter 1000" "Parallel Port #1"
root@host# /usr/lib/cups/backend/usb
direct usb://ACME/USB%20Printer?serial=1234 "ACME USB Printer" "USB Printer #1"
direct usb:/dev/usb/lp1 "Unknown" "USB Printer #2"

Upon start-up, cupsd successively executes all backends in /usr/lib/cups/backend/ in order to determine which of the backends are available on the respective system. Only the available backends can be used for the configuration of queues. The available back-ends are displayed with "lpinfo -v".

Command-line Tools

General information on the command-line tools:

  • Do not edit the configuration files in /etc/cups/ manually if suitable command-line tools are available for this purpose.

The configuration files are not reloaded for every print job. Rather, cupsd keeps much of the information in the main memory and writes information back to the configuration files whenever needed. Exception: /etc/cups/cupsd.conf
After modifications in this configuration file, cupsd must be restarted in order to make it use the modified configuration. See Section "Restarting the CUPS Server" in the "CUPS Software Administrators Manual" http://localhost:631/sam.html#RESTARTING or [file:///usr/share/doc/packages/cups/sam.html#RESTARTING file:///usr/share/doc/packages/cups/sam.html#RESTARTING].

  • Never copy configuration files from other systems to your system unless you know exactly what you are doing. Use command-line tools instead.

For example, to set up the same queues on several machines (e.g., for a backup server), do not copy /etc/cups/printers.conf and /etc/cups/ppd/*, but write the respective commands in a script (usually a sequence of lpadmin commands) and run the script on the various machines. In this way, any error messages will be displayed on the respective machines (e.g., if a PPD file is not available on a machine or if a backend is not available or not ready to use). Furthermore with such a script you have something like a log-file of the settings, enabling you to restore the settings by running the script at any time.

  • If you are not sure which graphical tool is best suited for certain special configurations, use command-line tools instead.
  • In many cases, the sequence of the options is significant. Read the man pages. For example, the following commands are all different:
  lpadmin -E -p queue,
  lpadmin -p queue -E
  lpadmin -E -p queue -E


Command-line tools for creating or editing queues:

  • Example for creating a queue:
  root@host# lpadmin -p funprinter1000 -v parallel:/dev/lp0 -E -P /usr/share/cups/model/Postscript.ppd.gz
Use the following command to check what was created:
  user@host$ lpstat -a funprinter1000 -p funprinter1000 -v funprinter1000
  funprinter1000 accepting requests since Jan 01 00:00
  printer funprinter1000 is idle.  enabled since Jan 01 00:00
  device for funprinter1000: parallel:/dev/lp0
Alternatively, take a look at /etc/cups/printers.conf:
  <Printer funprinter1000>
  Info funprinter1000
  DeviceURI parallel:/dev/lp0
  State Idle
  Accepting Yes
  JobSheets none none
  QuotaPeriod 0
  PageLimit 0
  KLimit 0
Or query the system with the web front-end: http://localhost:631/printers/funprinter1000
  • Editing the queue (e.g., changing the description and location):
  root@host# lpadmin -p funprinter1000 -D "ACME FunPrinter 1000" -L "2. floor: room 3"
  • Displaying the printer-specific options and their default settings in /etc/cups/ppd/funprinter1000.ppd:
  user@host$ lpoptions -p funprinter1000 -l
  Resolution/Output Resolution: 150dpi *300dpi 600dpi 1200dpi 2400dpi
  PageSize/Media Size: Letter Legal Executive *A4 A5
The output has the following syntax:
  main-keyword/translation-string: option-keyword option-keyword option-keyword ...
The default setting is marked with an * preceding the "option-keyword".
  • Changing the printer-specific default settings in /etc/cups/ppd/funprinter1000.ppd:
  root@host# lpadmin -p funprinter1000 -o Resolution=600dpi -o PageSize=Letter
The syntax is as follows:
  lpadmin -p queue -o main-keyword1=option-keyword1 -o main-keyword2=option-keyword2 ...
Do not use lpoptions for this purpose. Refer to the Support Database article "Print Settings with CUPS": SDB:Print Settings with CUPS. Normal users can use lpoptions to save their personal default settings in ~/.lpoptions. More information on this is presented in the same Support Database article.
  • Use "accept" and "reject" to accept and reject print jobs for a queue. Use "/usr/bin/enable" ("enable" is a bash built-in) and "disable" to enable and disable printing in a queue (e.g., to avoid print jobs from being lost while doing maintenance work on the printer).
  • Deleting the queue:
  root@host# lpadmin -x funprinter1000

Command-line tools for daily use:

  • Avoid BSD-type commands (lpr, lpq, lprm), as these only support a limited number of generic options. Use System V-type commands (lp, lpstat, cancel) instead.
  • Use lpoptions to save personal printer-specific option settings in ~/.lpoptions. Example:
  user@host$ lpoptions -o Resolution=1200dpi -p funprinter1000
  • The generally available printing options are described in the Section "Standard Printer Options" in the "CUPS Software Users Manual": http://localhost:631/sum.html#STANDARD_OPTIONS or [file:///usr/share/doc/packages/cups/sum.html#STANDARD_OPTIONS file:///usr/share/doc/packages/cups/sum.html#STANDARD_OPTIONS].

cupsd Web Front-end

Every cupsd in the network has an HTTP web front-end. The URLs for a local cupsd is http://localhost:631/. The URL for a remote cupsd on "host.domain" is http://host.domain:631/. Access to the remote cupsd is only possible if the respective host and cupsd permit the access.


In daily operations, the web front-end is usually the best source of information about queues and print jobs. For example, http://localhost:631/printers/ provides an overview of all queues of a local cupsd. The URL http://host.domain:631/printers/funprinter1000?which_jobs=completed displays the completed print jobs of the queue "funprinter1000" on "host.domain".

The web front-end is the best way to get documentation on the respective cupsd (cupsd version). For example, the URL for the documentation for the local cupsd is http://localhost:631/documentation.html. The URL for the documentation for a remote cupsd on "host.domain" is http://host.domain:631/documentation.html.

Even the PPD files in /etc/cups/ppd/ can be accessed by way of the web front-end. For example, the PPD file of the queue "funprinter1000" on the local host (/etc/cups/ppd/funprinter1000.ppd) can be accessed with the URL http://localhost:631/printers/funprinter1000.ppd. The PPD file of "queue" on "host.domain" can be accessed with a URL in the form http://host.domain:631/printers/queue.ppd.

Configuring CUPS in the Network

Intrinsic design of CUPS for printing in the network:

  • CUPS network servers (hosts on which spooling and filtering is done):
    • The cupsd of a CUPS network server sends information about its queues to a list of IP addresses (host addresses and/or broadcast addresses). The default setting is an empty list.
    • The transmission is repeated after preset intervals. The default setting is 30 seconds.
  • Clients (hosts that only send print jobs to servers):
    • By default, cupsd listens to information from servers. Therefore, a local cupsd should run on every client. There is a list of servers from which information is accepted. By default, information is accepted from all servers.
    • The information about a specific queue is deleted on a client if no new information about the queue comes in within a set interval. The default setting is 300 seconds.

In this way, the queues of the server are available directly on the client. Users on the clients can browse the queues on various servers. Therefore the whole stuff is called "Browsing".

Browsing is activated by default. All incoming browsing information is accepted, but no browsing information is sent (see above).

Configuration of the CUPS network servers:

  1. Configure the queues for the printers associated with the server on the server.
  2. Allow the clients to access the queues.
  3. Activate the sending of browsing information to the clients.

Subnetworks should be used to facilitate the configuration. If subnets are used, it is sufficient to send the browsing information to a fixed broadcast address instead of continuously maintaining a list of individual host addresses.

The access to the queues of a server is handled independently, regardless to which hosts the server sends browsing information. A server can grant all clients in the network access to its queues, while sending browsing information to only some of the clients. However, a server should not send any browsing information to clients that do not have access to its queues.

The following is not possible:

Sending of browsing information about only some of the queues of a server.

In a large company, it is not possible to have only one large server that sends browsing information for some of the queues to the clients in one department or one building and browsing information for other queues to other clients.

Several servers (one for every department or building) are needed for this.


  1. Configuration of the queues for the printers associated with the server:

The printers belonging to a server are the ones for which the filtering takes place on the server.

    1. Configure the printers in such a way that printing works correctly on the server for normal users.

If problems are encountered:

      1. Set the "LogLevel debug" in /etc/cups/cupsd.conf.
      2. Stop cupsd.
      3. Move /var/log/cups/error_log* to another location (or delete it) in order to avoid having to search through gigantic log files.
      4. Start cupsd.
      5. Retry the action leading to the problem.
      6. Now /var/log/cups/error_log* contains many messages that are useful for troubleshooting.
    1. Allow the clients to access the queues:

From SUSE LINUX 9.0, the default setting in /etc/cups/cupsd.conf is as follows:

    BrowseAllow @LOCAL
    <Location />
    Allow From @LOCAL

This setting allows all LOCAL hosts to access cupsd. LOCAL hosts are those whose IP addresses are associated with non-PPP interfaces (more precisely, interfaces whose IFF_POINTOPOINT flag is not set) and whose IP address belongs to the same network as the CUPS server. Packets from all other hosts are rejected immediately. More information on "BrowseAllow" is presented in the Support Database article "Printer Configuration from SUSE LINUX 9.0 on": SDB:Printer Configuration from SUSE LINUX 9.0 on. To further restrict the access or to allow non-LOCAL hosts to access the server, modify the above entries. The possibilities are commented in /etc/cups/cupsd.conf. We recommend the use of IP addresses instead of names.

    1. Activate the sending of browsing information to the clients:

In /etc/cups/cupsd.conf, activate the entry "BrowseAddress @LOCAL" in order to send browsing information to all LOCAL hosts, or insert entries in the form "BrowseAddress" or "BrowseAddress network.broadcast.IP.address". The various possibilities are commented in /etc/cups/cupsd.conf.

    1. Remember the information in the Section "Restarting the CUPS Server" in the "CUPS Software Administrators Manual" (see above).

The sending of browsing information to the clients is somewhat optional:

    • If it is omitted, the clients will not automatically receive information about the queues on the server.
    • Nevertheless, due to the previous step the clients are able to address the queues of the server.

Especially in large networks it may make sense to grant access to all clients, but to send browsing information only to some of the clients (e.g., only to the clients located in the same department or building as the server).

  1. Configuration of the clients:
    • Recommended:
      1. Activate /etc/init.d/cups so that cupsd is started when the client is booted.
      2. Start cupsd.

From SUSE LINUX 9.1, this takes place by default. If necessary, this can be done with the YaST Runlevel Editor or with insserv. Under normal circumstances, you should not configure anything else, especially

      • no local queues on clients and
      • no changes in the default settings for cupsd on clients.
    • Special cases:
      • Optional:

Insert entries in the form "BrowseAllow IP.of.desired.server" and "BrowseDeny IP.of.unwanted.server" in /etc/cups/cupsd.conf in order to reject all kinds of packets (including browsing information) from undesired servers. We recommend the use of IP addresses instead of names. In certain cases, it may be useful to adapt the "BrowseOrder" entry. If there are servers that do not send any browsing information but whose queues can be accessed (e.g., servers in other departments or buildings), you may want to poll the server's browsing information. To do this, insert an entry in the form "BrowsePoll IP.of.the.server:631" for every server in /etc/cups/cupsd.conf. We recommend the use of IP addresses instead of names. By default, the port on the server is 631. After cupsd is restarted, a cups-polld will be started for every "BrowsePoll" entry.

      • If browsing is generally undesired:

Set "Browsing Off" in /etc/cups/cupsd.conf. This does not mean that the queues on the server can no longer be accessed. Utilities like the command-line tools can still be used; however, the server must be specified explicitly (normally with the option "-h", see the man pages).

      • Client-only configuration:

If browsing is generally undesired, there is no reason for running a cupsd on the client. In this case, a client-only configuration should be set up. This can be done with YaST or manually as described below:

        1. Stop and deactivate cupsd (using the YaST Runlevel Editor or insserv).
        2. In /etc/cups/client.conf, insert an entry in the form "ServerName IP.of.the.server".

This kind of entry should not exist together with a running local cupsd. As only one entry is possible, the preferred server should be entered. To access a different server, the server must be specified explicitly (option "-h") when using the command-line tools, or the environment variable CUPS_SERVER must be set accordingly. Some applications ignore the "ServerName" entry. In this case, it may be useful to set CUPS_SERVER, or the server can be specified explicitly in the application (e.g., with the option "-h" in the print command).

      • Minimal client installations:

The standard minimum requirement for addressing CUPS servers is to install the "cups-libs" and "cups-client" packages. In this case, servers can be addressed with the command-line tools. The absolute minimum requirement for addressing a CUPS server is to install only the "cups-libs" package. In this case, only programs that use the CUPS libraries directly (e.g., kprinter) can be used. <keyword>cups,printer,printing</keyword>