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