]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/ipp-support.c
Support face-up printers (Issue #5345)
[thirdparty/cups.git] / cups / ipp-support.c
1 /*
2 * Internet Printing Protocol support functions for CUPS.
3 *
4 * Copyright © 2007-2018 by Apple Inc.
5 * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
6 *
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
8 * information.
9 */
10
11 /*
12 * Include necessary headers...
13 */
14
15 #include "cups-private.h"
16
17
18 /*
19 * Local globals...
20 */
21
22 static const char * const ipp_states[] =
23 {
24 "IPP_STATE_ERROR",
25 "IPP_STATE_IDLE",
26 "IPP_STATE_HEADER",
27 "IPP_STATE_ATTRIBUTE",
28 "IPP_STATE_DATA"
29 };
30 static const char * const ipp_status_oks[] = /* "OK" status codes */
31 { /* (name) = abandoned standard value */
32 "successful-ok",
33 "successful-ok-ignored-or-substituted-attributes",
34 "successful-ok-conflicting-attributes",
35 "successful-ok-ignored-subscriptions",
36 "(successful-ok-ignored-notifications)",
37 "successful-ok-too-many-events",
38 "(successful-ok-but-cancel-subscription)",
39 "successful-ok-events-complete"
40 },
41 * const ipp_status_400s[] = /* Client errors */
42 { /* (name) = abandoned standard value */
43 "client-error-bad-request",
44 "client-error-forbidden",
45 "client-error-not-authenticated",
46 "client-error-not-authorized",
47 "client-error-not-possible",
48 "client-error-timeout",
49 "client-error-not-found",
50 "client-error-gone",
51 "client-error-request-entity-too-large",
52 "client-error-request-value-too-long",
53 "client-error-document-format-not-supported",
54 "client-error-attributes-or-values-not-supported",
55 "client-error-uri-scheme-not-supported",
56 "client-error-charset-not-supported",
57 "client-error-conflicting-attributes",
58 "client-error-compression-not-supported",
59 "client-error-compression-error",
60 "client-error-document-format-error",
61 "client-error-document-access-error",
62 "client-error-attributes-not-settable",
63 "client-error-ignored-all-subscriptions",
64 "client-error-too-many-subscriptions",
65 "(client-error-ignored-all-notifications)",
66 "(client-error-client-print-support-file-not-found)",
67 "client-error-document-password-error",
68 "client-error-document-permission-error",
69 "client-error-document-security-error",
70 "client-error-document-unprintable-error",
71 "client-error-account-info-needed",
72 "client-error-account-closed",
73 "client-error-account-limit-reached",
74 "client-error-account-authorization-failed",
75 "client-error-not-fetchable"
76 },
77 * const ipp_status_480s[] = /* Vendor client errors */
78 {
79 /* 0x0480 - 0x048F */
80 "0x0480",
81 "0x0481",
82 "0x0482",
83 "0x0483",
84 "0x0484",
85 "0x0485",
86 "0x0486",
87 "0x0487",
88 "0x0488",
89 "0x0489",
90 "0x048A",
91 "0x048B",
92 "0x048C",
93 "0x048D",
94 "0x048E",
95 "0x048F",
96 /* 0x0490 - 0x049F */
97 "0x0490",
98 "0x0491",
99 "0x0492",
100 "0x0493",
101 "0x0494",
102 "0x0495",
103 "0x0496",
104 "0x0497",
105 "0x0498",
106 "0x0499",
107 "0x049A",
108 "0x049B",
109 "cups-error-account-info-needed",
110 "cups-error-account-closed",
111 "cups-error-account-limit-reached",
112 "cups-error-account-authorization-failed"
113 },
114 * const ipp_status_500s[] = /* Server errors */
115 {
116 "server-error-internal-error",
117 "server-error-operation-not-supported",
118 "server-error-service-unavailable",
119 "server-error-version-not-supported",
120 "server-error-device-error",
121 "server-error-temporary-error",
122 "server-error-not-accepting-jobs",
123 "server-error-busy",
124 "server-error-job-canceled",
125 "server-error-multiple-document-jobs-not-supported",
126 "server-error-printer-is-deactivated",
127 "server-error-too-many-jobs",
128 "server-error-too-many-documents"
129 },
130 * const ipp_status_1000s[] = /* CUPS internal */
131 {
132 "cups-authentication-canceled",
133 "cups-pki-error",
134 "cups-upgrade-required"
135 };
136 static const char * const ipp_std_ops[] =
137 {
138 /* 0x0000 - 0x000f */
139 "0x0000",
140 "0x0001",
141 "Print-Job", /* RFC 8011 */
142 "Print-URI", /* RFC 8011 */
143 "Validate-Job", /* RFC 8011 */
144 "Create-Job", /* RFC 8011 */
145 "Send-Document", /* RFC 8011 */
146 "Send-URI", /* RFC 8011 */
147 "Cancel-Job", /* RFC 8011 */
148 "Get-Job-Attributes", /* RFC 8011 */
149 "Get-Jobs", /* RFC 8011 */
150 "Get-Printer-Attributes", /* RFC 8011 */
151 "Hold-Job", /* RFC 8011 */
152 "Release-Job", /* RFC 8011 */
153 "Restart-Job", /* RFC 8011 */
154 "0x000f",
155
156 /* 0x0010 - 0x001f */
157 "Pause-Printer", /* RFC 8011 */
158 "Resume-Printer", /* RFC 8011 */
159 "Purge-Jobs", /* RFC 8011 */
160 "Set-Printer-Attributes", /* RFC 3380 */
161 "Set-Job-Attributes", /* RFC 3380 */
162 "Get-Printer-Supported-Values", /* RFC 3380 */
163 "Create-Printer-Subscriptions", /* RFC 3995 */
164 "Create-Job-Subscriptions", /* RFC 3995 */
165 "Get-Subscription-Attributes", /* RFC 3995 */
166 "Get-Subscriptions", /* RFC 3995 */
167 "Renew-Subscription", /* RFC 3995 */
168 "Cancel-Subscription", /* RFC 3995 */
169 "Get-Notifications", /* RFC 3996 */
170 "(Send-Notifications)",
171 "Get-Resource-Attributes", /* IPP System */
172 "(Get-Resource-Data)",
173
174 /* 0x0020 - 0x002f */
175 "Get-Resources", /* IPP System */
176 "(Get-Printer-Support-Files)",
177 "Enable-Printer", /* RFC 3998 */
178 "Disable-Printer", /* RFC 3998 */
179 "Pause-Printer-After-Current-Job", /* RFC 3998 */
180 "Hold-New-Jobs", /* RFC 3998 */
181 "Release-Held-New-Jobs", /* RFC 3998 */
182 "Deactivate-Printer", /* RFC 3998 */
183 "Activate-Printer", /* RFC 3998 */
184 "Restart-Printer", /* RFC 3998 */
185 "Shutdown-Printer", /* RFC 3998 */
186 "Startup-Printer", /* RFC 3998 */
187 "Reprocess-Job", /* RFC 3998 */
188 "Cancel-Current-Job", /* RFC 3998 */
189 "Suspend-Current-Job", /* RFC 3998 */
190 "Resume-Job", /* RFC 3998 */
191
192 /* 0x0030 - 0x003f */
193 "Promote-Job", /* RFC 3998 */
194 "Schedule-Job-After", /* RFC 3998 */
195 "0x0032",
196 "Cancel-Document", /* IPP DocObject */
197 "Get-Document-Attributes", /* IPP DocObject */
198 "Get-Documents", /* IPP DocObject */
199 "Delete-Document", /* IPP DocObject */
200 "Set-Document-Attributes", /* IPP DocObject */
201 "Cancel-Jobs", /* IPP JPS2 */
202 "Cancel-My-Jobs", /* IPP JPS2 */
203 "Resubmit-Job", /* IPP JPS2 */
204 "Close-Job", /* IPP JPS2 */
205 "Identify-Printer", /* IPP JPS3 */
206 "Validate-Document", /* IPP JPS3 */
207 "Add-Document-Images", /* IPP Scan */
208 "Acknowledge-Document", /* IPP INFRA */
209
210 /* 0x0040 - 0x004f */
211 "Acknowledge-Identify-Printer", /* IPP INFRA */
212 "Acknowledge-Job", /* IPP INFRA */
213 "Fetch-Document", /* IPP INFRA */
214 "Fetch-Job", /* IPP INFRA */
215 "Get-Output-Device-Attributes", /* IPP INFRA */
216 "Update-Active-Jobs", /* IPP INFRA */
217 "Deregister-Output-Device", /* IPP INFRA */
218 "Update-Document-Status", /* IPP INFRA */
219 "Update-Job-Status", /* IPP INFRA */
220 "Update-Output-Device-Attributes", /* IPP INFRA */
221 "Get-Next-Document-Data", /* IPP Scan */
222 "Allocate-Printer-Resources", /* IPP System */
223 "Create-Printer", /* IPP System */
224 "Deallocate-Printer-Resources", /* IPP System */
225 "Delete-Printer", /* IPP System */
226 "Get-Printers", /* IPP System */
227
228 /* 0x0050 - 0x005f */
229 "Shutdown-One-Printer", /* IPP System */
230 "Startup-One-Printer", /* IPP System */
231 "Cancel-Resource", /* IPP System */
232 "Create-Resource", /* IPP System */
233 "Install-Resource", /* IPP System */
234 "Send-Resource-Data", /* IPP System */
235 "Set-Resource-Attributes", /* IPP System */
236 "Create-Resource-Subscriptions", /* IPP System */
237 "Create-System-Subscriptions", /* IPP System */
238 "Disable-All-Printers", /* IPP System */
239 "Enable-All-Printers", /* IPP System */
240 "Get-System-Attributes", /* IPP System */
241 "Get-System-Supported-Values", /* IPP System */
242 "Pause-All-Printers", /* IPP System */
243 "Pause-All-Printers-After-Current-Job", /* IPP System */
244 "Register-Output-Device", /* IPP System */
245
246 /* 0x0060 - 0x0064 */
247 "Restart-System", /* IPP System */
248 "Resume-All-Printers", /* IPP System */
249 "Set-System-Attributes", /* IPP System */
250 "Shutdown-All-Printers", /* IPP System */
251 "Startup-All-Printers" /* IPP System */
252 },
253 * const ipp_cups_ops[] =
254 {
255 "CUPS-Get-Default",
256 "CUPS-Get-Printers",
257 "CUPS-Add-Modify-Printer",
258 "CUPS-Delete-Printer",
259 "CUPS-Get-Classes",
260 "CUPS-Add-Modify-Class",
261 "CUPS-Delete-Class",
262 "CUPS-Accept-Jobs",
263 "CUPS-Reject-Jobs",
264 "CUPS-Set-Default",
265 "CUPS-Get-Devices",
266 "CUPS-Get-PPDs",
267 "CUPS-Move-Job",
268 "CUPS-Authenticate-Job",
269 "CUPS-Get-PPD"
270 },
271 * const ipp_cups_ops2[] =
272 {
273 "CUPS-Get-Document",
274 "CUPS-Create-Local-Printer"
275 },
276 * const ipp_tag_names[] =
277 { /* Value/group tag names */
278 "zero", /* 0x00 */
279 "operation-attributes-tag",
280 /* 0x01 */
281 "job-attributes-tag", /* 0x02 */
282 "end-of-attributes-tag",
283 /* 0x03 */
284 "printer-attributes-tag",
285 /* 0x04 */
286 "unsupported-attributes-tag",
287 /* 0x05 */
288 "subscription-attributes-tag",
289 /* 0x06 - RFC 3995 */
290 "event-notification-attributes-tag",
291 /* 0x07 - RFC 3995 */
292 "resource-attributes-tag",
293 /* 0x08 - IPP System */
294 "document-attributes-tag",
295 /* 0x09 - IPP DocObject */
296 "system-attributes-tag",
297 /* 0x0a - IPP System */
298 "0x0b", /* 0x0b */
299 "0x0c", /* 0x0c */
300 "0x0d", /* 0x0d */
301 "0x0e", /* 0x0e */
302 "0x0f", /* 0x0f */
303 "unsupported", /* 0x10 */
304 "default", /* 0x11 */
305 "unknown", /* 0x12 */
306 "no-value", /* 0x13 */
307 "0x14", /* 0x14 */
308 "not-settable", /* 0x15 - RFC 3380 */
309 "delete-attribute", /* 0x16 - RFC 3380 */
310 "admin-define", /* 0x17 - RFC 3380 */
311 "0x18", /* 0x18 */
312 "0x19", /* 0x19 */
313 "0x1a", /* 0x1a */
314 "0x1b", /* 0x1b */
315 "0x1c", /* 0x1c */
316 "0x1d", /* 0x1d */
317 "0x1e", /* 0x1e */
318 "0x1f", /* 0x1f */
319 "0x20", /* 0x20 */
320 "integer", /* 0x21 */
321 "boolean", /* 0x22 */
322 "enum", /* 0x23 */
323 "0x24", /* 0x24 */
324 "0x25", /* 0x25 */
325 "0x26", /* 0x26 */
326 "0x27", /* 0x27 */
327 "0x28", /* 0x28 */
328 "0x29", /* 0x29 */
329 "0x2a", /* 0x2a */
330 "0x2b", /* 0x2b */
331 "0x2c", /* 0x2c */
332 "0x2d", /* 0x2d */
333 "0x2e", /* 0x2e */
334 "0x2f", /* 0x2f */
335 "octetString", /* 0x30 */
336 "dateTime", /* 0x31 */
337 "resolution", /* 0x32 */
338 "rangeOfInteger", /* 0x33 */
339 "collection", /* 0x34 */
340 "textWithLanguage", /* 0x35 */
341 "nameWithLanguage", /* 0x36 */
342 "endCollection", /* 0x37 */
343 "0x38", /* 0x38 */
344 "0x39", /* 0x39 */
345 "0x3a", /* 0x3a */
346 "0x3b", /* 0x3b */
347 "0x3c", /* 0x3c */
348 "0x3d", /* 0x3d */
349 "0x3e", /* 0x3e */
350 "0x3f", /* 0x3f */
351 "0x40", /* 0x40 */
352 "textWithoutLanguage",/* 0x41 */
353 "nameWithoutLanguage",/* 0x42 */
354 "0x43", /* 0x43 */
355 "keyword", /* 0x44 */
356 "uri", /* 0x45 */
357 "uriScheme", /* 0x46 */
358 "charset", /* 0x47 */
359 "naturalLanguage", /* 0x48 */
360 "mimeMediaType", /* 0x49 */
361 "memberAttrName" /* 0x4a */
362 };
363 static const char * const ipp_document_states[] =
364 { /* document-state-enums */
365 "pending",
366 "4",
367 "processing",
368 "processing-stopped", /* IPP INFRA */
369 "canceled",
370 "aborted",
371 "completed"
372 },
373 * const ipp_finishings[] =
374 { /* finishings enums */
375 "none",
376 "staple",
377 "punch",
378 "cover",
379 "bind",
380 "saddle-stitch",
381 "edge-stitch",
382 "fold",
383 "trim",
384 "bale",
385 "booklet-maker",
386 "jog-offset",
387 "coat", /* IPP Finishings 2.0 */
388 "laminate", /* IPP Finishings 2.0 */
389 "17",
390 "18",
391 "19",
392 "staple-top-left",
393 "staple-bottom-left",
394 "staple-top-right",
395 "staple-bottom-right",
396 "edge-stitch-left",
397 "edge-stitch-top",
398 "edge-stitch-right",
399 "edge-stitch-bottom",
400 "staple-dual-left",
401 "staple-dual-top",
402 "staple-dual-right",
403 "staple-dual-bottom",
404 "staple-triple-left", /* IPP Finishings 2.0 */
405 "staple-triple-top", /* IPP Finishings 2.0 */
406 "staple-triple-right",/* IPP Finishings 2.0 */
407 "staple-triple-bottom",/* IPP Finishings 2.0 */
408 "36",
409 "37",
410 "38",
411 "39",
412 "40",
413 "41",
414 "42",
415 "43",
416 "44",
417 "45",
418 "46",
419 "47",
420 "48",
421 "49",
422 "bind-left",
423 "bind-top",
424 "bind-right",
425 "bind-bottom",
426 "54",
427 "55",
428 "56",
429 "57",
430 "58",
431 "59",
432 "trim-after-pages",
433 "trim-after-documents",
434 "trim-after-copies",
435 "trim-after-job",
436 "64",
437 "65",
438 "66",
439 "67",
440 "68",
441 "69",
442 "punch-top-left", /* IPP Finishings 2.0 */
443 "punch-bottom-left", /* IPP Finishings 2.0 */
444 "punch-top-right", /* IPP Finishings 2.0 */
445 "punch-bottom-right", /* IPP Finishings 2.0 */
446 "punch-dual-left", /* IPP Finishings 2.0 */
447 "punch-dual-top", /* IPP Finishings 2.0 */
448 "punch-dual-right", /* IPP Finishings 2.0 */
449 "punch-dual-bottom", /* IPP Finishings 2.0 */
450 "punch-triple-left", /* IPP Finishings 2.0 */
451 "punch-triple-top", /* IPP Finishings 2.0 */
452 "punch-triple-right", /* IPP Finishings 2.0 */
453 "punch-triple-bottom",/* IPP Finishings 2.0 */
454 "punch-quad-left", /* IPP Finishings 2.0 */
455 "punch-quad-top", /* IPP Finishings 2.0 */
456 "punch-quad-right", /* IPP Finishings 2.0 */
457 "punch-quad-bottom", /* IPP Finishings 2.0 */
458 "punch-multiple-left",/* IPP Finishings 2.1/Canon */
459 "punch-multiple-top", /* IPP Finishings 2.1/Canon */
460 "punch-multiple-right",/* IPP Finishings 2.1/Canon */
461 "punch-multiple-bottom",/* IPP Finishings 2.1/Canon */
462 "fold-accordian", /* IPP Finishings 2.0 */
463 "fold-double-gate", /* IPP Finishings 2.0 */
464 "fold-gate", /* IPP Finishings 2.0 */
465 "fold-half", /* IPP Finishings 2.0 */
466 "fold-half-z", /* IPP Finishings 2.0 */
467 "fold-left-gate", /* IPP Finishings 2.0 */
468 "fold-letter", /* IPP Finishings 2.0 */
469 "fold-parallel", /* IPP Finishings 2.0 */
470 "fold-poster", /* IPP Finishings 2.0 */
471 "fold-right-gate", /* IPP Finishings 2.0 */
472 "fold-z", /* IPP Finishings 2.0 */
473 "fold-engineering-z" /* IPP Finishings 2.1 */
474 },
475 * const ipp_finishings_vendor[] =
476 {
477 /* 0x40000000 to 0x4000000F */
478 "0x40000000",
479 "0x40000001",
480 "0x40000002",
481 "0x40000003",
482 "0x40000004",
483 "0x40000005",
484 "0x40000006",
485 "0x40000007",
486 "0x40000008",
487 "0x40000009",
488 "0x4000000A",
489 "0x4000000B",
490 "0x4000000C",
491 "0x4000000D",
492 "0x4000000E",
493 "0x4000000F",
494 /* 0x40000010 to 0x4000001F */
495 "0x40000010",
496 "0x40000011",
497 "0x40000012",
498 "0x40000013",
499 "0x40000014",
500 "0x40000015",
501 "0x40000016",
502 "0x40000017",
503 "0x40000018",
504 "0x40000019",
505 "0x4000001A",
506 "0x4000001B",
507 "0x4000001C",
508 "0x4000001D",
509 "0x4000001E",
510 "0x4000001F",
511 /* 0x40000020 to 0x4000002F */
512 "0x40000020",
513 "0x40000021",
514 "0x40000022",
515 "0x40000023",
516 "0x40000024",
517 "0x40000025",
518 "0x40000026",
519 "0x40000027",
520 "0x40000028",
521 "0x40000029",
522 "0x4000002A",
523 "0x4000002B",
524 "0x4000002C",
525 "0x4000002D",
526 "0x4000002E",
527 "0x4000002F",
528 /* 0x40000030 to 0x4000003F */
529 "0x40000030",
530 "0x40000031",
531 "0x40000032",
532 "0x40000033",
533 "0x40000034",
534 "0x40000035",
535 "0x40000036",
536 "0x40000037",
537 "0x40000038",
538 "0x40000039",
539 "0x4000003A",
540 "0x4000003B",
541 "0x4000003C",
542 "0x4000003D",
543 "0x4000003E",
544 "0x4000003F",
545 /* 0x40000040 - 0x4000004F */
546 "0x40000040",
547 "0x40000041",
548 "0x40000042",
549 "0x40000043",
550 "0x40000044",
551 "0x40000045",
552 "cups-punch-top-left",
553 "cups-punch-bottom-left",
554 "cups-punch-top-right",
555 "cups-punch-bottom-right",
556 "cups-punch-dual-left",
557 "cups-punch-dual-top",
558 "cups-punch-dual-right",
559 "cups-punch-dual-bottom",
560 "cups-punch-triple-left",
561 "cups-punch-triple-top",
562 /* 0x40000050 - 0x4000005F */
563 "cups-punch-triple-right",
564 "cups-punch-triple-bottom",
565 "cups-punch-quad-left",
566 "cups-punch-quad-top",
567 "cups-punch-quad-right",
568 "cups-punch-quad-bottom",
569 "0x40000056",
570 "0x40000057",
571 "0x40000058",
572 "0x40000059",
573 "cups-fold-accordian",
574 "cups-fold-double-gate",
575 "cups-fold-gate",
576 "cups-fold-half",
577 "cups-fold-half-z",
578 "cups-fold-left-gate",
579 /* 0x40000060 - 0x40000064 */
580 "cups-fold-letter",
581 "cups-fold-parallel",
582 "cups-fold-poster",
583 "cups-fold-right-gate",
584 "cups-fold-z"
585 },
586 * const ipp_job_collation_types[] =
587 { /* job-collation-type enums */
588 "uncollated-sheets",
589 "collated-documents",
590 "uncollated-documents"
591 },
592 * const ipp_job_states[] =
593 { /* job-state enums */
594 "pending",
595 "pending-held",
596 "processing",
597 "processing-stopped",
598 "canceled",
599 "aborted",
600 "completed"
601 },
602 * const ipp_orientation_requesteds[] =
603 { /* orientation-requested enums */
604 "portrait",
605 "landscape",
606 "reverse-landscape",
607 "reverse-portrait",
608 "none"
609 },
610 * const ipp_print_qualities[] =
611 { /* print-quality enums */
612 "draft",
613 "normal",
614 "high"
615 },
616 * const ipp_printer_states[] =
617 { /* printer-state enums */
618 "idle",
619 "processing",
620 "stopped"
621 },
622 * const ipp_resource_states[] =
623 { /* resource-state enums */
624 "pending",
625 "available",
626 "installed",
627 "canceled",
628 "aborted"
629 },
630 * const ipp_system_states[] =
631 { /* system-state enums */
632 "idle",
633 "processing",
634 "stopped"
635 };
636
637
638 /*
639 * Local functions...
640 */
641
642 static size_t ipp_col_string(ipp_t *col, char *buffer, size_t bufsize);
643
644
645 /*
646 * 'ippAttributeString()' - Convert the attribute's value to a string.
647 *
648 * Returns the number of bytes that would be written, not including the
649 * trailing nul. The buffer pointer can be NULL to get the required length,
650 * just like (v)snprintf.
651 *
652 * @since CUPS 1.6/macOS 10.8@
653 */
654
655 size_t /* O - Number of bytes less nul */
656 ippAttributeString(
657 ipp_attribute_t *attr, /* I - Attribute */
658 char *buffer, /* I - String buffer or NULL */
659 size_t bufsize) /* I - Size of string buffer */
660 {
661 int i; /* Looping var */
662 char *bufptr, /* Pointer into buffer */
663 *bufend, /* End of buffer */
664 temp[256]; /* Temporary string */
665 const char *ptr, /* Pointer into string */
666 *end; /* Pointer to end of string */
667 _ipp_value_t *val; /* Current value */
668
669
670 if (!attr || !attr->name)
671 {
672 if (buffer)
673 *buffer = '\0';
674
675 return (0);
676 }
677
678 bufptr = buffer;
679 if (buffer)
680 bufend = buffer + bufsize - 1;
681 else
682 bufend = NULL;
683
684 for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
685 {
686 if (val > attr->values)
687 {
688 if (buffer && bufptr < bufend)
689 *bufptr++ = ',';
690 else
691 bufptr ++;
692 }
693
694 switch (attr->value_tag & ~IPP_TAG_CUPS_CONST)
695 {
696 case IPP_TAG_ENUM :
697 ptr = ippEnumString(attr->name, val->integer);
698
699 if (buffer && bufptr < bufend)
700 strlcpy(bufptr, ptr, (size_t)(bufend - bufptr + 1));
701
702 bufptr += strlen(ptr);
703 break;
704
705 case IPP_TAG_INTEGER :
706 if (buffer && bufptr < bufend)
707 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%d", val->integer);
708 else
709 bufptr += snprintf(temp, sizeof(temp), "%d", val->integer);
710 break;
711
712 case IPP_TAG_BOOLEAN :
713 if (buffer && bufptr < bufend)
714 strlcpy(bufptr, val->boolean ? "true" : "false", (size_t)(bufend - bufptr + 1));
715
716 bufptr += val->boolean ? 4 : 5;
717 break;
718
719 case IPP_TAG_RANGE :
720 if (buffer && bufptr < bufend)
721 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%d-%d", val->range.lower, val->range.upper);
722 else
723 bufptr += snprintf(temp, sizeof(temp), "%d-%d", val->range.lower, val->range.upper);
724 break;
725
726 case IPP_TAG_RESOLUTION :
727 if (val->resolution.xres == val->resolution.yres)
728 {
729 if (buffer && bufptr < bufend)
730 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%d%s", val->resolution.xres, val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
731 else
732 bufptr += snprintf(temp, sizeof(temp), "%d%s", val->resolution.xres, val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
733 }
734 else if (buffer && bufptr < bufend)
735 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%dx%d%s", val->resolution.xres, val->resolution.yres, val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
736 else
737 bufptr += snprintf(temp, sizeof(temp), "%dx%d%s", val->resolution.xres, val->resolution.yres, val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
738 break;
739
740 case IPP_TAG_DATE :
741 {
742 unsigned year; /* Year */
743
744 year = ((unsigned)val->date[0] << 8) + (unsigned)val->date[1];
745
746 if (val->date[9] == 0 && val->date[10] == 0)
747 snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ",
748 year, val->date[2], val->date[3], val->date[4],
749 val->date[5], val->date[6]);
750 else
751 snprintf(temp, sizeof(temp),
752 "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u",
753 year, val->date[2], val->date[3], val->date[4],
754 val->date[5], val->date[6], val->date[8], val->date[9],
755 val->date[10]);
756
757 if (buffer && bufptr < bufend)
758 strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));
759
760 bufptr += strlen(temp);
761 }
762 break;
763
764 case IPP_TAG_TEXT :
765 case IPP_TAG_NAME :
766 case IPP_TAG_KEYWORD :
767 case IPP_TAG_CHARSET :
768 case IPP_TAG_URI :
769 case IPP_TAG_URISCHEME :
770 case IPP_TAG_MIMETYPE :
771 case IPP_TAG_LANGUAGE :
772 case IPP_TAG_TEXTLANG :
773 case IPP_TAG_NAMELANG :
774 if (!val->string.text)
775 break;
776
777 for (ptr = val->string.text; *ptr; ptr ++)
778 {
779 if (*ptr == '\\' || *ptr == '\"' || *ptr == '[')
780 {
781 if (buffer && bufptr < bufend)
782 *bufptr = '\\';
783 bufptr ++;
784 }
785
786 if (buffer && bufptr < bufend)
787 *bufptr = *ptr;
788 bufptr ++;
789 }
790
791 if (val->string.language)
792 {
793 /*
794 * Add "[language]" to end of string...
795 */
796
797 if (buffer && bufptr < bufend)
798 *bufptr = '[';
799 bufptr ++;
800
801 if (buffer && bufptr < bufend)
802 strlcpy(bufptr, val->string.language, (size_t)(bufend - bufptr));
803 bufptr += strlen(val->string.language);
804
805 if (buffer && bufptr < bufend)
806 *bufptr = ']';
807 bufptr ++;
808 }
809 break;
810
811 case IPP_TAG_BEGIN_COLLECTION :
812 if (buffer && bufptr < bufend)
813 bufptr += ipp_col_string(val->collection, bufptr, (size_t)(bufend - bufptr + 1));
814 else
815 bufptr += ipp_col_string(val->collection, NULL, 0);
816 break;
817
818 case IPP_TAG_STRING :
819 for (ptr = val->unknown.data, end = ptr + val->unknown.length;
820 ptr < end; ptr ++)
821 {
822 if (*ptr == '\\' || _cups_isspace(*ptr))
823 {
824 if (buffer && bufptr < bufend)
825 *bufptr = '\\';
826 bufptr ++;
827
828 if (buffer && bufptr < bufend)
829 *bufptr = *ptr;
830 bufptr ++;
831 }
832 else if (!isprint(*ptr & 255))
833 {
834 if (buffer && bufptr < bufend)
835 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "\\%03o", *ptr & 255);
836 else
837 bufptr += snprintf(temp, sizeof(temp), "\\%03o", *ptr & 255);
838 }
839 else
840 {
841 if (buffer && bufptr < bufend)
842 *bufptr = *ptr;
843 bufptr ++;
844 }
845 }
846 break;
847
848 default :
849 ptr = ippTagString(attr->value_tag);
850 if (buffer && bufptr < bufend)
851 strlcpy(bufptr, ptr, (size_t)(bufend - bufptr + 1));
852 bufptr += strlen(ptr);
853 break;
854 }
855 }
856
857 if (buffer && bufptr < bufend)
858 *bufptr = '\0';
859 else if (bufend)
860 *bufend = '\0';
861
862 return ((size_t)(bufptr - buffer));
863 }
864
865
866 /*
867 * 'ippCreateRequestedArray()' - Create a CUPS array of attribute names from the
868 * given requested-attributes attribute.
869 *
870 * This function creates a (sorted) CUPS array of attribute names matching the
871 * list of "requested-attribute" values supplied in an IPP request. All IANA-
872 * registered values are supported in addition to the CUPS IPP extension
873 * attributes.
874 *
875 * The @code request@ parameter specifies the request message that was read from
876 * the client.
877 *
878 * @code NULL@ is returned if all attributes should be returned. Otherwise, the
879 * result is a sorted array of attribute names, where @code cupsArrayFind(array,
880 * "attribute-name")@ will return a non-NULL pointer. The array must be freed
881 * using the @code cupsArrayDelete@ function.
882 *
883 * @since CUPS 1.7/macOS 10.9@
884 */
885
886 cups_array_t * /* O - CUPS array or @code NULL@ if all */
887 ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
888 {
889 int i, j, /* Looping vars */
890 count, /* Number of values */
891 added; /* Was name added? */
892 ipp_op_t op; /* IPP operation code */
893 ipp_attribute_t *requested; /* requested-attributes attribute */
894 cups_array_t *ra; /* Requested attributes array */
895 const char *value; /* Current value */
896 /* The following lists come from the current IANA IPP registry of attributes */
897 static const char * const document_description[] =
898 { /* document-description group */
899 "compression",
900 "copies-actual",
901 "cover-back-actual",
902 "cover-front-actual",
903 "current-page-order",
904 "date-time-at-completed",
905 "date-time-at-creation",
906 "date-time-at-processing",
907 "detailed-status-messages",
908 "document-access-errors",
909 "document-charset",
910 "document-digital-signature",
911 "document-format",
912 "document-format-details",
913 "document-format-detected",
914 "document-format-version",
915 "document-format-version-detected",
916 "document-job-id",
917 "document-job-uri",
918 "document-message",
919 "document-metadata",
920 "document-name",
921 "document-natural-language",
922 "document-number",
923 "document-printer-uri",
924 "document-state",
925 "document-state-message",
926 "document-state-reasons",
927 "document-uri",
928 "document-uuid", /* IPP JPS3 */
929 "errors-count",
930 "finishings-actual",
931 "finishings-col-actual",
932 "force-front-side-actual",
933 "imposition-template-actual",
934 "impressions",
935 "impressions-col",
936 "impressions-completed",
937 "impressions-completed-col",
938 "impressions-completed-current-copy",
939 "insert-sheet-actual",
940 "k-octets",
941 "k-octets-processed",
942 "last-document",
943 "materials-col-actual", /* IPP 3D */
944 "media-actual",
945 "media-col-actual",
946 "media-input-tray-check-actual",
947 "media-sheets",
948 "media-sheets-col",
949 "media-sheets-completed",
950 "media-sheets-completed-col",
951 "more-info",
952 "multiple-object-handling-actual", /* IPP 3D */
953 "number-up-actual",
954 "orientation-requested-actual",
955 "output-bin-actual",
956 "output-device-assigned",
957 "overrides-actual",
958 "page-delivery-actual",
959 "page-order-received-actual",
960 "page-ranges-actual",
961 "pages",
962 "pages-col",
963 "pages-completed",
964 "pages-completed-col",
965 "pages-completed-current-copy",
966 "platform-temperature-actual", /* IPP 3D */
967 "presentation-direction-number-up-actual",
968 "print-accuracy-actual", /* IPP 3D */
969 "print-base-actual", /* IPP 3D */
970 "print-color-mode-actual",
971 "print-content-optimize-actual",
972 "print-objects-actual", /* IPP 3D */
973 "print-quality-actual",
974 "print-rendering-intent-actual",
975 "print-scaling-actual", /* IPP Paid Printing */
976 "print-supports-actual", /* IPP 3D */
977 "printer-resolution-actual",
978 "printer-up-time",
979 "separator-sheets-actual",
980 "sheet-completed-copy-number",
981 "sides-actual",
982 "time-at-completed",
983 "time-at-creation",
984 "time-at-processing",
985 "x-image-position-actual",
986 "x-image-shift-actual",
987 "x-side1-image-shift-actual",
988 "x-side2-image-shift-actual",
989 "y-image-position-actual",
990 "y-image-shift-actual",
991 "y-side1-image-shift-actual",
992 "y-side2-image-shift-actual"
993 };
994 static const char * const document_template[] =
995 { /* document-template group */
996 "chamber-humidity", /* IPP 3D */
997 "chamber-humidity-default", /* IPP 3D */
998 "chamber-humidity-supported", /* IPP 3D */
999 "chamber-temperature", /* IPP 3D */
1000 "chamber-temperature-default", /* IPP 3D */
1001 "chamber-temperature-supported", /* IPP 3D */
1002 "copies",
1003 "copies-default",
1004 "copies-supported",
1005 "cover-back",
1006 "cover-back-default",
1007 "cover-back-supported",
1008 "cover-front",
1009 "cover-front-default",
1010 "cover-front-supported",
1011 "feed-orientation",
1012 "feed-orientation-default",
1013 "feed-orientation-supported",
1014 "finishings",
1015 "finishings-col",
1016 "finishings-col-database",
1017 "finishings-col-default",
1018 "finishings-col-ready",
1019 "finishings-col-supported",
1020 "finishings-default",
1021 "finishings-ready",
1022 "finishings-supported",
1023 "font-name-requested",
1024 "font-name-requested-default",
1025 "font-name-requested-supported",
1026 "font-size-requested",
1027 "font-size-requested-default",
1028 "font-size-requested-supported",
1029 "force-front-side",
1030 "force-front-side-default",
1031 "force-front-side-supported",
1032 "imposition-template",
1033 "imposition-template-default",
1034 "imposition-template-supported",
1035 "insert-after-page-number-supported",
1036 "insert-count-supported",
1037 "insert-sheet",
1038 "insert-sheet-default",
1039 "insert-sheet-supported",
1040 "material-amount-units-supported", /* IPP 3D */
1041 "material-diameter-supported", /* IPP 3D */
1042 "material-purpose-supported", /* IPP 3D */
1043 "material-rate-supported", /* IPP 3D */
1044 "material-rate-units-supported", /* IPP 3D */
1045 "material-shell-thickness-supported",/* IPP 3D */
1046 "material-temperature-supported", /* IPP 3D */
1047 "material-type-supported", /* IPP 3D */
1048 "materials-col", /* IPP 3D */
1049 "materials-col-database", /* IPP 3D */
1050 "materials-col-default", /* IPP 3D */
1051 "materials-col-ready", /* IPP 3D */
1052 "materials-col-supported", /* IPP 3D */
1053 "max-materials-col-supported", /* IPP 3D */
1054 "max-stitching-locations-supported",
1055 "media",
1056 "media-back-coating-supported",
1057 "media-bottom-margin-supported",
1058 "media-col",
1059 "media-col-default",
1060 "media-col-ready",
1061 "media-col-supported",
1062 "media-color-supported",
1063 "media-default",
1064 "media-front-coating-supported",
1065 "media-grain-supported",
1066 "media-hole-count-supported",
1067 "media-info-supported",
1068 "media-input-tray-check",
1069 "media-input-tray-check-default",
1070 "media-input-tray-check-supported",
1071 "media-key-supported",
1072 "media-left-margin-supported",
1073 "media-order-count-supported",
1074 "media-pre-printed-supported",
1075 "media-ready",
1076 "media-recycled-supported",
1077 "media-right-margin-supported",
1078 "media-size-supported",
1079 "media-source-supported",
1080 "media-supported",
1081 "media-thickness-supported",
1082 "media-top-margin-supported",
1083 "media-type-supported",
1084 "media-weight-metric-supported",
1085 "multiple-document-handling",
1086 "multiple-document-handling-default",
1087 "multiple-document-handling-supported",
1088 "multiple-object-handling", /* IPP 3D */
1089 "multiple-object-handling-default", /* IPP 3D */
1090 "multiple-object-handling-supported",/* IPP 3D */
1091 "number-up",
1092 "number-up-default",
1093 "number-up-supported",
1094 "orientation-requested",
1095 "orientation-requested-default",
1096 "orientation-requested-supported",
1097 "output-mode", /* CUPS extension */
1098 "output-mode-default", /* CUPS extension */
1099 "output-mode-supported", /* CUPS extension */
1100 "overrides",
1101 "overrides-supported",
1102 "page-delivery",
1103 "page-delivery-default",
1104 "page-delivery-supported",
1105 "page-order-received",
1106 "page-order-received-default",
1107 "page-order-received-supported",
1108 "page-ranges",
1109 "page-ranges-supported",
1110 "pages-per-subset",
1111 "pages-per-subset-supported",
1112 "pdl-init-file",
1113 "pdl-init-file-default",
1114 "pdl-init-file-entry-supported",
1115 "pdl-init-file-location-supported",
1116 "pdl-init-file-name-subdirectory-supported",
1117 "pdl-init-file-name-supported",
1118 "pdl-init-file-supported",
1119 "platform-temperature", /* IPP 3D */
1120 "platform-temperature-default", /* IPP 3D */
1121 "platform-temperature-supported", /* IPP 3D */
1122 "presentation-direction-number-up",
1123 "presentation-direction-number-up-default",
1124 "presentation-direction-number-up-supported",
1125 "print-accuracy", /* IPP 3D */
1126 "print-accuracy-default", /* IPP 3D */
1127 "print-accuracy-supported", /* IPP 3D */
1128 "print-base", /* IPP 3D */
1129 "print-base-default", /* IPP 3D */
1130 "print-base-supported", /* IPP 3D */
1131 "print-color-mode",
1132 "print-color-mode-default",
1133 "print-color-mode-supported",
1134 "print-content-optimize",
1135 "print-content-optimize-default",
1136 "print-content-optimize-supported",
1137 "print-objects", /* IPP 3D */
1138 "print-objects-default", /* IPP 3D */
1139 "print-objects-supported", /* IPP 3D */
1140 "print-quality",
1141 "print-quality-default",
1142 "print-quality-supported",
1143 "print-rendering-intent",
1144 "print-rendering-intent-default",
1145 "print-rendering-intent-supported",
1146 "print-scaling", /* IPP Paid Printing */
1147 "print-scaling-default", /* IPP Paid Printing */
1148 "print-scaling-supported", /* IPP Paid Printing */
1149 "print-supports", /* IPP 3D */
1150 "print-supports-default", /* IPP 3D */
1151 "print-supports-supported", /* IPP 3D */
1152 "printer-resolution",
1153 "printer-resolution-default",
1154 "printer-resolution-supported",
1155 "separator-sheets",
1156 "separator-sheets-default",
1157 "separator-sheets-supported",
1158 "sheet-collate",
1159 "sheet-collate-default",
1160 "sheet-collate-supported",
1161 "sides",
1162 "sides-default",
1163 "sides-supported",
1164 "stitching-locations-supported",
1165 "stitching-offset-supported",
1166 "x-image-position",
1167 "x-image-position-default",
1168 "x-image-position-supported",
1169 "x-image-shift",
1170 "x-image-shift-default",
1171 "x-image-shift-supported",
1172 "x-side1-image-shift",
1173 "x-side1-image-shift-default",
1174 "x-side1-image-shift-supported",
1175 "x-side2-image-shift",
1176 "x-side2-image-shift-default",
1177 "x-side2-image-shift-supported",
1178 "y-image-position",
1179 "y-image-position-default",
1180 "y-image-position-supported",
1181 "y-image-shift",
1182 "y-image-shift-default",
1183 "y-image-shift-supported",
1184 "y-side1-image-shift",
1185 "y-side1-image-shift-default",
1186 "y-side1-image-shift-supported",
1187 "y-side2-image-shift",
1188 "y-side2-image-shift-default",
1189 "y-side2-image-shift-supported"
1190 };
1191 static const char * const job_description[] =
1192 { /* job-description group */
1193 "chamber-humidity-actual", /* IPP 3D */
1194 "chamber-temperature-actual", /* IPP 3D */
1195 "compression-supplied",
1196 "copies-actual",
1197 "cover-back-actual",
1198 "cover-front-actual",
1199 "current-page-order",
1200 "date-time-at-completed",
1201 "date-time-at-creation",
1202 "date-time-at-processing",
1203 "destination-statuses",
1204 "document-charset-supplied",
1205 "document-digital-signature-supplied",
1206 "document-format-details-supplied",
1207 "document-format-supplied",
1208 "document-message-supplied",
1209 "document-metadata",
1210 "document-name-supplied",
1211 "document-natural-language-supplied",
1212 "document-overrides-actual",
1213 "errors-count",
1214 "finishings-actual",
1215 "finishings-col-actual",
1216 "force-front-side-actual",
1217 "imposition-template-actual",
1218 "impressions-completed-current-copy",
1219 "insert-sheet-actual",
1220 "job-account-id-actual",
1221 "job-accounting-sheets-actual",
1222 "job-accounting-user-id-actual",
1223 "job-attribute-fidelity",
1224 "job-charge-info", /* CUPS extension */
1225 "job-collation-type",
1226 "job-collation-type-actual",
1227 "job-copies-actual",
1228 "job-cover-back-actual",
1229 "job-cover-front-actual",
1230 "job-detailed-status-message",
1231 "job-document-access-errors",
1232 "job-error-sheet-actual",
1233 "job-finishings-actual",
1234 "job-finishings-col-actual",
1235 "job-hold-until-actual",
1236 "job-id",
1237 "job-impressions",
1238 "job-impressions-col",
1239 "job-impressions-completed",
1240 "job-impressions-completed-col",
1241 "job-k-octets",
1242 "job-k-octets-processed",
1243 "job-mandatory-attributes",
1244 "job-media-progress", /* CUPS extension */
1245 "job-media-sheets",
1246 "job-media-sheets-col",
1247 "job-media-sheets-completed",
1248 "job-media-sheets-completed-col",
1249 "job-message-from-operator",
1250 "job-more-info",
1251 "job-name",
1252 "job-originating-host-name", /* CUPS extension */
1253 "job-originating-user-name",
1254 "job-originating-user-uri", /* IPP JPS3 */
1255 "job-pages",
1256 "job-pages-col",
1257 "job-pages-completed",
1258 "job-pages-completed-col",
1259 "job-pages-completed-current-copy",
1260 "job-printer-state-message", /* CUPS extension */
1261 "job-printer-state-reasons", /* CUPS extension */
1262 "job-printer-up-time",
1263 "job-printer-uri",
1264 "job-priority-actual",
1265 "job-resource-ids", /* IPP System */
1266 "job-save-printer-make-and-model",
1267 "job-sheet-message-actual",
1268 "job-sheets-actual",
1269 "job-sheets-col-actual",
1270 "job-state",
1271 "job-state-message",
1272 "job-state-reasons",
1273 "job-uri",
1274 "job-uuid", /* IPP JPS3 */
1275 "materials-col-actual", /* IPP 3D */
1276 "media-actual",
1277 "media-col-actual",
1278 "media-check-input-tray-actual",
1279 "multiple-document-handling-actual",
1280 "multiple-object-handling-actual", /* IPP 3D */
1281 "number-of-documents",
1282 "number-of-intervening-jobs",
1283 "number-up-actual",
1284 "orientation-requested-actual",
1285 "original-requesting-user-name",
1286 "output-bin-actual",
1287 "output-device-assigned",
1288 "output-device-job-state", /* IPP INFRA */
1289 "output-device-job-state-message", /* IPP INFRA */
1290 "output-device-job-state-reasons", /* IPP INFRA */
1291 "output-device-uuid-assigned", /* IPP INFRA */
1292 "overrides-actual",
1293 "page-delivery-actual",
1294 "page-order-received-actual",
1295 "page-ranges-actual",
1296 "platform-temperature-actual", /* IPP 3D */
1297 "presentation-direction-number-up-actual",
1298 "print-accuracy-actual", /* IPP 3D */
1299 "print-base-actual", /* IPP 3D */
1300 "print-color-mode-actual",
1301 "print-content-optimize-actual",
1302 "print-objects-actual", /* IPP 3D */
1303 "print-quality-actual",
1304 "print-rendering-intent-actual",
1305 "print-scaling-actual", /* IPP Paid Printing */
1306 "print-supports-actual", /* IPP 3D */
1307 "printer-resolution-actual",
1308 "separator-sheets-actual",
1309 "sheet-collate-actual",
1310 "sheet-completed-copy-number",
1311 "sheet-completed-document-number",
1312 "sides-actual",
1313 "time-at-completed",
1314 "time-at-creation",
1315 "time-at-processing",
1316 "warnings-count",
1317 "x-image-position-actual",
1318 "x-image-shift-actual",
1319 "x-side1-image-shift-actual",
1320 "x-side2-image-shift-actual",
1321 "y-image-position-actual",
1322 "y-image-shift-actual",
1323 "y-side1-image-shift-actual",
1324 "y-side2-image-shift-actual"
1325 };
1326 static const char * const job_template[] =
1327 { /* job-template group */
1328 "accuracy-units-supported", /* IPP 3D */
1329 "chamber-humidity", /* IPP 3D */
1330 "chamber-humidity-default", /* IPP 3D */
1331 "chamber-humidity-supported", /* IPP 3D */
1332 "chamber-temperature", /* IPP 3D */
1333 "chamber-temperature-default", /* IPP 3D */
1334 "chamber-temperature-supported", /* IPP 3D */
1335 "confirmation-sheet-print", /* IPP FaxOut */
1336 "confirmation-sheet-print-default",
1337 "copies",
1338 "copies-default",
1339 "copies-supported",
1340 "cover-back",
1341 "cover-back-default",
1342 "cover-back-supported",
1343 "cover-front",
1344 "cover-front-default",
1345 "cover-front-supported",
1346 "cover-sheet-info", /* IPP FaxOut */
1347 "cover-sheet-info-default",
1348 "cover-sheet-info-supported",
1349 "destination-uri-schemes-supported",/* IPP FaxOut */
1350 "destination-uris", /* IPP FaxOut */
1351 "destination-uris-supported",
1352 "feed-orientation",
1353 "feed-orientation-default",
1354 "feed-orientation-supported",
1355 "finishings",
1356 "finishings-col",
1357 "finishings-col-database",
1358 "finishings-col-default",
1359 "finishings-col-ready",
1360 "finishings-col-supported",
1361 "finishings-default",
1362 "finishings-ready",
1363 "finishings-supported",
1364 "font-name-requested",
1365 "font-name-requested-default",
1366 "font-name-requested-supported",
1367 "font-size-requested",
1368 "font-size-requested-default",
1369 "font-size-requested-supported",
1370 "force-front-side",
1371 "force-front-side-default",
1372 "force-front-side-supported",
1373 "imposition-template",
1374 "imposition-template-default",
1375 "imposition-template-supported",
1376 "insert-after-page-number-supported",
1377 "insert-count-supported",
1378 "insert-sheet",
1379 "insert-sheet-default",
1380 "insert-sheet-supported",
1381 "job-account-id",
1382 "job-account-id-default",
1383 "job-account-id-supported",
1384 "job-accounting-sheets"
1385 "job-accounting-sheets-default"
1386 "job-accounting-sheets-supported"
1387 "job-accounting-user-id",
1388 "job-accounting-user-id-default",
1389 "job-accounting-user-id-supported",
1390 "job-copies",
1391 "job-copies-default",
1392 "job-copies-supported",
1393 "job-cover-back",
1394 "job-cover-back-default",
1395 "job-cover-back-supported",
1396 "job-cover-front",
1397 "job-cover-front-default",
1398 "job-cover-front-supported",
1399 "job-delay-output-until",
1400 "job-delay-output-until-default",
1401 "job-delay-output-until-supported",
1402 "job-delay-output-until-time",
1403 "job-delay-output-until-time-default",
1404 "job-delay-output-until-time-supported",
1405 "job-error-action",
1406 "job-error-action-default",
1407 "job-error-action-supported",
1408 "job-error-sheet",
1409 "job-error-sheet-default",
1410 "job-error-sheet-supported",
1411 "job-finishings",
1412 "job-finishings-col",
1413 "job-finishings-col-default",
1414 "job-finishings-col-supported",
1415 "job-finishings-default",
1416 "job-finishings-supported",
1417 "job-hold-until",
1418 "job-hold-until-default",
1419 "job-hold-until-supported",
1420 "job-hold-until-time",
1421 "job-hold-until-time-default",
1422 "job-hold-until-time-supported",
1423 "job-message-to-operator",
1424 "job-message-to-operator-default",
1425 "job-message-to-operator-supported",
1426 "job-phone-number",
1427 "job-phone-number-default",
1428 "job-phone-number-supported",
1429 "job-priority",
1430 "job-priority-default",
1431 "job-priority-supported",
1432 "job-recipient-name",
1433 "job-recipient-name-default",
1434 "job-recipient-name-supported",
1435 "job-save-disposition",
1436 "job-save-disposition-default",
1437 "job-save-disposition-supported",
1438 "job-sheets",
1439 "job-sheets-col",
1440 "job-sheets-col-default",
1441 "job-sheets-col-supported",
1442 "job-sheets-default",
1443 "job-sheets-supported",
1444 "logo-uri-schemes-supported",
1445 "material-amount-units-supported", /* IPP 3D */
1446 "material-diameter-supported", /* IPP 3D */
1447 "material-purpose-supported", /* IPP 3D */
1448 "material-rate-supported", /* IPP 3D */
1449 "material-rate-units-supported", /* IPP 3D */
1450 "material-shell-thickness-supported",/* IPP 3D */
1451 "material-temperature-supported", /* IPP 3D */
1452 "material-type-supported", /* IPP 3D */
1453 "materials-col", /* IPP 3D */
1454 "materials-col-database", /* IPP 3D */
1455 "materials-col-default", /* IPP 3D */
1456 "materials-col-ready", /* IPP 3D */
1457 "materials-col-supported", /* IPP 3D */
1458 "max-materials-col-supported", /* IPP 3D */
1459 "max-save-info-supported",
1460 "max-stitching-locations-supported",
1461 "media",
1462 "media-back-coating-supported",
1463 "media-bottom-margin-supported",
1464 "media-col",
1465 "media-col-default",
1466 "media-col-ready",
1467 "media-col-supported",
1468 "media-color-supported",
1469 "media-default",
1470 "media-front-coating-supported",
1471 "media-grain-supported",
1472 "media-hole-count-supported",
1473 "media-info-supported",
1474 "media-input-tray-check",
1475 "media-input-tray-check-default",
1476 "media-input-tray-check-supported",
1477 "media-key-supported",
1478 "media-left-margin-supported",
1479 "media-order-count-supported",
1480 "media-pre-printed-supported",
1481 "media-ready",
1482 "media-recycled-supported",
1483 "media-right-margin-supported",
1484 "media-size-supported",
1485 "media-source-supported",
1486 "media-supported",
1487 "media-thickness-supported",
1488 "media-top-margin-supported",
1489 "media-type-supported",
1490 "media-weight-metric-supported",
1491 "multiple-document-handling",
1492 "multiple-document-handling-default",
1493 "multiple-document-handling-supported",
1494 "multiple-object-handling", /* IPP 3D */
1495 "multiple-object-handling-default", /* IPP 3D */
1496 "multiple-object-handling-supported",/* IPP 3D */
1497 "number-of-retries", /* IPP FaxOut */
1498 "number-of-retries-default",
1499 "number-of-retries-supported",
1500 "number-up",
1501 "number-up-default",
1502 "number-up-supported",
1503 "orientation-requested",
1504 "orientation-requested-default",
1505 "orientation-requested-supported",
1506 "output-bin",
1507 "output-bin-default",
1508 "output-bin-supported",
1509 "output-device",
1510 "output-device-supported",
1511 "output-device-uuid-supported", /* IPP INFRA */
1512 "output-mode", /* CUPS extension */
1513 "output-mode-default", /* CUPS extension */
1514 "output-mode-supported", /* CUPS extension */
1515 "overrides",
1516 "overrides-supported",
1517 "page-delivery",
1518 "page-delivery-default",
1519 "page-delivery-supported",
1520 "page-order-received",
1521 "page-order-received-default",
1522 "page-order-received-supported",
1523 "page-ranges",
1524 "page-ranges-supported",
1525 "pages-per-subset",
1526 "pages-per-subset-supported",
1527 "pdl-init-file",
1528 "pdl-init-file-default",
1529 "pdl-init-file-entry-supported",
1530 "pdl-init-file-location-supported",
1531 "pdl-init-file-name-subdirectory-supported",
1532 "pdl-init-file-name-supported",
1533 "pdl-init-file-supported",
1534 "platform-temperature", /* IPP 3D */
1535 "platform-temperature-default", /* IPP 3D */
1536 "platform-temperature-supported", /* IPP 3D */
1537 "presentation-direction-number-up",
1538 "presentation-direction-number-up-default",
1539 "presentation-direction-number-up-supported",
1540 "print-accuracy", /* IPP 3D */
1541 "print-accuracy-default", /* IPP 3D */
1542 "print-accuracy-supported", /* IPP 3D */
1543 "print-base", /* IPP 3D */
1544 "print-base-default", /* IPP 3D */
1545 "print-base-supported", /* IPP 3D */
1546 "print-color-mode",
1547 "print-color-mode-default",
1548 "print-color-mode-supported",
1549 "print-content-optimize",
1550 "print-content-optimize-default",
1551 "print-content-optimize-supported",
1552 "print-objects", /* IPP 3D */
1553 "print-objects-default", /* IPP 3D */
1554 "print-objects-supported", /* IPP 3D */
1555 "print-quality",
1556 "print-quality-default",
1557 "print-quality-supported",
1558 "print-rendering-intent",
1559 "print-rendering-intent-default",
1560 "print-rendering-intent-supported",
1561 "print-scaling", /* IPP Paid Printing */
1562 "print-scaling-default", /* IPP Paid Printing */
1563 "print-scaling-supported", /* IPP Paid Printing */
1564 "print-supports", /* IPP 3D */
1565 "print-supports-default", /* IPP 3D */
1566 "print-supports-supported", /* IPP 3D */
1567 "printer-resolution",
1568 "printer-resolution-default",
1569 "printer-resolution-supported",
1570 "proof-print",
1571 "proof-print-default",
1572 "proof-print-supported",
1573 "retry-interval", /* IPP FaxOut */
1574 "retry-interval-default",
1575 "retry-interval-supported",
1576 "retry-timeout", /* IPP FaxOut */
1577 "retry-timeout-default",
1578 "retry-timeout-supported",
1579 "save-disposition-supported",
1580 "save-document-format-default",
1581 "save-document-format-supported",
1582 "save-location-default",
1583 "save-location-supported",
1584 "save-name-subdirectory-supported",
1585 "save-name-supported",
1586 "separator-sheets",
1587 "separator-sheets-default",
1588 "separator-sheets-supported",
1589 "sheet-collate",
1590 "sheet-collate-default",
1591 "sheet-collate-supported",
1592 "sides",
1593 "sides-default",
1594 "sides-supported",
1595 "stitching-locations-supported",
1596 "stitching-offset-supported",
1597 "x-image-position",
1598 "x-image-position-default",
1599 "x-image-position-supported",
1600 "x-image-shift",
1601 "x-image-shift-default",
1602 "x-image-shift-supported",
1603 "x-side1-image-shift",
1604 "x-side1-image-shift-default",
1605 "x-side1-image-shift-supported",
1606 "x-side2-image-shift",
1607 "x-side2-image-shift-default",
1608 "x-side2-image-shift-supported",
1609 "y-image-position",
1610 "y-image-position-default",
1611 "y-image-position-supported",
1612 "y-image-shift",
1613 "y-image-shift-default",
1614 "y-image-shift-supported",
1615 "y-side1-image-shift",
1616 "y-side1-image-shift-default",
1617 "y-side1-image-shift-supported",
1618 "y-side2-image-shift",
1619 "y-side2-image-shift-default",
1620 "y-side2-image-shift-supported"
1621 };
1622 static const char * const printer_description[] =
1623 { /* printer-description group */
1624 "auth-info-required", /* CUPS extension */
1625 "chamber-humidity-current", /* IPP 3D */
1626 "chamber-temperature-current", /* IPP 3D */
1627 "charset-configured",
1628 "charset-supported",
1629 "color-supported",
1630 "compression-supported",
1631 "device-service-count",
1632 "device-uri", /* CUPS extension */
1633 "device-uuid",
1634 "document-charset-default",
1635 "document-charset-supported",
1636 "document-creation-attributes-supported",
1637 "document-digital-signature-default",
1638 "document-digital-signature-supported",
1639 "document-format-default",
1640 "document-format-details-default",
1641 "document-format-details-supported",
1642 "document-format-supported",
1643 "document-format-varying-attributes",
1644 "document-format-version-default",
1645 "document-format-version-supported",
1646 "document-natural-language-default",
1647 "document-natural-language-supported",
1648 "document-password-supported",
1649 "document-privacy-attributes", /* IPP Privacy Attributes */
1650 "document-privacy-scope", /* IPP Privacy Attributes */
1651 "generated-natural-language-supported",
1652 "identify-actions-default",
1653 "identify-actions-supported",
1654 "input-source-supported",
1655 "ipp-features-supported",
1656 "ipp-versions-supported",
1657 "ippget-event-life",
1658 "job-authorization-uri-supported", /* CUPS extension */
1659 "job-constraints-supported",
1660 "job-creation-attributes-supported",
1661 "job-finishings-col-ready",
1662 "job-finishings-ready",
1663 "job-ids-supported",
1664 "job-impressions-supported",
1665 "job-k-limit", /* CUPS extension */
1666 "job-k-octets-supported",
1667 "job-media-sheets-supported",
1668 "job-page-limit", /* CUPS extension */
1669 "job-password-encryption-supported",
1670 "job-password-supported",
1671 "job-presets-supported", /* IPP Presets */
1672 "job-privacy-attributes", /* IPP Privacy Attributes */
1673 "job-privacy-scope", /* IPP Privacy Attributes */
1674 "job-quota-period", /* CUPS extension */
1675 "job-resolvers-supported",
1676 "job-settable-attributes-supported",
1677 "job-spooling-supported",
1678 "job-triggers-supported", /* IPP Presets */
1679 "jpeg-k-octets-supported", /* CUPS extension */
1680 "jpeg-x-dimension-supported", /* CUPS extension */
1681 "jpeg-y-dimension-supported", /* CUPS extension */
1682 "landscape-orientation-requested-preferred",
1683 /* CUPS extension */
1684 "marker-change-time", /* CUPS extension */
1685 "marker-colors", /* CUPS extension */
1686 "marker-high-levels", /* CUPS extension */
1687 "marker-levels", /* CUPS extension */
1688 "marker-low-levels", /* CUPS extension */
1689 "marker-message", /* CUPS extension */
1690 "marker-names", /* CUPS extension */
1691 "marker-types", /* CUPS extension */
1692 "member-names", /* CUPS extension */
1693 "member-uris", /* CUPS extension */
1694 "multiple-destination-uris-supported",/* IPP FaxOut */
1695 "multiple-document-jobs-supported",
1696 "multiple-operation-time-out",
1697 "multiple-operation-time-out-action",
1698 "natural-language-configured",
1699 "operations-supported",
1700 "pages-per-minute",
1701 "pages-per-minute-color",
1702 "pdf-k-octets-supported", /* CUPS extension */
1703 "pdf-features-supported", /* IPP 3D */
1704 "pdf-versions-supported", /* CUPS extension */
1705 "pdl-override-supported",
1706 "platform-shape", /* IPP 3D */
1707 "port-monitor", /* CUPS extension */
1708 "port-monitor-supported", /* CUPS extension */
1709 "preferred-attributes-supported",
1710 "printer-alert",
1711 "printer-alert-description",
1712 "printer-camera-image-uri", /* IPP 3D */
1713 "printer-charge-info",
1714 "printer-charge-info-uri",
1715 "printer-commands", /* CUPS extension */
1716 "printer-config-change-date-time",
1717 "printer-config-change-time",
1718 "printer-config-changes", /* IPP System */
1719 "printer-contact-col", /* IPP System */
1720 "printer-current-time",
1721 "printer-detailed-status-messages",
1722 "printer-device-id",
1723 "printer-dns-sd-name", /* CUPS extension */
1724 "printer-driver-installer",
1725 "printer-fax-log-uri", /* IPP FaxOut */
1726 "printer-fax-modem-info", /* IPP FaxOut */
1727 "printer-fax-modem-name", /* IPP FaxOut */
1728 "printer-fax-modem-number", /* IPP FaxOut */
1729 "printer-firmware-name", /* PWG 5110.1 */
1730 "printer-firmware-patches", /* PWG 5110.1 */
1731 "printer-firmware-string-version", /* PWG 5110.1 */
1732 "printer-firmware-version", /* PWG 5110.1 */
1733 "printer-geo-location",
1734 "printer-get-attributes-supported",
1735 "printer-icc-profiles",
1736 "printer-icons",
1737 "printer-id", /* IPP System */
1738 "printer-info",
1739 "printer-input-tray", /* IPP JPS3 */
1740 "printer-is-accepting-jobs",
1741 "printer-is-shared", /* CUPS extension */
1742 "printer-is-temporary", /* CUPS extension */
1743 "printer-kind", /* IPP Paid Printing */
1744 "printer-location",
1745 "printer-make-and-model",
1746 "printer-mandatory-job-attributes",
1747 "printer-message-date-time",
1748 "printer-message-from-operator",
1749 "printer-message-time",
1750 "printer-more-info",
1751 "printer-more-info-manufacturer",
1752 "printer-name",
1753 "printer-native-formats",
1754 "printer-organization",
1755 "printer-organizational-unit",
1756 "printer-output-tray", /* IPP JPS3 */
1757 "printer-service-type", /* IPP System */
1758 "printer-settable-attributes-supported",
1759 "printer-state",
1760 "printer-state-change-date-time",
1761 "printer-state-change-time",
1762 "printer-state-message",
1763 "printer-state-reasons",
1764 "printer-supply",
1765 "printer-supply-description",
1766 "printer-supply-info-uri",
1767 "printer-type", /* CUPS extension */
1768 "printer-up-time",
1769 "printer-uri-supported",
1770 "printer-uuid",
1771 "printer-xri-supported",
1772 "pwg-raster-document-resolution-supported",
1773 "pwg-raster-document-sheet-back",
1774 "pwg-raster-document-type-supported",
1775 "queued-job-count",
1776 "reference-uri-schemes-supported",
1777 "repertoire-supported",
1778 "requesting-user-name-allowed", /* CUPS extension */
1779 "requesting-user-name-denied", /* CUPS extension */
1780 "requesting-user-uri-supported",
1781 "subordinate-printers-supported",
1782 "subscription-privacy-attributes", /* IPP Privacy Attributes */
1783 "subscription-privacy-scope", /* IPP Privacy Attributes */
1784 "urf-supported", /* CUPS extension */
1785 "uri-authentication-supported",
1786 "uri-security-supported",
1787 "user-defined-value-supported",
1788 "which-jobs-supported",
1789 "xri-authentication-supported",
1790 "xri-security-supported",
1791 "xri-uri-scheme-supported"
1792 };
1793 static const char * const resource_description[] =
1794 { /* resource-description group - IPP System */
1795 "resource-info",
1796 "resource-name"
1797 };
1798 static const char * const resource_status[] =
1799 { /* resource-status group - IPP System */
1800 "date-time-at-canceled",
1801 "date-time-at-creation",
1802 "date-time-at-installed",
1803 "resource-data-uri",
1804 "resource-format",
1805 "resource-id",
1806 "resource-k-octets",
1807 "resource-state",
1808 "resource-state-message",
1809 "resource-state-reasons",
1810 "resource-string-version",
1811 "resource-type",
1812 "resource-use-count",
1813 "resource-uuid",
1814 "resource-version",
1815 "time-at-canceled",
1816 "time-at-creation",
1817 "time-at-installed"
1818 };
1819 static const char * const resource_template[] =
1820 { /* resource-template group - IPP System */
1821 "resource-format",
1822 "resource-format-supported",
1823 "resource-info",
1824 "resource-name",
1825 "resource-type",
1826 "resource-type-supported"
1827 };
1828 static const char * const subscription_description[] =
1829 { /* subscription-description group */
1830 "notify-job-id",
1831 "notify-lease-expiration-time",
1832 "notify-printer-up-time",
1833 "notify-printer-uri",
1834 "notify-resource-id", /* IPP System */
1835 "notify-system-uri", /* IPP System */
1836 "notify-sequence-number",
1837 "notify-subscriber-user-name",
1838 "notify-subscriber-user-uri",
1839 "notify-subscription-id",
1840 "notify-subscription-uuid" /* IPP JPS3 */
1841 };
1842 static const char * const subscription_template[] =
1843 { /* subscription-template group */
1844 "notify-attributes",
1845 "notify-attributes-supported",
1846 "notify-charset",
1847 "notify-events",
1848 "notify-events-default",
1849 "notify-events-supported",
1850 "notify-lease-duration",
1851 "notify-lease-duration-default",
1852 "notify-lease-duration-supported",
1853 "notify-max-events-supported",
1854 "notify-natural-language",
1855 "notify-pull-method",
1856 "notify-pull-method-supported",
1857 "notify-recipient-uri",
1858 "notify-schemes-supported",
1859 "notify-time-interval",
1860 "notify-user-data"
1861 };
1862 static const char * const system_description[] =
1863 { /* system-description group - IPP System */
1864 "charset-configured",
1865 "charset-supported",
1866 "generated-natural-language-supported",
1867 "ipp-features-supported",
1868 "ipp-versions-supported",
1869 "natural-language-configured",
1870 "operations-supported",
1871 "power-calendar-policy-col",
1872 "power-event-policy-col",
1873 "power-timeout-policy-col",
1874 "printer-creation-attributes-supported",
1875 "resource-settable-attributes-supported",
1876 "system-contact-col",
1877 "system-current-time",
1878 "system-default-printer-id",
1879 "system-device-id",
1880 "system-geo-location",
1881 "system-info",
1882 "system-location",
1883 "system-mandatory-printer-attributes",
1884 "system-make-and-model",
1885 "system-message-from-operator",
1886 "system-name",
1887 "system-settable-attributes-supported",
1888 "system-strings-languages-supported",
1889 "system-strings-uri",
1890 "system-xri-supported"
1891 };
1892 static const char * const system_status[] =
1893 { /* system-status group - IPP System */
1894 "power-log-col",
1895 "power-state-capabilities-col",
1896 "power-state-counters-col",
1897 "power-state-monitor-col",
1898 "power-state-transitions-col",
1899 "system-config-change-date-time",
1900 "system-config-change-time",
1901 "system-config-changes",
1902 "system-configured-printers",
1903 "system-configured-resources",
1904 "system-serial-number",
1905 "system-state",
1906 "system-state-change-date-time",
1907 "system-state-change-time",
1908 "system-state-message",
1909 "system-state-reasons",
1910 "system-up-time",
1911 "system-uuid"
1912 };
1913
1914
1915 /*
1916 * Get the requested-attributes attribute...
1917 */
1918
1919 op = ippGetOperation(request);
1920
1921 if ((requested = ippFindAttribute(request, "requested-attributes", IPP_TAG_KEYWORD)) == NULL)
1922 {
1923 /*
1924 * The Get-Jobs operation defaults to "job-id" and "job-uri", all others
1925 * default to "all"...
1926 */
1927
1928 if (op == IPP_OP_GET_JOBS)
1929 {
1930 ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
1931 cupsArrayAdd(ra, "job-id");
1932 cupsArrayAdd(ra, "job-uri");
1933
1934 return (ra);
1935 }
1936 else
1937 return (NULL);
1938 }
1939
1940 /*
1941 * If the attribute contains a single "all" keyword, return NULL...
1942 */
1943
1944 count = ippGetCount(requested);
1945 if (count == 1 && !strcmp(ippGetString(requested, 0, NULL), "all"))
1946 return (NULL);
1947
1948 /*
1949 * Create an array using "strcmp" as the comparison function...
1950 */
1951
1952 ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
1953
1954 for (i = 0; i < count; i ++)
1955 {
1956 added = 0;
1957 value = ippGetString(requested, i, NULL);
1958
1959 if (!strcmp(value, "document-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_JOB_ATTRIBUTES || op == IPP_OP_GET_JOBS || op == IPP_OP_GET_DOCUMENT_ATTRIBUTES || op == IPP_OP_GET_DOCUMENTS)))
1960 {
1961 for (j = 0; j < (int)(sizeof(document_description) / sizeof(document_description[0])); j ++)
1962 cupsArrayAdd(ra, (void *)document_description[j]);
1963
1964 added = 1;
1965 }
1966
1967 if (!strcmp(value, "document-template") || !strcmp(value, "all"))
1968 {
1969 for (j = 0; j < (int)(sizeof(document_template) / sizeof(document_template[0])); j ++)
1970 cupsArrayAdd(ra, (void *)document_template[j]);
1971
1972 added = 1;
1973 }
1974
1975 if (!strcmp(value, "job-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_JOB_ATTRIBUTES || op == IPP_OP_GET_JOBS)))
1976 {
1977 for (j = 0; j < (int)(sizeof(job_description) / sizeof(job_description[0])); j ++)
1978 cupsArrayAdd(ra, (void *)job_description[j]);
1979
1980 added = 1;
1981 }
1982
1983 if (!strcmp(value, "job-template") || (!strcmp(value, "all") && (op == IPP_OP_GET_JOB_ATTRIBUTES || op == IPP_OP_GET_JOBS || op == IPP_OP_GET_PRINTER_ATTRIBUTES)))
1984 {
1985 for (j = 0; j < (int)(sizeof(job_template) / sizeof(job_template[0])); j ++)
1986 cupsArrayAdd(ra, (void *)job_template[j]);
1987
1988 added = 1;
1989 }
1990
1991 if (!strcmp(value, "printer-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_PRINTER_ATTRIBUTES || op == IPP_OP_GET_PRINTERS || op == IPP_OP_CUPS_GET_DEFAULT || op == IPP_OP_CUPS_GET_PRINTERS || op == IPP_OP_CUPS_GET_CLASSES)))
1992 {
1993 for (j = 0; j < (int)(sizeof(printer_description) / sizeof(printer_description[0])); j ++)
1994 cupsArrayAdd(ra, (void *)printer_description[j]);
1995
1996 added = 1;
1997 }
1998
1999 if (!strcmp(value, "resource-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_RESOURCE_ATTRIBUTES || op == IPP_OP_GET_RESOURCES)))
2000 {
2001 for (j = 0; j < (int)(sizeof(resource_description) / sizeof(resource_description[0])); j ++)
2002 cupsArrayAdd(ra, (void *)resource_description[j]);
2003
2004 added = 1;
2005 }
2006
2007 if (!strcmp(value, "resource-status") || (!strcmp(value, "all") && (op == IPP_OP_GET_RESOURCE_ATTRIBUTES || op == IPP_OP_GET_RESOURCES)))
2008 {
2009 for (j = 0; j < (int)(sizeof(resource_status) / sizeof(resource_status[0])); j ++)
2010 cupsArrayAdd(ra, (void *)resource_status[j]);
2011
2012 added = 1;
2013 }
2014
2015 if (!strcmp(value, "resource-template") || (!strcmp(value, "all") && (op == IPP_OP_GET_RESOURCE_ATTRIBUTES || op == IPP_OP_GET_RESOURCES || op == IPP_OP_GET_SYSTEM_ATTRIBUTES)))
2016 {
2017 for (j = 0; j < (int)(sizeof(resource_template) / sizeof(resource_template[0])); j ++)
2018 cupsArrayAdd(ra, (void *)resource_template[j]);
2019
2020 added = 1;
2021 }
2022
2023 if (!strcmp(value, "subscription-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_SUBSCRIPTION_ATTRIBUTES || op == IPP_OP_GET_SUBSCRIPTIONS)))
2024 {
2025 for (j = 0; j < (int)(sizeof(subscription_description) / sizeof(subscription_description[0])); j ++)
2026 cupsArrayAdd(ra, (void *)subscription_description[j]);
2027
2028 added = 1;
2029 }
2030
2031 if (!strcmp(value, "subscription-template") || (!strcmp(value, "all") && (op == IPP_OP_GET_SUBSCRIPTION_ATTRIBUTES || op == IPP_OP_GET_SUBSCRIPTIONS)))
2032 {
2033 for (j = 0; j < (int)(sizeof(subscription_template) / sizeof(subscription_template[0])); j ++)
2034 cupsArrayAdd(ra, (void *)subscription_template[j]);
2035
2036 added = 1;
2037 }
2038
2039 if (!strcmp(value, "system-description") || (!strcmp(value, "all") && op == IPP_OP_GET_SYSTEM_ATTRIBUTES))
2040 {
2041 for (j = 0; j < (int)(sizeof(system_description) / sizeof(system_description[0])); j ++)
2042 cupsArrayAdd(ra, (void *)system_description[j]);
2043
2044 added = 1;
2045 }
2046
2047 if (!strcmp(value, "system-status") || (!strcmp(value, "all") && op == IPP_OP_GET_SYSTEM_ATTRIBUTES))
2048 {
2049 for (j = 0; j < (int)(sizeof(system_status) / sizeof(system_status[0])); j ++)
2050 cupsArrayAdd(ra, (void *)system_status[j]);
2051
2052 added = 1;
2053 }
2054
2055 if (!added)
2056 cupsArrayAdd(ra, (void *)value);
2057 }
2058
2059 return (ra);
2060 }
2061
2062
2063 /*
2064 * 'ippEnumString()' - Return a string corresponding to the enum value.
2065 */
2066
2067 const char * /* O - Enum string */
2068 ippEnumString(const char *attrname, /* I - Attribute name */
2069 int enumvalue) /* I - Enum value */
2070 {
2071 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
2072
2073
2074 /*
2075 * Check for standard enum values...
2076 */
2077
2078 if (!strcmp(attrname, "document-state") && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_document_states) / sizeof(ipp_document_states[0]))))
2079 return (ipp_document_states[enumvalue - 3]);
2080 else if (!strcmp(attrname, "finishings") || !strcmp(attrname, "finishings-actual") || !strcmp(attrname, "finishings-default") || !strcmp(attrname, "finishings-ready") || !strcmp(attrname, "finishings-supported") || !strcmp(attrname, "job-finishings") || !strcmp(attrname, "job-finishings-default") || !strcmp(attrname, "job-finishings-supported"))
2081 {
2082 if (enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_finishings) / sizeof(ipp_finishings[0]))))
2083 return (ipp_finishings[enumvalue - 3]);
2084 else if (enumvalue >= 0x40000000 && enumvalue <= (0x40000000 + (int)(sizeof(ipp_finishings_vendor) / sizeof(ipp_finishings_vendor[0]))))
2085 return (ipp_finishings_vendor[enumvalue - 0x40000000]);
2086 }
2087 else if ((!strcmp(attrname, "job-collation-type") || !strcmp(attrname, "job-collation-type-actual")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_job_collation_types) / sizeof(ipp_job_collation_types[0]))))
2088 return (ipp_job_collation_types[enumvalue - 3]);
2089 else if (!strcmp(attrname, "job-state") && enumvalue >= IPP_JSTATE_PENDING && enumvalue <= IPP_JSTATE_COMPLETED)
2090 return (ipp_job_states[enumvalue - IPP_JSTATE_PENDING]);
2091 else if (!strcmp(attrname, "operations-supported"))
2092 return (ippOpString((ipp_op_t)enumvalue));
2093 else if ((!strcmp(attrname, "orientation-requested") || !strcmp(attrname, "orientation-requested-actual") || !strcmp(attrname, "orientation-requested-default") || !strcmp(attrname, "orientation-requested-supported")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_orientation_requesteds) / sizeof(ipp_orientation_requesteds[0]))))
2094 return (ipp_orientation_requesteds[enumvalue - 3]);
2095 else if ((!strcmp(attrname, "print-quality") || !strcmp(attrname, "print-quality-actual") || !strcmp(attrname, "print-quality-default") || !strcmp(attrname, "print-quality-supported")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_print_qualities) / sizeof(ipp_print_qualities[0]))))
2096 return (ipp_print_qualities[enumvalue - 3]);
2097 else if (!strcmp(attrname, "printer-state") && enumvalue >= IPP_PSTATE_IDLE && enumvalue <= IPP_PSTATE_STOPPED)
2098 return (ipp_printer_states[enumvalue - IPP_PSTATE_IDLE]);
2099 else if (!strcmp(attrname, "resource-state") && enumvalue >= IPP_RSTATE_PENDING && enumvalue <= IPP_RSTATE_ABORTED)
2100 return (ipp_resource_states[enumvalue - IPP_RSTATE_PENDING]);
2101 else if (!strcmp(attrname, "system-state") && enumvalue >= IPP_SSTATE_IDLE && enumvalue <= IPP_SSTATE_STOPPED)
2102 return (ipp_system_states[enumvalue - IPP_SSTATE_IDLE]);
2103
2104 /*
2105 * Not a standard enum value, just return the decimal equivalent...
2106 */
2107
2108 snprintf(cg->ipp_unknown, sizeof(cg->ipp_unknown), "%d", enumvalue);
2109 return (cg->ipp_unknown);
2110 }
2111
2112
2113 /*
2114 * 'ippEnumValue()' - Return the value associated with a given enum string.
2115 */
2116
2117 int /* O - Enum value or -1 if unknown */
2118 ippEnumValue(const char *attrname, /* I - Attribute name */
2119 const char *enumstring) /* I - Enum string */
2120 {
2121 int i, /* Looping var */
2122 num_strings; /* Number of strings to compare */
2123 const char * const *strings; /* Strings to compare */
2124
2125
2126 /*
2127 * If the string is just a number, return it...
2128 */
2129
2130 if (isdigit(*enumstring & 255))
2131 return ((int)strtol(enumstring, NULL, 0));
2132
2133 /*
2134 * Otherwise look up the string...
2135 */
2136
2137 if (!strcmp(attrname, "document-state"))
2138 {
2139 num_strings = (int)(sizeof(ipp_document_states) / sizeof(ipp_document_states[0]));
2140 strings = ipp_document_states;
2141 }
2142 else if (!strcmp(attrname, "finishings") ||
2143 !strcmp(attrname, "finishings-actual") ||
2144 !strcmp(attrname, "finishings-default") ||
2145 !strcmp(attrname, "finishings-ready") ||
2146 !strcmp(attrname, "finishings-supported"))
2147 {
2148 for (i = 0;
2149 i < (int)(sizeof(ipp_finishings_vendor) /
2150 sizeof(ipp_finishings_vendor[0]));
2151 i ++)
2152 if (!strcmp(enumstring, ipp_finishings_vendor[i]))
2153 return (i + 0x40000000);
2154
2155 num_strings = (int)(sizeof(ipp_finishings) / sizeof(ipp_finishings[0]));
2156 strings = ipp_finishings;
2157 }
2158 else if (!strcmp(attrname, "job-collation-type") ||
2159 !strcmp(attrname, "job-collation-type-actual"))
2160 {
2161 num_strings = (int)(sizeof(ipp_job_collation_types) /
2162 sizeof(ipp_job_collation_types[0]));
2163 strings = ipp_job_collation_types;
2164 }
2165 else if (!strcmp(attrname, "job-state"))
2166 {
2167 num_strings = (int)(sizeof(ipp_job_states) / sizeof(ipp_job_states[0]));
2168 strings = ipp_job_states;
2169 }
2170 else if (!strcmp(attrname, "operations-supported"))
2171 return (ippOpValue(enumstring));
2172 else if (!strcmp(attrname, "orientation-requested") ||
2173 !strcmp(attrname, "orientation-requested-actual") ||
2174 !strcmp(attrname, "orientation-requested-default") ||
2175 !strcmp(attrname, "orientation-requested-supported"))
2176 {
2177 num_strings = (int)(sizeof(ipp_orientation_requesteds) /
2178 sizeof(ipp_orientation_requesteds[0]));
2179 strings = ipp_orientation_requesteds;
2180 }
2181 else if (!strcmp(attrname, "print-quality") ||
2182 !strcmp(attrname, "print-quality-actual") ||
2183 !strcmp(attrname, "print-quality-default") ||
2184 !strcmp(attrname, "print-quality-supported"))
2185 {
2186 num_strings = (int)(sizeof(ipp_print_qualities) / sizeof(ipp_print_qualities[0]));
2187 strings = ipp_print_qualities;
2188 }
2189 else if (!strcmp(attrname, "printer-state"))
2190 {
2191 num_strings = (int)(sizeof(ipp_printer_states) / sizeof(ipp_printer_states[0]));
2192 strings = ipp_printer_states;
2193 }
2194 else if (!strcmp(attrname, "resource-state"))
2195 {
2196 num_strings = (int)(sizeof(ipp_resource_states) / sizeof(ipp_resource_states[0]));
2197 strings = ipp_resource_states;
2198 }
2199 else if (!strcmp(attrname, "system-state"))
2200 {
2201 num_strings = (int)(sizeof(ipp_system_states) / sizeof(ipp_system_states[0]));
2202 strings = ipp_system_states;
2203 }
2204 else
2205 return (-1);
2206
2207 for (i = 0; i < num_strings; i ++)
2208 if (!strcmp(enumstring, strings[i]))
2209 return (i + 3);
2210
2211 return (-1);
2212 }
2213
2214
2215 /*
2216 * 'ippErrorString()' - Return a name for the given status code.
2217 */
2218
2219 const char * /* O - Text string */
2220 ippErrorString(ipp_status_t error) /* I - Error status */
2221 {
2222 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
2223
2224
2225 /*
2226 * See if the error code is a known value...
2227 */
2228
2229 if (error >= IPP_STATUS_OK && error <= IPP_STATUS_OK_EVENTS_COMPLETE)
2230 return (ipp_status_oks[error]);
2231 else if (error == IPP_STATUS_REDIRECTION_OTHER_SITE)
2232 return ("redirection-other-site");
2233 else if (error == IPP_STATUS_CUPS_SEE_OTHER)
2234 return ("cups-see-other");
2235 else if (error >= IPP_STATUS_ERROR_BAD_REQUEST &&
2236 error <= IPP_STATUS_ERROR_ACCOUNT_AUTHORIZATION_FAILED)
2237 return (ipp_status_400s[error - IPP_STATUS_ERROR_BAD_REQUEST]);
2238 else if (error >= 0x480 &&
2239 error <= IPP_STATUS_ERROR_CUPS_ACCOUNT_AUTHORIZATION_FAILED)
2240 return (ipp_status_480s[error - 0x0480]);
2241 else if (error >= IPP_STATUS_ERROR_INTERNAL &&
2242 error <= IPP_STATUS_ERROR_TOO_MANY_DOCUMENTS)
2243 return (ipp_status_500s[error - IPP_STATUS_ERROR_INTERNAL]);
2244 else if (error >= IPP_STATUS_ERROR_CUPS_AUTHENTICATION_CANCELED &&
2245 error <= IPP_STATUS_ERROR_CUPS_UPGRADE_REQUIRED)
2246 return (ipp_status_1000s[error -
2247 IPP_STATUS_ERROR_CUPS_AUTHENTICATION_CANCELED]);
2248
2249 /*
2250 * No, build an "0xxxxx" error string...
2251 */
2252
2253 sprintf(cg->ipp_unknown, "0x%04x", error);
2254
2255 return (cg->ipp_unknown);
2256 }
2257
2258
2259 /*
2260 * 'ippErrorValue()' - Return a status code for the given name.
2261 *
2262 * @since CUPS 1.2/macOS 10.5@
2263 */
2264
2265 ipp_status_t /* O - IPP status code */
2266 ippErrorValue(const char *name) /* I - Name */
2267 {
2268 size_t i; /* Looping var */
2269
2270
2271 for (i = 0; i < (sizeof(ipp_status_oks) / sizeof(ipp_status_oks[0])); i ++)
2272 if (!_cups_strcasecmp(name, ipp_status_oks[i]))
2273 return ((ipp_status_t)i);
2274
2275 if (!_cups_strcasecmp(name, "redirection-other-site"))
2276 return (IPP_STATUS_REDIRECTION_OTHER_SITE);
2277
2278 if (!_cups_strcasecmp(name, "cups-see-other"))
2279 return (IPP_STATUS_CUPS_SEE_OTHER);
2280
2281 for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++)
2282 if (!_cups_strcasecmp(name, ipp_status_400s[i]))
2283 return ((ipp_status_t)(i + 0x400));
2284
2285 for (i = 0; i < (sizeof(ipp_status_480s) / sizeof(ipp_status_480s[0])); i ++)
2286 if (!_cups_strcasecmp(name, ipp_status_480s[i]))
2287 return ((ipp_status_t)(i + 0x480));
2288
2289 for (i = 0; i < (sizeof(ipp_status_500s) / sizeof(ipp_status_500s[0])); i ++)
2290 if (!_cups_strcasecmp(name, ipp_status_500s[i]))
2291 return ((ipp_status_t)(i + 0x500));
2292
2293 for (i = 0; i < (sizeof(ipp_status_1000s) / sizeof(ipp_status_1000s[0])); i ++)
2294 if (!_cups_strcasecmp(name, ipp_status_1000s[i]))
2295 return ((ipp_status_t)(i + 0x1000));
2296
2297 return ((ipp_status_t)-1);
2298 }
2299
2300
2301 /*
2302 * 'ippOpString()' - Return a name for the given operation id.
2303 *
2304 * @since CUPS 1.2/macOS 10.5@
2305 */
2306
2307 const char * /* O - Name */
2308 ippOpString(ipp_op_t op) /* I - Operation ID */
2309 {
2310 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
2311
2312
2313 /*
2314 * See if the operation ID is a known value...
2315 */
2316
2317 if (op >= IPP_OP_PRINT_JOB && op < (ipp_op_t)(sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])))
2318 return (ipp_std_ops[op]);
2319 else if (op == IPP_OP_PRIVATE)
2320 return ("windows-ext");
2321 else if (op >= IPP_OP_CUPS_GET_DEFAULT && op <= IPP_OP_CUPS_GET_PPD)
2322 return (ipp_cups_ops[op - IPP_OP_CUPS_GET_DEFAULT]);
2323 else if (op >= IPP_OP_CUPS_GET_DOCUMENT && op <= IPP_OP_CUPS_CREATE_LOCAL_PRINTER)
2324 return (ipp_cups_ops2[op - IPP_OP_CUPS_GET_DOCUMENT]);
2325
2326 /*
2327 * No, build an "0xxxxx" operation string...
2328 */
2329
2330 sprintf(cg->ipp_unknown, "0x%04x", op);
2331
2332 return (cg->ipp_unknown);
2333 }
2334
2335
2336 /*
2337 * 'ippOpValue()' - Return an operation id for the given name.
2338 *
2339 * @since CUPS 1.2/macOS 10.5@
2340 */
2341
2342 ipp_op_t /* O - Operation ID */
2343 ippOpValue(const char *name) /* I - Textual name */
2344 {
2345 size_t i; /* Looping var */
2346
2347
2348 if (!strncmp(name, "0x", 2))
2349 return ((ipp_op_t)strtol(name + 2, NULL, 16));
2350
2351 for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++)
2352 if (!_cups_strcasecmp(name, ipp_std_ops[i]))
2353 return ((ipp_op_t)i);
2354
2355 if (!_cups_strcasecmp(name, "windows-ext"))
2356 return (IPP_OP_PRIVATE);
2357
2358 for (i = 0; i < (sizeof(ipp_cups_ops) / sizeof(ipp_cups_ops[0])); i ++)
2359 if (!_cups_strcasecmp(name, ipp_cups_ops[i]))
2360 return ((ipp_op_t)(i + 0x4001));
2361
2362 for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++)
2363 if (!_cups_strcasecmp(name, ipp_cups_ops2[i]))
2364 return ((ipp_op_t)(i + 0x4027));
2365
2366 if (!_cups_strcasecmp(name, "Create-Job-Subscription"))
2367 return (IPP_OP_CREATE_JOB_SUBSCRIPTIONS);
2368
2369 if (!_cups_strcasecmp(name, "Create-Printer-Subscription"))
2370 return (IPP_OP_CREATE_PRINTER_SUBSCRIPTIONS);
2371
2372 if (!_cups_strcasecmp(name, "CUPS-Add-Class"))
2373 return (IPP_OP_CUPS_ADD_MODIFY_CLASS);
2374
2375 if (!_cups_strcasecmp(name, "CUPS-Add-Printer"))
2376 return (IPP_OP_CUPS_ADD_MODIFY_PRINTER);
2377
2378 return (IPP_OP_CUPS_INVALID);
2379 }
2380
2381
2382 /*
2383 * 'ippPort()' - Return the default IPP port number.
2384 */
2385
2386 int /* O - Port number */
2387 ippPort(void)
2388 {
2389 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
2390
2391
2392 DEBUG_puts("ippPort()");
2393
2394 if (!cg->ipp_port)
2395 _cupsSetDefaults();
2396
2397 DEBUG_printf(("1ippPort: Returning %d...", cg->ipp_port));
2398
2399 return (cg->ipp_port);
2400 }
2401
2402
2403 /*
2404 * 'ippSetPort()' - Set the default port number.
2405 */
2406
2407 void
2408 ippSetPort(int p) /* I - Port number to use */
2409 {
2410 DEBUG_printf(("ippSetPort(p=%d)", p));
2411
2412 _cupsGlobals()->ipp_port = p;
2413 }
2414
2415
2416 /*
2417 * 'ippStateString()' - Return the name corresponding to a state value.
2418 *
2419 * @since CUPS 2.0/OS 10.10@
2420 */
2421
2422 const char * /* O - State name */
2423 ippStateString(ipp_state_t state) /* I - State value */
2424 {
2425 if (state >= IPP_STATE_ERROR && state <= IPP_STATE_DATA)
2426 return (ipp_states[state - IPP_STATE_ERROR]);
2427 else
2428 return ("UNKNOWN");
2429 }
2430
2431
2432 /*
2433 * 'ippTagString()' - Return the tag name corresponding to a tag value.
2434 *
2435 * The returned names are defined in RFC 8011 and the IANA IPP Registry.
2436 *
2437 * @since CUPS 1.4/macOS 10.6@
2438 */
2439
2440 const char * /* O - Tag name */
2441 ippTagString(ipp_tag_t tag) /* I - Tag value */
2442 {
2443 tag &= IPP_TAG_CUPS_MASK;
2444
2445 if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])))
2446 return (ipp_tag_names[tag]);
2447 else
2448 return ("UNKNOWN");
2449 }
2450
2451
2452 /*
2453 * 'ippTagValue()' - Return the tag value corresponding to a tag name.
2454 *
2455 * The tag names are defined in RFC 8011 and the IANA IPP Registry.
2456 *
2457 * @since CUPS 1.4/macOS 10.6@
2458 */
2459
2460 ipp_tag_t /* O - Tag value */
2461 ippTagValue(const char *name) /* I - Tag name */
2462 {
2463 size_t i; /* Looping var */
2464
2465
2466 for (i = 0; i < (sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])); i ++)
2467 if (!_cups_strcasecmp(name, ipp_tag_names[i]))
2468 return ((ipp_tag_t)i);
2469
2470 if (!_cups_strcasecmp(name, "operation"))
2471 return (IPP_TAG_OPERATION);
2472 else if (!_cups_strcasecmp(name, "job"))
2473 return (IPP_TAG_JOB);
2474 else if (!_cups_strcasecmp(name, "printer"))
2475 return (IPP_TAG_PRINTER);
2476 else if (!_cups_strcasecmp(name, "unsupported"))
2477 return (IPP_TAG_UNSUPPORTED_GROUP);
2478 else if (!_cups_strcasecmp(name, "subscription"))
2479 return (IPP_TAG_SUBSCRIPTION);
2480 else if (!_cups_strcasecmp(name, "event"))
2481 return (IPP_TAG_EVENT_NOTIFICATION);
2482 else if (!_cups_strcasecmp(name, "language"))
2483 return (IPP_TAG_LANGUAGE);
2484 else if (!_cups_strcasecmp(name, "mimetype"))
2485 return (IPP_TAG_MIMETYPE);
2486 else if (!_cups_strcasecmp(name, "name"))
2487 return (IPP_TAG_NAME);
2488 else if (!_cups_strcasecmp(name, "text"))
2489 return (IPP_TAG_TEXT);
2490 else if (!_cups_strcasecmp(name, "begCollection"))
2491 return (IPP_TAG_BEGIN_COLLECTION);
2492 else
2493 return (IPP_TAG_ZERO);
2494 }
2495
2496
2497 /*
2498 * 'ipp_col_string()' - Convert a collection to a string.
2499 */
2500
2501 static size_t /* O - Number of bytes */
2502 ipp_col_string(ipp_t *col, /* I - Collection attribute */
2503 char *buffer, /* I - Buffer or NULL */
2504 size_t bufsize) /* I - Size of buffer */
2505 {
2506 char *bufptr, /* Position in buffer */
2507 *bufend, /* End of buffer */
2508 prefix = '{', /* Prefix character */
2509 temp[256]; /* Temporary string */
2510 ipp_attribute_t *attr; /* Current member attribute */
2511
2512
2513 if (!col)
2514 {
2515 if (buffer)
2516 *buffer = '\0';
2517
2518 return (0);
2519 }
2520
2521 bufptr = buffer;
2522 bufend = buffer + bufsize - 1;
2523
2524 for (attr = col->attrs; attr; attr = attr->next)
2525 {
2526 if (!attr->name)
2527 continue;
2528
2529 if (buffer && bufptr < bufend)
2530 *bufptr = prefix;
2531 bufptr ++;
2532 prefix = ' ';
2533
2534 if (buffer && bufptr < bufend)
2535 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%s=", attr->name);
2536 else
2537 bufptr += strlen(attr->name) + 1;
2538
2539 if (buffer && bufptr < bufend)
2540 bufptr += ippAttributeString(attr, bufptr, (size_t)(bufend - bufptr + 1));
2541 else
2542 bufptr += ippAttributeString(attr, temp, sizeof(temp));
2543 }
2544
2545 if (prefix == '{')
2546 {
2547 if (buffer && bufptr < bufend)
2548 *bufptr = prefix;
2549 bufptr ++;
2550 }
2551
2552 if (buffer && bufptr < bufend)
2553 *bufptr = '}';
2554 bufptr ++;
2555
2556 return ((size_t)(bufptr - buffer));
2557 }