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