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