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