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