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