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