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