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