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