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