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