]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
1106b00e | 2 | * "$Id: ipp-support.c 9371 2010-11-17 06:21:32Z mike $" |
ef416fc2 | 3 | * |
71e16022 | 4 | * Internet Printing Protocol support functions for CUPS. |
ef416fc2 | 5 | * |
88f9aafc | 6 | * Copyright 2007-2011 by Apple Inc. |
b94498cf | 7 | * Copyright 1997-2007 by Easy Software Products, all rights reserved. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * which should have been included with this file. If this file is | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
ef416fc2 | 14 | * |
15 | * This file is subject to the Apple OS-Developed Software exception. | |
16 | * | |
17 | * Contents: | |
18 | * | |
aaf19ab0 | 19 | * _ippAttrString() - Convert the attribute's value to a string. |
ef416fc2 | 20 | * ippErrorString() - Return a name for the given status code. |
21 | * ippErrorValue() - Return a status code for the given name. | |
22 | * ippOpString() - Return a name for the given operation id. | |
23 | * ippOpValue() - Return an operation id for the given name. | |
24 | * ippPort() - Return the default IPP port number. | |
25 | * ippSetPort() - Set the default port number. | |
ed6e7faf MS |
26 | * ippTagString() - Return the tag name corresponding to a tag value. |
27 | * ippTagValue() - Return the tag value corresponding to a tag name. | |
aaf19ab0 | 28 | * ipp_col_string() - Convert a collection to a string. |
ef416fc2 | 29 | */ |
30 | ||
31 | /* | |
32 | * Include necessary headers... | |
33 | */ | |
34 | ||
71e16022 | 35 | #include "cups-private.h" |
ef416fc2 | 36 | |
37 | ||
38 | /* | |
39 | * Local globals... | |
40 | */ | |
41 | ||
42 | static const char * const ipp_status_oks[] = /* "OK" status codes */ | |
43 | { | |
44 | "successful-ok", | |
45 | "successful-ok-ignored-or-substituted-attributes", | |
46 | "successful-ok-conflicting-attributes", | |
47 | "successful-ok-ignored-subscriptions", | |
48 | "successful-ok-ignored-notifications", | |
49 | "successful-ok-too-many-events", | |
bd7854cb | 50 | "successful-ok-but-cancel-subscription", |
51 | "successful-ok-events-complete" | |
ef416fc2 | 52 | }, |
53 | * const ipp_status_400s[] = /* Client errors */ | |
54 | { | |
55 | "client-error-bad-request", | |
56 | "client-error-forbidden", | |
57 | "client-error-not-authenticated", | |
58 | "client-error-not-authorized", | |
59 | "client-error-not-possible", | |
60 | "client-error-timeout", | |
61 | "client-error-not-found", | |
62 | "client-error-gone", | |
63 | "client-error-request-entity-too-large", | |
64 | "client-error-request-value-too-long", | |
65 | "client-error-document-format-not-supported", | |
66 | "client-error-attributes-or-values-not-supported", | |
67 | "client-error-uri-scheme-not-supported", | |
68 | "client-error-charset-not-supported", | |
69 | "client-error-conflicting-attributes", | |
70 | "client-error-compression-not-supported", | |
71 | "client-error-compression-error", | |
72 | "client-error-document-format-error", | |
73 | "client-error-document-access-error", | |
74 | "client-error-attributes-not-settable", | |
75 | "client-error-ignored-all-subscriptions", | |
76 | "client-error-too-many-subscriptions", | |
77 | "client-error-ignored-all-notifications", | |
78 | "client-error-print-support-file-not-found" | |
79 | }, | |
80 | * const ipp_status_500s[] = /* Server errors */ | |
81 | { | |
82 | "server-error-internal-error", | |
83 | "server-error-operation-not-supported", | |
84 | "server-error-service-unavailable", | |
85 | "server-error-version-not-supported", | |
86 | "server-error-device-error", | |
87 | "server-error-temporary-error", | |
88 | "server-error-not-accepting-jobs", | |
89 | "server-error-busy", | |
90 | "server-error-job-canceled", | |
91 | "server-error-multiple-document-jobs-not-supported", | |
92 | "server-error-printer-is-deactivated" | |
7cf5915e MS |
93 | }, |
94 | * const ipp_status_1000s[] = /* CUPS internal */ | |
95 | { | |
96 | "cups-authorization-canceled", | |
97 | "cups-pki-error", | |
98 | "cups-upgrade-required" | |
ef416fc2 | 99 | }; |
100 | static char * const ipp_std_ops[] = | |
101 | { | |
102 | /* 0x0000 - 0x000f */ | |
aaf19ab0 MS |
103 | "unknown-00", |
104 | "unknown-01", | |
105 | "Print-Job", | |
106 | "Print-URI", | |
107 | "Validate-Job", | |
108 | "Create-Job", | |
109 | "Send-Document", | |
110 | "Send-URI", | |
111 | "Cancel-Job", | |
112 | "Get-Job-Attributes", | |
113 | "Get-Jobs", | |
114 | "Get-Printer-Attributes", | |
115 | "Hold-Job", | |
116 | "Release-Job", | |
117 | "Restart-Job", | |
118 | "unknown-0f", | |
ef416fc2 | 119 | |
120 | /* 0x0010 - 0x001f */ | |
aaf19ab0 MS |
121 | "Pause-Printer", |
122 | "Resume-Printer", | |
123 | "Purge-Jobs", | |
124 | "Set-Printer-Attributes", | |
ef416fc2 | 125 | "Set-Job-Attributes", |
126 | "Get-Printer-Supported-Values", | |
127 | "Create-Printer-Subscription", | |
128 | "Create-Job-Subscription", | |
129 | "Get-Subscription-Attributes", | |
aaf19ab0 MS |
130 | "Get-Subscriptions", |
131 | "Renew-Subscription", | |
132 | "Cancel-Subscription", | |
133 | "Get-Notifications", | |
134 | "Send-Notifications", | |
135 | "unknown-1e", | |
136 | "unknown-1f", | |
ef416fc2 | 137 | |
138 | /* 0x0020 - 0x002f */ | |
aaf19ab0 | 139 | "unknown-20", |
ef416fc2 | 140 | "Get-Printer-Support-Files", |
141 | "Enable-Printer", | |
142 | "Disable-Printer", | |
143 | "Pause-Printer-After-Current-Job", | |
144 | "Hold-New-Jobs", | |
145 | "Release-Held-New-Jobs", | |
146 | "Deactivate-Printer", | |
147 | "Activate-Printer", | |
148 | "Restart-Printer", | |
149 | "Shutdown-Printer", | |
150 | "Startup-Printer", | |
151 | "Reprocess-Job", | |
152 | "Cancel-Current-Job", | |
153 | "Suspend-Current-Job", | |
154 | "Resume-Job", | |
155 | ||
aaf19ab0 | 156 | /* 0x0030 - 0x003b */ |
ef416fc2 | 157 | "Promote-Job", |
aaf19ab0 MS |
158 | "Schedule-Job-After", |
159 | "unknown-32", | |
160 | "Cancel-Document", | |
161 | "Get-Document-Attributes", | |
162 | "Get-Documents", | |
163 | "Delete-Document", | |
164 | "Set-Document-Attributes", | |
165 | "Cancel-Jobs", | |
166 | "Cancel-My-Jobs", | |
167 | "Resubmit-Job", | |
771bd8cb MS |
168 | "Close-Job", |
169 | "Identify-Printer" | |
ef416fc2 | 170 | }, |
171 | * const ipp_cups_ops[] = | |
172 | { | |
173 | "CUPS-Get-Default", | |
174 | "CUPS-Get-Printers", | |
480ef0fe | 175 | "CUPS-Add-Modify-Printer", |
ef416fc2 | 176 | "CUPS-Delete-Printer", |
177 | "CUPS-Get-Classes", | |
480ef0fe | 178 | "CUPS-Add-Modify-Class", |
ef416fc2 | 179 | "CUPS-Delete-Class", |
180 | "CUPS-Accept-Jobs", | |
181 | "CUPS-Reject-Jobs", | |
182 | "CUPS-Set-Default", | |
183 | "CUPS-Get-Devices", | |
184 | "CUPS-Get-PPDs", | |
185 | "CUPS-Move-Job", | |
b94498cf | 186 | "CUPS-Authenticate-Job", |
187 | "CUPS-Get-PPD" | |
2e4ff8af MS |
188 | }, |
189 | * const ipp_cups_ops2[] = | |
190 | { | |
191 | "CUPS-Get-Document" | |
1ff0402e MS |
192 | }, |
193 | * const ipp_tag_names[] = | |
194 | { /* Value/group tag names */ | |
195 | "zero", /* 0x00 */ | |
196 | "operation-attributes-tag", | |
197 | /* 0x01 */ | |
198 | "job-attributes-tag", /* 0x02 */ | |
199 | "end-of-attributes-tag", | |
200 | /* 0x03 */ | |
201 | "printer-attributes-tag", | |
202 | /* 0x04 */ | |
203 | "unsupported-attributes-tag", | |
204 | /* 0x05 */ | |
205 | "subscription-attributes-tag", | |
206 | /* 0x06 */ | |
207 | "event-notification-attributes-tag", | |
208 | /* 0x07 */ | |
209 | "unknown-08", /* 0x08 */ | |
210 | "unknown-09", /* 0x09 */ | |
211 | "unknown-0a", /* 0x0a */ | |
212 | "unknown-0b", /* 0x0b */ | |
213 | "unknown-0c", /* 0x0c */ | |
214 | "unknown-0d", /* 0x0d */ | |
215 | "unknown-0e", /* 0x0e */ | |
216 | "unknown-0f", /* 0x0f */ | |
217 | "unsupported", /* 0x10 */ | |
218 | "default", /* 0x11 */ | |
219 | "unknown", /* 0x12 */ | |
220 | "no-value", /* 0x13 */ | |
221 | "unknown-14", /* 0x14 */ | |
222 | "not-settable", /* 0x15 */ | |
223 | "delete-attribute", /* 0x16 */ | |
224 | "admin-define", /* 0x17 */ | |
225 | "unknown-18", /* 0x18 */ | |
226 | "unknown-19", /* 0x19 */ | |
227 | "unknown-1a", /* 0x1a */ | |
228 | "unknown-1b", /* 0x1b */ | |
229 | "unknown-1c", /* 0x1c */ | |
230 | "unknown-1d", /* 0x1d */ | |
231 | "unknown-1e", /* 0x1e */ | |
232 | "unknown-1f", /* 0x1f */ | |
233 | "unknown-20", /* 0x20 */ | |
234 | "integer", /* 0x21 */ | |
235 | "boolean", /* 0x22 */ | |
236 | "enum", /* 0x23 */ | |
237 | "unknown-24", /* 0x24 */ | |
238 | "unknown-25", /* 0x25 */ | |
239 | "unknown-26", /* 0x26 */ | |
240 | "unknown-27", /* 0x27 */ | |
241 | "unknown-28", /* 0x28 */ | |
242 | "unknown-29", /* 0x29 */ | |
243 | "unknown-2a", /* 0x2a */ | |
244 | "unknown-2b", /* 0x2b */ | |
245 | "unknown-2c", /* 0x2c */ | |
246 | "unknown-2d", /* 0x2d */ | |
247 | "unknown-2e", /* 0x2e */ | |
248 | "unknown-2f", /* 0x2f */ | |
249 | "octetString", /* 0x30 */ | |
250 | "dateTime", /* 0x31 */ | |
251 | "resolution", /* 0x32 */ | |
252 | "rangeOfInteger", /* 0x33 */ | |
f8b3a85b | 253 | "collection", /* 0x34 */ |
1ff0402e MS |
254 | "textWithLanguage", /* 0x35 */ |
255 | "nameWithLanguage", /* 0x36 */ | |
256 | "endCollection", /* 0x37 */ | |
257 | "unknown-38", /* 0x38 */ | |
258 | "unknown-39", /* 0x39 */ | |
259 | "unknown-3a", /* 0x3a */ | |
260 | "unknown-3b", /* 0x3b */ | |
261 | "unknown-3c", /* 0x3c */ | |
262 | "unknown-3d", /* 0x3d */ | |
263 | "unknown-3e", /* 0x3e */ | |
264 | "unknown-3f", /* 0x3f */ | |
265 | "unknown-40", /* 0x40 */ | |
266 | "textWithoutLanguage",/* 0x41 */ | |
267 | "nameWithoutLanguage",/* 0x42 */ | |
268 | "unknown-43", /* 0x43 */ | |
269 | "keyword", /* 0x44 */ | |
270 | "uri", /* 0x45 */ | |
271 | "uriScheme", /* 0x46 */ | |
272 | "charset", /* 0x47 */ | |
273 | "naturalLanguage", /* 0x48 */ | |
274 | "mimeMediaType", /* 0x49 */ | |
275 | "memberAttrName" /* 0x4a */ | |
ef416fc2 | 276 | }; |
aaf19ab0 MS |
277 | static const char * const job_states[] = |
278 | { /* job-state enums */ | |
279 | "pending", | |
280 | "pending-held", | |
281 | "processing", | |
39ff2fe7 | 282 | "processing-stopped", |
aaf19ab0 MS |
283 | "canceled", |
284 | "aborted", | |
285 | "completed" | |
286 | }; | |
287 | static const char * const printer_states[] = | |
288 | { /* printer-state enums */ | |
289 | "idle", | |
290 | "processing", | |
291 | "stopped", | |
292 | }; | |
293 | ||
294 | ||
295 | /* | |
296 | * Local functions... | |
297 | */ | |
298 | ||
299 | static size_t ipp_col_string(ipp_t *col, char *buffer, size_t bufsize); | |
300 | ||
301 | ||
302 | /* | |
303 | * '_ippAttrString()' - Convert the attribute's value to a string. | |
304 | * | |
305 | * Returns the number of bytes that would be written, not including the | |
306 | * trailing nul. The buffer pointer can be NULL to get the required length, | |
307 | * just like (v)snprintf. | |
308 | */ | |
309 | ||
310 | size_t /* O - Number of bytes less nul */ | |
311 | _ippAttrString(ipp_attribute_t *attr, /* I - Attribute */ | |
312 | char *buffer, /* I - String buffer or NULL */ | |
313 | size_t bufsize) /* I - Size of string buffer */ | |
314 | { | |
315 | int i; /* Looping var */ | |
316 | char *bufptr, /* Pointer into buffer */ | |
317 | *bufend, /* End of buffer */ | |
318 | temp[256]; /* Temporary string */ | |
319 | const char *ptr; /* Pointer into string */ | |
320 | ipp_value_t *val; /* Current value */ | |
321 | ||
322 | ||
323 | if (!attr || !attr->name) | |
324 | { | |
325 | if (buffer) | |
326 | *buffer = '\0'; | |
327 | ||
328 | return (0); | |
329 | } | |
330 | ||
331 | bufptr = buffer; | |
332 | if (buffer) | |
333 | bufend = buffer + bufsize - 1; | |
334 | else | |
335 | bufend = NULL; | |
336 | ||
337 | for (i = attr->num_values, val = attr->values; i > 0; i --, val ++) | |
338 | { | |
339 | if (val > attr->values) | |
340 | { | |
7cf5915e | 341 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
342 | *bufptr++ = ','; |
343 | else | |
344 | bufptr ++; | |
345 | } | |
346 | ||
1106b00e | 347 | switch (attr->value_tag & ~IPP_TAG_COPY) |
aaf19ab0 MS |
348 | { |
349 | case IPP_TAG_ENUM : | |
350 | if (!strcmp(attr->name, "printer-state") && | |
351 | val->integer >= IPP_PRINTER_IDLE && | |
352 | val->integer <= IPP_PRINTER_STOPPED) | |
353 | { | |
354 | ptr = printer_states[val->integer - IPP_PRINTER_IDLE]; | |
355 | ||
7cf5915e | 356 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
357 | strlcpy(bufptr, ptr, bufend - bufptr + 1); |
358 | ||
359 | bufptr += strlen(ptr); | |
360 | break; | |
361 | } | |
362 | else if (!strcmp(attr->name, "job-state") && | |
363 | val->integer >= IPP_JOB_PENDING && | |
364 | val->integer <= IPP_JOB_COMPLETED) | |
365 | { | |
366 | ptr = job_states[val->integer - IPP_JOB_PENDING]; | |
367 | ||
7cf5915e | 368 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
369 | strlcpy(bufptr, ptr, bufend - bufptr + 1); |
370 | ||
371 | bufptr += strlen(ptr); | |
372 | break; | |
373 | } | |
374 | ||
375 | case IPP_TAG_INTEGER : | |
7cf5915e | 376 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
377 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d", val->integer); |
378 | else | |
379 | bufptr += snprintf(temp, sizeof(temp), "%d", val->integer); | |
380 | break; | |
381 | ||
382 | case IPP_TAG_BOOLEAN : | |
7cf5915e | 383 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
384 | strlcpy(bufptr, val->boolean ? "true" : "false", |
385 | bufend - bufptr + 1); | |
386 | ||
387 | bufptr += val->boolean ? 4 : 5; | |
388 | break; | |
389 | ||
390 | case IPP_TAG_RANGE : | |
7cf5915e | 391 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
392 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d-%d", |
393 | val->range.lower, val->range.upper); | |
394 | else | |
395 | bufptr += snprintf(temp, sizeof(temp), "%d-%d", val->range.lower, | |
396 | val->range.upper); | |
397 | break; | |
398 | ||
399 | case IPP_TAG_RESOLUTION : | |
7cf5915e | 400 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
401 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%dx%d%s", |
402 | val->resolution.xres, val->resolution.yres, | |
403 | val->resolution.units == IPP_RES_PER_INCH ? | |
404 | "dpi" : "dpc"); | |
405 | else | |
406 | bufptr += snprintf(temp, sizeof(temp), "%dx%d%s", | |
407 | val->resolution.xres, val->resolution.yres, | |
408 | val->resolution.units == IPP_RES_PER_INCH ? | |
409 | "dpi" : "dpc"); | |
410 | break; | |
411 | ||
412 | case IPP_TAG_DATE : | |
413 | { | |
414 | unsigned year; /* Year */ | |
415 | ||
416 | year = (val->date[0] << 8) + val->date[1]; | |
417 | ||
418 | if (val->date[9] == 0 && val->date[10] == 0) | |
419 | snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ", | |
420 | year, val->date[2], val->date[3], val->date[4], | |
421 | val->date[5], val->date[6]); | |
422 | else | |
423 | snprintf(temp, sizeof(temp), | |
424 | "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u", | |
425 | year, val->date[2], val->date[3], val->date[4], | |
426 | val->date[5], val->date[6], val->date[8], val->date[9], | |
427 | val->date[10]); | |
428 | ||
7cf5915e | 429 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
430 | strlcpy(bufptr, temp, bufend - bufptr + 1); |
431 | ||
432 | bufptr += strlen(temp); | |
433 | } | |
434 | break; | |
435 | ||
436 | case IPP_TAG_TEXT : | |
437 | case IPP_TAG_NAME : | |
438 | case IPP_TAG_KEYWORD : | |
439 | case IPP_TAG_CHARSET : | |
440 | case IPP_TAG_URI : | |
441 | case IPP_TAG_MIMETYPE : | |
442 | case IPP_TAG_LANGUAGE : | |
443 | case IPP_TAG_TEXTLANG : | |
444 | case IPP_TAG_NAMELANG : | |
7cf5915e MS |
445 | if (!val->string.text) |
446 | break; | |
447 | ||
aaf19ab0 MS |
448 | for (ptr = val->string.text; *ptr; ptr ++) |
449 | { | |
450 | if (*ptr == '\\' || *ptr == '\"') | |
451 | { | |
7cf5915e | 452 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
453 | *bufptr = '\\'; |
454 | bufptr ++; | |
455 | } | |
456 | ||
7cf5915e | 457 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
458 | *bufptr = *ptr; |
459 | bufptr ++; | |
460 | } | |
461 | break; | |
462 | ||
463 | case IPP_TAG_BEGIN_COLLECTION : | |
7cf5915e | 464 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
465 | bufptr += ipp_col_string(val->collection, bufptr, |
466 | bufend - bufptr + 1); | |
467 | else | |
468 | bufptr += ipp_col_string(val->collection, NULL, 0); | |
469 | break; | |
470 | ||
471 | case IPP_TAG_STRING : | |
472 | for (ptr = val->string.text; *ptr; ptr ++) | |
473 | { | |
7cf5915e | 474 | if (*ptr == '\\' || _cups_isspace(*ptr)) |
aaf19ab0 | 475 | { |
7cf5915e | 476 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
477 | *bufptr = '\\'; |
478 | bufptr ++; | |
479 | ||
7cf5915e | 480 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
481 | *bufptr = *ptr; |
482 | bufptr ++; | |
483 | } | |
484 | else if (!isprint(*ptr & 255)) | |
485 | { | |
7cf5915e | 486 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
487 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "\\%03o", |
488 | *ptr & 255); | |
489 | else | |
490 | bufptr += snprintf(temp, sizeof(temp), "\\%03o", | |
491 | *ptr & 255); | |
492 | } | |
493 | else | |
494 | { | |
7cf5915e | 495 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
496 | *bufptr = *ptr; |
497 | bufptr ++; | |
498 | } | |
499 | } | |
500 | break; | |
501 | ||
502 | default : | |
503 | ptr = ippTagString(attr->value_tag); | |
7cf5915e | 504 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
505 | strlcpy(bufptr, ptr, bufend - bufptr + 1); |
506 | bufptr += strlen(ptr); | |
507 | break; | |
508 | } | |
509 | } | |
510 | ||
7cf5915e | 511 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
512 | *bufptr = '\0'; |
513 | else if (bufend) | |
514 | *bufend = '\0'; | |
515 | ||
516 | return (bufptr - buffer); | |
517 | } | |
ef416fc2 | 518 | |
519 | ||
520 | /* | |
521 | * 'ippErrorString()' - Return a name for the given status code. | |
522 | */ | |
523 | ||
524 | const char * /* O - Text string */ | |
525 | ippErrorString(ipp_status_t error) /* I - Error status */ | |
526 | { | |
527 | _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ | |
528 | ||
529 | ||
530 | /* | |
531 | * See if the error code is a known value... | |
532 | */ | |
533 | ||
bd7854cb | 534 | if (error >= IPP_OK && error <= IPP_OK_EVENTS_COMPLETE) |
ef416fc2 | 535 | return (ipp_status_oks[error]); |
536 | else if (error == IPP_REDIRECTION_OTHER_SITE) | |
537 | return ("redirection-other-site"); | |
b94498cf | 538 | else if (error == CUPS_SEE_OTHER) |
539 | return ("cups-see-other"); | |
ef416fc2 | 540 | else if (error >= IPP_BAD_REQUEST && error <= IPP_PRINT_SUPPORT_FILE_NOT_FOUND) |
541 | return (ipp_status_400s[error - IPP_BAD_REQUEST]); | |
542 | else if (error >= IPP_INTERNAL_ERROR && error <= IPP_PRINTER_IS_DEACTIVATED) | |
543 | return (ipp_status_500s[error - IPP_INTERNAL_ERROR]); | |
6c48a6ca MS |
544 | else if (error >= IPP_AUTHENTICATION_CANCELED && error <= IPP_UPGRADE_REQUIRED) |
545 | return (ipp_status_1000s[error - IPP_AUTHENTICATION_CANCELED]); | |
ef416fc2 | 546 | |
547 | /* | |
548 | * No, build an "unknown-xxxx" error string... | |
549 | */ | |
550 | ||
551 | sprintf(cg->ipp_unknown, "unknown-%04x", error); | |
552 | ||
553 | return (cg->ipp_unknown); | |
554 | } | |
555 | ||
556 | ||
557 | /* | |
558 | * 'ippErrorValue()' - Return a status code for the given name. | |
559 | * | |
426c6a59 | 560 | * @since CUPS 1.2/Mac OS X 10.5@ |
ef416fc2 | 561 | */ |
562 | ||
563 | ipp_status_t /* O - IPP status code */ | |
564 | ippErrorValue(const char *name) /* I - Name */ | |
565 | { | |
566 | int i; | |
567 | ||
568 | ||
569 | for (i = 0; i < (sizeof(ipp_status_oks) / sizeof(ipp_status_oks[0])); i ++) | |
88f9aafc | 570 | if (!_cups_strcasecmp(name, ipp_status_oks[i])) |
ef416fc2 | 571 | return ((ipp_status_t)i); |
572 | ||
88f9aafc | 573 | if (!_cups_strcasecmp(name, "redirection-other-site")) |
ef416fc2 | 574 | return (IPP_REDIRECTION_OTHER_SITE); |
575 | ||
88f9aafc | 576 | if (!_cups_strcasecmp(name, "cups-see-other")) |
b94498cf | 577 | return (CUPS_SEE_OTHER); |
578 | ||
ef416fc2 | 579 | for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++) |
88f9aafc | 580 | if (!_cups_strcasecmp(name, ipp_status_400s[i])) |
ef416fc2 | 581 | return ((ipp_status_t)(i + 0x400)); |
582 | ||
583 | for (i = 0; i < (sizeof(ipp_status_500s) / sizeof(ipp_status_500s[0])); i ++) | |
88f9aafc | 584 | if (!_cups_strcasecmp(name, ipp_status_500s[i])) |
ef416fc2 | 585 | return ((ipp_status_t)(i + 0x500)); |
586 | ||
7cf5915e | 587 | for (i = 0; i < (sizeof(ipp_status_1000s) / sizeof(ipp_status_1000s[0])); i ++) |
88f9aafc | 588 | if (!_cups_strcasecmp(name, ipp_status_1000s[i])) |
7cf5915e MS |
589 | return ((ipp_status_t)(i + 0x1000)); |
590 | ||
ef416fc2 | 591 | return ((ipp_status_t)-1); |
592 | } | |
593 | ||
594 | ||
595 | /* | |
596 | * 'ippOpString()' - Return a name for the given operation id. | |
597 | * | |
426c6a59 | 598 | * @since CUPS 1.2/Mac OS X 10.5@ |
ef416fc2 | 599 | */ |
600 | ||
601 | const char * /* O - Name */ | |
602 | ippOpString(ipp_op_t op) /* I - Operation ID */ | |
603 | { | |
604 | _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ | |
605 | ||
606 | ||
607 | /* | |
608 | * See if the operation ID is a known value... | |
609 | */ | |
610 | ||
aaf19ab0 | 611 | if (op >= IPP_PRINT_JOB && op <= IPP_CLOSE_JOB) |
ef416fc2 | 612 | return (ipp_std_ops[op]); |
613 | else if (op == IPP_PRIVATE) | |
614 | return ("windows-ext"); | |
b94498cf | 615 | else if (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD) |
ef416fc2 | 616 | return (ipp_cups_ops[op - CUPS_GET_DEFAULT]); |
2e4ff8af MS |
617 | else if (op == CUPS_GET_DOCUMENT) |
618 | return (ipp_cups_ops2[0]); | |
ef416fc2 | 619 | |
620 | /* | |
621 | * No, build an "unknown-xxxx" operation string... | |
622 | */ | |
623 | ||
624 | sprintf(cg->ipp_unknown, "unknown-%04x", op); | |
625 | ||
626 | return (cg->ipp_unknown); | |
627 | } | |
628 | ||
629 | ||
630 | /* | |
631 | * 'ippOpValue()' - Return an operation id for the given name. | |
632 | * | |
426c6a59 | 633 | * @since CUPS 1.2/Mac OS X 10.5@ |
ef416fc2 | 634 | */ |
635 | ||
636 | ipp_op_t /* O - Operation ID */ | |
637 | ippOpValue(const char *name) /* I - Textual name */ | |
638 | { | |
639 | int i; | |
640 | ||
641 | ||
642 | for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++) | |
88f9aafc | 643 | if (!_cups_strcasecmp(name, ipp_std_ops[i])) |
ef416fc2 | 644 | return ((ipp_op_t)i); |
645 | ||
88f9aafc | 646 | if (!_cups_strcasecmp(name, "windows-ext")) |
ef416fc2 | 647 | return (IPP_PRIVATE); |
648 | ||
649 | for (i = 0; i < (sizeof(ipp_cups_ops) / sizeof(ipp_cups_ops[0])); i ++) | |
88f9aafc | 650 | if (!_cups_strcasecmp(name, ipp_cups_ops[i])) |
ef416fc2 | 651 | return ((ipp_op_t)(i + 0x4001)); |
652 | ||
2e4ff8af | 653 | for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++) |
88f9aafc | 654 | if (!_cups_strcasecmp(name, ipp_cups_ops2[i])) |
2e4ff8af MS |
655 | return ((ipp_op_t)(i + 0x4027)); |
656 | ||
88f9aafc | 657 | if (!_cups_strcasecmp(name, "CUPS-Add-Class")) |
480ef0fe | 658 | return (CUPS_ADD_MODIFY_CLASS); |
659 | ||
88f9aafc | 660 | if (!_cups_strcasecmp(name, "CUPS-Add-Printer")) |
480ef0fe | 661 | return (CUPS_ADD_MODIFY_PRINTER); |
662 | ||
ef416fc2 | 663 | return ((ipp_op_t)-1); |
664 | } | |
665 | ||
666 | ||
667 | /* | |
668 | * 'ippPort()' - Return the default IPP port number. | |
669 | */ | |
670 | ||
671 | int /* O - Port number */ | |
672 | ippPort(void) | |
673 | { | |
ef416fc2 | 674 | _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ |
675 | ||
676 | ||
d09495fa | 677 | DEBUG_puts("ippPort()"); |
678 | ||
679 | if (!cg->ipp_port) | |
e07d4801 | 680 | _cupsSetDefaults(); |
d09495fa | 681 | |
e07d4801 | 682 | DEBUG_printf(("1ippPort: Returning %d...", cg->ipp_port)); |
d09495fa | 683 | |
ef416fc2 | 684 | return (cg->ipp_port); |
685 | } | |
686 | ||
687 | ||
688 | /* | |
689 | * 'ippSetPort()' - Set the default port number. | |
690 | */ | |
691 | ||
692 | void | |
693 | ippSetPort(int p) /* I - Port number to use */ | |
694 | { | |
e07d4801 | 695 | DEBUG_printf(("ippSetPort(p=%d)", p)); |
d09495fa | 696 | |
ef416fc2 | 697 | _cupsGlobals()->ipp_port = p; |
698 | } | |
699 | ||
700 | ||
701 | /* | |
1ff0402e MS |
702 | * 'ippTagString()' - Return the tag name corresponding to a tag value. |
703 | * | |
704 | * The returned names are defined in RFC 2911 and 3382. | |
705 | * | |
178cb736 | 706 | * @since CUPS 1.4/Mac OS X 10.6@ |
1ff0402e MS |
707 | */ |
708 | ||
709 | const char * /* O - Tag name */ | |
710 | ippTagString(ipp_tag_t tag) /* I - Tag value */ | |
711 | { | |
ed6e7faf MS |
712 | tag &= IPP_TAG_MASK; |
713 | ||
1ff0402e MS |
714 | if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0]))) |
715 | return (ipp_tag_names[tag]); | |
716 | else | |
717 | return ("UNKNOWN"); | |
718 | } | |
719 | ||
720 | ||
721 | /* | |
722 | * 'ippTagValue()' - Return the tag value corresponding to a tag name. | |
723 | * | |
724 | * The tag names are defined in RFC 2911 and 3382. | |
725 | * | |
178cb736 | 726 | * @since CUPS 1.4/Mac OS X 10.6@ |
1ff0402e MS |
727 | */ |
728 | ||
729 | ipp_tag_t /* O - Tag value */ | |
730 | ippTagValue(const char *name) /* I - Tag name */ | |
731 | { | |
732 | int i; /* Looping var */ | |
733 | ||
734 | ||
735 | for (i = 0; i < (sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])); i ++) | |
88f9aafc | 736 | if (!_cups_strcasecmp(name, ipp_tag_names[i])) |
1ff0402e MS |
737 | return ((ipp_tag_t)i); |
738 | ||
88f9aafc | 739 | if (!_cups_strcasecmp(name, "operation")) |
1ff0402e | 740 | return (IPP_TAG_OPERATION); |
88f9aafc | 741 | else if (!_cups_strcasecmp(name, "job")) |
1ff0402e | 742 | return (IPP_TAG_JOB); |
88f9aafc | 743 | else if (!_cups_strcasecmp(name, "printer")) |
1ff0402e | 744 | return (IPP_TAG_PRINTER); |
88f9aafc | 745 | else if (!_cups_strcasecmp(name, "unsupported")) |
5a6b583a | 746 | return (IPP_TAG_UNSUPPORTED_GROUP); |
88f9aafc | 747 | else if (!_cups_strcasecmp(name, "subscription")) |
1ff0402e | 748 | return (IPP_TAG_SUBSCRIPTION); |
88f9aafc | 749 | else if (!_cups_strcasecmp(name, "event")) |
5a6b583a | 750 | return (IPP_TAG_EVENT_NOTIFICATION); |
88f9aafc | 751 | else if (!_cups_strcasecmp(name, "language")) |
1ff0402e | 752 | return (IPP_TAG_LANGUAGE); |
88f9aafc | 753 | else if (!_cups_strcasecmp(name, "mimetype")) |
1ff0402e | 754 | return (IPP_TAG_MIMETYPE); |
88f9aafc | 755 | else if (!_cups_strcasecmp(name, "name")) |
1ff0402e | 756 | return (IPP_TAG_NAME); |
88f9aafc | 757 | else if (!_cups_strcasecmp(name, "text")) |
1ff0402e | 758 | return (IPP_TAG_TEXT); |
88f9aafc | 759 | else if (!_cups_strcasecmp(name, "begCollection")) |
5a6b583a | 760 | return (IPP_TAG_BEGIN_COLLECTION); |
1ff0402e MS |
761 | else |
762 | return (IPP_TAG_ZERO); | |
763 | } | |
764 | ||
765 | ||
766 | /* | |
1106b00e MS |
767 | * 'ipp_col_string()' - Convert a collection to a string. |
768 | */ | |
769 | ||
770 | static size_t /* O - Number of bytes */ | |
771 | ipp_col_string(ipp_t *col, /* I - Collection attribute */ | |
772 | char *buffer, /* I - Buffer or NULL */ | |
773 | size_t bufsize) /* I - Size of buffer */ | |
774 | { | |
775 | char *bufptr, /* Position in buffer */ | |
776 | *bufend, /* End of buffer */ | |
777 | temp[256]; /* Temporary string */ | |
778 | ipp_attribute_t *attr; /* Current member attribute */ | |
779 | ||
780 | ||
781 | bufptr = buffer; | |
782 | bufend = buffer + bufsize - 1; | |
783 | ||
784 | if (buffer && bufptr < bufend) | |
785 | *bufptr = '{'; | |
786 | bufptr ++; | |
787 | ||
788 | for (attr = col->attrs; attr; attr = attr->next) | |
789 | { | |
790 | if (!attr->name) | |
791 | continue; | |
792 | ||
793 | if (buffer && bufptr < bufend) | |
794 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%s=", attr->name); | |
795 | else | |
796 | bufptr += strlen(attr->name) + 1; | |
797 | ||
798 | if (buffer && bufptr < bufend) | |
799 | bufptr += _ippAttrString(attr, bufptr, bufend - bufptr + 1); | |
800 | else | |
801 | bufptr += _ippAttrString(attr, temp, sizeof(temp)); | |
802 | } | |
803 | ||
804 | if (buffer && bufptr < bufend) | |
805 | *bufptr = '}'; | |
806 | bufptr ++; | |
807 | ||
808 | return (bufptr - buffer); | |
809 | } | |
810 | ||
811 | ||
812 | /* | |
813 | * End of "$Id: ipp-support.c 9371 2010-11-17 06:21:32Z mike $". | |
ef416fc2 | 814 | */ |