]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/ipp-support.c
Merge pull request #5317 from nils-van-zuijlen/typo-fr
[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 * const ipp_resource_states[] =
622 { /* resource-state enums */
623 "pending",
624 "available",
625 "installed",
626 "canceled",
627 "aborted"
628 },
629 * const ipp_system_states[] =
630 { /* system-state enums */
631 "idle",
632 "processing",
633 "stopped"
634 };
635
636
637 /*
638 * Local functions...
639 */
640
641 static size_t ipp_col_string(ipp_t *col, char *buffer, size_t bufsize);
642
643
644 /*
645 * 'ippAttributeString()' - Convert the attribute's value to a string.
646 *
647 * Returns the number of bytes that would be written, not including the
648 * trailing nul. The buffer pointer can be NULL to get the required length,
649 * just like (v)snprintf.
650 *
651 * @since CUPS 1.6/macOS 10.8@
652 */
653
654 size_t /* O - Number of bytes less nul */
655 ippAttributeString(
656 ipp_attribute_t *attr, /* I - Attribute */
657 char *buffer, /* I - String buffer or NULL */
658 size_t bufsize) /* I - Size of string buffer */
659 {
660 int i; /* Looping var */
661 char *bufptr, /* Pointer into buffer */
662 *bufend, /* End of buffer */
663 temp[256]; /* Temporary string */
664 const char *ptr, /* Pointer into string */
665 *end; /* Pointer to end of string */
666 _ipp_value_t *val; /* Current value */
667
668
669 if (!attr || !attr->name)
670 {
671 if (buffer)
672 *buffer = '\0';
673
674 return (0);
675 }
676
677 bufptr = buffer;
678 if (buffer)
679 bufend = buffer + bufsize - 1;
680 else
681 bufend = NULL;
682
683 for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
684 {
685 if (val > attr->values)
686 {
687 if (buffer && bufptr < bufend)
688 *bufptr++ = ',';
689 else
690 bufptr ++;
691 }
692
693 switch (attr->value_tag & ~IPP_TAG_CUPS_CONST)
694 {
695 case IPP_TAG_ENUM :
696 ptr = ippEnumString(attr->name, val->integer);
697
698 if (buffer && bufptr < bufend)
699 strlcpy(bufptr, ptr, (size_t)(bufend - bufptr + 1));
700
701 bufptr += strlen(ptr);
702 break;
703
704 case IPP_TAG_INTEGER :
705 if (buffer && bufptr < bufend)
706 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%d", val->integer);
707 else
708 bufptr += snprintf(temp, sizeof(temp), "%d", val->integer);
709 break;
710
711 case IPP_TAG_BOOLEAN :
712 if (buffer && bufptr < bufend)
713 strlcpy(bufptr, val->boolean ? "true" : "false", (size_t)(bufend - bufptr + 1));
714
715 bufptr += val->boolean ? 4 : 5;
716 break;
717
718 case IPP_TAG_RANGE :
719 if (buffer && bufptr < bufend)
720 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%d-%d", val->range.lower, val->range.upper);
721 else
722 bufptr += snprintf(temp, sizeof(temp), "%d-%d", val->range.lower, val->range.upper);
723 break;
724
725 case IPP_TAG_RESOLUTION :
726 if (val->resolution.xres == val->resolution.yres)
727 {
728 if (buffer && bufptr < bufend)
729 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%d%s", val->resolution.xres, val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
730 else
731 bufptr += snprintf(temp, sizeof(temp), "%d%s", val->resolution.xres, val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
732 }
733 else if (buffer && bufptr < bufend)
734 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");
735 else
736 bufptr += snprintf(temp, sizeof(temp), "%dx%d%s", val->resolution.xres, val->resolution.yres, val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
737 break;
738
739 case IPP_TAG_DATE :
740 {
741 unsigned year; /* Year */
742
743 year = ((unsigned)val->date[0] << 8) + (unsigned)val->date[1];
744
745 if (val->date[9] == 0 && val->date[10] == 0)
746 snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ",
747 year, val->date[2], val->date[3], val->date[4],
748 val->date[5], val->date[6]);
749 else
750 snprintf(temp, sizeof(temp),
751 "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u",
752 year, val->date[2], val->date[3], val->date[4],
753 val->date[5], val->date[6], val->date[8], val->date[9],
754 val->date[10]);
755
756 if (buffer && bufptr < bufend)
757 strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));
758
759 bufptr += strlen(temp);
760 }
761 break;
762
763 case IPP_TAG_TEXT :
764 case IPP_TAG_NAME :
765 case IPP_TAG_KEYWORD :
766 case IPP_TAG_CHARSET :
767 case IPP_TAG_URI :
768 case IPP_TAG_URISCHEME :
769 case IPP_TAG_MIMETYPE :
770 case IPP_TAG_LANGUAGE :
771 case IPP_TAG_TEXTLANG :
772 case IPP_TAG_NAMELANG :
773 if (!val->string.text)
774 break;
775
776 for (ptr = val->string.text; *ptr; ptr ++)
777 {
778 if (*ptr == '\\' || *ptr == '\"' || *ptr == '[')
779 {
780 if (buffer && bufptr < bufend)
781 *bufptr = '\\';
782 bufptr ++;
783 }
784
785 if (buffer && bufptr < bufend)
786 *bufptr = *ptr;
787 bufptr ++;
788 }
789
790 if (val->string.language)
791 {
792 /*
793 * Add "[language]" to end of string...
794 */
795
796 if (buffer && bufptr < bufend)
797 *bufptr = '[';
798 bufptr ++;
799
800 if (buffer && bufptr < bufend)
801 strlcpy(bufptr, val->string.language, (size_t)(bufend - bufptr));
802 bufptr += strlen(val->string.language);
803
804 if (buffer && bufptr < bufend)
805 *bufptr = ']';
806 bufptr ++;
807 }
808 break;
809
810 case IPP_TAG_BEGIN_COLLECTION :
811 if (buffer && bufptr < bufend)
812 bufptr += ipp_col_string(val->collection, bufptr, (size_t)(bufend - bufptr + 1));
813 else
814 bufptr += ipp_col_string(val->collection, NULL, 0);
815 break;
816
817 case IPP_TAG_STRING :
818 for (ptr = val->unknown.data, end = ptr + val->unknown.length;
819 ptr < end; ptr ++)
820 {
821 if (*ptr == '\\' || _cups_isspace(*ptr))
822 {
823 if (buffer && bufptr < bufend)
824 *bufptr = '\\';
825 bufptr ++;
826
827 if (buffer && bufptr < bufend)
828 *bufptr = *ptr;
829 bufptr ++;
830 }
831 else if (!isprint(*ptr & 255))
832 {
833 if (buffer && bufptr < bufend)
834 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "\\%03o", *ptr & 255);
835 else
836 bufptr += snprintf(temp, sizeof(temp), "\\%03o", *ptr & 255);
837 }
838 else
839 {
840 if (buffer && bufptr < bufend)
841 *bufptr = *ptr;
842 bufptr ++;
843 }
844 }
845 break;
846
847 default :
848 ptr = ippTagString(attr->value_tag);
849 if (buffer && bufptr < bufend)
850 strlcpy(bufptr, ptr, (size_t)(bufend - bufptr + 1));
851 bufptr += strlen(ptr);
852 break;
853 }
854 }
855
856 if (buffer && bufptr < bufend)
857 *bufptr = '\0';
858 else if (bufend)
859 *bufend = '\0';
860
861 return ((size_t)(bufptr - buffer));
862 }
863
864
865 /*
866 * 'ippCreateRequestedArray()' - Create a CUPS array of attribute names from the
867 * given requested-attributes attribute.
868 *
869 * This function creates a (sorted) CUPS array of attribute names matching the
870 * list of "requested-attribute" values supplied in an IPP request. All IANA-
871 * registered values are supported in addition to the CUPS IPP extension
872 * attributes.
873 *
874 * The @code request@ parameter specifies the request message that was read from
875 * the client.
876 *
877 * @code NULL@ is returned if all attributes should be returned. Otherwise, the
878 * result is a sorted array of attribute names, where @code cupsArrayFind(array,
879 * "attribute-name")@ will return a non-NULL pointer. The array must be freed
880 * using the @code cupsArrayDelete@ function.
881 *
882 * @since CUPS 1.7/macOS 10.9@
883 */
884
885 cups_array_t * /* O - CUPS array or @code NULL@ if all */
886 ippCreateRequestedArray(ipp_t *request) /* I - IPP request */
887 {
888 int i, j, /* Looping vars */
889 count, /* Number of values */
890 added; /* Was name added? */
891 ipp_attribute_t *requested; /* requested-attributes attribute */
892 cups_array_t *ra; /* Requested attributes array */
893 const char *value; /* Current value */
894 /* The following lists come from the current IANA IPP registry of attributes */
895 static const char * const document_description[] =
896 { /* document-description group */
897 "compression",
898 "copies-actual",
899 "cover-back-actual",
900 "cover-front-actual",
901 "current-page-order",
902 "date-time-at-completed",
903 "date-time-at-creation",
904 "date-time-at-processing",
905 "detailed-status-messages",
906 "document-access-errors",
907 "document-charset",
908 "document-digital-signature",
909 "document-format",
910 "document-format-details",
911 "document-format-detected",
912 "document-format-version",
913 "document-format-version-detected",
914 "document-job-id",
915 "document-job-uri",
916 "document-message",
917 "document-metadata",
918 "document-name",
919 "document-natural-language",
920 "document-number",
921 "document-printer-uri",
922 "document-state",
923 "document-state-message",
924 "document-state-reasons",
925 "document-uri",
926 "document-uuid",
927 "errors-count",
928 "finishings-actual",
929 "finishings-col-actual",
930 "force-front-side-actual",
931 "imposition-template-actual",
932 "impressions",
933 "impressions-col",
934 "impressions-completed",
935 "impressions-completed-col",
936 "impressions-completed-current-copy",
937 "insert-sheet-actual",
938 "k-octets",
939 "k-octets-processed",
940 "last-document",
941 "materials-col-actual", /* IPP 3D */
942 "media-actual",
943 "media-col-actual",
944 "media-input-tray-check-actual",
945 "media-sheets",
946 "media-sheets-col",
947 "media-sheets-completed",
948 "media-sheets-completed-col",
949 "more-info",
950 "multiple-object-handling-actual", /* IPP 3D */
951 "number-up-actual",
952 "orientation-requested-actual",
953 "output-bin-actual",
954 "output-device-assigned",
955 "overrides-actual",
956 "page-delivery-actual",
957 "page-order-received-actual",
958 "page-ranges-actual",
959 "pages",
960 "pages-col",
961 "pages-completed",
962 "pages-completed-col",
963 "pages-completed-current-copy",
964 "platform-temperature-actual", /* IPP 3D */
965 "presentation-direction-number-up-actual",
966 "print-accuracy-actual", /* IPP 3D */
967 "print-base-actual", /* IPP 3D */
968 "print-color-mode-actual",
969 "print-content-optimize-actual",
970 "print-objects-actual", /* IPP 3D */
971 "print-quality-actual",
972 "print-rendering-intent-actual",
973 "print-scaling-actual", /* IPP Paid Printing */
974 "print-supports-actual", /* IPP 3D */
975 "printer-resolution-actual",
976 "printer-up-time",
977 "separator-sheets-actual",
978 "sheet-completed-copy-number",
979 "sides-actual",
980 "time-at-completed",
981 "time-at-creation",
982 "time-at-processing",
983 "x-image-position-actual",
984 "x-image-shift-actual",
985 "x-side1-image-shift-actual",
986 "x-side2-image-shift-actual",
987 "y-image-position-actual",
988 "y-image-shift-actual",
989 "y-side1-image-shift-actual",
990 "y-side2-image-shift-actual"
991 };
992 static const char * const document_template[] =
993 { /* document-template group */
994 "copies",
995 "copies-default",
996 "copies-supported",
997 "cover-back",
998 "cover-back-default",
999 "cover-back-supported",
1000 "cover-front",
1001 "cover-front-default",
1002 "cover-front-supported",
1003 "feed-orientation",
1004 "feed-orientation-default",
1005 "feed-orientation-supported",
1006 "finishings",
1007 "finishings-col",
1008 "finishings-col-database",
1009 "finishings-col-default",
1010 "finishings-col-ready",
1011 "finishings-col-supported",
1012 "finishings-default",
1013 "finishings-ready",
1014 "finishings-supported",
1015 "font-name-requested",
1016 "font-name-requested-default",
1017 "font-name-requested-supported",
1018 "font-size-requested",
1019 "font-size-requested-default",
1020 "font-size-requested-supported",
1021 "force-front-side",
1022 "force-front-side-default",
1023 "force-front-side-supported",
1024 "imposition-template",
1025 "imposition-template-default",
1026 "imposition-template-supported",
1027 "insert-after-page-number-supported",
1028 "insert-count-supported",
1029 "insert-sheet",
1030 "insert-sheet-default",
1031 "insert-sheet-supported",
1032 "material-amount-units-supported", /* IPP 3D */
1033 "material-diameter-supported", /* IPP 3D */
1034 "material-purpose-supported", /* IPP 3D */
1035 "material-rate-supported", /* IPP 3D */
1036 "material-rate-units-supported", /* IPP 3D */
1037 "material-shell-thickness-supported",/* IPP 3D */
1038 "material-temperature-supported", /* IPP 3D */
1039 "material-type-supported", /* IPP 3D */
1040 "materials-col", /* IPP 3D */
1041 "materials-col-database", /* IPP 3D */
1042 "materials-col-default", /* IPP 3D */
1043 "materials-col-ready", /* IPP 3D */
1044 "materials-col-supported", /* IPP 3D */
1045 "max-materials-col-supported", /* IPP 3D */
1046 "max-stitching-locations-supported",
1047 "media",
1048 "media-back-coating-supported",
1049 "media-bottom-margin-supported",
1050 "media-col",
1051 "media-col-default",
1052 "media-col-ready",
1053 "media-col-supported",
1054 "media-color-supported",
1055 "media-default",
1056 "media-front-coating-supported",
1057 "media-grain-supported",
1058 "media-hole-count-supported",
1059 "media-info-supported",
1060 "media-input-tray-check",
1061 "media-input-tray-check-default",
1062 "media-input-tray-check-supported",
1063 "media-key-supported",
1064 "media-left-margin-supported",
1065 "media-order-count-supported",
1066 "media-pre-printed-supported",
1067 "media-ready",
1068 "media-recycled-supported",
1069 "media-right-margin-supported",
1070 "media-size-supported",
1071 "media-source-supported",
1072 "media-supported",
1073 "media-thickness-supported",
1074 "media-top-margin-supported",
1075 "media-type-supported",
1076 "media-weight-metric-supported",
1077 "multiple-document-handling",
1078 "multiple-document-handling-default",
1079 "multiple-document-handling-supported",
1080 "multiple-object-handling", /* IPP 3D */
1081 "multiple-object-handling-default", /* IPP 3D */
1082 "multiple-object-handling-supported",/* IPP 3D */
1083 "number-up",
1084 "number-up-default",
1085 "number-up-supported",
1086 "orientation-requested",
1087 "orientation-requested-default",
1088 "orientation-requested-supported",
1089 "output-mode", /* CUPS extension */
1090 "output-mode-default", /* CUPS extension */
1091 "output-mode-supported", /* CUPS extension */
1092 "overrides",
1093 "overrides-supported",
1094 "page-delivery",
1095 "page-delivery-default",
1096 "page-delivery-supported",
1097 "page-order-received",
1098 "page-order-received-default",
1099 "page-order-received-supported",
1100 "page-ranges",
1101 "page-ranges-supported",
1102 "pages-per-subset",
1103 "pages-per-subset-supported",
1104 "pdl-init-file",
1105 "pdl-init-file-default",
1106 "pdl-init-file-entry-supported",
1107 "pdl-init-file-location-supported",
1108 "pdl-init-file-name-subdirectory-supported",
1109 "pdl-init-file-name-supported",
1110 "pdl-init-file-supported",
1111 "platform-temperature", /* IPP 3D */
1112 "platform-temperature-default", /* IPP 3D */
1113 "platform-temperature-supported", /* IPP 3D */
1114 "presentation-direction-number-up",
1115 "presentation-direction-number-up-default",
1116 "presentation-direction-number-up-supported",
1117 "print-accuracy", /* IPP 3D */
1118 "print-accuracy-default", /* IPP 3D */
1119 "print-accuracy-supported", /* IPP 3D */
1120 "print-base", /* IPP 3D */
1121 "print-base-default", /* IPP 3D */
1122 "print-base-supported", /* IPP 3D */
1123 "print-color-mode",
1124 "print-color-mode-default",
1125 "print-color-mode-supported",
1126 "print-content-optimize",
1127 "print-content-optimize-default",
1128 "print-content-optimize-supported",
1129 "print-objects", /* IPP 3D */
1130 "print-objects-default", /* IPP 3D */
1131 "print-objects-supported", /* IPP 3D */
1132 "print-quality",
1133 "print-quality-default",
1134 "print-quality-supported",
1135 "print-rendering-intent",
1136 "print-rendering-intent-default",
1137 "print-rendering-intent-supported",
1138 "print-scaling", /* IPP Paid Printing */
1139 "print-scaling-default", /* IPP Paid Printing */
1140 "print-scaling-supported", /* IPP Paid Printing */
1141 "print-supports", /* IPP 3D */
1142 "print-supports-default", /* IPP 3D */
1143 "print-supports-supported", /* IPP 3D */
1144 "printer-resolution",
1145 "printer-resolution-default",
1146 "printer-resolution-supported",
1147 "separator-sheets",
1148 "separator-sheets-default",
1149 "separator-sheets-supported",
1150 "sheet-collate",
1151 "sheet-collate-default",
1152 "sheet-collate-supported",
1153 "sides",
1154 "sides-default",
1155 "sides-supported",
1156 "stitching-locations-supported",
1157 "stitching-offset-supported",
1158 "x-image-position",
1159 "x-image-position-default",
1160 "x-image-position-supported",
1161 "x-image-shift",
1162 "x-image-shift-default",
1163 "x-image-shift-supported",
1164 "x-side1-image-shift",
1165 "x-side1-image-shift-default",
1166 "x-side1-image-shift-supported",
1167 "x-side2-image-shift",
1168 "x-side2-image-shift-default",
1169 "x-side2-image-shift-supported",
1170 "y-image-position",
1171 "y-image-position-default",
1172 "y-image-position-supported",
1173 "y-image-shift",
1174 "y-image-shift-default",
1175 "y-image-shift-supported",
1176 "y-side1-image-shift",
1177 "y-side1-image-shift-default",
1178 "y-side1-image-shift-supported",
1179 "y-side2-image-shift",
1180 "y-side2-image-shift-default",
1181 "y-side2-image-shift-supported"
1182 };
1183 static const char * const job_description[] =
1184 { /* job-description group */
1185 "compression-supplied",
1186 "copies-actual",
1187 "cover-back-actual",
1188 "cover-front-actual",
1189 "current-page-order",
1190 "date-time-at-completed",
1191 "date-time-at-creation",
1192 "date-time-at-processing",
1193 "destination-statuses",
1194 "document-charset-supplied",
1195 "document-digital-signature-supplied",
1196 "document-format-details-supplied",
1197 "document-format-supplied",
1198 "document-message-supplied",
1199 "document-metadata",
1200 "document-name-supplied",
1201 "document-natural-language-supplied",
1202 "document-overrides-actual",
1203 "errors-count",
1204 "finishings-actual",
1205 "finishings-col-actual",
1206 "force-front-side-actual",
1207 "imposition-template-actual",
1208 "impressions-completed-current-copy",
1209 "insert-sheet-actual",
1210 "job-account-id-actual",
1211 "job-accounting-sheets-actual",
1212 "job-accounting-user-id-actual",
1213 "job-attribute-fidelity",
1214 "job-charge-info", /* CUPS extension */
1215 "job-collation-type",
1216 "job-collation-type-actual",
1217 "job-copies-actual",
1218 "job-cover-back-actual",
1219 "job-cover-front-actual",
1220 "job-detailed-status-message",
1221 "job-document-access-errors",
1222 "job-error-sheet-actual",
1223 "job-finishings-actual",
1224 "job-finishings-col-actual",
1225 "job-hold-until-actual",
1226 "job-id",
1227 "job-impressions",
1228 "job-impressions-col",
1229 "job-impressions-completed",
1230 "job-impressions-completed-col",
1231 "job-k-octets",
1232 "job-k-octets-processed",
1233 "job-mandatory-attributes",
1234 "job-media-progress", /* CUPS extension */
1235 "job-media-sheets",
1236 "job-media-sheets-col",
1237 "job-media-sheets-completed",
1238 "job-media-sheets-completed-col",
1239 "job-message-from-operator",
1240 "job-more-info",
1241 "job-name",
1242 "job-originating-host-name", /* CUPS extension */
1243 "job-originating-user-name",
1244 "job-originating-user-uri",
1245 "job-pages",
1246 "job-pages-col",
1247 "job-pages-completed",
1248 "job-pages-completed-col",
1249 "job-pages-completed-current-copy",
1250 "job-printer-state-message", /* CUPS extension */
1251 "job-printer-state-reasons", /* CUPS extension */
1252 "job-printer-up-time",
1253 "job-printer-uri",
1254 "job-priority-actual",
1255 "job-save-printer-make-and-model",
1256 "job-sheet-message-actual",
1257 "job-sheets-actual",
1258 "job-sheets-col-actual",
1259 "job-state",
1260 "job-state-message",
1261 "job-state-reasons",
1262 "job-uri",
1263 "job-uuid",
1264 "materials-col-actual", /* IPP 3D */
1265 "media-actual",
1266 "media-col-actual",
1267 "media-check-input-tray-actual",
1268 "multiple-document-handling-actual",
1269 "multiple-object-handling-actual", /* IPP 3D */
1270 "number-of-documents",
1271 "number-of-intervening-jobs",
1272 "number-up-actual",
1273 "orientation-requested-actual",
1274 "original-requesting-user-name",
1275 "output-bin-actual",
1276 "output-device-assigned",
1277 "overrides-actual",
1278 "page-delivery-actual",
1279 "page-order-received-actual",
1280 "page-ranges-actual",
1281 "platform-temperature-actual", /* IPP 3D */
1282 "presentation-direction-number-up-actual",
1283 "print-accuracy-actual", /* IPP 3D */
1284 "print-base-actual", /* IPP 3D */
1285 "print-color-mode-actual",
1286 "print-content-optimize-actual",
1287 "print-objects-actual", /* IPP 3D */
1288 "print-quality-actual",
1289 "print-rendering-intent-actual",
1290 "print-scaling-actual", /* IPP Paid Printing */
1291 "print-supports-actual", /* IPP 3D */
1292 "printer-resolution-actual",
1293 "separator-sheets-actual",
1294 "sheet-collate-actual",
1295 "sheet-completed-copy-number",
1296 "sheet-completed-document-number",
1297 "sides-actual",
1298 "time-at-completed",
1299 "time-at-creation",
1300 "time-at-processing",
1301 "warnings-count",
1302 "x-image-position-actual",
1303 "x-image-shift-actual",
1304 "x-side1-image-shift-actual",
1305 "x-side2-image-shift-actual",
1306 "y-image-position-actual",
1307 "y-image-shift-actual",
1308 "y-side1-image-shift-actual",
1309 "y-side2-image-shift-actual"
1310 };
1311 static const char * const job_template[] =
1312 { /* job-template group */
1313 "accuracy-units-supported", /* IPP 3D */
1314 "confirmation-sheet-print", /* IPP FaxOut */
1315 "confirmation-sheet-print-default",
1316 "copies",
1317 "copies-default",
1318 "copies-supported",
1319 "cover-back",
1320 "cover-back-default",
1321 "cover-back-supported",
1322 "cover-front",
1323 "cover-front-default",
1324 "cover-front-supported",
1325 "cover-sheet-info", /* IPP FaxOut */
1326 "cover-sheet-info-default",
1327 "cover-sheet-info-supported",
1328 "destination-uri-schemes-supported",/* IPP FaxOut */
1329 "destination-uris", /* IPP FaxOut */
1330 "destination-uris-supported",
1331 "feed-orientation",
1332 "feed-orientation-default",
1333 "feed-orientation-supported",
1334 "finishings",
1335 "finishings-col",
1336 "finishings-col-database",
1337 "finishings-col-default",
1338 "finishings-col-ready",
1339 "finishings-col-supported",
1340 "finishings-default",
1341 "finishings-ready",
1342 "finishings-supported",
1343 "font-name-requested",
1344 "font-name-requested-default",
1345 "font-name-requested-supported",
1346 "font-size-requested",
1347 "font-size-requested-default",
1348 "font-size-requested-supported",
1349 "force-front-side",
1350 "force-front-side-default",
1351 "force-front-side-supported",
1352 "imposition-template",
1353 "imposition-template-default",
1354 "imposition-template-supported",
1355 "insert-after-page-number-supported",
1356 "insert-count-supported",
1357 "insert-sheet",
1358 "insert-sheet-default",
1359 "insert-sheet-supported",
1360 "job-account-id",
1361 "job-account-id-default",
1362 "job-account-id-supported",
1363 "job-accounting-sheets"
1364 "job-accounting-sheets-default"
1365 "job-accounting-sheets-supported"
1366 "job-accounting-user-id",
1367 "job-accounting-user-id-default",
1368 "job-accounting-user-id-supported",
1369 "job-copies",
1370 "job-copies-default",
1371 "job-copies-supported",
1372 "job-cover-back",
1373 "job-cover-back-default",
1374 "job-cover-back-supported",
1375 "job-cover-front",
1376 "job-cover-front-default",
1377 "job-cover-front-supported",
1378 "job-delay-output-until",
1379 "job-delay-output-until-default",
1380 "job-delay-output-until-supported",
1381 "job-delay-output-until-time",
1382 "job-delay-output-until-time-default",
1383 "job-delay-output-until-time-supported",
1384 "job-error-action",
1385 "job-error-action-default",
1386 "job-error-action-supported",
1387 "job-error-sheet",
1388 "job-error-sheet-default",
1389 "job-error-sheet-supported",
1390 "job-finishings",
1391 "job-finishings-col",
1392 "job-finishings-col-default",
1393 "job-finishings-col-supported",
1394 "job-finishings-default",
1395 "job-finishings-supported",
1396 "job-hold-until",
1397 "job-hold-until-default",
1398 "job-hold-until-supported",
1399 "job-hold-until-time",
1400 "job-hold-until-time-default",
1401 "job-hold-until-time-supported",
1402 "job-message-to-operator",
1403 "job-message-to-operator-default",
1404 "job-message-to-operator-supported",
1405 "job-phone-number",
1406 "job-phone-number-default",
1407 "job-phone-number-supported",
1408 "job-priority",
1409 "job-priority-default",
1410 "job-priority-supported",
1411 "job-recipient-name",
1412 "job-recipient-name-default",
1413 "job-recipient-name-supported",
1414 "job-save-disposition",
1415 "job-save-disposition-default",
1416 "job-save-disposition-supported",
1417 "job-sheets",
1418 "job-sheets-col",
1419 "job-sheets-col-default",
1420 "job-sheets-col-supported",
1421 "job-sheets-default",
1422 "job-sheets-supported",
1423 "logo-uri-schemes-supported",
1424 "material-amount-units-supported", /* IPP 3D */
1425 "material-diameter-supported", /* IPP 3D */
1426 "material-purpose-supported", /* IPP 3D */
1427 "material-rate-supported", /* IPP 3D */
1428 "material-rate-units-supported", /* IPP 3D */
1429 "material-shell-thickness-supported",/* IPP 3D */
1430 "material-temperature-supported", /* IPP 3D */
1431 "material-type-supported", /* IPP 3D */
1432 "materials-col", /* IPP 3D */
1433 "materials-col-database", /* IPP 3D */
1434 "materials-col-default", /* IPP 3D */
1435 "materials-col-ready", /* IPP 3D */
1436 "materials-col-supported", /* IPP 3D */
1437 "max-materials-col-supported", /* IPP 3D */
1438 "max-save-info-supported",
1439 "max-stitching-locations-supported",
1440 "media",
1441 "media-back-coating-supported",
1442 "media-bottom-margin-supported",
1443 "media-col",
1444 "media-col-default",
1445 "media-col-ready",
1446 "media-col-supported",
1447 "media-color-supported",
1448 "media-default",
1449 "media-front-coating-supported",
1450 "media-grain-supported",
1451 "media-hole-count-supported",
1452 "media-info-supported",
1453 "media-input-tray-check",
1454 "media-input-tray-check-default",
1455 "media-input-tray-check-supported",
1456 "media-key-supported",
1457 "media-left-margin-supported",
1458 "media-order-count-supported",
1459 "media-pre-printed-supported",
1460 "media-ready",
1461 "media-recycled-supported",
1462 "media-right-margin-supported",
1463 "media-size-supported",
1464 "media-source-supported",
1465 "media-supported",
1466 "media-thickness-supported",
1467 "media-top-margin-supported",
1468 "media-type-supported",
1469 "media-weight-metric-supported",
1470 "multiple-document-handling",
1471 "multiple-document-handling-default",
1472 "multiple-document-handling-supported",
1473 "multiple-object-handling", /* IPP 3D */
1474 "multiple-object-handling-default", /* IPP 3D */
1475 "multiple-object-handling-supported",/* IPP 3D */
1476 "number-of-retries", /* IPP FaxOut */
1477 "number-of-retries-default",
1478 "number-of-retries-supported",
1479 "number-up",
1480 "number-up-default",
1481 "number-up-supported",
1482 "orientation-requested",
1483 "orientation-requested-default",
1484 "orientation-requested-supported",
1485 "output-bin",
1486 "output-bin-default",
1487 "output-bin-supported",
1488 "output-device",
1489 "output-device-default",
1490 "output-device-supported",
1491 "output-mode", /* CUPS extension */
1492 "output-mode-default", /* CUPS extension */
1493 "output-mode-supported", /* CUPS extension */
1494 "overrides",
1495 "overrides-supported",
1496 "page-delivery",
1497 "page-delivery-default",
1498 "page-delivery-supported",
1499 "page-order-received",
1500 "page-order-received-default",
1501 "page-order-received-supported",
1502 "page-ranges",
1503 "page-ranges-supported",
1504 "pages-per-subset",
1505 "pages-per-subset-supported",
1506 "pdl-init-file",
1507 "pdl-init-file-default",
1508 "pdl-init-file-entry-supported",
1509 "pdl-init-file-location-supported",
1510 "pdl-init-file-name-subdirectory-supported",
1511 "pdl-init-file-name-supported",
1512 "pdl-init-file-supported",
1513 "platform-temperature", /* IPP 3D */
1514 "platform-temperature-default", /* IPP 3D */
1515 "platform-temperature-supported", /* IPP 3D */
1516 "presentation-direction-number-up",
1517 "presentation-direction-number-up-default",
1518 "presentation-direction-number-up-supported",
1519 "print-accuracy", /* IPP 3D */
1520 "print-accuracy-default", /* IPP 3D */
1521 "print-accuracy-supported", /* IPP 3D */
1522 "print-base", /* IPP 3D */
1523 "print-base-default", /* IPP 3D */
1524 "print-base-supported", /* IPP 3D */
1525 "print-color-mode",
1526 "print-color-mode-default",
1527 "print-color-mode-supported",
1528 "print-content-optimize",
1529 "print-content-optimize-default",
1530 "print-content-optimize-supported",
1531 "print-objects", /* IPP 3D */
1532 "print-objects-default", /* IPP 3D */
1533 "print-objects-supported", /* IPP 3D */
1534 "print-quality",
1535 "print-quality-default",
1536 "print-quality-supported",
1537 "print-rendering-intent",
1538 "print-rendering-intent-default",
1539 "print-rendering-intent-supported",
1540 "print-scaling", /* IPP Paid Printing */
1541 "print-scaling-default", /* IPP Paid Printing */
1542 "print-scaling-supported", /* IPP Paid Printing */
1543 "print-supports", /* IPP 3D */
1544 "print-supports-default", /* IPP 3D */
1545 "print-supports-supported", /* IPP 3D */
1546 "printer-resolution",
1547 "printer-resolution-default",
1548 "printer-resolution-supported",
1549 "proof-print",
1550 "proof-print-default",
1551 "proof-print-supported",
1552 "retry-interval", /* IPP FaxOut */
1553 "retry-interval-default",
1554 "retry-interval-supported",
1555 "retry-timeout", /* IPP FaxOut */
1556 "retry-timeout-default",
1557 "retry-timeout-supported",
1558 "save-disposition-supported",
1559 "save-document-format-default",
1560 "save-document-format-supported",
1561 "save-location-default",
1562 "save-location-supported",
1563 "save-name-subdirectory-supported",
1564 "save-name-supported",
1565 "separator-sheets",
1566 "separator-sheets-default",
1567 "separator-sheets-supported",
1568 "sheet-collate",
1569 "sheet-collate-default",
1570 "sheet-collate-supported",
1571 "sides",
1572 "sides-default",
1573 "sides-supported",
1574 "stitching-locations-supported",
1575 "stitching-offset-supported",
1576 "x-image-position",
1577 "x-image-position-default",
1578 "x-image-position-supported",
1579 "x-image-shift",
1580 "x-image-shift-default",
1581 "x-image-shift-supported",
1582 "x-side1-image-shift",
1583 "x-side1-image-shift-default",
1584 "x-side1-image-shift-supported",
1585 "x-side2-image-shift",
1586 "x-side2-image-shift-default",
1587 "x-side2-image-shift-supported",
1588 "y-image-position",
1589 "y-image-position-default",
1590 "y-image-position-supported",
1591 "y-image-shift",
1592 "y-image-shift-default",
1593 "y-image-shift-supported",
1594 "y-side1-image-shift",
1595 "y-side1-image-shift-default",
1596 "y-side1-image-shift-supported",
1597 "y-side2-image-shift",
1598 "y-side2-image-shift-default",
1599 "y-side2-image-shift-supported"
1600 };
1601 static const char * const printer_description[] =
1602 { /* printer-description group */
1603 "auth-info-required", /* CUPS extension */
1604 "charset-configured",
1605 "charset-supported",
1606 "color-supported",
1607 "compression-supported",
1608 "device-service-count",
1609 "device-uri", /* CUPS extension */
1610 "device-uuid",
1611 "document-charset-default",
1612 "document-charset-supported",
1613 "document-creation-attributes-supported",
1614 "document-digital-signature-default",
1615 "document-digital-signature-supported",
1616 "document-format-default",
1617 "document-format-details-default",
1618 "document-format-details-supported",
1619 "document-format-supported",
1620 "document-format-varying-attributes",
1621 "document-format-version-default",
1622 "document-format-version-supported",
1623 "document-natural-language-default",
1624 "document-natural-language-supported",
1625 "document-password-supported",
1626 "document-privacy-attributes", /* IPP Privacy Attributes */
1627 "document-privacy-scope", /* IPP Privacy Attributes */
1628 "generated-natural-language-supported",
1629 "identify-actions-default",
1630 "identify-actions-supported",
1631 "input-source-supported",
1632 "ipp-features-supported",
1633 "ipp-versions-supported",
1634 "ippget-event-life",
1635 "job-authorization-uri-supported", /* CUPS extension */
1636 "job-constraints-supported",
1637 "job-creation-attributes-supported",
1638 "job-finishings-col-ready",
1639 "job-finishings-ready",
1640 "job-ids-supported",
1641 "job-impressions-supported",
1642 "job-k-limit", /* CUPS extension */
1643 "job-k-octets-supported",
1644 "job-media-sheets-supported",
1645 "job-page-limit", /* CUPS extension */
1646 "job-password-encryption-supported",
1647 "job-password-supported",
1648 "job-presets-supported", /* IPP Presets */
1649 "job-privacy-attributes", /* IPP Privacy Attributes */
1650 "job-privacy-scope", /* IPP Privacy Attributes */
1651 "job-quota-period", /* CUPS extension */
1652 "job-resolvers-supported",
1653 "job-settable-attributes-supported",
1654 "job-spooling-supported",
1655 "job-triggers-supported", /* IPP Presets */
1656 "jpeg-k-octets-supported", /* CUPS extension */
1657 "jpeg-x-dimension-supported", /* CUPS extension */
1658 "jpeg-y-dimension-supported", /* CUPS extension */
1659 "landscape-orientation-requested-preferred",
1660 /* CUPS extension */
1661 "marker-change-time", /* CUPS extension */
1662 "marker-colors", /* CUPS extension */
1663 "marker-high-levels", /* CUPS extension */
1664 "marker-levels", /* CUPS extension */
1665 "marker-low-levels", /* CUPS extension */
1666 "marker-message", /* CUPS extension */
1667 "marker-names", /* CUPS extension */
1668 "marker-types", /* CUPS extension */
1669 "member-names", /* CUPS extension */
1670 "member-uris", /* CUPS extension */
1671 "multiple-destination-uris-supported",/* IPP FaxOut */
1672 "multiple-document-jobs-supported",
1673 "multiple-operation-time-out",
1674 "multiple-operation-time-out-action",
1675 "natural-language-configured",
1676 "operations-supported",
1677 "pages-per-minute",
1678 "pages-per-minute-color",
1679 "pdf-k-octets-supported", /* CUPS extension */
1680 "pdf-features-supported", /* IPP 3D */
1681 "pdf-versions-supported", /* CUPS extension */
1682 "pdl-override-supported",
1683 "port-monitor", /* CUPS extension */
1684 "port-monitor-supported", /* CUPS extension */
1685 "preferred-attributes-supported",
1686 "printer-alert",
1687 "printer-alert-description",
1688 "printer-charge-info",
1689 "printer-charge-info-uri",
1690 "printer-commands", /* CUPS extension */
1691 "printer-config-change-date-time",
1692 "printer-config-change-time",
1693 "printer-current-time",
1694 "printer-detailed-status-messages",
1695 "printer-device-id",
1696 "printer-dns-sd-name", /* CUPS extension */
1697 "printer-driver-installer",
1698 "printer-fax-log-uri", /* IPP FaxOut */
1699 "printer-fax-modem-info", /* IPP FaxOut */
1700 "printer-fax-modem-name", /* IPP FaxOut */
1701 "printer-fax-modem-number", /* IPP FaxOut */
1702 "printer-firmware-name", /* PWG 5110.1 */
1703 "printer-firmware-patches", /* PWG 5110.1 */
1704 "printer-firmware-string-version", /* PWG 5110.1 */
1705 "printer-firmware-version", /* PWG 5110.1 */
1706 "printer-geo-location",
1707 "printer-get-attributes-supported",
1708 "printer-icc-profiles",
1709 "printer-icons",
1710 "printer-id", /* CUPS extension */
1711 "printer-info",
1712 "printer-input-tray", /* IPP JPS3 */
1713 "printer-is-accepting-jobs",
1714 "printer-is-shared", /* CUPS extension */
1715 "printer-is-temporary", /* CUPS extension */
1716 "printer-kind", /* IPP Paid Printing */
1717 "printer-location",
1718 "printer-make-and-model",
1719 "printer-mandatory-job-attributes",
1720 "printer-message-date-time",
1721 "printer-message-from-operator",
1722 "printer-message-time",
1723 "printer-more-info",
1724 "printer-more-info-manufacturer",
1725 "printer-name",
1726 "printer-native-formats",
1727 "printer-organization",
1728 "printer-organizational-unit",
1729 "printer-output-tray", /* IPP JPS3 */
1730 "printer-queue-id", /* CUPS extension */
1731 "printer-settable-attributes-supported",
1732 "printer-state",
1733 "printer-state-change-date-time",
1734 "printer-state-change-time",
1735 "printer-state-message",
1736 "printer-state-reasons",
1737 "printer-supply",
1738 "printer-supply-description",
1739 "printer-supply-info-uri",
1740 "printer-type", /* CUPS extension */
1741 "printer-up-time",
1742 "printer-uri-supported",
1743 "printer-uuid",
1744 "printer-xri-supported",
1745 "pwg-raster-document-resolution-supported",
1746 "pwg-raster-document-sheet-back",
1747 "pwg-raster-document-type-supported",
1748 "queued-job-count",
1749 "reference-uri-schemes-supported",
1750 "repertoire-supported",
1751 "requesting-user-name-allowed", /* CUPS extension */
1752 "requesting-user-name-denied", /* CUPS extension */
1753 "requesting-user-uri-supported",
1754 "subordinate-printers-supported",
1755 "subscription-privacy-attributes", /* IPP Privacy Attributes */
1756 "subscription-privacy-scope", /* IPP Privacy Attributes */
1757 "urf-supported", /* CUPS extension */
1758 "uri-authentication-supported",
1759 "uri-security-supported",
1760 "user-defined-value-supported",
1761 "which-jobs-supported",
1762 "xri-authentication-supported",
1763 "xri-security-supported",
1764 "xri-uri-scheme-supported"
1765 };
1766 static const char * const subscription_description[] =
1767 { /* subscription-description group */
1768 "notify-job-id",
1769 "notify-lease-expiration-time",
1770 "notify-printer-up-time",
1771 "notify-printer-uri",
1772 "notify-sequence-number",
1773 "notify-subscriber-user-name",
1774 "notify-subscriber-user-uri",
1775 "notify-subscription-id",
1776 "notify-subscription-uuid"
1777 };
1778 static const char * const subscription_template[] =
1779 { /* subscription-template group */
1780 "notify-attributes",
1781 "notify-attributes-supported",
1782 "notify-charset",
1783 "notify-events",
1784 "notify-events-default",
1785 "notify-events-supported",
1786 "notify-lease-duration",
1787 "notify-lease-duration-default",
1788 "notify-lease-duration-supported",
1789 "notify-max-events-supported",
1790 "notify-natural-language",
1791 "notify-pull-method",
1792 "notify-pull-method-supported",
1793 "notify-recipient-uri",
1794 "notify-schemes-supported",
1795 "notify-time-interval",
1796 "notify-user-data"
1797 };
1798
1799
1800 /*
1801 * Get the requested-attributes attribute...
1802 */
1803
1804 if ((requested = ippFindAttribute(request, "requested-attributes",
1805 IPP_TAG_KEYWORD)) == NULL)
1806 {
1807 /*
1808 * The Get-Jobs operation defaults to "job-id" and "job-uri", all others
1809 * default to "all"...
1810 */
1811
1812 if (ippGetOperation(request) == IPP_OP_GET_JOBS)
1813 {
1814 ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
1815 cupsArrayAdd(ra, "job-id");
1816 cupsArrayAdd(ra, "job-uri");
1817
1818 return (ra);
1819 }
1820 else
1821 return (NULL);
1822 }
1823
1824 /*
1825 * If the attribute contains a single "all" keyword, return NULL...
1826 */
1827
1828 count = ippGetCount(requested);
1829 if (count == 1 && !strcmp(ippGetString(requested, 0, NULL), "all"))
1830 return (NULL);
1831
1832 /*
1833 * Create an array using "strcmp" as the comparison function...
1834 */
1835
1836 ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
1837
1838 for (i = 0; i < count; i ++)
1839 {
1840 added = 0;
1841 value = ippGetString(requested, i, NULL);
1842
1843 if (!strcmp(value, "document-description") || !strcmp(value, "all"))
1844 {
1845 for (j = 0;
1846 j < (int)(sizeof(document_description) /
1847 sizeof(document_description[0]));
1848 j ++)
1849 cupsArrayAdd(ra, (void *)document_description[j]);
1850
1851 added = 1;
1852 }
1853
1854 if (!strcmp(value, "document-template") || !strcmp(value, "all"))
1855 {
1856 for (j = 0;
1857 j < (int)(sizeof(document_template) / sizeof(document_template[0]));
1858 j ++)
1859 cupsArrayAdd(ra, (void *)document_template[j]);
1860
1861 added = 1;
1862 }
1863
1864 if (!strcmp(value, "job-description") || !strcmp(value, "all"))
1865 {
1866 for (j = 0;
1867 j < (int)(sizeof(job_description) / sizeof(job_description[0]));
1868 j ++)
1869 cupsArrayAdd(ra, (void *)job_description[j]);
1870
1871 added = 1;
1872 }
1873
1874 if (!strcmp(value, "job-template") || !strcmp(value, "all"))
1875 {
1876 for (j = 0;
1877 j < (int)(sizeof(job_template) / sizeof(job_template[0]));
1878 j ++)
1879 cupsArrayAdd(ra, (void *)job_template[j]);
1880
1881 added = 1;
1882 }
1883
1884 if (!strcmp(value, "printer-description") || !strcmp(value, "all"))
1885 {
1886 for (j = 0;
1887 j < (int)(sizeof(printer_description) /
1888 sizeof(printer_description[0]));
1889 j ++)
1890 cupsArrayAdd(ra, (void *)printer_description[j]);
1891
1892 added = 1;
1893 }
1894
1895 if (!strcmp(value, "subscription-description") || !strcmp(value, "all"))
1896 {
1897 for (j = 0;
1898 j < (int)(sizeof(subscription_description) /
1899 sizeof(subscription_description[0]));
1900 j ++)
1901 cupsArrayAdd(ra, (void *)subscription_description[j]);
1902
1903 added = 1;
1904 }
1905
1906 if (!strcmp(value, "subscription-template") || !strcmp(value, "all"))
1907 {
1908 for (j = 0;
1909 j < (int)(sizeof(subscription_template) /
1910 sizeof(subscription_template[0]));
1911 j ++)
1912 cupsArrayAdd(ra, (void *)subscription_template[j]);
1913
1914 added = 1;
1915 }
1916
1917 if (!added)
1918 cupsArrayAdd(ra, (void *)value);
1919 }
1920
1921 return (ra);
1922 }
1923
1924
1925 /*
1926 * 'ippEnumString()' - Return a string corresponding to the enum value.
1927 */
1928
1929 const char * /* O - Enum string */
1930 ippEnumString(const char *attrname, /* I - Attribute name */
1931 int enumvalue) /* I - Enum value */
1932 {
1933 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
1934
1935
1936 /*
1937 * Check for standard enum values...
1938 */
1939
1940 if (!strcmp(attrname, "document-state") && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_document_states) / sizeof(ipp_document_states[0]))))
1941 return (ipp_document_states[enumvalue - 3]);
1942 else if (!strcmp(attrname, "finishings") || !strcmp(attrname, "finishings-actual") || !strcmp(attrname, "finishings-default") || !strcmp(attrname, "finishings-ready") || !strcmp(attrname, "finishings-supported") || !strcmp(attrname, "job-finishings") || !strcmp(attrname, "job-finishings-default") || !strcmp(attrname, "job-finishings-supported"))
1943 {
1944 if (enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_finishings) / sizeof(ipp_finishings[0]))))
1945 return (ipp_finishings[enumvalue - 3]);
1946 else if (enumvalue >= 0x40000000 && enumvalue <= (0x40000000 + (int)(sizeof(ipp_finishings_vendor) / sizeof(ipp_finishings_vendor[0]))))
1947 return (ipp_finishings_vendor[enumvalue - 0x40000000]);
1948 }
1949 else if ((!strcmp(attrname, "job-collation-type") || !strcmp(attrname, "job-collation-type-actual")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_job_collation_types) / sizeof(ipp_job_collation_types[0]))))
1950 return (ipp_job_collation_types[enumvalue - 3]);
1951 else if (!strcmp(attrname, "job-state") && enumvalue >= IPP_JSTATE_PENDING && enumvalue <= IPP_JSTATE_COMPLETED)
1952 return (ipp_job_states[enumvalue - IPP_JSTATE_PENDING]);
1953 else if (!strcmp(attrname, "operations-supported"))
1954 return (ippOpString((ipp_op_t)enumvalue));
1955 else if ((!strcmp(attrname, "orientation-requested") || !strcmp(attrname, "orientation-requested-actual") || !strcmp(attrname, "orientation-requested-default") || !strcmp(attrname, "orientation-requested-supported")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_orientation_requesteds) / sizeof(ipp_orientation_requesteds[0]))))
1956 return (ipp_orientation_requesteds[enumvalue - 3]);
1957 else if ((!strcmp(attrname, "print-quality") || !strcmp(attrname, "print-quality-actual") || !strcmp(attrname, "print-quality-default") || !strcmp(attrname, "print-quality-supported")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_print_qualities) / sizeof(ipp_print_qualities[0]))))
1958 return (ipp_print_qualities[enumvalue - 3]);
1959 else if (!strcmp(attrname, "printer-state") && enumvalue >= IPP_PSTATE_IDLE && enumvalue <= IPP_PSTATE_STOPPED)
1960 return (ipp_printer_states[enumvalue - IPP_PSTATE_IDLE]);
1961 else if (!strcmp(attrname, "resource-state") && enumvalue >= IPP_RSTATE_PENDING && enumvalue <= IPP_RSTATE_ABORTED)
1962 return (ipp_resource_states[enumvalue - IPP_RSTATE_PENDING]);
1963 else if (!strcmp(attrname, "system-state") && enumvalue >= IPP_SSTATE_IDLE && enumvalue <= IPP_SSTATE_STOPPED)
1964 return (ipp_system_states[enumvalue - IPP_SSTATE_IDLE]);
1965
1966 /*
1967 * Not a standard enum value, just return the decimal equivalent...
1968 */
1969
1970 snprintf(cg->ipp_unknown, sizeof(cg->ipp_unknown), "%d", enumvalue);
1971 return (cg->ipp_unknown);
1972 }
1973
1974
1975 /*
1976 * 'ippEnumValue()' - Return the value associated with a given enum string.
1977 */
1978
1979 int /* O - Enum value or -1 if unknown */
1980 ippEnumValue(const char *attrname, /* I - Attribute name */
1981 const char *enumstring) /* I - Enum string */
1982 {
1983 int i, /* Looping var */
1984 num_strings; /* Number of strings to compare */
1985 const char * const *strings; /* Strings to compare */
1986
1987
1988 /*
1989 * If the string is just a number, return it...
1990 */
1991
1992 if (isdigit(*enumstring & 255))
1993 return ((int)strtol(enumstring, NULL, 0));
1994
1995 /*
1996 * Otherwise look up the string...
1997 */
1998
1999 if (!strcmp(attrname, "document-state"))
2000 {
2001 num_strings = (int)(sizeof(ipp_document_states) / sizeof(ipp_document_states[0]));
2002 strings = ipp_document_states;
2003 }
2004 else if (!strcmp(attrname, "finishings") ||
2005 !strcmp(attrname, "finishings-actual") ||
2006 !strcmp(attrname, "finishings-default") ||
2007 !strcmp(attrname, "finishings-ready") ||
2008 !strcmp(attrname, "finishings-supported"))
2009 {
2010 for (i = 0;
2011 i < (int)(sizeof(ipp_finishings_vendor) /
2012 sizeof(ipp_finishings_vendor[0]));
2013 i ++)
2014 if (!strcmp(enumstring, ipp_finishings_vendor[i]))
2015 return (i + 0x40000000);
2016
2017 num_strings = (int)(sizeof(ipp_finishings) / sizeof(ipp_finishings[0]));
2018 strings = ipp_finishings;
2019 }
2020 else if (!strcmp(attrname, "job-collation-type") ||
2021 !strcmp(attrname, "job-collation-type-actual"))
2022 {
2023 num_strings = (int)(sizeof(ipp_job_collation_types) /
2024 sizeof(ipp_job_collation_types[0]));
2025 strings = ipp_job_collation_types;
2026 }
2027 else if (!strcmp(attrname, "job-state"))
2028 {
2029 num_strings = (int)(sizeof(ipp_job_states) / sizeof(ipp_job_states[0]));
2030 strings = ipp_job_states;
2031 }
2032 else if (!strcmp(attrname, "operations-supported"))
2033 return (ippOpValue(enumstring));
2034 else if (!strcmp(attrname, "orientation-requested") ||
2035 !strcmp(attrname, "orientation-requested-actual") ||
2036 !strcmp(attrname, "orientation-requested-default") ||
2037 !strcmp(attrname, "orientation-requested-supported"))
2038 {
2039 num_strings = (int)(sizeof(ipp_orientation_requesteds) /
2040 sizeof(ipp_orientation_requesteds[0]));
2041 strings = ipp_orientation_requesteds;
2042 }
2043 else if (!strcmp(attrname, "print-quality") ||
2044 !strcmp(attrname, "print-quality-actual") ||
2045 !strcmp(attrname, "print-quality-default") ||
2046 !strcmp(attrname, "print-quality-supported"))
2047 {
2048 num_strings = (int)(sizeof(ipp_print_qualities) / sizeof(ipp_print_qualities[0]));
2049 strings = ipp_print_qualities;
2050 }
2051 else if (!strcmp(attrname, "printer-state"))
2052 {
2053 num_strings = (int)(sizeof(ipp_printer_states) / sizeof(ipp_printer_states[0]));
2054 strings = ipp_printer_states;
2055 }
2056 else if (!strcmp(attrname, "resource-state"))
2057 {
2058 num_strings = (int)(sizeof(ipp_resource_states) / sizeof(ipp_resource_states[0]));
2059 strings = ipp_resource_states;
2060 }
2061 else if (!strcmp(attrname, "system-state"))
2062 {
2063 num_strings = (int)(sizeof(ipp_system_states) / sizeof(ipp_system_states[0]));
2064 strings = ipp_system_states;
2065 }
2066 else
2067 return (-1);
2068
2069 for (i = 0; i < num_strings; i ++)
2070 if (!strcmp(enumstring, strings[i]))
2071 return (i + 3);
2072
2073 return (-1);
2074 }
2075
2076
2077 /*
2078 * 'ippErrorString()' - Return a name for the given status code.
2079 */
2080
2081 const char * /* O - Text string */
2082 ippErrorString(ipp_status_t error) /* I - Error status */
2083 {
2084 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
2085
2086
2087 /*
2088 * See if the error code is a known value...
2089 */
2090
2091 if (error >= IPP_STATUS_OK && error <= IPP_STATUS_OK_EVENTS_COMPLETE)
2092 return (ipp_status_oks[error]);
2093 else if (error == IPP_STATUS_REDIRECTION_OTHER_SITE)
2094 return ("redirection-other-site");
2095 else if (error == IPP_STATUS_CUPS_SEE_OTHER)
2096 return ("cups-see-other");
2097 else if (error >= IPP_STATUS_ERROR_BAD_REQUEST &&
2098 error <= IPP_STATUS_ERROR_ACCOUNT_AUTHORIZATION_FAILED)
2099 return (ipp_status_400s[error - IPP_STATUS_ERROR_BAD_REQUEST]);
2100 else if (error >= 0x480 &&
2101 error <= IPP_STATUS_ERROR_CUPS_ACCOUNT_AUTHORIZATION_FAILED)
2102 return (ipp_status_480s[error - 0x0480]);
2103 else if (error >= IPP_STATUS_ERROR_INTERNAL &&
2104 error <= IPP_STATUS_ERROR_TOO_MANY_DOCUMENTS)
2105 return (ipp_status_500s[error - IPP_STATUS_ERROR_INTERNAL]);
2106 else if (error >= IPP_STATUS_ERROR_CUPS_AUTHENTICATION_CANCELED &&
2107 error <= IPP_STATUS_ERROR_CUPS_UPGRADE_REQUIRED)
2108 return (ipp_status_1000s[error -
2109 IPP_STATUS_ERROR_CUPS_AUTHENTICATION_CANCELED]);
2110
2111 /*
2112 * No, build an "0xxxxx" error string...
2113 */
2114
2115 sprintf(cg->ipp_unknown, "0x%04x", error);
2116
2117 return (cg->ipp_unknown);
2118 }
2119
2120
2121 /*
2122 * 'ippErrorValue()' - Return a status code for the given name.
2123 *
2124 * @since CUPS 1.2/macOS 10.5@
2125 */
2126
2127 ipp_status_t /* O - IPP status code */
2128 ippErrorValue(const char *name) /* I - Name */
2129 {
2130 size_t i; /* Looping var */
2131
2132
2133 for (i = 0; i < (sizeof(ipp_status_oks) / sizeof(ipp_status_oks[0])); i ++)
2134 if (!_cups_strcasecmp(name, ipp_status_oks[i]))
2135 return ((ipp_status_t)i);
2136
2137 if (!_cups_strcasecmp(name, "redirection-other-site"))
2138 return (IPP_STATUS_REDIRECTION_OTHER_SITE);
2139
2140 if (!_cups_strcasecmp(name, "cups-see-other"))
2141 return (IPP_STATUS_CUPS_SEE_OTHER);
2142
2143 for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++)
2144 if (!_cups_strcasecmp(name, ipp_status_400s[i]))
2145 return ((ipp_status_t)(i + 0x400));
2146
2147 for (i = 0; i < (sizeof(ipp_status_480s) / sizeof(ipp_status_480s[0])); i ++)
2148 if (!_cups_strcasecmp(name, ipp_status_480s[i]))
2149 return ((ipp_status_t)(i + 0x480));
2150
2151 for (i = 0; i < (sizeof(ipp_status_500s) / sizeof(ipp_status_500s[0])); i ++)
2152 if (!_cups_strcasecmp(name, ipp_status_500s[i]))
2153 return ((ipp_status_t)(i + 0x500));
2154
2155 for (i = 0; i < (sizeof(ipp_status_1000s) / sizeof(ipp_status_1000s[0])); i ++)
2156 if (!_cups_strcasecmp(name, ipp_status_1000s[i]))
2157 return ((ipp_status_t)(i + 0x1000));
2158
2159 return ((ipp_status_t)-1);
2160 }
2161
2162
2163 /*
2164 * 'ippOpString()' - Return a name for the given operation id.
2165 *
2166 * @since CUPS 1.2/macOS 10.5@
2167 */
2168
2169 const char * /* O - Name */
2170 ippOpString(ipp_op_t op) /* I - Operation ID */
2171 {
2172 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
2173
2174
2175 /*
2176 * See if the operation ID is a known value...
2177 */
2178
2179 if (op >= IPP_OP_PRINT_JOB && op < (ipp_op_t)(sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])))
2180 return (ipp_std_ops[op]);
2181 else if (op == IPP_OP_PRIVATE)
2182 return ("windows-ext");
2183 else if (op >= IPP_OP_CUPS_GET_DEFAULT && op <= IPP_OP_CUPS_GET_PPD)
2184 return (ipp_cups_ops[op - IPP_OP_CUPS_GET_DEFAULT]);
2185 else if (op >= IPP_OP_CUPS_GET_DOCUMENT && op <= IPP_OP_CUPS_CREATE_LOCAL_PRINTER)
2186 return (ipp_cups_ops2[op - IPP_OP_CUPS_GET_DOCUMENT]);
2187
2188 /*
2189 * No, build an "0xxxxx" operation string...
2190 */
2191
2192 sprintf(cg->ipp_unknown, "0x%04x", op);
2193
2194 return (cg->ipp_unknown);
2195 }
2196
2197
2198 /*
2199 * 'ippOpValue()' - Return an operation id for the given name.
2200 *
2201 * @since CUPS 1.2/macOS 10.5@
2202 */
2203
2204 ipp_op_t /* O - Operation ID */
2205 ippOpValue(const char *name) /* I - Textual name */
2206 {
2207 size_t i; /* Looping var */
2208
2209
2210 if (!strncmp(name, "0x", 2))
2211 return ((ipp_op_t)strtol(name + 2, NULL, 16));
2212
2213 for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++)
2214 if (!_cups_strcasecmp(name, ipp_std_ops[i]))
2215 return ((ipp_op_t)i);
2216
2217 if (!_cups_strcasecmp(name, "windows-ext"))
2218 return (IPP_OP_PRIVATE);
2219
2220 for (i = 0; i < (sizeof(ipp_cups_ops) / sizeof(ipp_cups_ops[0])); i ++)
2221 if (!_cups_strcasecmp(name, ipp_cups_ops[i]))
2222 return ((ipp_op_t)(i + 0x4001));
2223
2224 for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++)
2225 if (!_cups_strcasecmp(name, ipp_cups_ops2[i]))
2226 return ((ipp_op_t)(i + 0x4027));
2227
2228 if (!_cups_strcasecmp(name, "Create-Job-Subscription"))
2229 return (IPP_OP_CREATE_JOB_SUBSCRIPTIONS);
2230
2231 if (!_cups_strcasecmp(name, "Create-Printer-Subscription"))
2232 return (IPP_OP_CREATE_PRINTER_SUBSCRIPTIONS);
2233
2234 if (!_cups_strcasecmp(name, "CUPS-Add-Class"))
2235 return (IPP_OP_CUPS_ADD_MODIFY_CLASS);
2236
2237 if (!_cups_strcasecmp(name, "CUPS-Add-Printer"))
2238 return (IPP_OP_CUPS_ADD_MODIFY_PRINTER);
2239
2240 return (IPP_OP_CUPS_INVALID);
2241 }
2242
2243
2244 /*
2245 * 'ippPort()' - Return the default IPP port number.
2246 */
2247
2248 int /* O - Port number */
2249 ippPort(void)
2250 {
2251 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
2252
2253
2254 DEBUG_puts("ippPort()");
2255
2256 if (!cg->ipp_port)
2257 _cupsSetDefaults();
2258
2259 DEBUG_printf(("1ippPort: Returning %d...", cg->ipp_port));
2260
2261 return (cg->ipp_port);
2262 }
2263
2264
2265 /*
2266 * 'ippSetPort()' - Set the default port number.
2267 */
2268
2269 void
2270 ippSetPort(int p) /* I - Port number to use */
2271 {
2272 DEBUG_printf(("ippSetPort(p=%d)", p));
2273
2274 _cupsGlobals()->ipp_port = p;
2275 }
2276
2277
2278 /*
2279 * 'ippStateString()' - Return the name corresponding to a state value.
2280 *
2281 * @since CUPS 2.0/OS 10.10@
2282 */
2283
2284 const char * /* O - State name */
2285 ippStateString(ipp_state_t state) /* I - State value */
2286 {
2287 if (state >= IPP_STATE_ERROR && state <= IPP_STATE_DATA)
2288 return (ipp_states[state - IPP_STATE_ERROR]);
2289 else
2290 return ("UNKNOWN");
2291 }
2292
2293
2294 /*
2295 * 'ippTagString()' - Return the tag name corresponding to a tag value.
2296 *
2297 * The returned names are defined in RFC 8011 and the IANA IPP Registry.
2298 *
2299 * @since CUPS 1.4/macOS 10.6@
2300 */
2301
2302 const char * /* O - Tag name */
2303 ippTagString(ipp_tag_t tag) /* I - Tag value */
2304 {
2305 tag &= IPP_TAG_CUPS_MASK;
2306
2307 if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])))
2308 return (ipp_tag_names[tag]);
2309 else
2310 return ("UNKNOWN");
2311 }
2312
2313
2314 /*
2315 * 'ippTagValue()' - Return the tag value corresponding to a tag name.
2316 *
2317 * The tag names are defined in RFC 8011 and the IANA IPP Registry.
2318 *
2319 * @since CUPS 1.4/macOS 10.6@
2320 */
2321
2322 ipp_tag_t /* O - Tag value */
2323 ippTagValue(const char *name) /* I - Tag name */
2324 {
2325 size_t i; /* Looping var */
2326
2327
2328 for (i = 0; i < (sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])); i ++)
2329 if (!_cups_strcasecmp(name, ipp_tag_names[i]))
2330 return ((ipp_tag_t)i);
2331
2332 if (!_cups_strcasecmp(name, "operation"))
2333 return (IPP_TAG_OPERATION);
2334 else if (!_cups_strcasecmp(name, "job"))
2335 return (IPP_TAG_JOB);
2336 else if (!_cups_strcasecmp(name, "printer"))
2337 return (IPP_TAG_PRINTER);
2338 else if (!_cups_strcasecmp(name, "unsupported"))
2339 return (IPP_TAG_UNSUPPORTED_GROUP);
2340 else if (!_cups_strcasecmp(name, "subscription"))
2341 return (IPP_TAG_SUBSCRIPTION);
2342 else if (!_cups_strcasecmp(name, "event"))
2343 return (IPP_TAG_EVENT_NOTIFICATION);
2344 else if (!_cups_strcasecmp(name, "language"))
2345 return (IPP_TAG_LANGUAGE);
2346 else if (!_cups_strcasecmp(name, "mimetype"))
2347 return (IPP_TAG_MIMETYPE);
2348 else if (!_cups_strcasecmp(name, "name"))
2349 return (IPP_TAG_NAME);
2350 else if (!_cups_strcasecmp(name, "text"))
2351 return (IPP_TAG_TEXT);
2352 else if (!_cups_strcasecmp(name, "begCollection"))
2353 return (IPP_TAG_BEGIN_COLLECTION);
2354 else
2355 return (IPP_TAG_ZERO);
2356 }
2357
2358
2359 /*
2360 * 'ipp_col_string()' - Convert a collection to a string.
2361 */
2362
2363 static size_t /* O - Number of bytes */
2364 ipp_col_string(ipp_t *col, /* I - Collection attribute */
2365 char *buffer, /* I - Buffer or NULL */
2366 size_t bufsize) /* I - Size of buffer */
2367 {
2368 char *bufptr, /* Position in buffer */
2369 *bufend, /* End of buffer */
2370 prefix = '{', /* Prefix character */
2371 temp[256]; /* Temporary string */
2372 ipp_attribute_t *attr; /* Current member attribute */
2373
2374
2375 if (!col)
2376 {
2377 if (buffer)
2378 *buffer = '\0';
2379
2380 return (0);
2381 }
2382
2383 bufptr = buffer;
2384 bufend = buffer + bufsize - 1;
2385
2386 for (attr = col->attrs; attr; attr = attr->next)
2387 {
2388 if (!attr->name)
2389 continue;
2390
2391 if (buffer && bufptr < bufend)
2392 *bufptr = prefix;
2393 bufptr ++;
2394 prefix = ' ';
2395
2396 if (buffer && bufptr < bufend)
2397 bufptr += snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%s=", attr->name);
2398 else
2399 bufptr += strlen(attr->name) + 1;
2400
2401 if (buffer && bufptr < bufend)
2402 bufptr += ippAttributeString(attr, bufptr, (size_t)(bufend - bufptr + 1));
2403 else
2404 bufptr += ippAttributeString(attr, temp, sizeof(temp));
2405 }
2406
2407 if (prefix == '{')
2408 {
2409 if (buffer && bufptr < bufend)
2410 *bufptr = prefix;
2411 bufptr ++;
2412 }
2413
2414 if (buffer && bufptr < bufend)
2415 *bufptr = '}';
2416 bufptr ++;
2417
2418 return ((size_t)(bufptr - buffer));
2419 }