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