| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <html> |
| <!-- SECTION: Programming --> |
| <head> |
| <title>Filter and Backend Programming </title> |
| <meta name="keywords" content="Programming"> |
| <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> |
| <meta name="creator" content="Mini-XML v2.7"> |
| <style type="text/css"><!-- |
| BODY { |
| font-family: lucida grande, geneva, helvetica, arial, sans-serif; |
| } |
| |
| H1, H2, H3, H4, H5, H6, P, TD, TH { |
| font-family: lucida grande, geneva, helvetica, arial, sans-serif; |
| } |
| |
| KBD { |
| font-family: monaco, courier, monospace; |
| font-weight: bold; |
| } |
| |
| PRE { |
| font-family: monaco, courier, monospace; |
| } |
| |
| PRE.command { |
| border: dotted thin #7f7f7f; |
| margin-left: 36pt; |
| padding: 10px; |
| } |
| |
| P.compact { |
| margin: 0; |
| } |
| |
| P.example { |
| font-style: italic; |
| margin-left: 36pt; |
| } |
| |
| PRE.example { |
| background: #eeeeee; |
| border: dotted thin #999999; |
| margin-left: 36pt; |
| padding: 10pt; |
| } |
| |
| PRE.command EM, PRE.example EM { |
| font-family: lucida grande, geneva, helvetica, arial, sans-serif; |
| } |
| |
| P.command { |
| font-family: monaco, courier, monospace; |
| margin-left: 36pt; |
| } |
| |
| P.formula { |
| font-style: italic; |
| margin-left: 36pt; |
| } |
| |
| BLOCKQUOTE { |
| background: #eeeeee; |
| border: solid thin #999999; |
| padding: 10pt; |
| } |
| |
| A IMG { |
| border: none; |
| } |
| |
| A:link:hover IMG { |
| background: #f0f0f0; |
| border-radius: 10px; |
| -moz-border-radius: 10px; |
| } |
| |
| A:link, A:visited { |
| font-weight: normal; |
| text-decoration: none; |
| } |
| |
| A:link:hover, A:visited:hover, A:active { |
| text-decoration: underline; |
| } |
| |
| SUB, SUP { |
| font-size: 50%; |
| } |
| |
| TR.data, TD.data, TR.data TD { |
| margin-top: 10pt; |
| padding: 5pt; |
| border-bottom: solid 1pt #999999; |
| } |
| |
| TR.data TH { |
| border-bottom: solid 1pt #999999; |
| padding-top: 10pt; |
| padding-left: 5pt; |
| text-align: left; |
| } |
| |
| DIV.table TABLE { |
| border: solid thin #999999; |
| border-collapse: collapse; |
| border-spacing: 0; |
| margin-left: auto; |
| margin-right: auto; |
| } |
| |
| DIV.table CAPTION { |
| caption-side: top; |
| font-size: 120%; |
| font-style: italic; |
| font-weight: bold; |
| margin-left: auto; |
| margin-right: auto; |
| } |
| |
| DIV.table TABLE TD { |
| border: solid thin #cccccc; |
| padding-top: 5pt; |
| } |
| |
| DIV.table TABLE TH { |
| background: #cccccc; |
| border: none; |
| border-bottom: solid thin #999999; |
| } |
| |
| DIV.figure TABLE { |
| margin-left: auto; |
| margin-right: auto; |
| } |
| |
| DIV.figure CAPTION { |
| caption-side: bottom; |
| font-size: 120%; |
| font-style: italic; |
| font-weight: bold; |
| margin-left: auto; |
| margin-right: auto; |
| } |
| |
| TH.label { |
| text-align: right; |
| vertical-align: top; |
| } |
| |
| TH.sublabel { |
| text-align: right; |
| font-weight: normal; |
| } |
| |
| HR { |
| border: solid thin; |
| } |
| |
| SPAN.info { |
| background: black; |
| border: thin solid black; |
| color: white; |
| font-size: 80%; |
| font-style: italic; |
| font-weight: bold; |
| white-space: nowrap; |
| } |
| |
| H2 SPAN.info, H3 SPAN.info, H4 SPAN.info { |
| float: right; |
| font-size: 100%; |
| } |
| |
| H1.title { |
| } |
| |
| H2.title, H3.title { |
| border-bottom: solid 2pt #000000; |
| } |
| |
| DIV.indent, TABLE.indent { |
| margin-top: 2em; |
| margin-left: auto; |
| margin-right: auto; |
| width: 90%; |
| } |
| |
| TABLE.indent { |
| border-collapse: collapse; |
| } |
| |
| TABLE.indent TD, TABLE.indent TH { |
| padding: 0; |
| } |
| |
| TABLE.list { |
| border-collapse: collapse; |
| margin-left: auto; |
| margin-right: auto; |
| width: 90%; |
| } |
| |
| TABLE.list TH { |
| background: white; |
| border-bottom: solid thin #cccccc; |
| color: #444444; |
| padding-top: 10pt; |
| padding-left: 5pt; |
| text-align: left; |
| vertical-align: bottom; |
| white-space: nowrap; |
| } |
| |
| TABLE.list TH A { |
| color: #4444cc; |
| } |
| |
| TABLE.list TD { |
| border-bottom: solid thin #eeeeee; |
| padding-top: 5pt; |
| padding-left: 5pt; |
| } |
| |
| TABLE.list TR:nth-child(even) { |
| background: #f8f8f8; |
| } |
| |
| TABLE.list TR:nth-child(odd) { |
| background: #f4f4f4; |
| } |
| |
| DT { |
| margin-left: 36pt; |
| margin-top: 12pt; |
| } |
| |
| DD { |
| margin-left: 54pt; |
| } |
| |
| DL.category DT { |
| font-weight: bold; |
| } |
| |
| P.summary { |
| margin-left: 36pt; |
| font-family: monaco, courier, monospace; |
| } |
| |
| DIV.summary TABLE { |
| border: solid thin #999999; |
| border-collapse: collapse; |
| border-spacing: 0; |
| margin: 10px; |
| } |
| |
| DIV.summary TABLE TD, DIV.summary TABLE TH { |
| border: solid thin #999999; |
| padding: 5px; |
| text-align: left; |
| vertical-align: top; |
| } |
| |
| DIV.summary TABLE THEAD TH { |
| background: #eeeeee; |
| } |
| |
| /* API documentation styles... */ |
| div.body h1 { |
| margin: 0; |
| } |
| div.body h2 { |
| margin-top: 1.5em; |
| } |
| div.body h3, div.body h4, div.body h5 { |
| margin-bottom: 0.5em; |
| margin-top: 1.5em; |
| } |
| .class, .enumeration, .function, .struct, .typedef, .union { |
| border-bottom: solid thin #999999; |
| margin-bottom: 0; |
| margin-top: 2em; |
| } |
| .description { |
| margin-top: 0.5em; |
| } |
| code, p.code, pre, ul.code li { |
| font-family: monaco, courier, monospace; |
| font-size: 90%; |
| } |
| ul.code, ul.contents, ul.subcontents { |
| list-style-type: none; |
| margin: 0; |
| padding-left: 0; |
| } |
| ul.code li { |
| margin: 0; |
| } |
| ul.contents > li { |
| margin-top: 1em; |
| } |
| ul.contents li ul.code, ul.contents li ul.subcontents { |
| padding-left: 2em; |
| } |
| div.body dl { |
| margin-left: 0; |
| margin-top: 0; |
| } |
| div.body dt { |
| font-style: italic; |
| margin-left: 0; |
| margin-top: 0; |
| } |
| div.body dd { |
| margin-bottom: 0.5em; |
| } |
| |
| /* This is just for the HTML files generated with the framedhelp target */ |
| div.contents { |
| background: #e8e8e8; |
| border: solid thin black; |
| padding: 10px; |
| } |
| div.contents h1 { |
| font-size: 110%; |
| } |
| div.contents h2 { |
| font-size: 100%; |
| } |
| div.contents ul.contents { |
| font-size: 80%; |
| } |
| div.contents ul.subcontents li { |
| margin-left: 1em; |
| text-indent: -1em; |
| } |
| --></style> |
| </head> |
| <body> |
| <div class='body'> |
| <!-- |
| "$Id$" |
| |
| Filter and backend programming header for CUPS. |
| |
| Copyright 2008-2011 by Apple Inc. |
| |
| These coded instructions, statements, and computer programs are the |
| property of Apple Inc. and are protected by Federal copyright |
| law. Distribution and use rights are outlined in the file "LICENSE.txt" |
| which should have been included with this file. If this file is |
| file is missing or damaged, see the license at "http://www.cups.org/". |
| --> |
| |
| <h1 class='title'>Filter and Backend Programming</h1> |
| |
| <div class='summary'><table summary='General Information'> |
| <thead> |
| <tr> |
| <th>Headers</th> |
| <th>cups/backend.h<br> |
| cups/sidechannel.h</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <th>Library</th> |
| <td>-lcups</td> |
| </tr> |
| <tr> |
| <th>See Also</th> |
| <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br> |
| Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br> |
| Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br> |
| Programming: <a href='api-raster.html' target='_top'>Raster API</a><br> |
| Programming: <a href='postscript-driver.html' target='_top'>Developing PostScript Printer Drivers</a><br> |
| Programming: <a href='raster-driver.html' target='_top'>Developing Raster Printer Drivers</a><br> |
| Specifications: <a href='spec-design.html' target='_top'>CUPS Design Description</a></td> |
| </tr> |
| </tbody> |
| </table></div> |
| <h2 class="title">Contents</h2> |
| <ul class="contents"> |
| <li><a href="#OVERVIEW">Overview</a><ul class="subcontents"> |
| <li><a href="#SECURITY">Security Considerations</a></li> |
| <li><a href="#SIGNALS">Signal Handling</a></li> |
| <li><a href="#TEMPFILES">Temporary Files</a></li> |
| <li><a href="#COPIES">Copy Generation</a></li> |
| <li><a href="#EXITCODES">Exit Codes</a></li> |
| <li><a href="#ENVIRONMENT">Environment Variables</a></li> |
| <li><a href="#MESSAGES">Communicating with the Scheduler</a></li> |
| <li><a href="#COMMUNICATING_BACKEND">Communicating with the Backend</a></li> |
| <li><a href="#COMMUNICATING_FILTER">Communicating with Filters</a></li> |
| <li><a href="#SNMP">Doing SNMP Queries with Network Printers</a></li> |
| </ul></li> |
| <li><a href="#FUNCTIONS">Functions</a><ul class="code"> |
| <li><a href="#cupsBackChannelRead" title="Read data from the backchannel.">cupsBackChannelRead</a></li> |
| <li><a href="#cupsBackChannelWrite" title="Write data to the backchannel.">cupsBackChannelWrite</a></li> |
| <li><a href="#cupsBackendDeviceURI" title="Get the device URI for a backend.">cupsBackendDeviceURI</a></li> |
| <li><a href="#cupsBackendReport" title="Write a device line from a backend.">cupsBackendReport</a></li> |
| <li><a href="#cupsSideChannelDoRequest" title="Send a side-channel command to a backend and wait for a response.">cupsSideChannelDoRequest</a></li> |
| <li><a href="#cupsSideChannelRead" title="Read a side-channel message.">cupsSideChannelRead</a></li> |
| <li><a href="#cupsSideChannelSNMPGet" title="Query a SNMP OID's value.">cupsSideChannelSNMPGet</a></li> |
| <li><a href="#cupsSideChannelSNMPWalk" title="Query multiple SNMP OID values.">cupsSideChannelSNMPWalk</a></li> |
| <li><a href="#cupsSideChannelWrite" title="Write a side-channel message.">cupsSideChannelWrite</a></li> |
| </ul></li> |
| <li><a href="#TYPES">Data Types</a><ul class="code"> |
| <li><a href="#cups_backend_t" title="Backend exit codes">cups_backend_t</a></li> |
| <li><a href="#cups_sc_bidi_t" title="Bidirectional capabilities">cups_sc_bidi_t</a></li> |
| <li><a href="#cups_sc_command_t" title="Request command codes">cups_sc_command_t</a></li> |
| <li><a href="#cups_sc_connected_t" title="Connectivity values">cups_sc_connected_t</a></li> |
| <li><a href="#cups_sc_state_t" title="Printer state bits">cups_sc_state_t</a></li> |
| <li><a href="#cups_sc_status_t" title="Response status codes">cups_sc_status_t</a></li> |
| <li><a href="#cups_sc_walk_func_t" title="SNMP walk callback">cups_sc_walk_func_t</a></li> |
| </ul></li> |
| <li><a href="#ENUMERATIONS">Constants</a><ul class="code"> |
| <li><a href="#cups_backend_e" title="Backend exit codes">cups_backend_e</a></li> |
| <li><a href="#cups_sc_bidi_e" title="Bidirectional capability values">cups_sc_bidi_e</a></li> |
| <li><a href="#cups_sc_command_e" title="Request command codes">cups_sc_command_e</a></li> |
| <li><a href="#cups_sc_connected_e" title="Connectivity values">cups_sc_connected_e</a></li> |
| <li><a href="#cups_sc_state_e" title="Printer state bits">cups_sc_state_e</a></li> |
| <li><a href="#cups_sc_status_e" title="Response status codes">cups_sc_status_e</a></li> |
| </ul></li> |
| </ul> |
| <!-- |
| "$Id$" |
| |
| Filter and backend programming introduction for CUPS. |
| |
| Copyright 2007-2011 by Apple Inc. |
| Copyright 1997-2006 by Easy Software Products, all rights reserved. |
| |
| These coded instructions, statements, and computer programs are the |
| property of Apple Inc. and are protected by Federal copyright |
| law. Distribution and use rights are outlined in the file "LICENSE.txt" |
| which should have been included with this file. If this file is |
| file is missing or damaged, see the license at "http://www.cups.org/". |
| --> |
| |
| <h2 class='title'><a name="OVERVIEW">Overview</a></h2> |
| |
| <p>Filters (which include printer drivers and port monitors) and backends |
| are used to convert job files to a printable format and send that data to the |
| printer itself. All of these programs use a common interface for processing |
| print jobs and communicating status information to the scheduler. Each is run |
| with a standard set of command-line arguments:<p> |
| |
| <dl class="code"> |
| |
| <dt>argv[1]</dt> |
| <dd>The job ID</dd> |
| |
| <dt>argv[2]</dt> |
| <dd>The user printing the job</dd> |
| |
| <dt>argv[3]</dt> |
| <dd>The job name/title</dd> |
| |
| <dt>argv[4]</dt> |
| <dd>The number of copies to print</dd> |
| |
| <dt>argv[5]</dt> |
| <dd>The options that were provided when the job was submitted</dd> |
| |
| <dt>argv[6]</dt> |
| <dd>The file to print (first program only)</dd> |
| </dl> |
| |
| <p>The scheduler runs one or more of these programs to print any given job. The |
| first filter reads from the print file and writes to the standard output, while |
| the remaining filters read from the standard input and write to the standard |
| output. The backend is the last filter in the chain and writes to the |
| device.</p> |
| |
| <p>Filters are always run as a non-privileged user, typically "lp", with no |
| connection to the user's desktop. Backends are run either as a non-privileged |
| user or as root if the file permissions do not allow user or group execution. |
| The <a href="#PERMISSIONS">file permissions</a> section talks about this in |
| more detail.</p> |
| |
| <h3><a name="SECURITY">Security Considerations</a></h3> |
| |
| <p>It is always important to use security programming practices. Filters and |
| most backends are run as a non-privileged user, so the major security |
| consideration is resource utilization - filters should not depend on unlimited |
| amounts of CPU, memory, or disk space, and should protect against conditions |
| that could lead to excess usage of any resource like infinite loops and |
| unbounded recursion. In addition, filters must <em>never</em> allow the user to |
| specify an arbitrary file path to a separator page, template, or other file |
| used by the filter since that can lead to an unauthorized disclosure of |
| information. <em>Always</em> treat input as suspect and validate it!</p> |
| |
| <p>If you are developing a backend that runs as root, make sure to check for |
| potential buffer overflows, integer under/overflow conditions, and file |
| accesses since these can lead to privilege escalations. When writing files, |
| always validate the file path and <em>never</em> allow a user to determine |
| where to store a file.</p> |
| |
| <blockquote><b>Note:</b> |
| |
| <p><em>Never</em> write files to a user's home directory. Aside from the |
| security implications, CUPS is a network print service and as such the network |
| user may not be the same as the local user and/or there may not be a local home |
| directory to write to.</p> |
| |
| <p>In addition, some operating systems provide additional security mechanisms |
| that further limit file system access, even for backends running as root. On |
| Mac OS X, for example, no backend may write to a user's home directory.</p> |
| </blockquote> |
| |
| <h3><a name="SIGNALS">Signal Handling</a><h3> |
| |
| <p>The scheduler sends <code>SIGTERM</code> when a printing job is canceled or |
| held. Filters, backends, and port monitors <em>must</em> catch |
| <code>SIGTERM</code> and perform any cleanup necessary to produce a valid output |
| file or return the printer to a known good state. The recommended behavior is to |
| end the output on the current page.</p> |
| |
| <p>Filters and backends may also receive <code>SIGPIPE</code> when an upstream or downstream filter/backend exits with a non-zero status. Developers should generally <code>ignore SIGPIPE</code> at the beginning of <code>main()</code> with the following function call:</p> |
| |
| <pre class="example"> |
| #include <signal.h>> |
| |
| ... |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| signal(SIGPIPE, SIG_IGN); |
| |
| ... |
| } |
| </pre> |
| |
| <h3><a name="PERMISSIONS">File Permissions</a></h3> |
| |
| <p>For security reasons, CUPS will only run filters and backends that are owned |
| by root and do not have world or group write permissions. The recommended |
| permissions for filters and backends are 0555 - read and execute but no write. |
| Backends that must run as root should use permissions of 0500 - read and execute |
| by root, no access for other users. Write permissions can be enabled for the |
| root user only.</p> |
| |
| <p>To avoid a warning message, the directory containing your filter(s) must also |
| be owned by root and have world and group write disabled - permissions of 0755 |
| or 0555 are strongly encouraged.</p> |
| |
| <h3><a name="TEMPFILES">Temporary Files</a></h3> |
| |
| <p>Temporary files should be created in the directory specified by the |
| "TMPDIR" environment variable. The |
| <a href="#cupsTempFile2"><code>cupsTempFile2</code></a> function can be |
| used to safely create temporary files in this directory.</p> |
| |
| <h3><a name="COPIES">Copy Generation</a></h3> |
| |
| <p>The <code>argv[4]</code> argument specifies the number of copies to produce |
| of the input file. In general, you should only generate copies if the |
| <em>filename</em> argument is supplied. The only exception to this are |
| filters that produce device-independent PostScript output, since the PostScript |
| filter <var>pstops</var> is responsible for generating copies of PostScript |
| files.</p> |
| |
| <h3><a name="EXITCODES">Exit Codes</a></h3> |
| |
| <p>Filters must exit with status 0 when they successfully generate print data |
| or 1 when they encounter an error. Backends can return any of the |
| <a href="#cups_backend_t"><code>cups_backend_t</code></a> constants.</p> |
| |
| <h3><a name="ENVIRONMENT">Environment Variables</a></h3> |
| |
| <p>The following environment variables are defined by the printing system |
| when running print filters and backends:</p> |
| |
| <dl class="code"> |
| |
| <dt>APPLE_LANGUAGE</dt> |
| <dd>The Apple language identifier associated with the job |
| (Mac OS X only).</dd> |
| |
| <dt>CHARSET</dt> |
| <dd>The job character set, typically "utf-8".</dd> |
| |
| <dt>CLASS</dt> |
| <dd>When a job is submitted to a printer class, contains the name of |
| the destination printer class. Otherwise this environment |
| variable will not be set.</dd> |
| |
| <dt>CONTENT_TYPE</dt> |
| <dd>The MIME type associated with the file (e.g. |
| application/postscript).</dd> |
| |
| <dt>CUPS_CACHEDIR</dt> |
| <dd>The directory where cache files can be stored. Cache files can be |
| used to retain information between jobs or files in a job.</dd> |
| |
| <dt>CUPS_DATADIR</dt> |
| <dd>The directory where (read-only) CUPS data files can be found.</dd> |
| |
| <dt>CUPS_FILETYPE</dt> |
| <dd>The type of file being printed: "job-sheet" for a banner page and |
| "document" for a regular print file.</dd> |
| |
| <dt>CUPS_SERVERROOT</dt> |
| <dd>The root directory of the server.</dd> |
| |
| <dt>DEVICE_URI</dt> |
| <dd>The device-uri associated with the printer.</dd> |
| |
| <dt>FINAL_CONTENT_TYPE</dt> |
| <dd>The MIME type associated with the printer (e.g. |
| application/vnd.cups-postscript).</dd> |
| |
| <dt>LANG</dt> |
| <dd>The language locale associated with the job.</dd> |
| |
| <dt>PPD</dt> |
| <dd>The full pathname of the PostScript Printer Description (PPD) |
| file for this printer.</dd> |
| |
| <dt>PRINTER</dt> |
| <dd>The queue name of the class or printer.</dd> |
| |
| <dt>RIP_CACHE</dt> |
| <dd>The recommended amount of memory to use for Raster Image |
| Processors (RIPs).</dd> |
| |
| <dt>TMPDIR</dt> |
| <dd>The directory where temporary files should be created.</dd> |
| |
| </dl> |
| |
| <h3><a name="MESSAGES">Communicating with the Scheduler</a></h3> |
| |
| <p>Filters and backends communicate with the scheduler by writing messages |
| to the standard error file. The scheduler reads messages from all filters in |
| a job and processes the message based on its prefix. For example, the following |
| code sets the current printer state message to "Printing page 5":</p> |
| |
| <pre class="example"> |
| int page = 5; |
| |
| fprintf(stderr, "INFO: Printing page %d\n", page); |
| </pre> |
| |
| <p>Each message is a single line of text starting with one of the following |
| prefix strings:</p> |
| |
| <dl class="code"> |
| |
| <dt>ALERT: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "alert" log level.</dd> |
| |
| <dt>ATTR: attribute=value [attribute=value]</dt> |
| <dd>Sets the named printer or job attribute(s). Typically this is used |
| to set the <code>marker-colors</code>, <code>marker-levels</code>, |
| <code>marker-message</code>, <code>marker-names</code>, |
| <code>marker-types</code>, <code>printer-alert</code>, and |
| <code>printer-alert-description</code> printer attributes. Standard |
| <code>marker-types</code> values are listed in <a href='#TABLE1'>Table |
| 1</a>.</dd> |
| |
| <dt>CRIT: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "critical" log |
| level.</dd> |
| |
| <dt>DEBUG: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "debug" log level.</dd> |
| |
| <dt>DEBUG2: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "debug2" log level.</dd> |
| |
| <dt>EMERG: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "emergency" log |
| level.</dd> |
| |
| <dt>ERROR: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "error" log level. |
| Use "ERROR:" messages for non-persistent processing errors.</dd> |
| |
| <dt>INFO: message</dt> |
| <dd>Sets the printer-state-message attribute. If the current log level |
| is set to "debug2", also adds the specified message to the current error |
| log file using the "info" log level.</dd> |
| |
| <dt>NOTICE: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "notice" log level.</dd> |
| |
| <dt>PAGE: page-number #-copies</dt> |
| <dt>PAGE: total #-pages</dt> |
| <dd>Adds an entry to the current page log file. The first form adds |
| #-copies to the job-media-sheets-completed attribute. The second |
| form sets the job-media-sheets-completed attribute to #-pages.</dd> |
| |
| <dt>PPD: keyword=value [keyword=value ...]</dt> |
| <dd>Changes or adds keywords to the printer's PPD file. Typically |
| this is used to update installable options or default media settings |
| based on the printer configuration.</dd> |
| |
| <dt>STATE: printer-state-reason [printer-state-reason ...]</dt> |
| <dt>STATE: + printer-state-reason [printer-state-reason ...]</dt> |
| <dt>STATE: - printer-state-reason [printer-state-reason ...]</dt> |
| <dd>Sets, adds, or removes printer-state-reason keywords to the |
| current queue. Typically this is used to indicate persistent media, |
| ink, toner, and configuration conditions or errors on a printer. |
| <a href='#TABLE2'>Table 2</a> lists the standard state keywords - |
| use vendor-prefixed ("com.acme.foo") keywords for custom states. |
| |
| <blockquote><b>Note:</b> |
| |
| <p>"STATE:" messages often provide visible alerts to the user. For example, on |
| Mac OS X setting a printer-state-reason value with an "-error" or "-warning" |
| suffix will cause the printer's dock item to bounce if the corresponding reason |
| is localized with a cupsIPPReason keyword in the printer's PPD file.</p> |
| |
| </blockquote></dd> |
| |
| <dt>WARNING: message</dt> |
| <dd>Sets the printer-state-message attribute and adds the specified |
| message to the current error log file using the "warning" log |
| level.</dd> |
| |
| </dl> |
| |
| <p>Messages without one of these prefixes are treated as if they began with |
| the "DEBUG:" prefix string.</p> |
| |
| <div class='table'><table width='80%' summary='Table 1: Standard marker-types Values'> |
| <caption>Table 1: <a name='TABLE1'>Standard marker-types Values</a></caption> |
| <thead> |
| <tr> |
| <th>marker-type</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>developer</td> |
| <td>Developer unit</td> |
| </tr> |
| <tr> |
| <td>fuser</td> |
| <td>Fuser unit</td> |
| </tr> |
| <tr> |
| <td>fuserCleaningPad</td> |
| <td>Fuser cleaning pad</td> |
| </tr> |
| <tr> |
| <td>fuserOil</td> |
| <td>Fuser oil</td> |
| </tr> |
| <tr> |
| <td>ink</td> |
| <td>Ink supply</td> |
| </tr> |
| <tr> |
| <td>opc</td> |
| <td>Photo conductor</td> |
| </tr> |
| <tr> |
| <td>solidWax</td> |
| <td>Wax supply</td> |
| </tr> |
| <tr> |
| <td>staples</td> |
| <td>Staple supply</td> |
| </tr> |
| <tr> |
| <td>toner</td> |
| <td>Toner supply</td> |
| </tr> |
| <tr> |
| <td>transferUnit</td> |
| <td>Transfer unit</td> |
| </tr> |
| <tr> |
| <td>wasteInk</td> |
| <td>Waste ink tank</td> |
| </tr> |
| <tr> |
| <td>wasteToner</td> |
| <td>Waste toner tank</td> |
| </tr> |
| <tr> |
| <td>wasteWax</td> |
| <td>Waste wax tank</td> |
| </tr> |
| </tbody> |
| </table></div> |
| |
| <br> |
| |
| <div class='table'><table width='80%' summary='Table 2: Standard State Keywords'> |
| <caption>Table 2: <a name='TABLE2'>Standard State Keywords</a></caption> |
| <thead> |
| <tr> |
| <th>Keyword</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>connecting-to-device</td> |
| <td>Connecting to printer but not printing yet</td> |
| </tr> |
| <tr> |
| <td>cover-open</td> |
| <td>A cover is open on the printer</td> |
| </tr> |
| <tr> |
| <td>input-tray-missing</td> |
| <td>An input tray is missing from the printer</td> |
| </tr> |
| <tr> |
| <td>marker-supply-empty</td> |
| <td>Out of ink</td> |
| </tr> |
| <tr> |
| <td>marker-supply-low</td> |
| <td>Low on ink</td> |
| </tr> |
| <tr> |
| <td>marker-waste-almost-full</td> |
| <td>Waste tank almost full</td> |
| </tr> |
| <tr> |
| <td>marker-waste-full</td> |
| <td>Waste tank full</td> |
| </tr> |
| <tr> |
| <td>media-empty</td> |
| <td>Out of media</td> |
| </tr> |
| <tr> |
| <td>media-jam</td> |
| <td>Media is jammed in the printer</td> |
| </tr> |
| <tr> |
| <td>media-low</td> |
| <td>Low on media</td> |
| </tr> |
| <tr> |
| <td>paused</td> |
| <td>Stop the printer</td> |
| </tr> |
| <tr> |
| <td>timed-out</td> |
| <td>Unable to connect to printer</td> |
| </tr> |
| <tr> |
| <td>toner-empty</td> |
| <td>Out of toner</td> |
| </tr> |
| <tr> |
| <td>toner-low</td> |
| <td>Low on toner</td> |
| </tr> |
| </tbody> |
| </table></div> |
| |
| <h3><a name="COMMUNICATING_BACKEND">Communicating with the Backend</a></h3> |
| |
| <p>Filters can communicate with the backend via the |
| <a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> and |
| <a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a> |
| functions. The |
| <a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function |
| reads data that has been sent back from the device and is typically used to |
| obtain status and configuration information. For example, the following code |
| polls the backend for back-channel data:</p> |
| |
| <pre class="example"> |
| #include <cups/cups.h> |
| |
| char buffer[8192]; |
| ssize_t bytes; |
| |
| /* Use a timeout of 0.0 seconds to poll for back-channel data */ |
| bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0); |
| </pre> |
| |
| <p>Filters can also use <code>select()</code> or <code>poll()</code> on the |
| back-channel file descriptor (3 or <code>CUPS_BC_FD</code>) to read data only |
| when it is available.</p> |
| |
| <p>The |
| <a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a> |
| function allows you to get out-of-band status information and do synchronization |
| with the device. For example, the following code gets the current IEEE-1284 |
| device ID string from the backend:</p> |
| |
| <pre class="example"> |
| #include <cups/sidechannel.h> |
| |
| char data[2049]; |
| int datalen; |
| <a href="#cups_sc_status_t">cups_sc_status_t</a> status; |
| |
| /* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for |
| nul-termination... */ |
| datalen = sizeof(data) - 1; |
| |
| /* Get the IEEE-1284 device ID, waiting for up to 1 second */ |
| status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &datalen, 1.0); |
| |
| /* Use the returned value if OK was returned and the length is non-zero */ |
| if (status == CUPS_SC_STATUS_OK && datalen > 0) |
| data[datalen] = '\0'; |
| else |
| data[0] = '\0'; |
| </pre> |
| |
| <h3><a name="COMMUNICATING_FILTER">Communicating with Filters</a></h3> |
| |
| <p>Backends communicate with filters using the reciprocal functions |
| <a href="#cupsBackChannelWrite"><code>cupsBackChannelWrite</code></a>, |
| <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>, and |
| <a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a>. We |
| recommend writing back-channel data using a timeout of 1.0 seconds:</p> |
| |
| <pre class="example"> |
| #include <cups/cups.h> |
| |
| char buffer[8192]; |
| ssize_t bytes; |
| |
| /* Obtain data from printer/device */ |
| ... |
| |
| /* Use a timeout of 1.0 seconds to give filters a chance to read */ |
| cupsBackChannelWrite(buffer, bytes, 1.0); |
| </pre> |
| |
| <p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a> |
| function reads a side-channel command from a filter, driver, or port monitor. |
| Backends can either poll for commands using a <code>timeout</code> of 0.0, wait |
| indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a |
| separate thread for that purpose), or use <code>select</code> or |
| <code>poll</code> on the <code>CUPS_SC_FD</code> file descriptor (4) to handle |
| input and output on several file descriptors at the same time.</p> |
| |
| <p>Once a command is processed, the backend uses the |
| <a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function |
| to send its response. For example, the following code shows how to poll for a |
| side-channel command and respond to it:</p> |
| |
| <pre class="example"> |
| #include <cups/sidechannel.h> |
| |
| <a href="#cups_sc_command_t">cups_sc_command_t</a> command; |
| <a href="#cups_sc_status_t">cups_sc_status_t</a> status; |
| char data[2048]; |
| int datalen = sizeof(data); |
| |
| /* Poll for a command... */ |
| if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&command, &status, data, &datalen, 0.0)) |
| { |
| switch (command) |
| { |
| /* handle supported commands, fill data/datalen/status with values as needed */ |
| |
| default : |
| status = CUPS_SC_STATUS_NOT_IMPLEMENTED; |
| datalen = 0; |
| break; |
| } |
| |
| /* Send a response... */ |
| <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0); |
| } |
| </pre> |
| |
| <h3><a name="SNMP">Doing SNMP Queries with Network Printers</a></h3> |
| |
| <p>The Simple Network Management Protocol (SNMP) allows you to get the current |
| status, page counter, and supply levels from most network printers. Every |
| piece of information is associated with an Object Identifier (OID), and |
| every printer has a <em>community</em> name associated with it. OIDs can be |
| queried directly or by "walking" over a range of OIDs with a common prefix.</p> |
| |
| <p>The two CUPS SNMP functions provide a simple API for querying network |
| printers through the side-channel interface. Each accepts a string containing |
| an OID like ".1.3.6.1.2.1.43.10.2.1.4.1.1" (the standard page counter OID) |
| along with a timeout for the query.</p> |
| |
| <p>The <a href="#cupsSideChannelSNMPGet"><code>cupsSideChannelSNMPGet</code></a> |
| function queries a single OID and returns the value as a string in a buffer |
| you supply:</p> |
| |
| <pre class="example"> |
| #include <cups/sidechannel.h> |
| |
| char data[512]; |
| int datalen = sizeof(data); |
| |
| if (<a href="#cupsSideChannelSNMPGet">cupsSideChannelSNMPGet</a>(".1.3.6.1.2.1.43.10.2.1.4.1.1", data, &datalen, 5.0) |
| == CUPS_SC_STATUS_OK) |
| { |
| /* Do something with the value */ |
| printf("Page counter is: %s\n", data); |
| } |
| </pre> |
| |
| <p>The |
| <a href="#cupsSideChannelSNMPWalk"><code>cupsSideChannelSNMPWalk</code></a> |
| function allows you to query a whole group of OIDs, calling a function of your |
| choice for each OID that is found:</p> |
| |
| <pre class="example"> |
| #include <cups/sidechannel.h> |
| |
| void |
| my_callback(const char *oid, const char *data, int datalen, void *context) |
| { |
| /* Do something with the value */ |
| printf("%s=%s\n", oid, data); |
| } |
| |
| ... |
| |
| void *my_data; |
| |
| <a href="#cupsSideChannelSNMPWalk">cupsSNMPSideChannelWalk</a>(".1.3.6.1.2.1.43", 5.0, my_callback, my_data); |
| </pre> |
| <h2 class="title"><a name="FUNCTIONS">Functions</a></h2> |
| <h3 class="function"><span class="info"> CUPS 1.2/Mac OS X 10.5 </span><a name="cupsBackChannelRead">cupsBackChannelRead</a></h3> |
| <p class="description">Read data from the backchannel.</p> |
| <p class="code"> |
| ssize_t cupsBackChannelRead (<br> |
| char *buffer,<br> |
| size_t bytes,<br> |
| double timeout<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>buffer</dt> |
| <dd class="description">Buffer to read into</dd> |
| <dt>bytes</dt> |
| <dd class="description">Bytes to read</dd> |
| <dt>timeout</dt> |
| <dd class="description">Timeout in seconds, typically 0.0 to poll</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">Bytes read or -1 on error</p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">Reads up to "bytes" bytes from the backchannel/backend. The "timeout" |
| parameter controls how many seconds to wait for the data - use 0.0 to |
| return immediately if there is no data, -1.0 to wait for data indefinitely. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.2/Mac OS X 10.5 </span><a name="cupsBackChannelWrite">cupsBackChannelWrite</a></h3> |
| <p class="description">Write data to the backchannel.</p> |
| <p class="code"> |
| ssize_t cupsBackChannelWrite (<br> |
| const char *buffer,<br> |
| size_t bytes,<br> |
| double timeout<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>buffer</dt> |
| <dd class="description">Buffer to write</dd> |
| <dt>bytes</dt> |
| <dd class="description">Bytes to write</dd> |
| <dt>timeout</dt> |
| <dd class="description">Timeout in seconds, typically 1.0</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">Bytes written or -1 on error</p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">Writes "bytes" bytes to the backchannel/filter. The "timeout" parameter |
| controls how many seconds to wait for the data to be written - use |
| 0.0 to return immediately if the data cannot be written, -1.0 to wait |
| indefinitely. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.2/Mac OS X 10.5 </span><a name="cupsBackendDeviceURI">cupsBackendDeviceURI</a></h3> |
| <p class="description">Get the device URI for a backend.</p> |
| <p class="code"> |
| const char *cupsBackendDeviceURI (<br> |
| char **argv<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>argv</dt> |
| <dd class="description">Command-line arguments</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">Device URI or <code>NULL</code></p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">The "argv" argument is the argv argument passed to main(). This |
| function returns the device URI passed in the DEVICE_URI environment |
| variable or the device URI passed in argv[0], whichever is found |
| first. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.4/Mac OS X 10.6 </span><a name="cupsBackendReport">cupsBackendReport</a></h3> |
| <p class="description">Write a device line from a backend.</p> |
| <p class="code"> |
| void cupsBackendReport (<br> |
| const char *device_scheme,<br> |
| const char *device_uri,<br> |
| const char *device_make_and_model,<br> |
| const char *device_info,<br> |
| const char *device_id,<br> |
| const char *device_location<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>device_scheme</dt> |
| <dd class="description">device-scheme string</dd> |
| <dt>device_uri</dt> |
| <dd class="description">device-uri string</dd> |
| <dt>device_make_and_model</dt> |
| <dd class="description">device-make-and-model string or <code>NULL</code></dd> |
| <dt>device_info</dt> |
| <dd class="description">device-info string or <code>NULL</code></dd> |
| <dt>device_id</dt> |
| <dd class="description">device-id string or <code>NULL</code></dd> |
| <dt>device_location</dt> |
| <dd class="description">device-location string or <code>NULL</code></dd> |
| </dl> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">This function writes a single device line to stdout for a backend. |
| It handles quoting of special characters in the device-make-and-model, |
| device-info, device-id, and device-location strings. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.3/Mac OS X 10.5 </span><a name="cupsSideChannelDoRequest">cupsSideChannelDoRequest</a></h3> |
| <p class="description">Send a side-channel command to a backend and wait for a response.</p> |
| <p class="code"> |
| <a href="#cups_sc_status_t">cups_sc_status_t</a> cupsSideChannelDoRequest (<br> |
| <a href="#cups_sc_command_t">cups_sc_command_t</a> command,<br> |
| char *data,<br> |
| int *datalen,<br> |
| double timeout<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>command</dt> |
| <dd class="description">Command to send</dd> |
| <dt>data</dt> |
| <dd class="description">Response data buffer pointer</dd> |
| <dt>datalen</dt> |
| <dd class="description">Size of data buffer on entry, number of bytes in buffer on return</dd> |
| <dt>timeout</dt> |
| <dd class="description">Timeout in seconds</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">Status of command</p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">This function is normally only called by filters, drivers, or port |
| monitors in order to communicate with the backend used by the current |
| printer. Programs must be prepared to handle timeout or "not |
| implemented" status codes, which indicate that the backend or device |
| do not support the specified side-channel command.<br> |
| <br> |
| The "datalen" parameter must be initialized to the size of the buffer |
| pointed to by the "data" parameter. cupsSideChannelDoRequest() will |
| update the value to contain the number of data bytes in the buffer. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.3/Mac OS X 10.5 </span><a name="cupsSideChannelRead">cupsSideChannelRead</a></h3> |
| <p class="description">Read a side-channel message.</p> |
| <p class="code"> |
| int cupsSideChannelRead (<br> |
| <a href="#cups_sc_command_t">cups_sc_command_t</a> *command,<br> |
| <a href="#cups_sc_status_t">cups_sc_status_t</a> *status,<br> |
| char *data,<br> |
| int *datalen,<br> |
| double timeout<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>command</dt> |
| <dd class="description">Command code</dd> |
| <dt>status</dt> |
| <dd class="description">Status code</dd> |
| <dt>data</dt> |
| <dd class="description">Data buffer pointer</dd> |
| <dt>datalen</dt> |
| <dd class="description">Size of data buffer on entry, number of bytes in buffer on return</dd> |
| <dt>timeout</dt> |
| <dd class="description">Timeout in seconds</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">0 on success, -1 on error</p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">This function is normally only called by backend programs to read |
| commands from a filter, driver, or port monitor program. The |
| caller must be prepared to handle incomplete or invalid messages |
| and return the corresponding status codes.<br> |
| <br> |
| The "datalen" parameter must be initialized to the size of the buffer |
| pointed to by the "data" parameter. cupsSideChannelDoRequest() will |
| update the value to contain the number of data bytes in the buffer. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.4/Mac OS X 10.6 </span><a name="cupsSideChannelSNMPGet">cupsSideChannelSNMPGet</a></h3> |
| <p class="description">Query a SNMP OID's value.</p> |
| <p class="code"> |
| <a href="#cups_sc_status_t">cups_sc_status_t</a> cupsSideChannelSNMPGet (<br> |
| const char *oid,<br> |
| char *data,<br> |
| int *datalen,<br> |
| double timeout<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>oid</dt> |
| <dd class="description">OID to query</dd> |
| <dt>data</dt> |
| <dd class="description">Buffer for OID value</dd> |
| <dt>datalen</dt> |
| <dd class="description">Size of OID buffer on entry, size of value on return</dd> |
| <dt>timeout</dt> |
| <dd class="description">Timeout in seconds</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">Query status</p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">This function asks the backend to do a SNMP OID query on behalf of the |
| filter, port monitor, or backend using the default community name.<br> |
| <br> |
| "oid" contains a numeric OID consisting of integers separated by periods, |
| for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not |
| supported and must be converted to their numeric forms.<br> |
| <br> |
| On input, "data" and "datalen" provide the location and size of the |
| buffer to hold the OID value as a string. HEX-String (binary) values are |
| converted to hexadecimal strings representing the binary data, while |
| NULL-Value and unknown OID types are returned as the empty string. |
| The returned "datalen" does not include the trailing nul. |
| |
| <code>CUPS_SC_STATUS_NOT_IMPLEMENTED</code> is returned by backends that do not |
| support SNMP queries. <code>CUPS_SC_STATUS_NO_RESPONSE</code> is returned when |
| the printer does not respond to the SNMP query. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.4/Mac OS X 10.6 </span><a name="cupsSideChannelSNMPWalk">cupsSideChannelSNMPWalk</a></h3> |
| <p class="description">Query multiple SNMP OID values.</p> |
| <p class="code"> |
| <a href="#cups_sc_status_t">cups_sc_status_t</a> cupsSideChannelSNMPWalk (<br> |
| const char *oid,<br> |
| double timeout,<br> |
| <a href="#cups_sc_walk_func_t">cups_sc_walk_func_t</a> cb,<br> |
| void *context<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>oid</dt> |
| <dd class="description">First numeric OID to query</dd> |
| <dt>timeout</dt> |
| <dd class="description">Timeout for each query in seconds</dd> |
| <dt>cb</dt> |
| <dd class="description">Function to call with each value</dd> |
| <dt>context</dt> |
| <dd class="description">Application-defined pointer to send to callback</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">Status of first query of <code>CUPS_SC_STATUS_OK</code> on success</p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">This function asks the backend to do multiple SNMP OID queries on behalf |
| of the filter, port monitor, or backend using the default community name. |
| All OIDs under the "parent" OID are queried and the results are sent to |
| the callback function you provide.<br> |
| <br> |
| "oid" contains a numeric OID consisting of integers separated by periods, |
| for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not |
| supported and must be converted to their numeric forms.<br> |
| <br> |
| "timeout" specifies the timeout for each OID query. The total amount of |
| time will depend on the number of OID values found and the time required |
| for each query.<br> |
| <br> |
| "cb" provides a function to call for every value that is found. "context" |
| is an application-defined pointer that is sent to the callback function |
| along with the OID and current data. The data passed to the callback is the |
| same as returned by <a href="#cupsSideChannelSNMPGet"><code>cupsSideChannelSNMPGet</code></a>. |
| |
| <code>CUPS_SC_STATUS_NOT_IMPLEMENTED</code> is returned by backends that do not |
| support SNMP queries. <code>CUPS_SC_STATUS_NO_RESPONSE</code> is returned when |
| the printer does not respond to the first SNMP query. |
| |
| </p> |
| <h3 class="function"><span class="info"> CUPS 1.3/Mac OS X 10.5 </span><a name="cupsSideChannelWrite">cupsSideChannelWrite</a></h3> |
| <p class="description">Write a side-channel message.</p> |
| <p class="code"> |
| int cupsSideChannelWrite (<br> |
| <a href="#cups_sc_command_t">cups_sc_command_t</a> command,<br> |
| <a href="#cups_sc_status_t">cups_sc_status_t</a> status,<br> |
| const char *data,<br> |
| int datalen,<br> |
| double timeout<br> |
| );</p> |
| <h4 class="parameters">Parameters</h4> |
| <dl> |
| <dt>command</dt> |
| <dd class="description">Command code</dd> |
| <dt>status</dt> |
| <dd class="description">Status code</dd> |
| <dt>data</dt> |
| <dd class="description">Data buffer pointer</dd> |
| <dt>datalen</dt> |
| <dd class="description">Number of bytes of data</dd> |
| <dt>timeout</dt> |
| <dd class="description">Timeout in seconds</dd> |
| </dl> |
| <h4 class="returnvalue">Return Value</h4> |
| <p class="description">0 on success, -1 on error</p> |
| <h4 class="discussion">Discussion</h4> |
| <p class="discussion">This function is normally only called by backend programs to send |
| responses to a filter, driver, or port monitor program. |
| |
| </p> |
| <h2 class="title"><a name="TYPES">Data Types</a></h2> |
| <h3 class="typedef"><a name="cups_backend_t">cups_backend_t</a></h3> |
| <p class="description">Backend exit codes</p> |
| <p class="code"> |
| typedef enum <a href="#cups_backend_e">cups_backend_e</a> cups_backend_t; |
| </p> |
| <h3 class="typedef"><a name="cups_sc_bidi_t">cups_sc_bidi_t</a></h3> |
| <p class="description">Bidirectional capabilities</p> |
| <p class="code"> |
| typedef enum <a href="#cups_sc_bidi_e">cups_sc_bidi_e</a> cups_sc_bidi_t; |
| </p> |
| <h3 class="typedef"><a name="cups_sc_command_t">cups_sc_command_t</a></h3> |
| <p class="description">Request command codes</p> |
| <p class="code"> |
| typedef enum <a href="#cups_sc_command_e">cups_sc_command_e</a> cups_sc_command_t; |
| </p> |
| <h3 class="typedef"><a name="cups_sc_connected_t">cups_sc_connected_t</a></h3> |
| <p class="description">Connectivity values</p> |
| <p class="code"> |
| typedef enum <a href="#cups_sc_connected_e">cups_sc_connected_e</a> cups_sc_connected_t; |
| </p> |
| <h3 class="typedef"><a name="cups_sc_state_t">cups_sc_state_t</a></h3> |
| <p class="description">Printer state bits</p> |
| <p class="code"> |
| typedef enum <a href="#cups_sc_state_e">cups_sc_state_e</a> cups_sc_state_t; |
| </p> |
| <h3 class="typedef"><a name="cups_sc_status_t">cups_sc_status_t</a></h3> |
| <p class="description">Response status codes</p> |
| <p class="code"> |
| typedef enum <a href="#cups_sc_status_e">cups_sc_status_e</a> cups_sc_status_t; |
| </p> |
| <h3 class="typedef"><a name="cups_sc_walk_func_t">cups_sc_walk_func_t</a></h3> |
| <p class="description">SNMP walk callback</p> |
| <p class="code"> |
| typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, int datalen, void *context); |
| </p> |
| <h2 class="title"><a name="ENUMERATIONS">Constants</a></h2> |
| <h3 class="enumeration"><a name="cups_backend_e">cups_backend_e</a></h3> |
| <p class="description">Backend exit codes</p> |
| <h4 class="constants">Constants</h4> |
| <dl> |
| <dt>CUPS_BACKEND_AUTH_REQUIRED </dt> |
| <dd class="description">Job failed, authentication required</dd> |
| <dt>CUPS_BACKEND_CANCEL </dt> |
| <dd class="description">Job failed, cancel job</dd> |
| <dt>CUPS_BACKEND_FAILED </dt> |
| <dd class="description">Job failed, use error-policy</dd> |
| <dt>CUPS_BACKEND_HOLD </dt> |
| <dd class="description">Job failed, hold job</dd> |
| <dt>CUPS_BACKEND_OK </dt> |
| <dd class="description">Job completed successfully</dd> |
| <dt>CUPS_BACKEND_RETRY </dt> |
| <dd class="description">Job failed, retry this job later</dd> |
| <dt>CUPS_BACKEND_RETRY_CURRENT </dt> |
| <dd class="description">Job failed, retry this job immediately</dd> |
| <dt>CUPS_BACKEND_STOP </dt> |
| <dd class="description">Job failed, stop queue</dd> |
| </dl> |
| <h3 class="enumeration"><a name="cups_sc_bidi_e">cups_sc_bidi_e</a></h3> |
| <p class="description">Bidirectional capability values</p> |
| <h4 class="constants">Constants</h4> |
| <dl> |
| <dt>CUPS_SC_BIDI_NOT_SUPPORTED </dt> |
| <dd class="description">Bidirectional I/O is not supported</dd> |
| <dt>CUPS_SC_BIDI_SUPPORTED </dt> |
| <dd class="description">Bidirectional I/O is supported</dd> |
| </dl> |
| <h3 class="enumeration"><a name="cups_sc_command_e">cups_sc_command_e</a></h3> |
| <p class="description">Request command codes</p> |
| <h4 class="constants">Constants</h4> |
| <dl> |
| <dt>CUPS_SC_CMD_DRAIN_OUTPUT </dt> |
| <dd class="description">Drain all pending output</dd> |
| <dt>CUPS_SC_CMD_GET_BIDI </dt> |
| <dd class="description">Return bidirectional capabilities</dd> |
| <dt>CUPS_SC_CMD_GET_CONNECTED <span class="info"> CUPS 1.5/Mac OS X 10.7 </span></dt> |
| <dd class="description">Return whether the backend is "connected" to the printer </dd> |
| <dt>CUPS_SC_CMD_GET_DEVICE_ID </dt> |
| <dd class="description">Return the IEEE-1284 device ID</dd> |
| <dt>CUPS_SC_CMD_GET_STATE </dt> |
| <dd class="description">Return the device state</dd> |
| <dt>CUPS_SC_CMD_SNMP_GET <span class="info"> CUPS 1.4/Mac OS X 10.6 </span></dt> |
| <dd class="description">Query an SNMP OID </dd> |
| <dt>CUPS_SC_CMD_SNMP_GET_NEXT <span class="info"> CUPS 1.4/Mac OS X 10.6 </span></dt> |
| <dd class="description">Query the next SNMP OID </dd> |
| <dt>CUPS_SC_CMD_SOFT_RESET </dt> |
| <dd class="description">Do a soft reset</dd> |
| </dl> |
| <h3 class="enumeration"><a name="cups_sc_connected_e">cups_sc_connected_e</a></h3> |
| <p class="description">Connectivity values</p> |
| <h4 class="constants">Constants</h4> |
| <dl> |
| <dt>CUPS_SC_CONNECTED </dt> |
| <dd class="description">Backend is "connected" to printer</dd> |
| <dt>CUPS_SC_NOT_CONNECTED </dt> |
| <dd class="description">Backend is not "connected" to printer</dd> |
| </dl> |
| <h3 class="enumeration"><a name="cups_sc_state_e">cups_sc_state_e</a></h3> |
| <p class="description">Printer state bits</p> |
| <h4 class="constants">Constants</h4> |
| <dl> |
| <dt>CUPS_SC_STATE_BUSY </dt> |
| <dd class="description">Device is busy</dd> |
| <dt>CUPS_SC_STATE_ERROR </dt> |
| <dd class="description">Other error condition</dd> |
| <dt>CUPS_SC_STATE_MARKER_EMPTY </dt> |
| <dd class="description">Toner/ink out condition</dd> |
| <dt>CUPS_SC_STATE_MARKER_LOW </dt> |
| <dd class="description">Toner/ink low condition</dd> |
| <dt>CUPS_SC_STATE_MEDIA_EMPTY </dt> |
| <dd class="description">Paper out condition</dd> |
| <dt>CUPS_SC_STATE_MEDIA_LOW </dt> |
| <dd class="description">Paper low condition</dd> |
| <dt>CUPS_SC_STATE_OFFLINE </dt> |
| <dd class="description">Device is offline</dd> |
| <dt>CUPS_SC_STATE_ONLINE </dt> |
| <dd class="description">Device is online</dd> |
| </dl> |
| <h3 class="enumeration"><a name="cups_sc_status_e">cups_sc_status_e</a></h3> |
| <p class="description">Response status codes</p> |
| <h4 class="constants">Constants</h4> |
| <dl> |
| <dt>CUPS_SC_STATUS_BAD_MESSAGE </dt> |
| <dd class="description">The command/response message was invalid</dd> |
| <dt>CUPS_SC_STATUS_IO_ERROR </dt> |
| <dd class="description">An I/O error occurred</dd> |
| <dt>CUPS_SC_STATUS_NONE </dt> |
| <dd class="description">No status</dd> |
| <dt>CUPS_SC_STATUS_NOT_IMPLEMENTED </dt> |
| <dd class="description">Command not implemented</dd> |
| <dt>CUPS_SC_STATUS_NO_RESPONSE </dt> |
| <dd class="description">The device did not respond</dd> |
| <dt>CUPS_SC_STATUS_OK </dt> |
| <dd class="description">Operation succeeded</dd> |
| <dt>CUPS_SC_STATUS_TIMEOUT </dt> |
| <dd class="description">The backend did not respond</dd> |
| <dt>CUPS_SC_STATUS_TOO_BIG </dt> |
| <dd class="description">Response too big</dd> |
| </dl> |
| </div> |
| </body> |
| </html> |