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