]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - doc/help/api-filter.html
Merge changes from CUPS 1.5svn-r8849.
[thirdparty/cups.git] / doc / help / api-filter.html
index 308d0ce07a14999016e977f819b5b9244ae47a54..568aa07b87700cba77d9b20b7faf56b49aa3a059 100644 (file)
-<!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 APIs</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.3'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>Filter and Backend Programming</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.6">
+<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 {
+  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: 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 the Common UNIX Printing System
+  (CUPS).
+
+  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
+  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' target='_top'>CUPS Design Description</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+<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>
+<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_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_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>
 <!--
   "$Id$"
 
-  Filter and backend API introduction for the Common UNIX Printing System (CUPS).
+  Filter and backend programming introduction for the Common UNIX Printing
+  System (CUPS).
 
-  Copyright 1997-2006 by Easy Software Products.
+  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
-  property of Easy Software Products 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 missing or damaged please contact Easy Software Products
-  at:
-
-      Attn: CUPS Licensing Information
-      Easy Software Products
-      44141 Airport View Drive, Suite 204
-      Hollywood, Maryland 20636 USA
-
-      Voice: (301) 373-9600
-      EMail: cups-info@cups.org
-       WWW: http://www.cups.org
+  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'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
 
-<p>The CUPS filter and backend APIs define standard exit codes
-and provide access to the backchannel data stream. They are only
-used when writing backends, filters, and port monitors.</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>
 
-<h2 class='title'>General Usage</h2>
+<dl class="code">
 
-<p>The <var>&lt;cups/backend.h&gt;</var> and
-<var>&lt;cups/cups.h&gt;</var> header files must be included to
-use the <tt>CUPS_BACKEND_</tt> constants and
-<tt>cupsBackChannel</tt> functions, respectively.</p>
+       <dt>argv[1]</dt>
+       <dd>The job ID</dd>
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+       <dt>argv[2]</dt>
+       <dd>The user printing the job</dd>
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
-</pre>
+       <dt>argv[3]</dt>
+       <dd>The job name/title</dd>
 
-<h2 class='title'>Compatibility</h2>
-
-<p>All of these functions require CUPS 1.2 or higher.</p>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#cupsBackChannelRead'><tt>cupsBackChannelRead()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsBackChannelWrite'><tt>cupsBackChannelWrite()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsBackChannelRead'>cupsBackChannelRead()</a></h3>
-<h4>Description</h4>
-<p>Read data from the backchannel.
-
-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.
+       <dt>argv[4]</dt>
+       <dd>The number of copies to print</dd>
 
-</p>
-<h4>Syntax</h4>
-<pre>
-ssize_t
-cupsBackChannelRead(
-    char * buffer,
-    size_t bytes,
-    double timeout);
+       <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-priviledged 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="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>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
+
+<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><tt>buffer</tt></td><td>Buffer to read</td></tr>
-<tr><td><tt>bytes</tt></td><td>Bytes to read</td></tr>
-<tr><td><tt>timeout</tt></td><td>Timeout in seconds</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Bytes read or -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsBackChannelWrite'>cupsBackChannelWrite()</a></h3>
-<h4>Description</h4>
-<p>Write data to the backchannel.
-
-Writes &quot;bytes&quot; bytes to the backchannel. The &quot;timeout&quot; parameter
+<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 &lt;cups/cups.h&gt;
+
+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 &lt;cups/sidechannel.h&gt;
+
+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, &amp;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 &lt;cups/cups.h&gt;
+
+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 &lt;cups/sidechannel.h&gt;
+
+<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>(&amp;command, &amp;status, data, &amp;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 &lt;cups/sidechannel.h&gt;
+
+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, &amp;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 &lt;cups/sidechannel.h&gt;
+
+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">&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>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bytes,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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 &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/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>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bytes,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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 &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>
-<h4>Syntax</h4>
-<pre>
-ssize_t
-cupsBackChannelWrite(
-    const char * buffer,
-    size_t bytes,
-    double timeout);
-</pre>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>buffer</tt></td><td>Buffer to write</td></tr>
-<tr><td><tt>bytes</tt></td><td>Bytes to write</td></tr>
-<tr><td><tt>timeout</tt></td><td>Timeout in seconds</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Bytes written or -1 on error</p>
+<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>
+&nbsp;&nbsp;&nbsp;&nbsp;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 &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.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>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_command_t">cups_sc_command_t</a> command,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *datalen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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 &quot;not
+implemented&quot; status codes, which indicate that the backend or device
+do not support the specified side-channel command.<br>
+<br>
+The &quot;datalen&quot; parameter must be initialized to the size of the buffer
+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/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>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_command_t">cups_sc_command_t</a> *command,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_status_t">cups_sc_status_t</a> *status,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *datalen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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 &quot;datalen&quot; parameter must be initialized to the size of the buffer
+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/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>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *oid,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *datalen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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>
+&quot;oid&quot; contains a numeric OID consisting of integers separated by periods,
+for example &quot;.1.3.6.1.2.1.43&quot;.  Symbolic names from SNMP MIBs are not
+supported and must be converted to their numeric forms.<br>
+<br>
+On input, &quot;data&quot; and &quot;datalen&quot; 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 &quot;datalen&quot; 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">&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>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *oid,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;double timeout,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_walk_func_t">cups_sc_walk_func_t</a> cb,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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 &quot;parent&quot; OID are queried and the results are sent to
+the callback function you provide.<br>
+<br>
+&quot;oid&quot; contains a numeric OID consisting of integers separated by periods,
+for example &quot;.1.3.6.1.2.1.43&quot;.  Symbolic names from SNMP MIBs are not
+supported and must be converted to their numeric forms.<br>
+<br>
+&quot;timeout&quot; 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>
+&quot;cb&quot; provides a function to call for every value that is found. &quot;context&quot;
+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">&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>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_command_t">cups_sc_command_t</a> command,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_status_t">cups_sc_status_t</a> status,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int datalen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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_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_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_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">&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/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>
+</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>