]> git.ipfire.org Git - thirdparty/cups.git/blame - doc/help/api-filter.html
Merge pull request #1312 from weblate/weblate-cups-cups
[thirdparty/cups.git] / doc / help / api-filter.html
CommitLineData
73721e3e 1<!DOCTYPE html>
b47dab17 2<html lang="en-US">
ef416fc2 3<!-- SECTION: Programming -->
b47dab17
MS
4<head>
5<title>Filter and Backend Programming</title>
6<meta name="keywords" content="Programming">
7<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
b6008d6b 8<meta name="generator" content="codedoc v3.8">
b47dab17
MS
9<meta name="author" content="Unknown">
10<meta name="language" content="en-US">
11<meta name="copyright" content="Unknown">
12<meta name="version" content="0.0">
13<style type="text/css"><!--
14body {
a2f718d4
MS
15 background: white;
16 color: black;
17 font-family: sans-serif;
18 font-size: 12pt;
5a738aea 19}
a2f718d4
MS
20a {
21 color: black;
e4572d57 22}
b47dab17 23a:link, a:visited {
a2f718d4 24 color: #00f;
5a738aea 25}
b47dab17 26a:link:hover, a:visited:hover, a:active {
a2f718d4 27 color: #c0c;
5a738aea 28}
a2f718d4
MS
29body, p, h1, h2, h3, h4, h5, h6 {
30 font-family: sans-serif;
31 line-height: 1.4;
5a738aea 32}
a2f718d4 33h1, h2, h3, h4, h5, h6 {
5a738aea 34 font-weight: bold;
a2f718d4 35 page-break-inside: avoid;
5a738aea 36}
a2f718d4 37h1 {
699fe020 38 font-size: 250%;
5a738aea
MS
39 margin: 0;
40}
a2f718d4 41h2 {
699fe020 42 font-size: 250%;
5a738aea
MS
43 margin-top: 1.5em;
44}
a2f718d4
MS
45h3 {
46 font-size: 200%;
5a738aea
MS
47 margin-bottom: 0.5em;
48 margin-top: 1.5em;
49}
a2f718d4
MS
50h4 {
51 font-size: 150%;
699fe020
MS
52 margin-bottom: 0.5em;
53 margin-top: 1.5em;
54}
a2f718d4
MS
55h5 {
56 font-size: 125%;
699fe020
MS
57 margin-bottom: 0.5em;
58 margin-top: 1.5em;
59}
a2f718d4 60h6 {
699fe020 61 font-size: 110%;
a2f718d4
MS
62 margin-bottom: 0.5em;
63 margin-top: 1.5em;
699fe020 64}
a2f718d4
MS
65img.title {
66 width: 256px;
699fe020 67}
a2f718d4
MS
68div.header h1, div.header p {
69 text-align: center;
699fe020 70}
a2f718d4
MS
71div.contents, div.body, div.footer {
72 page-break-before: always;
699fe020 73}
a2f718d4
MS
74.class, .enumeration, .function, .struct, .typedef, .union {
75 border-bottom: solid 2px gray;
5a738aea
MS
76}
77.description {
78 margin-top: 0.5em;
79}
699fe020 80.function {
699fe020
MS
81 margin-bottom: 0;
82}
699fe020
MS
83blockquote {
84 border: solid thin gray;
a2f718d4
MS
85 box-shadow: 3px 3px 5px rgba(127,127,127,0.25);
86 margin: 1em 0;
87 padding: 10px;
699fe020
MS
88 page-break-inside: avoid;
89}
0350eba5
MS
90blockquote :first-child {
91 margin-top: 0;
92}
93blockquote :first-child {
94 margin-bottom: 0;
95}
699fe020 96p code, li code, p.code, pre, ul.code li {
699fe020 97 font-family: monospace;
699fe020
MS
98 hyphens: manual;
99 -webkit-hyphens: manual;
699fe020
MS
100}
101p.code, pre, ul.code li {
a2f718d4
MS
102 background: rgba(127,127,127,0.25);
103 border: thin dotted gray;
699fe020 104 padding: 10px;
a2f718d4 105 page-break-inside: avoid;
699fe020 106}
a2f718d4
MS
107pre {
108 white-space: pre-wrap;
699fe020
MS
109}
110a:link, a:visited {
111 text-decoration: none;
112}
113span.info {
114 background: black;
115 border: solid thin black;
116 color: white;
117 font-size: 80%;
118 font-style: italic;
119 font-weight: bold;
120 white-space: nowrap;
121}
a2f718d4
MS
122h1 span.info, h2 span.info, h3 span.info, h4 span.info {
123 border-top-left-radius: 10px;
124 border-top-right-radius: 10px;
699fe020
MS
125 float: right;
126 padding: 3px 6px;
5a738aea
MS
127}
128ul.code, ul.contents, ul.subcontents {
129 list-style-type: none;
130 margin: 0;
131 padding-left: 0;
132}
133ul.code li {
134 margin: 0;
135}
136ul.contents > li {
137 margin-top: 1em;
138}
139ul.contents li ul.code, ul.contents li ul.subcontents {
140 padding-left: 2em;
141}
a2f718d4
MS
142table {
143 border-collapse: collapse;
144 border-spacing: 0;
145}
146td {
147 border: solid 1px gray;
148 padding: 5px 10px;
149 vertical-align: top;
150}
151td.left {
152 text-align: left;
153}
154td.center {
155 text-align: center;
156}
157td.right {
158 text-align: right;
159}
160th {
161 border-bottom: solid 2px gray;
162 padding: 1px 5px;
163 text-align: center;
164 vertical-align: bottom;
165}
166tr:nth-child(even) {
167 background: rgba(127,127,127,0.25);
168}
699fe020
MS
169table.list {
170 border-collapse: collapse;
171 width: 100%;
172}
699fe020 173table.list th {
a2f718d4 174 border-bottom: none;
699fe020
MS
175 border-right: 2px solid gray;
176 font-family: monospace;
a2f718d4 177 font-weight: normal;
699fe020
MS
178 padding: 5px 10px 5px 2px;
179 text-align: right;
180 vertical-align: top;
5a738aea 181}
699fe020 182table.list td {
a2f718d4 183 border: none;
699fe020
MS
184 padding: 5px 2px 5px 10px;
185 text-align: left;
186 vertical-align: top;
5a738aea 187}
a2f718d4
MS
188h2.title, h3.title {
189 border-bottom: solid 2px gray;
5a738aea 190}
a2f718d4
MS
191/* Syntax highlighting */
192span.comment {
193 color: darkgreen;
194}
195span.directive {
0350eba5 196 color: red;
a2f718d4
MS
197}
198span.number {
199 color: brown;
200}
201span.reserved {
0350eba5 202 color: blue;
a2f718d4
MS
203}
204span.string {
205 color: magenta;
206}
207/* Dark mode overrides */
208@media (prefers-color-scheme: dark) {
209 body {
210 background: black;
211 color: #ccc;
212 }
213 a {
214 color: #ccc;
215 }
216 a:link, a:visited {
217 color: #66f;
218 }
219 a:link:hover, a:visited:hover, a:active {
220 color: #f06;
221 }
222}
223/* Show contents on left side in web browser */
224@media screen and (min-width: 800px) {
225 div.contents {
226 border-right: solid thin gray;
227 bottom: 0px;
228 box-shadow: 3px 3px 5px rgba(127,127,127,0.5);
229 font-size: 10pt;
230 left: 0px;
231 overflow: scroll;
232 padding: 1%;
233 position: fixed;
234 top: 0px;
235 width: 18%;
236 }
237 div.contents h2.title {
238 margin-top: 0px;
239 }
240 div.header, div.body, div.footer {
241 margin-left: 20%;
242 padding: 1% 2%;
243 }
244}
245/* Center title page content vertically */
246@media print {
247 div.header {
248 padding-top: 33%;
249 }
ac884b6a 250}
5a738aea 251--></style>
b47dab17
MS
252</head>
253<body>
254<div class="header">
ef416fc2 255<!--
321d8d57 256 Filter and backend programming header for CUPS.
21075eff 257
76b6aade 258 Copyright © 2020-2024 by OpenPrinting.
53f8d64f 259 Copyright © 2008-2016 by Apple Inc.
ef416fc2 260
53f8d64f
MS
261 Licensed under Apache License v2.0. See the file "LICENSE" for more
262 information.
ef416fc2 263-->
264
178cb736
MS
265<h1 class='title'>Filter and Backend Programming</h1>
266
5a738aea
MS
267<div class='summary'><table summary='General Information'>
268<thead>
269<tr>
ac884b6a 270 <th>Headers</th>
5a738aea 271 <th>cups/backend.h<br>
dffa3c74 272 cups/ppd.h<br>
79e1d494 273 cups/sidechannel.h</th>
5a738aea
MS
274</tr>
275</thead>
276<tbody>
277<tr>
278 <th>Library</th>
279 <td>-lcups</td>
280</tr>
281<tr>
282 <th>See Also</th>
283 <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
284 Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
285 Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
79e1d494 286 Programming: <a href='api-raster.html' target='_top'>Raster API</a><br>
b0f6947b
MS
287 Programming: <a href='postscript-driver.html' target='_top'>Developing PostScript Printer Drivers</a><br>
288 Programming: <a href='raster-driver.html' target='_top'>Developing Raster Printer Drivers</a><br>
10d09e33 289 Specifications: <a href='spec-design.html' target='_top'>CUPS Design Description</a></td>
5a738aea
MS
290</tr>
291</tbody>
292</table></div>
b47dab17
MS
293</div>
294<div class="contents">
295<h2 class="title">Contents</h2>
296<ul class="contents">
297<li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
298<li><a href="#SECURITY">Security Considerations</a></li>
299<li><a href="#SIGNALS">Canceled Jobs and Signal Handling</a></li>
300<li><a href="#PERMISSIONS">File Permissions</a></li>
301<li><a href="#TEMPFILES">Temporary Files</a></li>
302<li><a href="#COPIES">Copy Generation</a></li>
303<li><a href="#EXITCODES">Exit Codes</a></li>
304<li><a href="#ENVIRONMENT">Environment Variables</a></li>
305<li><a href="#MESSAGES">Communicating with the Scheduler</a></li>
306<li><a href="#COMMUNICATING_BACKEND">Communicating with the Backend</a></li>
307<li><a href="#COMMUNICATING_FILTER">Communicating with Filters</a></li>
308<li><a href="#SNMP">Doing SNMP Queries with Network Printers</a></li>
309</ul></li>
310<li><a href="#SANDBOXING">Sandboxing on macOS</a></li>
311<li><a href="#FUNCTIONS">Functions</a><ul class="subcontents">
312<li><a href="#cupsBackChannelRead">cupsBackChannelRead</a></li>
313<li><a href="#cupsBackChannelWrite">cupsBackChannelWrite</a></li>
314<li><a href="#cupsBackendDeviceURI">cupsBackendDeviceURI</a></li>
315<li><a href="#cupsBackendReport">cupsBackendReport</a></li>
316<li><a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a></li>
317<li><a href="#cupsSideChannelRead">cupsSideChannelRead</a></li>
318<li><a href="#cupsSideChannelSNMPGet">cupsSideChannelSNMPGet</a></li>
319<li><a href="#cupsSideChannelSNMPWalk">cupsSideChannelSNMPWalk</a></li>
320<li><a href="#cupsSideChannelWrite">cupsSideChannelWrite</a></li>
321</ul></li>
322<li><a href="#TYPES">Data Types</a><ul class="subcontents">
323<li><a href="#cups_backend_t">cups_backend_t</a></li>
324<li><a href="#cups_sc_bidi_t">cups_sc_bidi_t</a></li>
325<li><a href="#cups_sc_command_t">cups_sc_command_t</a></li>
326<li><a href="#cups_sc_connected_t">cups_sc_connected_t</a></li>
327<li><a href="#cups_sc_state_t">cups_sc_state_t</a></li>
328<li><a href="#cups_sc_status_t">cups_sc_status_t</a></li>
329<li><a href="#cups_sc_walk_func_t">cups_sc_walk_func_t</a></li>
330</ul></li>
331<li><a href="#ENUMERATIONS">Enumerations</a><ul class="subcontents">
332<li><a href="#cups_backend_e">cups_backend_e</a></li>
333<li><a href="#cups_sc_bidi_e">cups_sc_bidi_e</a></li>
334<li><a href="#cups_sc_command_e">cups_sc_command_e</a></li>
335<li><a href="#cups_sc_connected_e">cups_sc_connected_e</a></li>
336<li><a href="#cups_sc_state_e">cups_sc_state_e</a></li>
337<li><a href="#cups_sc_status_e">cups_sc_status_e</a></li>
338</ul></li>
339</ul>
340</div>
341<div class="body">
5a738aea 342<!--
22c9029b 343 Filter and backend programming introduction for CUPS.
ef416fc2 344
76b6aade 345 Copyright © 2020-2024 by OpenPrinting.
53f8d64f
MS
346 Copyright © 2007-2016 by Apple Inc.
347 Copyright © 1997-2006 by Easy Software Products, all rights reserved.
ef416fc2 348
53f8d64f
MS
349 Licensed under Apache License v2.0. See the file "LICENSE" for more
350 information.
5a738aea 351-->
f7deaa1a 352
5a738aea 353<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
ef416fc2 354
79e1d494
MS
355<p>Filters (which include printer drivers and port monitors) and backends
356are used to convert job files to a printable format and send that data to the
357printer itself. All of these programs use a common interface for processing
358print jobs and communicating status information to the scheduler. Each is run
359with a standard set of command-line arguments:<p>
ef416fc2 360
5a738aea 361<dl class="code">
f7deaa1a 362
5a738aea
MS
363 <dt>argv[1]</dt>
364 <dd>The job ID</dd>
ef416fc2 365
5a738aea
MS
366 <dt>argv[2]</dt>
367 <dd>The user printing the job</dd>
f7deaa1a 368
5a738aea
MS
369 <dt>argv[3]</dt>
370 <dd>The job name/title</dd>
f7deaa1a 371
5a738aea
MS
372 <dt>argv[4]</dt>
373 <dd>The number of copies to print</dd>
f7deaa1a 374
5a738aea
MS
375 <dt>argv[5]</dt>
376 <dd>The options that were provided when the job was submitted</dd>
f7deaa1a 377
5a738aea 378 <dt>argv[6]</dt>
79e1d494 379 <dd>The file to print (first program only)</dd>
5a738aea 380</dl>
f7deaa1a 381
5a738aea
MS
382<p>The scheduler runs one or more of these programs to print any given job. The
383first filter reads from the print file and writes to the standard output, while
384the remaining filters read from the standard input and write to the standard
385output. The backend is the last filter in the chain and writes to the
386device.</p>
f7deaa1a 387
178cb736
MS
388<p>Filters are always run as a non-privileged user, typically "lp", with no
389connection to the user's desktop. Backends are run either as a non-privileged
390user or as root if the file permissions do not allow user or group execution.
391The <a href="#PERMISSIONS">file permissions</a> section talks about this in
392more detail.</p>
393
ac884b6a
MS
394<h3><a name="SECURITY">Security Considerations</a></h3>
395
396<p>It is always important to use security programming practices. Filters and
eac3a0a0 397most backends are run as a non-privileged user, so the major security
ac884b6a
MS
398consideration is resource utilization - filters should not depend on unlimited
399amounts of CPU, memory, or disk space, and should protect against conditions
400that could lead to excess usage of any resource like infinite loops and
401unbounded recursion. In addition, filters must <em>never</em> allow the user to
402specify an arbitrary file path to a separator page, template, or other file
403used by the filter since that can lead to an unauthorized disclosure of
404information. <em>Always</em> treat input as suspect and validate it!</p>
405
4d301e69 406<p>If you are developing a backend that runs as root, make sure to check for
ac884b6a
MS
407potential buffer overflows, integer under/overflow conditions, and file
408accesses since these can lead to privilege escalations. When writing files,
409always validate the file path and <em>never</em> allow a user to determine
410where to store a file.</p>
411
412<blockquote><b>Note:</b>
413
414<p><em>Never</em> write files to a user's home directory. Aside from the
415security implications, CUPS is a network print service and as such the network
416user may not be the same as the local user and/or there may not be a local home
417directory to write to.</p>
418
419<p>In addition, some operating systems provide additional security mechanisms
178cb736 420that further limit file system access, even for backends running as root. On
8072030b 421macOS, for example, no backend may write to a user's home directory. See the <a href="#SANDBOXING">Sandboxing on macOS</a> section for more information.</p>
ac884b6a
MS
422</blockquote>
423
f228370c 424<h3><a name="SIGNALS">Canceled Jobs and Signal Handling</a></h3>
22c9029b
MS
425
426<p>The scheduler sends <code>SIGTERM</code> when a printing job is canceled or
427held. Filters, backends, and port monitors <em>must</em> catch
428<code>SIGTERM</code> and perform any cleanup necessary to produce a valid output
429file or return the printer to a known good state. The recommended behavior is to
88f9aafc
MS
430end the output on the current page, preferably on the current line or object
431being printed.</p>
22c9029b 432
88f9aafc 433<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 ignore <code>SIGPIPE</code> at the beginning of <code>main()</code> with the following function call:</p>
eac3a0a0
MS
434
435<pre class="example">
8b3724f8 436#include &lt;signal.h&gt;
eac3a0a0
MS
437
438...
439
440int
441main(int argc, char *argv[])
442{
443 signal(SIGPIPE, SIG_IGN);
444
445 ...
446}
447</pre>
448
178cb736
MS
449<h3><a name="PERMISSIONS">File Permissions</a></h3>
450
451<p>For security reasons, CUPS will only run filters and backends that are owned
4d301e69
MS
452by root and do not have world or group write permissions. The recommended
453permissions for filters and backends are 0555 - read and execute but no write.
454Backends that must run as root should use permissions of 0500 - read and execute
455by root, no access for other users. Write permissions can be enabled for the
456root user only.</p>
178cb736
MS
457
458<p>To avoid a warning message, the directory containing your filter(s) must also
4d301e69
MS
459be owned by root and have world and group write disabled - permissions of 0755
460or 0555 are strongly encouraged.</p>
178cb736 461
ac884b6a
MS
462<h3><a name="TEMPFILES">Temporary Files</a></h3>
463
464<p>Temporary files should be created in the directory specified by the
465"TMPDIR" environment variable. The
466<a href="#cupsTempFile2"><code>cupsTempFile2</code></a> function can be
467used to safely create temporary files in this directory.</p>
468
469<h3><a name="COPIES">Copy Generation</a></h3>
470
471<p>The <code>argv[4]</code> argument specifies the number of copies to produce
472of the input file. In general, you should only generate copies if the
473<em>filename</em> argument is supplied. The only exception to this are
474filters that produce device-independent PostScript output, since the PostScript
475filter <var>pstops</var> is responsible for generating copies of PostScript
476files.</p>
477
5a738aea 478<h3><a name="EXITCODES">Exit Codes</a></h3>
f7deaa1a 479
5a738aea
MS
480<p>Filters must exit with status 0 when they successfully generate print data
481or 1 when they encounter an error. Backends can return any of the
482<a href="#cups_backend_t"><code>cups_backend_t</code></a> constants.</p>
f7deaa1a 483
5a738aea 484<h3><a name="ENVIRONMENT">Environment Variables</a></h3>
f7deaa1a 485
79e1d494
MS
486<p>The following environment variables are defined by the printing system
487when running print filters and backends:</p>
f7deaa1a 488
5a738aea 489<dl class="code">
f7deaa1a 490
acb056cb 491 <dt>APPLE_LANGUAGE</dt>
5a738aea 492 <dd>The Apple language identifier associated with the job
8072030b 493 (macOS only).</dd>
f7deaa1a 494
5a738aea
MS
495 <dt>CHARSET</dt>
496 <dd>The job character set, typically "utf-8".</dd>
f7deaa1a 497
5a738aea
MS
498 <dt>CLASS</dt>
499 <dd>When a job is submitted to a printer class, contains the name of
500 the destination printer class. Otherwise this environment
501 variable will not be set.</dd>
f7deaa1a 502
5a738aea
MS
503 <dt>CONTENT_TYPE</dt>
504 <dd>The MIME type associated with the file (e.g.
505 application/postscript).</dd>
f7deaa1a 506
5a738aea 507 <dt>CUPS_CACHEDIR</dt>
79e1d494
MS
508 <dd>The directory where cache files can be stored. Cache files can be
509 used to retain information between jobs or files in a job.</dd>
f7deaa1a 510
5a738aea 511 <dt>CUPS_DATADIR</dt>
79e1d494 512 <dd>The directory where (read-only) CUPS data files can be found.</dd>
f7deaa1a 513
758a062f
MS
514 <dt>CUPS_FILETYPE</dt>
515 <dd>The type of file being printed: "job-sheet" for a banner page and
516 "document" for a regular print file.</dd>
517
5a738aea
MS
518 <dt>CUPS_SERVERROOT</dt>
519 <dd>The root directory of the server.</dd>
f7deaa1a 520
5a738aea
MS
521 <dt>DEVICE_URI</dt>
522 <dd>The device-uri associated with the printer.</dd>
f7deaa1a 523
5a738aea
MS
524 <dt>FINAL_CONTENT_TYPE</dt>
525 <dd>The MIME type associated with the printer (e.g.
526 application/vnd.cups-postscript).</dd>
f7deaa1a 527
5a738aea
MS
528 <dt>LANG</dt>
529 <dd>The language locale associated with the job.</dd>
f7deaa1a 530
5a738aea
MS
531 <dt>PPD</dt>
532 <dd>The full pathname of the PostScript Printer Description (PPD)
533 file for this printer.</dd>
f7deaa1a 534
5a738aea 535 <dt>PRINTER</dt>
79e1d494 536 <dd>The queue name of the class or printer.</dd>
f7deaa1a 537
5a738aea
MS
538 <dt>RIP_CACHE</dt>
539 <dd>The recommended amount of memory to use for Raster Image
540 Processors (RIPs).</dd>
f7deaa1a 541
79e1d494
MS
542 <dt>TMPDIR</dt>
543 <dd>The directory where temporary files should be created.</dd>
544
5a738aea 545</dl>
f7deaa1a 546
5a738aea 547<h3><a name="MESSAGES">Communicating with the Scheduler</a></h3>
f7deaa1a 548
79e1d494
MS
549<p>Filters and backends communicate with the scheduler by writing messages
550to the standard error file. The scheduler reads messages from all filters in
551a job and processes the message based on its prefix. For example, the following
552code sets the current printer state message to "Printing page 5":</p>
f7deaa1a 553
5a738aea
MS
554<pre class="example">
555int page = 5;
f7deaa1a 556
5a738aea 557fprintf(stderr, "INFO: Printing page %d\n", page);
f7deaa1a 558</pre>
559
5a738aea
MS
560<p>Each message is a single line of text starting with one of the following
561prefix strings:</p>
562
563<dl class="code">
564
565 <dt>ALERT: message</dt>
566 <dd>Sets the printer-state-message attribute and adds the specified
567 message to the current error log file using the "alert" log level.</dd>
568
569 <dt>ATTR: attribute=value [attribute=value]</dt>
570 <dd>Sets the named printer or job attribute(s). Typically this is used
88f9aafc
MS
571 to set the <code>marker-colors</code>, <code>marker-high-levels</code>,
572 <code>marker-levels</code>, <code>marker-low-levels</code>,
75bd9771
MS
573 <code>marker-message</code>, <code>marker-names</code>,
574 <code>marker-types</code>, <code>printer-alert</code>, and
575 <code>printer-alert-description</code> printer attributes. Standard
576 <code>marker-types</code> values are listed in <a href='#TABLE1'>Table
ca6b43fc 577 1</a>. String values need special handling - see <a href="#ATTR_STRINGS">Reporting Attribute String Values</a> below.</dd>
5a738aea
MS
578
579 <dt>CRIT: message</dt>
580 <dd>Sets the printer-state-message attribute and adds the specified
581 message to the current error log file using the "critical" log
582 level.</dd>
583
584 <dt>DEBUG: message</dt>
585 <dd>Sets the printer-state-message attribute and adds the specified
586 message to the current error log file using the "debug" log level.</dd>
587
588 <dt>DEBUG2: message</dt>
589 <dd>Sets the printer-state-message attribute and adds the specified
590 message to the current error log file using the "debug2" log level.</dd>
591
592 <dt>EMERG: message</dt>
593 <dd>Sets the printer-state-message attribute and adds the specified
594 message to the current error log file using the "emergency" log
595 level.</dd>
596
597 <dt>ERROR: message</dt>
598 <dd>Sets the printer-state-message attribute and adds the specified
79e1d494
MS
599 message to the current error log file using the "error" log level.
600 Use "ERROR:" messages for non-persistent processing errors.</dd>
5a738aea
MS
601
602 <dt>INFO: message</dt>
603 <dd>Sets the printer-state-message attribute. If the current log level
604 is set to "debug2", also adds the specified message to the current error
605 log file using the "info" log level.</dd>
606
607 <dt>NOTICE: message</dt>
608 <dd>Sets the printer-state-message attribute and adds the specified
609 message to the current error log file using the "notice" log level.</dd>
610
611 <dt>PAGE: page-number #-copies</dt>
612 <dt>PAGE: total #-pages</dt>
613 <dd>Adds an entry to the current page log file. The first form adds
614 #-copies to the job-media-sheets-completed attribute. The second
615 form sets the job-media-sheets-completed attribute to #-pages.</dd>
616
20fbc903
MS
617 <dt>PPD: keyword=value [keyword=value ...]</dt>
618 <dd>Changes or adds keywords to the printer's PPD file. Typically
619 this is used to update installable options or default media settings
620 based on the printer configuration.</dd>
621
5a738aea
MS
622 <dt>STATE: + printer-state-reason [printer-state-reason ...]</dt>
623 <dt>STATE: - printer-state-reason [printer-state-reason ...]</dt>
88f9aafc
MS
624 <dd>Sets or clears printer-state-reason keywords for the current queue.
625 Typically this is used to indicate persistent media, ink, toner, and
626 configuration conditions or errors on a printer.
8d7608ec 627 <a href='#TABLE2'>Table 2</a> lists some of the standard "printer-state-reasons" keywords from the <a href="http://www.iana.org/assignments/ipp-registrations/ipp-registrations.xhtml#ipp-registrations-4">IANA IPP Registry</a> -
88f9aafc
MS
628 use vendor-prefixed ("com.example.foo") keywords for custom states. See
629 <a href="#MANAGING_STATE">Managing Printer State in a Filter</a> for more
630 information.
5a738aea
MS
631
632 <dt>WARNING: message</dt>
633 <dd>Sets the printer-state-message attribute and adds the specified
634 message to the current error log file using the "warning" log
635 level.</dd>
636
637</dl>
638
639<p>Messages without one of these prefixes are treated as if they began with
640the "DEBUG:" prefix string.</p>
641
79e1d494
MS
642<div class='table'><table width='80%' summary='Table 1: Standard marker-types Values'>
643<caption>Table 1: <a name='TABLE1'>Standard marker-types Values</a></caption>
644<thead>
645<tr>
646 <th>marker-type</th>
647 <th>Description</th>
648</tr>
649</thead>
650<tbody>
651<tr>
652 <td>developer</td>
653 <td>Developer unit</td>
654</tr>
655<tr>
656 <td>fuser</td>
657 <td>Fuser unit</td>
658</tr>
659<tr>
ca6b43fc 660 <td>fuser-cleaning-pad</td>
79e1d494
MS
661 <td>Fuser cleaning pad</td>
662</tr>
663<tr>
ca6b43fc 664 <td>fuser-oil</td>
79e1d494
MS
665 <td>Fuser oil</td>
666</tr>
667<tr>
668 <td>ink</td>
669 <td>Ink supply</td>
670</tr>
671<tr>
672 <td>opc</td>
673 <td>Photo conductor</td>
674</tr>
675<tr>
ca6b43fc 676 <td>solid-wax</td>
79e1d494
MS
677 <td>Wax supply</td>
678</tr>
679<tr>
680 <td>staples</td>
681 <td>Staple supply</td>
682</tr>
683<tr>
684 <td>toner</td>
685 <td>Toner supply</td>
686</tr>
687<tr>
ca6b43fc 688 <td>transfer-unit</td>
79e1d494
MS
689 <td>Transfer unit</td>
690</tr>
691<tr>
ca6b43fc 692 <td>waste-ink</td>
79e1d494
MS
693 <td>Waste ink tank</td>
694</tr>
695<tr>
ca6b43fc 696 <td>waste-toner</td>
79e1d494
MS
697 <td>Waste toner tank</td>
698</tr>
699<tr>
ca6b43fc 700 <td>waste-wax</td>
79e1d494
MS
701 <td>Waste wax tank</td>
702</tr>
703</tbody>
704</table></div>
705
706<br>
707
708<div class='table'><table width='80%' summary='Table 2: Standard State Keywords'>
709<caption>Table 2: <a name='TABLE2'>Standard State Keywords</a></caption>
710<thead>
711<tr>
712 <th>Keyword</th>
713 <th>Description</th>
714</tr>
715</thead>
716<tbody>
717<tr>
718 <td>connecting-to-device</td>
88f9aafc 719 <td>Connecting to printer but not printing yet.</td>
79e1d494
MS
720</tr>
721<tr>
722 <td>cover-open</td>
88f9aafc 723 <td>The printer's cover is open.</td>
79e1d494
MS
724</tr>
725<tr>
726 <td>input-tray-missing</td>
88f9aafc 727 <td>The paper tray is missing.</td>
79e1d494
MS
728</tr>
729<tr>
730 <td>marker-supply-empty</td>
88f9aafc 731 <td>The printer is out of ink.</td>
79e1d494
MS
732</tr>
733<tr>
734 <td>marker-supply-low</td>
88f9aafc 735 <td>The printer is almost out of ink.</td>
79e1d494
MS
736</tr>
737<tr>
738 <td>marker-waste-almost-full</td>
88f9aafc 739 <td>The printer's waste bin is almost full.</td>
79e1d494
MS
740</tr>
741<tr>
742 <td>marker-waste-full</td>
88f9aafc 743 <td>The printer's waste bin is full.</td>
79e1d494
MS
744</tr>
745<tr>
746 <td>media-empty</td>
88f9aafc 747 <td>The paper tray (any paper tray) is empty.</td>
79e1d494
MS
748</tr>
749<tr>
750 <td>media-jam</td>
88f9aafc 751 <td>There is a paper jam.</td>
79e1d494
MS
752</tr>
753<tr>
754 <td>media-low</td>
88f9aafc
MS
755 <td>The paper tray (any paper tray) is almost empty.</td>
756</tr>
757<tr>
758 <td>media-needed</td>
759 <td>The paper tray needs to be filled (for a job that is printing).</td>
79e1d494
MS
760</tr>
761<tr>
762 <td>paused</td>
88f9aafc 763 <td>Stop the printer.</td>
79e1d494
MS
764</tr>
765<tr>
766 <td>timed-out</td>
88f9aafc 767 <td>Unable to connect to printer.</td>
79e1d494
MS
768</tr>
769<tr>
770 <td>toner-empty</td>
88f9aafc 771 <td>The printer is out of toner.</td>
79e1d494
MS
772</tr>
773<tr>
774 <td>toner-low</td>
88f9aafc
MS
775 <td>The printer is low on toner.</td>
776</tr>
777</tbody>
778</table></div>
779
ca6b43fc
MS
780
781<h4><a name="ATTR_STRINGS">Reporting Attribute String Values</a></h4>
782
783<p>When reporting string values using "ATTR:" messages, a filter or backend must take special care to appropriately quote those values. The scheduler uses the CUPS option parsing code for attributes, so the general syntax is:</p>
784
785<pre class="example">
786name=simple
787name=simple,simple,...
788name='complex value'
789name="complex value"
790name='"complex value"','"complex value"',...
791</pre>
792
793<p>Simple values are strings that do not contain spaces, quotes, backslashes, or the comma and can be placed verbatim in the "ATTR:" message, for example:</p>
794
795<pre class="example">
796int levels[4] = { 40, 50, 60, 70 }; /* CMYK */
797
798fputs("ATTR: marker-colors=#00FFFF,#FF00FF,#FFFF00,#000000\n", stderr);
799fputs("ATTR: marker-high-levels=100,100,100,100\n", stderr);
800fprintf(stderr, "ATTR: marker-levels=%d,%d,%d,%d\n", levels[0], levels[1],
801 levels[2], levels[3], levels[4]);
802fputs("ATTR: marker-low-levels=5,5,5,5\n", stderr);
803fputs("ATTR: marker-types=toner,toner,toner,toner\n", stderr);
804</pre>
805
806<p>Complex values that contains spaces, quotes, backslashes, or the comma must be quoted. For a single value a single set of quotes is sufficient:</p>
807
808<pre class="example">
809fputs("ATTR: marker-message='Levels shown are approximate.'\n", stderr);
810</pre>
811
812<p>When multiple values are reported, each value must be enclosed by a set of single and double quotes:</p>
813
814<pre class="example">
815fputs("ATTR: marker-names='\"Cyan Toner\"','\"Magenta Toner\"',"
816 "'\"Yellow Toner\"','\"Black Toner\"'\n", stderr);
817</pre>
818
819<p>The IPP backend includes a <var>quote_string</var> function that may be used to properly quote a complex value in an "ATTR:" message:</p>
820
821<pre class="example">
822static const char * /* O - Quoted string */
823quote_string(const char *s, /* I - String */
824 char *q, /* I - Quoted string buffer */
825 size_t qsize) /* I - Size of quoted string buffer */
826{
827 char *qptr, /* Pointer into string buffer */
828 *qend; /* End of string buffer */
829
830
831 qptr = q;
832 qend = q + qsize - 5;
833
834 if (qend &lt; q)
835 {
836 *q = '\0';
837 return (q);
838 }
839
840 *qptr++ = '\'';
841 *qptr++ = '\"';
842
843 while (*s && qptr &lt; qend)
844 {
845 if (*s == '\\' || *s == '\"' || *s == '\'')
846 {
847 if (qptr &lt; (qend - 4))
848 {
849 *qptr++ = '\\';
850 *qptr++ = '\\';
851 *qptr++ = '\\';
852 }
853 else
854 break;
855 }
856
857 *qptr++ = *s++;
858 }
859
860 *qptr++ = '\"';
861 *qptr++ = '\'';
862 *qptr = '\0';
863
864 return (q);
865}
866</pre>
867
868
88f9aafc
MS
869<h4><a name="MANAGING_STATE">Managing Printer State in a Filter</a></h4>
870
871<p>Filters are responsible for managing the state keywords they set using
872"STATE:" messages. Typically you will update <em>all</em> of the keywords that
873are used by the filter at startup, for example:</p>
874
875<pre class="example">
876if (foo_condition != 0)
877 fputs("STATE: +com.example.foo\n", stderr);
878else
879 fputs("STATE: -com.example.foo\n", stderr);
880
881if (bar_condition != 0)
882 fputs("STATE: +com.example.bar\n", stderr);
883else
884 fputs("STATE: -com.example.bar\n", stderr);
885</pre>
886
887<p>Then as conditions change, your filter sends "STATE: +keyword" or "STATE:
888-keyword" messages as necessary to set or clear the corresponding keyword,
889respectively.</p>
890
891<p>State keywords are often used to notify the user of issues that span across
892jobs, for example "media-empty-warning" that indicates one or more paper trays
893are empty. These keywords should not be cleared unless the corresponding issue
894no longer exists.</p>
895
896<p>Filters should clear job-related keywords on startup and exit so that they
897do not remain set between jobs. For example, "connecting-to-device" is a job
898sub-state and not an issue that applies when a job is not printing.</p>
899
900<blockquote><b>Note:</b>
901
902<p>"STATE:" messages often provide visible alerts to the user. For example,
8072030b 903on macOS setting a printer-state-reason value with an "-error" or
88f9aafc
MS
904"-warning" suffix will cause the printer's dock item to bounce if the
905corresponding reason is localized with a cupsIPPReason keyword in the
906printer's PPD file.</p>
907
908<p>When providing a vendor-prefixed keyword, <em>always</em> provide the
909corresponding standard keyword (if any) to allow clients to respond to the
910condition correctly. For example, if you provide a vendor-prefixed keyword
911for a low cyan ink condition ("com.example.cyan-ink-low") you must also set the
912"marker-supply-low-warning" keyword. In such cases you should also refrain
913from localizing the vendor-prefixed keyword in the PPD file - otherwise both
914the generic and vendor-specific keyword will be shown in the user
915interface.</p>
916
7374e9e5 917</blockquote>
88f9aafc
MS
918
919<h4><a name="REPORTING_SUPPLIES">Reporting Supply Levels</a></h4>
920
921<p>CUPS tracks several "marker-*" attributes for ink/toner supply level
922reporting. These attributes allow applications to display the current supply
923levels for a printer without printer-specific software. <a href="#TABLE3">Table 3</a> lists the marker attributes and what they represent.</p>
924
925<p>Filters set marker attributes by sending "ATTR:" messages to stderr. For
926example, a filter supporting an inkjet printer with black and tri-color ink
927cartridges would use the following to initialize the supply attributes:</p>
928
929<pre class="example">
930fputs("ATTR: marker-colors=#000000,#00FFFF#FF00FF#FFFF00\n", stderr);
931fputs("ATTR: marker-low-levels=5,10\n", stderr);
932fputs("ATTR: marker-names=Black,Tri-Color\n", stderr);
933fputs("ATTR: marker-types=ink,ink\n", stderr);
934</pre>
935
936<p>Then periodically the filter queries the printer for its current supply
937levels and updates them with a separate "ATTR:" message:</p>
938
939<pre class="example">
940int black_level, tri_level;
941...
942fprintf(stderr, "ATTR: marker-levels=%d,%d\n", black_level, tri_level);
943</pre>
944
945<div class='table'><table width='80%' summary='Table 3: Supply Level Attributes'>
946<caption>Table 3: <a name='TABLE3'>Supply Level Attributes</a></caption>
947<thead>
948<tr>
949 <th>Attribute</th>
950 <th>Description</th>
951</tr>
952</thead>
953<tbody>
954<tr>
955 <td>marker-colors</td>
956 <td>A list of comma-separated colors; each color is either "none" or one or
957 more hex-encoded sRGB colors of the form "#RRGGBB".</td>
958</tr>
959<tr>
960 <td>marker-high-levels</td>
961 <td>A list of comma-separated "almost full" level values from 0 to 100; a
962 value of 100 should be used for supplies that are consumed/emptied like ink
963 cartridges.</td>
964</tr>
965<tr>
966 <td>marker-levels</td>
967 <td>A list of comma-separated level values for each supply. A value of -1
968 indicates the level is unavailable, -2 indicates unknown, and -3 indicates
969 the level is unknown but has not yet reached capacity. Values from 0 to 100
970 indicate the corresponding percentage.</td>
971</tr>
972<tr>
973 <td>marker-low-levels</td>
974 <td>A list of comma-separated "almost empty" level values from 0 to 100; a
975 value of 0 should be used for supplies that are filled like waste ink
976 tanks.</td>
977</tr>
978<tr>
979 <td>marker-message</td>
980 <td>A human-readable supply status message for the user like "12 pages of
981 ink remaining."</td>
982</tr>
983<tr>
984 <td>marker-names</td>
985 <td>A list of comma-separated supply names like "Cyan Ink", "Fuser",
986 etc.</td>
987</tr>
988<tr>
989 <td>marker-types</td>
990 <td>A list of comma-separated supply types; the types are listed in
991 <a href="#TABLE1">Table 1</a>.</td>
79e1d494
MS
992</tr>
993</tbody>
994</table></div>
995
20fbc903 996<h3><a name="COMMUNICATING_BACKEND">Communicating with the Backend</a></h3>
5a738aea
MS
997
998<p>Filters can communicate with the backend via the
999<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> and
1000<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
22c9029b 1001functions. The
5a738aea
MS
1002<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function
1003reads data that has been sent back from the device and is typically used to
1004obtain status and configuration information. For example, the following code
1005polls the backend for back-channel data:</p>
1006
1007<pre class="example">
1008#include &lt;cups/cups.h&gt;
1009
1010char buffer[8192];
1011ssize_t bytes;
1012
1013/* Use a timeout of 0.0 seconds to poll for back-channel data */
1014bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
1015</pre>
f7deaa1a 1016
79e1d494
MS
1017<p>Filters can also use <code>select()</code> or <code>poll()</code> on the
1018back-channel file descriptor (3 or <code>CUPS_BC_FD</code>) to read data only
1019when it is available.</p>
1020
1021<p>The
5a738aea
MS
1022<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
1023function allows you to get out-of-band status information and do synchronization
1024with the device. For example, the following code gets the current IEEE-1284
1025device ID string from the backend:</p>
1026
1027<pre class="example">
f7deaa1a 1028#include &lt;cups/sidechannel.h&gt;
1029
1030char data[2049];
1031int datalen;
5a738aea 1032<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
f7deaa1a 1033
79e1d494
MS
1034/* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for
1035 nul-termination... */
f7deaa1a 1036datalen = sizeof(data) - 1;
1037
1038/* Get the IEEE-1284 device ID, waiting for up to 1 second */
5a738aea 1039status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
f7deaa1a 1040
1041/* Use the returned value if OK was returned and the length is non-zero */
7374e9e5 1042if (status == CUPS_SC_STATUS_OK &amp;&amp; datalen > 0)
f7deaa1a 1043 data[datalen] = '\0';
1044else
1045 data[0] = '\0';
1046</pre>
1047
88f9aafc
MS
1048<h4><a name="DRAIN_OUTPUT">Forcing All Output to a Printer</a></h4>
1049
1050<p>The
1051<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
1052function allows you to tell the backend to send all pending data to the printer.
1053This is most often needed when sending query commands to the printer. For example:</p>
1054
1055<pre class="example">
1056#include &lt;cups/cups.h&gt;
1057#include &lt;cups/sidechannel.h&gt;
1058
1059char data[1024];
1060int datalen = sizeof(data);
1061<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
1062
1063/* Flush pending output to stdout */
1064fflush(stdout);
1065
1066/* Drain output to backend, waiting for up to 30 seconds */
1067status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_DRAIN_OUTPUT, data, &amp;datalen, 30.0);
1068
1069/* Read the response if the output was sent */
1070if (status == CUPS_SC_STATUS_OK)
1071{
1072 ssize_t bytes;
1073
1074 /* Wait up to 10.0 seconds for back-channel data */
1075 bytes = cupsBackChannelRead(data, sizeof(data), 10.0);
1076 /* do something with the data from the printer */
1077}
1078</pre>
1079
20fbc903
MS
1080<h3><a name="COMMUNICATING_FILTER">Communicating with Filters</a></h3>
1081
5a738aea
MS
1082<p>Backends communicate with filters using the reciprocal functions
1083<a href="#cupsBackChannelWrite"><code>cupsBackChannelWrite</code></a>,
1084<a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>, and
1085<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a>. We
1086recommend writing back-channel data using a timeout of 1.0 seconds:</p>
f7deaa1a 1087
5a738aea
MS
1088<pre class="example">
1089#include &lt;cups/cups.h&gt;
f7deaa1a 1090
5a738aea
MS
1091char buffer[8192];
1092ssize_t bytes;
f7deaa1a 1093
79e1d494
MS
1094/* Obtain data from printer/device */
1095...
1096
5a738aea
MS
1097/* Use a timeout of 1.0 seconds to give filters a chance to read */
1098cupsBackChannelWrite(buffer, bytes, 1.0);
f7deaa1a 1099</pre>
1100
5a738aea
MS
1101<p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>
1102function reads a side-channel command from a filter, driver, or port monitor.
1103Backends can either poll for commands using a <code>timeout</code> of 0.0, wait
1104indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a
1105separate thread for that purpose), or use <code>select</code> or
1106<code>poll</code> on the <code>CUPS_SC_FD</code> file descriptor (4) to handle
20fbc903 1107input and output on several file descriptors at the same time.</p>
5a738aea
MS
1108
1109<p>Once a command is processed, the backend uses the
1110<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function
1111to send its response. For example, the following code shows how to poll for a
1112side-channel command and respond to it:</p>
1113
1114<pre class="example">
f7deaa1a 1115#include &lt;cups/sidechannel.h&gt;
1116
5a738aea
MS
1117<a href="#cups_sc_command_t">cups_sc_command_t</a> command;
1118<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
20fbc903
MS
1119char data[2048];
1120int datalen = sizeof(data);
f7deaa1a 1121
1122/* Poll for a command... */
20fbc903 1123if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;status, data, &amp;datalen, 0.0))
f7deaa1a 1124{
f7deaa1a 1125 switch (command)
1126 {
20fbc903 1127 /* handle supported commands, fill data/datalen/status with values as needed */
f7deaa1a 1128
1129 default :
1130 status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
1131 datalen = 0;
1132 break;
1133 }
1134
1135 /* Send a response... */
5a738aea 1136 <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
f7deaa1a 1137}
1138</pre>
ac884b6a
MS
1139
1140<h3><a name="SNMP">Doing SNMP Queries with Network Printers</a></h3>
1141
1142<p>The Simple Network Management Protocol (SNMP) allows you to get the current
1143status, page counter, and supply levels from most network printers. Every
1144piece of information is associated with an Object Identifier (OID), and
1145every printer has a <em>community</em> name associated with it. OIDs can be
1146queried directly or by "walking" over a range of OIDs with a common prefix.</p>
1147
20fbc903
MS
1148<p>The two CUPS SNMP functions provide a simple API for querying network
1149printers through the side-channel interface. Each accepts a string containing
1150an OID like ".1.3.6.1.2.1.43.10.2.1.4.1.1" (the standard page counter OID)
1151along with a timeout for the query.</p>
ac884b6a 1152
20fbc903
MS
1153<p>The <a href="#cupsSideChannelSNMPGet"><code>cupsSideChannelSNMPGet</code></a>
1154function queries a single OID and returns the value as a string in a buffer
1155you supply:</p>
ac884b6a
MS
1156
1157<pre class="example">
20fbc903 1158#include &lt;cups/sidechannel.h&gt;
ac884b6a 1159
20fbc903
MS
1160char data[512];
1161int datalen = sizeof(data);
ac884b6a 1162
20fbc903
MS
1163if (<a href="#cupsSideChannelSNMPGet">cupsSideChannelSNMPGet</a>(".1.3.6.1.2.1.43.10.2.1.4.1.1", data, &amp;datalen, 5.0)
1164 == CUPS_SC_STATUS_OK)
ac884b6a
MS
1165{
1166 /* Do something with the value */
20fbc903 1167 printf("Page counter is: %s\n", data);
ac884b6a
MS
1168}
1169</pre>
1170
20fbc903
MS
1171<p>The
1172<a href="#cupsSideChannelSNMPWalk"><code>cupsSideChannelSNMPWalk</code></a>
1173function allows you to query a whole group of OIDs, calling a function of your
1174choice for each OID that is found:</p>
ac884b6a
MS
1175
1176<pre class="example">
20fbc903 1177#include &lt;cups/sidechannel.h&gt;
ac884b6a
MS
1178
1179void
20fbc903 1180my_callback(const char *oid, const char *data, int datalen, void *context)
ac884b6a
MS
1181{
1182 /* Do something with the value */
20fbc903 1183 printf("%s=%s\n", oid, data);
ac884b6a
MS
1184}
1185
20fbc903
MS
1186...
1187
ac884b6a
MS
1188void *my_data;
1189
20fbc903 1190<a href="#cupsSideChannelSNMPWalk">cupsSNMPSideChannelWalk</a>(".1.3.6.1.2.1.43", 5.0, my_callback, my_data);
ac884b6a 1191</pre>
82d1ebb9 1192
8072030b 1193<h2><a name="SANDBOXING">Sandboxing on macOS</a></h2>
82d1ebb9 1194
8072030b 1195<p>Starting with macOS 10.6, filters and backends are run inside a security "sandbox" which further limits (beyond the normal UNIX user/group permissions) what a filter or backend can do. This helps to both secure the printing system from malicious software and enforce the functional separation of components in the CUPS filter chain. What follows is a list of actions that are explicitly allowed for all filters and backends:</p>
82d1ebb9
MS
1196
1197<ol>
1198
1199 <li>Reading of files: pursuant to normal UNIX file permissions, filters and backends can read files for the current job from the <var>/private/var/spool/cups</var> directory and other files on mounted filesystems <em>except</em> for user home directories under <var>/Users</var>.</li>
1200
1201 <li>Writing of files: pursuant to normal UNIX file permissions, filters and backends can read/write files to the cache directory specified by the <code>CUPS_CACHEDIR</code> environment variable, to the state directory specified by the <code>CUPS_STATEDIR</code> environment variable, to the temporary directory specified by the <code>TMPDIR</code> environment variable, and under the <var>/private/var/db</var>, <var>/private/var/folders</var>, <var>/private/var/lib</var>, <var>/private/var/mysql</var>, <var>/private/var/run</var>, <var>/private/var/spool</var> (except <var>/private/var/spool/cups</var>), <var>/Library/Application&nbsp;Support</var>, <var>/Library/Caches</var>, <var>/Library/Logs</var>, <var>/Library/Preferences</var>, <var>/Library/WebServer</var>, and <var>/Users/Shared</var> directories.</li>
1202
1203 <li>Execution of programs: pursuant to normal UNIX file permissions, filters and backends can execute any program not located under the <var>/Users</var> directory. Child processes inherit the sandbox and are subject to the same restrictions as the parent.</li>
1204
1205 <li>Bluetooth and USB: backends can access Bluetooth and USB printers through IOKit. <em>Filters cannot access Bluetooth and USB printers directly.</em></li>
1206
abcaca57 1207 <li>Network: filters and backends can access UNIX domain sockets under the <var>/private/tmp</var>, <var>/private/var/run</var>, and <var>/private/var/tmp</var> directories. Backends can also create IPv4 and IPv6 TCP (outgoing) and UDP (incoming and outgoing) socket, and bind to local source ports. <em>Filters cannot directly create IPv4 and IPv6 TCP or UDP sockets.</em></li>
82d1ebb9
MS
1208
1209 <li>Notifications: filters and backends can send notifications via the Darwin <code>notify_post()</code> API.</li>
1210
1211</ol>
1212
73721e3e
MS
1213<blockquote><b>Note:</b>
1214
1215<p>The sandbox profile used in CUPS still allows some actions that are not listed above - these privileges will be removed over time until the profile matches the list above.</p>
1216</blockquote>
b47dab17 1217<h2 class="title"><a id="FUNCTIONS">Functions</a></h2>
b6008d6b 1218<h3 class="function"><span class="info">&#160;CUPS 1.2&#160;</span><a id="cupsBackChannelRead">cupsBackChannelRead</a></h3>
b47dab17 1219<p class="description">Read data from the backchannel.</p>
5a738aea 1220<p class="code">
0350eba5 1221ssize_t cupsBackChannelRead(<span class="reserved">char</span> *buffer, size_t bytes, <span class="reserved">double</span> timeout);</p>
5a738aea 1222<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1223<table class="list"><tbody>
1224<tr><th>buffer</th>
b47dab17 1225<td class="description">Buffer to read into</td></tr>
98d88c8d 1226<tr><th>bytes</th>
b47dab17 1227<td class="description">Bytes to read</td></tr>
98d88c8d 1228<tr><th>timeout</th>
b47dab17 1229<td class="description">Timeout in seconds, typically 0.0 to poll</td></tr>
98d88c8d 1230</tbody></table>
5a738aea 1231<h4 class="returnvalue">Return Value</h4>
b47dab17 1232<p class="description">Bytes read or -1 on error</p>
5a738aea 1233<h4 class="discussion">Discussion</h4>
b47dab17 1234<p class="discussion">Reads up to &quot;bytes&quot; bytes from the backchannel/backend. The &quot;timeout&quot;
79e1d494
MS
1235parameter controls how many seconds to wait for the data - use 0.0 to
1236return immediately if there is no data, -1.0 to wait for data indefinitely.
ef416fc2 1237
5a738aea 1238</p>
b6008d6b 1239<h3 class="function"><span class="info">&#160;CUPS 1.2&#160;</span><a id="cupsBackChannelWrite">cupsBackChannelWrite</a></h3>
b47dab17 1240<p class="description">Write data to the backchannel.</p>
5a738aea 1241<p class="code">
0350eba5 1242ssize_t cupsBackChannelWrite(<span class="reserved">const</span> <span class="reserved">char</span> *buffer, size_t bytes, <span class="reserved">double</span> timeout);</p>
5a738aea 1243<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1244<table class="list"><tbody>
1245<tr><th>buffer</th>
b47dab17 1246<td class="description">Buffer to write</td></tr>
98d88c8d 1247<tr><th>bytes</th>
b47dab17 1248<td class="description">Bytes to write</td></tr>
98d88c8d 1249<tr><th>timeout</th>
b47dab17 1250<td class="description">Timeout in seconds, typically 1.0</td></tr>
98d88c8d 1251</tbody></table>
5a738aea 1252<h4 class="returnvalue">Return Value</h4>
b47dab17 1253<p class="description">Bytes written or -1 on error</p>
5a738aea 1254<h4 class="discussion">Discussion</h4>
b47dab17 1255<p class="discussion">Writes &quot;bytes&quot; bytes to the backchannel/filter. The &quot;timeout&quot; parameter
ef416fc2 1256controls how many seconds to wait for the data to be written - use
12570.0 to return immediately if the data cannot be written, -1.0 to wait
1258indefinitely.
1259
ac884b6a 1260</p>
b6008d6b 1261<h3 class="function"><span class="info">&#160;CUPS 1.2&#160;</span><a id="cupsBackendDeviceURI">cupsBackendDeviceURI</a></h3>
b47dab17 1262<p class="description">Get the device URI for a backend.</p>
ac884b6a 1263<p class="code">
0350eba5 1264<span class="reserved">const</span> <span class="reserved">char</span> *cupsBackendDeviceURI(<span class="reserved">char</span> **argv);</p>
ac884b6a 1265<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1266<table class="list"><tbody>
1267<tr><th>argv</th>
b47dab17 1268<td class="description">Command-line arguments</td></tr>
98d88c8d 1269</tbody></table>
ac884b6a 1270<h4 class="returnvalue">Return Value</h4>
b47dab17 1271<p class="description">Device URI or <code>NULL</code></p>
ac884b6a 1272<h4 class="discussion">Discussion</h4>
b47dab17 1273<p class="discussion">The &quot;argv&quot; argument is the argv argument passed to main(). This
ac884b6a
MS
1274function returns the device URI passed in the DEVICE_URI environment
1275variable or the device URI passed in argv[0], whichever is found
426c6a59
MS
1276first.
1277
1278</p>
b6008d6b 1279<h3 class="function"><span class="info">&#160;CUPS 1.4&#160;</span><a id="cupsBackendReport">cupsBackendReport</a></h3>
b47dab17 1280<p class="description">Write a device line from a backend.</p>
06d4e77b 1281<p class="code">
0350eba5 1282<span class="reserved">void</span> cupsBackendReport(<span class="reserved">const</span> <span class="reserved">char</span> *device_scheme, <span class="reserved">const</span> <span class="reserved">char</span> *device_uri, <span class="reserved">const</span> <span class="reserved">char</span> *device_make_and_model, <span class="reserved">const</span> <span class="reserved">char</span> *device_info, <span class="reserved">const</span> <span class="reserved">char</span> *device_id, <span class="reserved">const</span> <span class="reserved">char</span> *device_location);</p>
06d4e77b 1283<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1284<table class="list"><tbody>
1285<tr><th>device_scheme</th>
b47dab17 1286<td class="description">device-scheme string</td></tr>
98d88c8d 1287<tr><th>device_uri</th>
b47dab17 1288<td class="description">device-uri string</td></tr>
98d88c8d 1289<tr><th>device_make_and_model</th>
b47dab17 1290<td class="description">device-make-and-model string or <code>NULL</code></td></tr>
98d88c8d 1291<tr><th>device_info</th>
b47dab17 1292<td class="description">device-info string or <code>NULL</code></td></tr>
98d88c8d 1293<tr><th>device_id</th>
b47dab17 1294<td class="description">device-id string or <code>NULL</code></td></tr>
98d88c8d 1295<tr><th>device_location</th>
b47dab17 1296<td class="description">device-location string or <code>NULL</code></td></tr>
98d88c8d
MS
1297</tbody></table>
1298<h4 class="discussion">Discussion</h4>
b47dab17 1299<p class="discussion">This function writes a single device line to stdout for a backend.
06d4e77b 1300It handles quoting of special characters in the device-make-and-model,
426c6a59
MS
1301device-info, device-id, and device-location strings.
1302
1303</p>
b6008d6b 1304<h3 class="function"><span class="info">&#160;CUPS 1.3&#160;</span><a id="cupsSideChannelDoRequest">cupsSideChannelDoRequest</a></h3>
b47dab17 1305<p class="description">Send a side-channel command to a backend and wait for a response.</p>
5a738aea 1306<p class="code">
0350eba5 1307<a href="#cups_sc_status_t">cups_sc_status_t</a> cupsSideChannelDoRequest(<a href="#cups_sc_command_t">cups_sc_command_t</a> command, <span class="reserved">char</span> *data, <span class="reserved">int</span> *datalen, <span class="reserved">double</span> timeout);</p>
5a738aea 1308<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1309<table class="list"><tbody>
1310<tr><th>command</th>
b47dab17 1311<td class="description">Command to send</td></tr>
98d88c8d 1312<tr><th>data</th>
b47dab17 1313<td class="description">Response data buffer pointer</td></tr>
98d88c8d 1314<tr><th>datalen</th>
b47dab17 1315<td class="description">Size of data buffer on entry, number of bytes in buffer on return</td></tr>
98d88c8d 1316<tr><th>timeout</th>
b47dab17 1317<td class="description">Timeout in seconds</td></tr>
98d88c8d 1318</tbody></table>
5a738aea 1319<h4 class="returnvalue">Return Value</h4>
b47dab17 1320<p class="description">Status of command</p>
5a738aea 1321<h4 class="discussion">Discussion</h4>
b47dab17 1322<p class="discussion">This function is normally only called by filters, drivers, or port
f7deaa1a 1323monitors in order to communicate with the backend used by the current
1324printer. Programs must be prepared to handle timeout or &quot;not
1325implemented&quot; status codes, which indicate that the backend or device
5a738aea
MS
1326do not support the specified side-channel command.<br>
1327<br>
1328The &quot;datalen&quot; parameter must be initialized to the size of the buffer
f7deaa1a 1329pointed to by the &quot;data&quot; parameter. cupsSideChannelDoRequest() will
1330update the value to contain the number of data bytes in the buffer.
1331
5a738aea 1332</p>
b6008d6b 1333<h3 class="function"><span class="info">&#160;CUPS 1.3&#160;</span><a id="cupsSideChannelRead">cupsSideChannelRead</a></h3>
b47dab17 1334<p class="description">Read a side-channel message.</p>
5a738aea 1335<p class="code">
0350eba5 1336<span class="reserved">int</span> cupsSideChannelRead(<a href="#cups_sc_command_t">cups_sc_command_t</a> *command, <a href="#cups_sc_status_t">cups_sc_status_t</a> *status, <span class="reserved">char</span> *data, <span class="reserved">int</span> *datalen, <span class="reserved">double</span> timeout);</p>
5a738aea 1337<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1338<table class="list"><tbody>
1339<tr><th>command</th>
b47dab17 1340<td class="description">Command code</td></tr>
98d88c8d 1341<tr><th>status</th>
b47dab17 1342<td class="description">Status code</td></tr>
98d88c8d 1343<tr><th>data</th>
b47dab17 1344<td class="description">Data buffer pointer</td></tr>
98d88c8d 1345<tr><th>datalen</th>
b47dab17 1346<td class="description">Size of data buffer on entry, number of bytes in buffer on return</td></tr>
98d88c8d 1347<tr><th>timeout</th>
b47dab17 1348<td class="description">Timeout in seconds</td></tr>
98d88c8d 1349</tbody></table>
5a738aea 1350<h4 class="returnvalue">Return Value</h4>
b47dab17 1351<p class="description">0 on success, -1 on error</p>
5a738aea 1352<h4 class="discussion">Discussion</h4>
b47dab17 1353<p class="discussion">This function is normally only called by backend programs to read
f7deaa1a 1354commands from a filter, driver, or port monitor program. The
1355caller must be prepared to handle incomplete or invalid messages
5a738aea
MS
1356and return the corresponding status codes.<br>
1357<br>
1358The &quot;datalen&quot; parameter must be initialized to the size of the buffer
f7deaa1a 1359pointed to by the &quot;data&quot; parameter. cupsSideChannelDoRequest() will
1360update the value to contain the number of data bytes in the buffer.
1361
20fbc903 1362</p>
b6008d6b 1363<h3 class="function"><span class="info">&#160;CUPS 1.4&#160;</span><a id="cupsSideChannelSNMPGet">cupsSideChannelSNMPGet</a></h3>
b47dab17 1364<p class="description">Query a SNMP OID's value.</p>
20fbc903 1365<p class="code">
0350eba5 1366<a href="#cups_sc_status_t">cups_sc_status_t</a> cupsSideChannelSNMPGet(<span class="reserved">const</span> <span class="reserved">char</span> *oid, <span class="reserved">char</span> *data, <span class="reserved">int</span> *datalen, <span class="reserved">double</span> timeout);</p>
20fbc903 1367<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1368<table class="list"><tbody>
1369<tr><th>oid</th>
b47dab17 1370<td class="description">OID to query</td></tr>
98d88c8d 1371<tr><th>data</th>
b47dab17 1372<td class="description">Buffer for OID value</td></tr>
98d88c8d 1373<tr><th>datalen</th>
b47dab17 1374<td class="description">Size of OID buffer on entry, size of value on return</td></tr>
98d88c8d 1375<tr><th>timeout</th>
b47dab17 1376<td class="description">Timeout in seconds</td></tr>
98d88c8d 1377</tbody></table>
20fbc903 1378<h4 class="returnvalue">Return Value</h4>
b47dab17 1379<p class="description">Query status</p>
20fbc903 1380<h4 class="discussion">Discussion</h4>
b47dab17 1381<p class="discussion">This function asks the backend to do a SNMP OID query on behalf of the
20fbc903
MS
1382filter, port monitor, or backend using the default community name.<br>
1383<br>
1384&quot;oid&quot; contains a numeric OID consisting of integers separated by periods,
1385for example &quot;.1.3.6.1.2.1.43&quot;. Symbolic names from SNMP MIBs are not
1386supported and must be converted to their numeric forms.<br>
1387<br>
1388On input, &quot;data&quot; and &quot;datalen&quot; provide the location and size of the
1389buffer to hold the OID value as a string. HEX-String (binary) values are
1390converted to hexadecimal strings representing the binary data, while
1391NULL-Value and unknown OID types are returned as the empty string.
1392The returned &quot;datalen&quot; does not include the trailing nul.
1393
1394<code>CUPS_SC_STATUS_NOT_IMPLEMENTED</code> is returned by backends that do not
1395support SNMP queries. <code>CUPS_SC_STATUS_NO_RESPONSE</code> is returned when
1396the printer does not respond to the SNMP query.
1397
1398</p>
b6008d6b 1399<h3 class="function"><span class="info">&#160;CUPS 1.4&#160;</span><a id="cupsSideChannelSNMPWalk">cupsSideChannelSNMPWalk</a></h3>
b47dab17 1400<p class="description">Query multiple SNMP OID values.</p>
20fbc903 1401<p class="code">
0350eba5 1402<a href="#cups_sc_status_t">cups_sc_status_t</a> cupsSideChannelSNMPWalk(<span class="reserved">const</span> <span class="reserved">char</span> *oid, <span class="reserved">double</span> timeout, <a href="#cups_sc_walk_func_t">cups_sc_walk_func_t</a> cb, <span class="reserved">void</span> *context);</p>
20fbc903 1403<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1404<table class="list"><tbody>
1405<tr><th>oid</th>
b47dab17 1406<td class="description">First numeric OID to query</td></tr>
98d88c8d 1407<tr><th>timeout</th>
b47dab17 1408<td class="description">Timeout for each query in seconds</td></tr>
98d88c8d 1409<tr><th>cb</th>
b47dab17 1410<td class="description">Function to call with each value</td></tr>
98d88c8d 1411<tr><th>context</th>
b47dab17 1412<td class="description">Application-defined pointer to send to callback</td></tr>
98d88c8d 1413</tbody></table>
20fbc903 1414<h4 class="returnvalue">Return Value</h4>
b47dab17 1415<p class="description">Status of first query of <code>CUPS_SC_STATUS_OK</code> on success</p>
20fbc903 1416<h4 class="discussion">Discussion</h4>
b47dab17 1417<p class="discussion">This function asks the backend to do multiple SNMP OID queries on behalf
20fbc903
MS
1418of the filter, port monitor, or backend using the default community name.
1419All OIDs under the &quot;parent&quot; OID are queried and the results are sent to
1420the callback function you provide.<br>
1421<br>
1422&quot;oid&quot; contains a numeric OID consisting of integers separated by periods,
1423for example &quot;.1.3.6.1.2.1.43&quot;. Symbolic names from SNMP MIBs are not
1424supported and must be converted to their numeric forms.<br>
1425<br>
1426&quot;timeout&quot; specifies the timeout for each OID query. The total amount of
1427time will depend on the number of OID values found and the time required
1428for each query.<br>
1429<br>
1430&quot;cb&quot; provides a function to call for every value that is found. &quot;context&quot;
1431is an application-defined pointer that is sent to the callback function
1432along with the OID and current data. The data passed to the callback is the
1433same as returned by <a href="#cupsSideChannelSNMPGet"><code>cupsSideChannelSNMPGet</code></a>.
1434
1435<code>CUPS_SC_STATUS_NOT_IMPLEMENTED</code> is returned by backends that do not
1436support SNMP queries. <code>CUPS_SC_STATUS_NO_RESPONSE</code> is returned when
1437the printer does not respond to the first SNMP query.
1438
5a738aea 1439</p>
b6008d6b 1440<h3 class="function"><span class="info">&#160;CUPS 1.3&#160;</span><a id="cupsSideChannelWrite">cupsSideChannelWrite</a></h3>
b47dab17 1441<p class="description">Write a side-channel message.</p>
5a738aea 1442<p class="code">
0350eba5 1443<span class="reserved">int</span> cupsSideChannelWrite(<a href="#cups_sc_command_t">cups_sc_command_t</a> command, <a href="#cups_sc_status_t">cups_sc_status_t</a> status, <span class="reserved">const</span> <span class="reserved">char</span> *data, <span class="reserved">int</span> datalen, <span class="reserved">double</span> timeout);</p>
5a738aea 1444<h4 class="parameters">Parameters</h4>
98d88c8d
MS
1445<table class="list"><tbody>
1446<tr><th>command</th>
b47dab17 1447<td class="description">Command code</td></tr>
98d88c8d 1448<tr><th>status</th>
b47dab17 1449<td class="description">Status code</td></tr>
98d88c8d 1450<tr><th>data</th>
b47dab17 1451<td class="description">Data buffer pointer</td></tr>
98d88c8d 1452<tr><th>datalen</th>
b47dab17 1453<td class="description">Number of bytes of data</td></tr>
98d88c8d 1454<tr><th>timeout</th>
b47dab17 1455<td class="description">Timeout in seconds</td></tr>
98d88c8d 1456</tbody></table>
5a738aea 1457<h4 class="returnvalue">Return Value</h4>
b47dab17 1458<p class="description">0 on success, -1 on error</p>
5a738aea 1459<h4 class="discussion">Discussion</h4>
b47dab17 1460<p class="discussion">This function is normally only called by backend programs to send
f7deaa1a 1461responses to a filter, driver, or port monitor program.
1462
5a738aea 1463</p>
b47dab17
MS
1464<h2 class="title"><a id="TYPES">Data Types</a></h2>
1465<h3 class="typedef"><a id="cups_backend_t">cups_backend_t</a></h3>
1466<p class="description">Backend exit codes</p>
1467<p class="code">
5a738aea
MS
1468typedef enum <a href="#cups_backend_e">cups_backend_e</a> cups_backend_t;
1469</p>
b47dab17
MS
1470<h3 class="typedef"><a id="cups_sc_bidi_t">cups_sc_bidi_t</a></h3>
1471<p class="description">Bidirectional capabilities</p>
1472<p class="code">
5a738aea
MS
1473typedef enum <a href="#cups_sc_bidi_e">cups_sc_bidi_e</a> cups_sc_bidi_t;
1474</p>
b47dab17
MS
1475<h3 class="typedef"><a id="cups_sc_command_t">cups_sc_command_t</a></h3>
1476<p class="description">Request command codes</p>
1477<p class="code">
5a738aea
MS
1478typedef enum <a href="#cups_sc_command_e">cups_sc_command_e</a> cups_sc_command_t;
1479</p>
b47dab17
MS
1480<h3 class="typedef"><a id="cups_sc_connected_t">cups_sc_connected_t</a></h3>
1481<p class="description">Connectivity values</p>
1482<p class="code">
82f97232
MS
1483typedef enum <a href="#cups_sc_connected_e">cups_sc_connected_e</a> cups_sc_connected_t;
1484</p>
b47dab17
MS
1485<h3 class="typedef"><a id="cups_sc_state_t">cups_sc_state_t</a></h3>
1486<p class="description">Printer state bits</p>
1487<p class="code">
5a738aea
MS
1488typedef enum <a href="#cups_sc_state_e">cups_sc_state_e</a> cups_sc_state_t;
1489</p>
b47dab17
MS
1490<h3 class="typedef"><a id="cups_sc_status_t">cups_sc_status_t</a></h3>
1491<p class="description">Response status codes</p>
1492<p class="code">
5a738aea
MS
1493typedef enum <a href="#cups_sc_status_e">cups_sc_status_e</a> cups_sc_status_t;
1494</p>
b47dab17
MS
1495<h3 class="typedef"><a id="cups_sc_walk_func_t">cups_sc_walk_func_t</a></h3>
1496<p class="description">SNMP walk callback</p>
1497<p class="code">
20fbc903
MS
1498typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, int datalen, void *context);
1499</p>
b47dab17
MS
1500<h2 class="title"><a id="ENUMERATIONS">Constants</a></h2>
1501<h3 class="enumeration"><a id="cups_backend_e">cups_backend_e</a></h3>
1502<p class="description">Backend exit codes</p>
1503<h4 class="constants">Constants</h4>
1504<table class="list"><tbody>
1505<tr><th>CUPS_BACKEND_AUTH_REQUIRED </th><td class="description">Job failed, authentication required</td></tr>
1506<tr><th>CUPS_BACKEND_CANCEL </th><td class="description">Job failed, cancel job</td></tr>
1507<tr><th>CUPS_BACKEND_FAILED </th><td class="description">Job failed, use error-policy</td></tr>
1508<tr><th>CUPS_BACKEND_HOLD </th><td class="description">Job failed, hold job</td></tr>
1509<tr><th>CUPS_BACKEND_OK </th><td class="description">Job completed successfully</td></tr>
1510<tr><th>CUPS_BACKEND_RETRY </th><td class="description">Job failed, retry this job later</td></tr>
1511<tr><th>CUPS_BACKEND_RETRY_CURRENT </th><td class="description">Job failed, retry this job immediately</td></tr>
1512<tr><th>CUPS_BACKEND_STOP </th><td class="description">Job failed, stop queue</td></tr>
98d88c8d 1513</tbody></table>
b47dab17
MS
1514<h3 class="enumeration"><a id="cups_sc_bidi_e">cups_sc_bidi_e</a></h3>
1515<p class="description">Bidirectional capability values</p>
1516<h4 class="constants">Constants</h4>
1517<table class="list"><tbody>
1518<tr><th>CUPS_SC_BIDI_NOT_SUPPORTED </th><td class="description">Bidirectional I/O is not supported</td></tr>
1519<tr><th>CUPS_SC_BIDI_SUPPORTED </th><td class="description">Bidirectional I/O is supported</td></tr>
98d88c8d 1520</tbody></table>
b47dab17
MS
1521<h3 class="enumeration"><a id="cups_sc_command_e">cups_sc_command_e</a></h3>
1522<p class="description">Request command codes</p>
1523<h4 class="constants">Constants</h4>
1524<table class="list"><tbody>
1525<tr><th>CUPS_SC_CMD_DRAIN_OUTPUT </th><td class="description">Drain all pending output</td></tr>
1526<tr><th>CUPS_SC_CMD_GET_BIDI </th><td class="description">Return bidirectional capabilities</td></tr>
b6008d6b 1527<tr><th>CUPS_SC_CMD_GET_CONNECTED <span class="info">&#160;CUPS 1.5&#160;</span></th><td class="description">Return whether the backend is &quot;connected&quot; to the printer </td></tr>
b47dab17
MS
1528<tr><th>CUPS_SC_CMD_GET_DEVICE_ID </th><td class="description">Return the IEEE-1284 device ID</td></tr>
1529<tr><th>CUPS_SC_CMD_GET_STATE </th><td class="description">Return the device state</td></tr>
b6008d6b
MS
1530<tr><th>CUPS_SC_CMD_SNMP_GET <span class="info">&#160;CUPS 1.4&#160;</span></th><td class="description">Query an SNMP OID </td></tr>
1531<tr><th>CUPS_SC_CMD_SNMP_GET_NEXT <span class="info">&#160;CUPS 1.4&#160;</span></th><td class="description">Query the next SNMP OID </td></tr>
b47dab17 1532<tr><th>CUPS_SC_CMD_SOFT_RESET </th><td class="description">Do a soft reset</td></tr>
98d88c8d 1533</tbody></table>
b47dab17
MS
1534<h3 class="enumeration"><a id="cups_sc_connected_e">cups_sc_connected_e</a></h3>
1535<p class="description">Connectivity values</p>
1536<h4 class="constants">Constants</h4>
1537<table class="list"><tbody>
1538<tr><th>CUPS_SC_CONNECTED </th><td class="description">Backend is &quot;connected&quot; to printer</td></tr>
1539<tr><th>CUPS_SC_NOT_CONNECTED </th><td class="description">Backend is not &quot;connected&quot; to printer</td></tr>
98d88c8d 1540</tbody></table>
b47dab17
MS
1541<h3 class="enumeration"><a id="cups_sc_state_e">cups_sc_state_e</a></h3>
1542<p class="description">Printer state bits</p>
1543<h4 class="constants">Constants</h4>
1544<table class="list"><tbody>
1545<tr><th>CUPS_SC_STATE_BUSY </th><td class="description">Device is busy</td></tr>
1546<tr><th>CUPS_SC_STATE_ERROR </th><td class="description">Other error condition</td></tr>
1547<tr><th>CUPS_SC_STATE_MARKER_EMPTY </th><td class="description">Toner/ink out condition</td></tr>
1548<tr><th>CUPS_SC_STATE_MARKER_LOW </th><td class="description">Toner/ink low condition</td></tr>
1549<tr><th>CUPS_SC_STATE_MEDIA_EMPTY </th><td class="description">Paper out condition</td></tr>
1550<tr><th>CUPS_SC_STATE_MEDIA_LOW </th><td class="description">Paper low condition</td></tr>
1551<tr><th>CUPS_SC_STATE_OFFLINE </th><td class="description">Device is offline</td></tr>
1552<tr><th>CUPS_SC_STATE_ONLINE </th><td class="description">Device is online</td></tr>
98d88c8d 1553</tbody></table>
b47dab17
MS
1554<h3 class="enumeration"><a id="cups_sc_status_e">cups_sc_status_e</a></h3>
1555<p class="description">Response status codes</p>
1556<h4 class="constants">Constants</h4>
1557<table class="list"><tbody>
1558<tr><th>CUPS_SC_STATUS_BAD_MESSAGE </th><td class="description">The command/response message was invalid</td></tr>
1559<tr><th>CUPS_SC_STATUS_IO_ERROR </th><td class="description">An I/O error occurred</td></tr>
1560<tr><th>CUPS_SC_STATUS_NONE </th><td class="description">No status</td></tr>
1561<tr><th>CUPS_SC_STATUS_NOT_IMPLEMENTED </th><td class="description">Command not implemented</td></tr>
1562<tr><th>CUPS_SC_STATUS_NO_RESPONSE </th><td class="description">The device did not respond</td></tr>
1563<tr><th>CUPS_SC_STATUS_OK </th><td class="description">Operation succeeded</td></tr>
1564<tr><th>CUPS_SC_STATUS_TIMEOUT </th><td class="description">The backend did not respond</td></tr>
1565<tr><th>CUPS_SC_STATUS_TOO_BIG </th><td class="description">Response too big</td></tr>
98d88c8d 1566</tbody></table>
b47dab17
MS
1567</div>
1568</body>
ef416fc2 1569</html>