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