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