]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - doc/help/api-filter.html
Merge changes from CUPS 1.4svn-r8628.
[thirdparty/cups.git] / doc / help / api-filter.html
index 279d180140712e8d00f7f63371f33522cd430edb..e7686298e355ed9b8e32fb5556a2311f7171f1e5 100644 (file)
@@ -1,10 +1,10 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<!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 name="creator" content="Mini-XML v2.5">
+<meta name="creator" content="Mini-XML v2.6">
 <style type="text/css"><!--
 BODY {
   font-family: lucida grande, geneva, helvetica, arial, sans-serif;
@@ -27,11 +27,20 @@ PRE.command {
   margin-left: 36pt;
 }
 
+P.compact {
+  margin: 0;
+}
+
+P.example {
+  font-style: italic;
+  margin-left: 36pt;
+}
+  
 PRE.example {
   background: #eeeeee;
   border: dotted thin #999999;
   margin-left: 36pt;
-  padding: 10px;
+  padding: 10pt;
 }
 
 PRE.command EM, PRE.example EM {
@@ -49,11 +58,21 @@ P.formula {
 }
 
 BLOCKQUOTE {
-  background: #cccccc;
+  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;
@@ -67,6 +86,19 @@ 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;
@@ -110,19 +142,23 @@ DIV.figure CAPTION {
 }
 
 TH.label {
-  padding-top: 5pt;
   text-align: right;
   vertical-align: top;
 }
 
+TH.sublabel {
+  text-align: right;
+  font-weight: normal;
+}
+
 HR {
   border: solid thin;
 }
 
 SPAN.info {
-  background: #000000;
-  border: thin solid #000000;
-  color: #ffffff;
+  background: black;
+  border: thin solid black;
+  color: white;
   font-size: 80%;
   font-style: italic;
   font-weight: bold;
@@ -134,10 +170,64 @@ H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
   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;
@@ -156,11 +246,6 @@ P.summary {
   font-family: monaco, courier, monospace;
 }
 
-SPAN.message {
-  font-style: italic;
-  font-size: smaller;
-}
-
 DIV.summary TABLE {
   border: solid thin #999999;
   border-collapse: collapse;
@@ -253,12 +338,12 @@ div.contents ul.subcontents li {
 <body>
 <div class='body'>
 <!--
-  "$Id: api-filter.header 7285 2008-02-01 23:57:39Z mike $"
+  "$Id: api-filter.header 8627 2009-05-13 21:39:17Z mike $"
 
   Filter and backend programming header for the Common UNIX Printing System
   (CUPS).
 
-  Copyright 2008 by Apple Inc.
+  Copyright 2008-2009 by Apple Inc.
 
   These coded instructions, statements, and computer programs are the
   property of Apple Inc. and are protected by Federal copyright
@@ -267,15 +352,14 @@ div.contents ul.subcontents li {
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h1 class="title">Filter and Backend Programming</h1>
+<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<br>
-       cups/snmp.h</th>
+       cups/sidechannel.h</th>
 </tr>
 </thead>
 <tbody>
@@ -288,15 +372,17 @@ div.contents ul.subcontents li {
        <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></td>
+       Programming: <a href='api-raster.html' target='_top'>Raster API</a><br>
+       Specifications: <a href='spec-design' target='_top'>CUPS Design Description</a></td>
 </tr>
 </tbody>
 </table></div>
 <h2 class="title">Contents</h2>
 <ul class="contents">
-</li>
+<ul class="subcontents">
 <li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
 <li><a href="#SECURITY">Security Considerations</a></li>
+<li><a href="#PERMISSIONS">File Permissions</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>
@@ -310,12 +396,13 @@ div.contents ul.subcontents li {
 <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>
+</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>
@@ -326,19 +413,18 @@ div.contents ul.subcontents 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 capabilities">cups_sc_bidi_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_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: api-filter.shtml 7502 2008-04-28 21:30:12Z mike $"
+  "$Id: api-filter.shtml 7962 2008-09-18 17:31:33Z mike $"
 
   Filter and backend programming introduction for the Common UNIX Printing
   System (CUPS).
 
-  Copyright 2007-2008 by Apple Inc.
+  Copyright 2007-2009 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
@@ -350,9 +436,11 @@ div.contents ul.subcontents li {
 
 <h2 class='title'><a name="OVERVIEW">Overview</a></h2>
 
-<p>Filters, printer drivers, port monitors, and backends use a common interface
-for processing print jobs and communicating status information to the scheduler.
-Each filter is run with a standard set of command-line arguments:<p>
+<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">
 
@@ -372,7 +460,7 @@ Each filter is run with a standard set of command-line arguments:<p>
        <dd>The options that were provided when the job was submitted</dd>
 
        <dt>argv[6]</dt>
-       <dd>The file to print (first filter only)</dd>
+       <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
@@ -381,6 +469,12 @@ 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
@@ -393,7 +487,7 @@ 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
+<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
@@ -407,10 +501,23 @@ 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
+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="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 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 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
@@ -435,7 +542,8 @@ or 1 when they encounter an error. Backends can return any of the
 
 <h3><a name="ENVIRONMENT">Environment Variables</a></h3>
 
-<p>The following environment variables are defined by the printing system:</p>
+<p>The following environment variables are defined by the printing system
+when running print filters and backends:</p>
 
 <dl class="code">
 
@@ -456,10 +564,15 @@ or 1 when they encounter an error. Backends can return any of the
        application/postscript).</dd>
 
        <dt>CUPS_CACHEDIR</dt>
-       <dd>The directory where cache files can be stored.</dd>
+       <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 data files can be found.</dd>
+       <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>
@@ -479,19 +592,23 @@ or 1 when they encounter an error. Backends can return any of the
        file for this printer.</dd>
 
        <dt>PRINTER</dt>
-       <dd>The name of the printer.</dd>
+       <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 wih the scheduler by writing messages
-to the standard error file. For example, the following code sets the current
-printer state message to "Printing page 5":</p>
+<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;
@@ -511,9 +628,11 @@ prefix strings:</p>
        <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-names</code>, <code>marker-types</code>,
-       <code>printer-alert</code>, and <code>printer-alert-description</code>
-       printer attributes.</dd>
+       <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
@@ -535,7 +654,8 @@ prefix strings:</p>
 
        <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.</dd>
+       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
@@ -561,8 +681,10 @@ prefix strings:</p>
        <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 media, ink, and
-       toner conditions on a printer.</dd>
+       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.</dd>
 
        <dt>WARNING: message</dt>
        <dd>Sets the printer-state-message attribute and adds the specified
@@ -574,6 +696,141 @@ prefix strings:</p>
 <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
@@ -595,7 +852,11 @@ ssize_t bytes;
 bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
 </pre>
 
-The
+<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
@@ -608,7 +869,8 @@ 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... */
+/* 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 */
@@ -635,6 +897,9 @@ recommend writing back-channel data using a timeout of 1.0 seconds:</p>
 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>
@@ -731,7 +996,7 @@ 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">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsBackChannelRead">cupsBackChannelRead</a></h3>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2/Mac OS X 10.5&nbsp;</span><a name="cupsBackChannelRead">cupsBackChannelRead</a></h3>
 <p class="description">Read data from the backchannel.</p>
 <p class="code">
 ssize_t cupsBackChannelRead (<br>
@@ -742,22 +1007,21 @@ ssize_t cupsBackChannelRead (<br>
 <h4 class="parameters">Parameters</h4>
 <dl>
 <dt>buffer</dt>
-<dd class="description">Buffer to read</dd>
+<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</dd>
+<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 &quot;bytes&quot; bytes from the backchannel. The &quot;timeout&quot;
-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 class="discussion">Reads up to &quot;bytes&quot; bytes from the backchannel/backend. The &quot;timeout&quot;
+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">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsBackChannelWrite">cupsBackChannelWrite</a></h3>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2/Mac OS X 10.5&nbsp;</span><a name="cupsBackChannelWrite">cupsBackChannelWrite</a></h3>
 <p class="description">Write data to the backchannel.</p>
 <p class="code">
 ssize_t cupsBackChannelWrite (<br>
@@ -772,18 +1036,18 @@ ssize_t cupsBackChannelWrite (<br>
 <dt>bytes</dt>
 <dd class="description">Bytes to write</dd>
 <dt>timeout</dt>
-<dd class="description">Timeout in seconds</dd>
+<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 &quot;bytes&quot; bytes to the backchannel. The &quot;timeout&quot; parameter
+<p class="discussion">Writes &quot;bytes&quot; bytes to the backchannel/filter. The &quot;timeout&quot; 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"><a name="cupsBackendDeviceURI">cupsBackendDeviceURI</a></h3>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2/Mac OS X 10.5&nbsp;</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>
@@ -800,8 +1064,42 @@ const char *cupsBackendDeviceURI (<br>
 <p class="discussion">The &quot;argv&quot; 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">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSideChannelDoRequest">cupsSideChannelDoRequest</a></h3>
+first.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span><a name="cupsBackendReport">cupsBackendReport</a></h3>
+<p class="description">Write a device line from a backend.</p>
+<p class="code">
+void cupsBackendReport (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *device_scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *device_uri,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *device_make_and_model,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *device_info,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *device_id,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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">&nbsp;CUPS 1.3/Mac OS X 10.5&nbsp;</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>
@@ -835,7 +1133,7 @@ pointed to by the &quot;data&quot; parameter.  cupsSideChannelDoRequest() will
 update the value to contain the number of data bytes in the buffer.
 
 </p>
-<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSideChannelRead">cupsSideChannelRead</a></h3>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3/Mac OS X 10.5&nbsp;</span><a name="cupsSideChannelRead">cupsSideChannelRead</a></h3>
 <p class="description">Read a side-channel message.</p>
 <p class="code">
 int cupsSideChannelRead (<br>
@@ -871,7 +1169,7 @@ pointed to by the &quot;data&quot; parameter.  cupsSideChannelDoRequest() will
 update the value to contain the number of data bytes in the buffer.
 
 </p>
-<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSideChannelSNMPGet">cupsSideChannelSNMPGet</a></h3>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</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>
@@ -912,7 +1210,7 @@ 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">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSideChannelSNMPWalk">cupsSideChannelSNMPWalk</a></h3>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</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>
@@ -958,7 +1256,7 @@ 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">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSideChannelWrite">cupsSideChannelWrite</a></h3>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3/Mac OS X 10.5&nbsp;</span><a name="cupsSideChannelWrite">cupsSideChannelWrite</a></h3>
 <p class="description">Write a side-channel message.</p>
 <p class="code">
 int cupsSideChannelWrite (<br>
@@ -1038,7 +1336,7 @@ typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, int datal
 <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 capabilities</p>
+<p class="description">Bidirectional capability values</p>
 <h4 class="constants">Constants</h4>
 <dl>
 <dt>CUPS_SC_BIDI_NOT_SUPPORTED </dt>
@@ -1058,9 +1356,9 @@ typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, int datal
 <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">&nbsp;CUPS 1.4&nbsp;</span></dt>
+<dt>CUPS_SC_CMD_SNMP_GET <span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span></dt>
 <dd class="description">Query an SNMP OID </dd>
-<dt>CUPS_SC_CMD_SNMP_GET_NEXT <span class="info">&nbsp;CUPS 1.4&nbsp;</span></dt>
+<dt>CUPS_SC_CMD_SNMP_GET_NEXT <span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</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>
@@ -1082,9 +1380,9 @@ typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, int datal
 <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 off-line</dd>
+<dd class="description">Device is offline</dd>
 <dt>CUPS_SC_STATE_ONLINE </dt>
-<dd class="description">Device is on-line</dd>
+<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>