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