backend(7)

πŸ“¦
version 2.4.19 Β· 4 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, centos-stream 10, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

✨ backend(7) β€” the OpenPrinting glow-up edition ✨

okay bestie, sit down, hydrate, because today we're learning about backends in the backend(7) manual. this is the OpenPrinting era of CUPS and honestly? it's giving plumbing but make it fashion. πŸ’…


πŸ’– NAME πŸ’–

backend β€” cups backend transmission interfaces. that's it, that's the name, no notes. πŸŽ€


πŸ¦‹ SYNOPSIS πŸ¦‹

backend
backend job user title num-copies options [ filename ]

#include <cups/cups.h>

const char *cupsBackendDeviceURI(char **argv);

void cupsBackendReport(const char *device_scheme,
                       const char *device_uri,
                       const char *device_make_and_model,
                       const char *device_info,
                       const char *device_id,
                       const char *device_location);

ssize_t cupsBackChannelWrite(const char *buffer,
                             size_t bytes, double timeout);

int cupsSideChannelRead(cups_sc_command_t *command,
                        cups_sc_status_t *status, char *data,
                        int *datalen, double timeout);

int cupsSideChannelWrite(cups_sc_command_t command,
                         cups_sc_status_t status, const char *data,
                         int datalen, double timeout);

copy that character for character, no cap. ✨


🌸 DESCRIPTION 🌸

so. backends are a special type of filter(7) whose whole job is sending print data to devices on the system and discovering different devices. main character energy, truly. πŸ‘‘

like filters, backends have to be able to read from a filename given on the command line or from standard input β€” and they copy standard input to a temporary file whenever the physical interface needs it. 🫢

the command name (argv[0]) is set to the device URI of the destination printer. important: authentication info inside argv[0] gets removed, so backend devs are urged to use the DEVICE_URI environment variable whenever auth info is required. use cupsBackendDeviceURI() to retrieve the correct device URI. πŸ”

back-channel data coming from the device should be relayed to the job filters using the cupsBackChannelWrite function. πŸ”₯

backends are also responsible for reading side-channel requests with cupsSideChannelRead() and responding with cupsSideChannelWrite(). and the CUPS_SC_FD constant defines the file descriptor you should be monitoring for incoming requests. iykyk. ⭐

πŸ” DEVICE DISCOVERY πŸ”

when run with no arguments, the backend should list the devices and schemes it supports or is advertising, straight to standard output. the output is zero or more lines, and each line is one of these forms:

device-class scheme "Unknown" "device-info"
device-class device-uri "device-make-and-model" "device-info"
device-class device-uri "device-make-and-model" "device-info" "device-id"
device-class device-uri "device-make-and-model" "device-info" "device-id" "device-location"

the cupsBackendReport() function can generate these lines for you and handle all the necessary escaping of characters in the various strings. obsessed, honestly. πŸ’–

the device-class field is one of these values:

  • direct β€” the device-uri refers to a specific direct-access device with no options, like a parallel, USB, or SCSI device. plug it in, it just goes. πŸ’…
  • file β€” the device-uri refers to a file on disk. yes, a file. we love a low-stakes device. πŸ“
  • network β€” the device-uri refers to a networked device and conforms to the general form for network URIs. wi-fi bestie behavior. 🌈
  • serial β€” the device-uri refers to a serial device with configurable baud rate and other options. and if the device-uri contains a baud value, that value represents the maximum baud rate supported by the device. ⚑

the scheme field provides the URI scheme supported by the backend. backends should use this form only when the backend supports any URI using that scheme. the device-uri field specifies the full URI to use when communicating with the device. πŸ¦‹

the device-make-and-model field specifies the make and model of the device, e.g. "Example Foojet 2000". and if the make and model is not known? you must report "Unknown". no guessing, no vibes-based labeling. periodt. 😭

the device-info field specifies additional information about the device β€” typically the make and model along with the port number or network address, e.g. "Example Foojet 2000 USB #1". 🌸

the optional device-id field specifies the IEEE-1284 device ID string for the device, which is used to select a matching driver. ✨

the optional device-location field specifies the physical location of the device, which is often used to pre-populate the printer-location attribute when adding a printer. πŸ“

πŸ” PERMISSIONS πŸ”

backends without world read and execute permissions are run as the root user. otherwise, the backend runs under an unprivileged user account β€” typically "lp". so like, permissions are literally the vibe check here. πŸ‘‘


πŸ’€ EXIT STATUS πŸ’€

here are the exit codes defined for backends. memorize them or at least screenshot this:

  • CUPS_BACKEND_OK β€” the print file was successfully transmitted to the device or remote server. slay!! πŸŽ‰
  • CUPS_BACKEND_FAILED β€” the print file was not successfully transmitted to the device or remote server. the scheduler responds by canceling the job, retrying the job, or stopping the queue, depending on the state of the printer-error-policy attribute. 😭
  • CUPS_BACKEND_AUTH_REQUIRED β€” the print file was not successfully transmitted because valid authentication information is required. the scheduler responds by holding the job and adding the 'cups-held-for-authentication' keyword to the "job-reasons" Job Description attribute. πŸ”
  • CUPS_BACKEND_HOLD β€” the print file was not successfully transmitted because it cannot be printed at this time. the scheduler responds by holding the job. ⏸️
  • CUPS_BACKEND_STOP β€” the print file was not successfully transmitted because it cannot be printed at this time. the scheduler responds by stopping the queue. πŸ›‘
  • CUPS_BACKEND_CANCEL β€” the print file was not successfully transmitted because one or more attributes are not supported, or the job was canceled at the printer. the scheduler responds by canceling the job. πŸ’€
  • CUPS_BACKEND_RETRY β€” the print file was not successfully transmitted because of a temporary issue. the scheduler will retry the job at a future time β€” and heads up, other jobs may print before this one. ⏳
  • CUPS_BACKEND_RETRY_CURRENT β€” the print file was not successfully transmitted because of a temporary issue. the scheduler will retry the job immediately without allowing intervening jobs. queue jump, but make it legal. πŸš€
and all other exit code values are reserved. do not go inventing your own, bestie, that's not your lane. πŸ™ˆ

🌈 ENVIRONMENT 🌈

on top of the environment variables listed in cups(1) and filter(7), CUPS backends can expect this one:

  • DEVICE_URI β€” the device URI associated with the printer. 🫢

πŸŽ€ FILES πŸŽ€

  • /etc/cups/cups-files.conf

⭐ NOTES ⭐

CUPS backends are not generally designed to be run directly by the user. aside from the whole device URI situation (argv[0] and the DEVICE_URI environment variable contain the device URI), CUPS backends also expect specific environment variables and file descriptors, and they typically run in a user session that β€” on macOS β€” has additional restrictions that affect how it runs. backends can also be installed with restricted permissions (0500 or 0700), which tell the scheduler to run them as the "root" user instead of an unprivileged user (typically "lp") on the system. 😳

unless you are a developer and you know what you are doing, please do not run backends directly. instead, use the lp(1) or lpr(1) programs to send print jobs, or lpinfo(8) to query for available printers using the backend. the one exception is the SNMP backend β€” see cups-snmp(8) for more info. ✨

🚨 NOTES 🚨

CUPS printer drivers and backends are deprecated and will no longer be supported in a future feature release of CUPS. printers that do not support IPP can be supported using applications such as ippevprinter(1). yes, it's giving end of an era. plan accordingly. πŸ’”

πŸ‘‘ SEE ALSO πŸ‘‘

cups(1), cups-files.conf(5), cups-snmp(8), cupsd(8), filter(7), lp(1), lpinfo(8), lpr(1), CUPS Online Help (http://localhost:631/help)


Copyright Β© 2020-2024 by OpenPrinting.


and that's the whole page, bestie!! this one came from the CUPS backend(7) man page, dated 2021-02-28, sourced from CUPS β€” and honestly it ate. go forth and print responsibly. πŸ–¨οΈβœ¨πŸ’…

πŸ“¦ where this page comes from