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