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