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