]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/ipp-support.c
Merge changes from CUPS 1.4svn-r8162.
[thirdparty/cups.git] / cups / ipp-support.c
1 /*
2 * "$Id: ipp-support.c 7847 2008-08-19 04:22:14Z mike $"
3 *
4 * Internet Printing Protocol support functions for the Common UNIX
5 * Printing System (CUPS).
6 *
7 * Copyright 2007-2008 by Apple Inc.
8 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
9 *
10 * These coded instructions, statements, and computer programs are the
11 * property of Apple Inc. and are protected by Federal copyright
12 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
13 * which should have been included with this file. If this file is
14 * file is missing or damaged, see the license at "http://www.cups.org/".
15 *
16 * This file is subject to the Apple OS-Developed Software exception.
17 *
18 * Contents:
19 *
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.
26 * ippTagString() - Return the tag name corresponding to a tag value.
27 * ippTagValue() - Return the tag value corresponding to a tag name.
28 */
29
30 /*
31 * Include necessary headers...
32 */
33
34 #include "globals.h"
35 #include "debug.h"
36 #include <stdlib.h>
37
38
39 /*
40 * Local globals...
41 */
42
43 static const char * const ipp_status_oks[] = /* "OK" status codes */
44 {
45 "successful-ok",
46 "successful-ok-ignored-or-substituted-attributes",
47 "successful-ok-conflicting-attributes",
48 "successful-ok-ignored-subscriptions",
49 "successful-ok-ignored-notifications",
50 "successful-ok-too-many-events",
51 "successful-ok-but-cancel-subscription",
52 "successful-ok-events-complete"
53 },
54 * const ipp_status_400s[] = /* Client errors */
55 {
56 "client-error-bad-request",
57 "client-error-forbidden",
58 "client-error-not-authenticated",
59 "client-error-not-authorized",
60 "client-error-not-possible",
61 "client-error-timeout",
62 "client-error-not-found",
63 "client-error-gone",
64 "client-error-request-entity-too-large",
65 "client-error-request-value-too-long",
66 "client-error-document-format-not-supported",
67 "client-error-attributes-or-values-not-supported",
68 "client-error-uri-scheme-not-supported",
69 "client-error-charset-not-supported",
70 "client-error-conflicting-attributes",
71 "client-error-compression-not-supported",
72 "client-error-compression-error",
73 "client-error-document-format-error",
74 "client-error-document-access-error",
75 "client-error-attributes-not-settable",
76 "client-error-ignored-all-subscriptions",
77 "client-error-too-many-subscriptions",
78 "client-error-ignored-all-notifications",
79 "client-error-print-support-file-not-found"
80 },
81 * const ipp_status_500s[] = /* Server errors */
82 {
83 "server-error-internal-error",
84 "server-error-operation-not-supported",
85 "server-error-service-unavailable",
86 "server-error-version-not-supported",
87 "server-error-device-error",
88 "server-error-temporary-error",
89 "server-error-not-accepting-jobs",
90 "server-error-busy",
91 "server-error-job-canceled",
92 "server-error-multiple-document-jobs-not-supported",
93 "server-error-printer-is-deactivated"
94 };
95 static char * const ipp_std_ops[] =
96 {
97 /* 0x0000 - 0x000f */
98 "", "", "Print-Job", "Print-URI",
99 "Validate-Job", "Create-Job", "Send-Document",
100 "Send-URI", "Cancel-Job", "Get-Job-Attributes",
101 "Get-Jobs", "Get-Printer-Attributes",
102 "Hold-Job", "Release-Job", "Restart-Job", "",
103
104 /* 0x0010 - 0x001f */
105 "Pause-Printer", "Resume-Printer",
106 "Purge-Jobs", "Set-Printer-Attributes",
107 "Set-Job-Attributes",
108 "Get-Printer-Supported-Values",
109 "Create-Printer-Subscription",
110 "Create-Job-Subscription",
111 "Get-Subscription-Attributes",
112 "Get-Subscriptions", "Renew-Subscription",
113 "Cancel-Subscription", "Get-Notifications",
114 "Send-Notifications", "", "",
115
116 /* 0x0020 - 0x002f */
117 "",
118 "Get-Printer-Support-Files",
119 "Enable-Printer",
120 "Disable-Printer",
121 "Pause-Printer-After-Current-Job",
122 "Hold-New-Jobs",
123 "Release-Held-New-Jobs",
124 "Deactivate-Printer",
125 "Activate-Printer",
126 "Restart-Printer",
127 "Shutdown-Printer",
128 "Startup-Printer",
129 "Reprocess-Job",
130 "Cancel-Current-Job",
131 "Suspend-Current-Job",
132 "Resume-Job",
133
134 /* 0x0030 - 0x0031 */
135 "Promote-Job",
136 "Schedule-Job-After"
137 },
138 * const ipp_cups_ops[] =
139 {
140 "CUPS-Get-Default",
141 "CUPS-Get-Printers",
142 "CUPS-Add-Modify-Printer",
143 "CUPS-Delete-Printer",
144 "CUPS-Get-Classes",
145 "CUPS-Add-Modify-Class",
146 "CUPS-Delete-Class",
147 "CUPS-Accept-Jobs",
148 "CUPS-Reject-Jobs",
149 "CUPS-Set-Default",
150 "CUPS-Get-Devices",
151 "CUPS-Get-PPDs",
152 "CUPS-Move-Job",
153 "CUPS-Authenticate-Job",
154 "CUPS-Get-PPD"
155 },
156 * const ipp_cups_ops2[] =
157 {
158 "CUPS-Get-Document"
159 },
160 * const ipp_tag_names[] =
161 { /* Value/group tag names */
162 "zero", /* 0x00 */
163 "operation-attributes-tag",
164 /* 0x01 */
165 "job-attributes-tag", /* 0x02 */
166 "end-of-attributes-tag",
167 /* 0x03 */
168 "printer-attributes-tag",
169 /* 0x04 */
170 "unsupported-attributes-tag",
171 /* 0x05 */
172 "subscription-attributes-tag",
173 /* 0x06 */
174 "event-notification-attributes-tag",
175 /* 0x07 */
176 "unknown-08", /* 0x08 */
177 "unknown-09", /* 0x09 */
178 "unknown-0a", /* 0x0a */
179 "unknown-0b", /* 0x0b */
180 "unknown-0c", /* 0x0c */
181 "unknown-0d", /* 0x0d */
182 "unknown-0e", /* 0x0e */
183 "unknown-0f", /* 0x0f */
184 "unsupported", /* 0x10 */
185 "default", /* 0x11 */
186 "unknown", /* 0x12 */
187 "no-value", /* 0x13 */
188 "unknown-14", /* 0x14 */
189 "not-settable", /* 0x15 */
190 "delete-attribute", /* 0x16 */
191 "admin-define", /* 0x17 */
192 "unknown-18", /* 0x18 */
193 "unknown-19", /* 0x19 */
194 "unknown-1a", /* 0x1a */
195 "unknown-1b", /* 0x1b */
196 "unknown-1c", /* 0x1c */
197 "unknown-1d", /* 0x1d */
198 "unknown-1e", /* 0x1e */
199 "unknown-1f", /* 0x1f */
200 "unknown-20", /* 0x20 */
201 "integer", /* 0x21 */
202 "boolean", /* 0x22 */
203 "enum", /* 0x23 */
204 "unknown-24", /* 0x24 */
205 "unknown-25", /* 0x25 */
206 "unknown-26", /* 0x26 */
207 "unknown-27", /* 0x27 */
208 "unknown-28", /* 0x28 */
209 "unknown-29", /* 0x29 */
210 "unknown-2a", /* 0x2a */
211 "unknown-2b", /* 0x2b */
212 "unknown-2c", /* 0x2c */
213 "unknown-2d", /* 0x2d */
214 "unknown-2e", /* 0x2e */
215 "unknown-2f", /* 0x2f */
216 "octetString", /* 0x30 */
217 "dateTime", /* 0x31 */
218 "resolution", /* 0x32 */
219 "rangeOfInteger", /* 0x33 */
220 "begCollection", /* 0x34 */
221 "textWithLanguage", /* 0x35 */
222 "nameWithLanguage", /* 0x36 */
223 "endCollection", /* 0x37 */
224 "unknown-38", /* 0x38 */
225 "unknown-39", /* 0x39 */
226 "unknown-3a", /* 0x3a */
227 "unknown-3b", /* 0x3b */
228 "unknown-3c", /* 0x3c */
229 "unknown-3d", /* 0x3d */
230 "unknown-3e", /* 0x3e */
231 "unknown-3f", /* 0x3f */
232 "unknown-40", /* 0x40 */
233 "textWithoutLanguage",/* 0x41 */
234 "nameWithoutLanguage",/* 0x42 */
235 "unknown-43", /* 0x43 */
236 "keyword", /* 0x44 */
237 "uri", /* 0x45 */
238 "uriScheme", /* 0x46 */
239 "charset", /* 0x47 */
240 "naturalLanguage", /* 0x48 */
241 "mimeMediaType", /* 0x49 */
242 "memberAttrName" /* 0x4a */
243 };
244
245
246 /*
247 * 'ippErrorString()' - Return a name for the given status code.
248 */
249
250 const char * /* O - Text string */
251 ippErrorString(ipp_status_t error) /* I - Error status */
252 {
253 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
254
255
256 /*
257 * See if the error code is a known value...
258 */
259
260 if (error >= IPP_OK && error <= IPP_OK_EVENTS_COMPLETE)
261 return (ipp_status_oks[error]);
262 else if (error == IPP_REDIRECTION_OTHER_SITE)
263 return ("redirection-other-site");
264 else if (error == CUPS_SEE_OTHER)
265 return ("cups-see-other");
266 else if (error >= IPP_BAD_REQUEST && error <= IPP_PRINT_SUPPORT_FILE_NOT_FOUND)
267 return (ipp_status_400s[error - IPP_BAD_REQUEST]);
268 else if (error >= IPP_INTERNAL_ERROR && error <= IPP_PRINTER_IS_DEACTIVATED)
269 return (ipp_status_500s[error - IPP_INTERNAL_ERROR]);
270
271 /*
272 * No, build an "unknown-xxxx" error string...
273 */
274
275 sprintf(cg->ipp_unknown, "unknown-%04x", error);
276
277 return (cg->ipp_unknown);
278 }
279
280
281 /*
282 * 'ippErrorValue()' - Return a status code for the given name.
283 *
284 * @since CUPS 1.2@
285 */
286
287 ipp_status_t /* O - IPP status code */
288 ippErrorValue(const char *name) /* I - Name */
289 {
290 int i;
291
292
293 for (i = 0; i < (sizeof(ipp_status_oks) / sizeof(ipp_status_oks[0])); i ++)
294 if (!strcasecmp(name, ipp_status_oks[i]))
295 return ((ipp_status_t)i);
296
297 if (!strcasecmp(name, "redirection-other-site"))
298 return (IPP_REDIRECTION_OTHER_SITE);
299
300 if (!strcasecmp(name, "cups-see-other"))
301 return (CUPS_SEE_OTHER);
302
303 for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++)
304 if (!strcasecmp(name, ipp_status_400s[i]))
305 return ((ipp_status_t)(i + 0x400));
306
307 for (i = 0; i < (sizeof(ipp_status_500s) / sizeof(ipp_status_500s[0])); i ++)
308 if (!strcasecmp(name, ipp_status_500s[i]))
309 return ((ipp_status_t)(i + 0x500));
310
311 return ((ipp_status_t)-1);
312 }
313
314
315 /*
316 * 'ippOpString()' - Return a name for the given operation id.
317 *
318 * @since CUPS 1.2@
319 */
320
321 const char * /* O - Name */
322 ippOpString(ipp_op_t op) /* I - Operation ID */
323 {
324 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
325
326
327 /*
328 * See if the operation ID is a known value...
329 */
330
331 if (op >= IPP_PRINT_JOB && op <= IPP_SCHEDULE_JOB_AFTER)
332 return (ipp_std_ops[op]);
333 else if (op == IPP_PRIVATE)
334 return ("windows-ext");
335 else if (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD)
336 return (ipp_cups_ops[op - CUPS_GET_DEFAULT]);
337 else if (op == CUPS_GET_DOCUMENT)
338 return (ipp_cups_ops2[0]);
339
340 /*
341 * No, build an "unknown-xxxx" operation string...
342 */
343
344 sprintf(cg->ipp_unknown, "unknown-%04x", op);
345
346 return (cg->ipp_unknown);
347 }
348
349
350 /*
351 * 'ippOpValue()' - Return an operation id for the given name.
352 *
353 * @since CUPS 1.2@
354 */
355
356 ipp_op_t /* O - Operation ID */
357 ippOpValue(const char *name) /* I - Textual name */
358 {
359 int i;
360
361
362 for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++)
363 if (!strcasecmp(name, ipp_std_ops[i]))
364 return ((ipp_op_t)i);
365
366 if (!strcasecmp(name, "windows-ext"))
367 return (IPP_PRIVATE);
368
369 for (i = 0; i < (sizeof(ipp_cups_ops) / sizeof(ipp_cups_ops[0])); i ++)
370 if (!strcasecmp(name, ipp_cups_ops[i]))
371 return ((ipp_op_t)(i + 0x4001));
372
373 for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++)
374 if (!strcasecmp(name, ipp_cups_ops2[i]))
375 return ((ipp_op_t)(i + 0x4027));
376
377 if (!strcasecmp(name, "CUPS-Add-Class"))
378 return (CUPS_ADD_MODIFY_CLASS);
379
380 if (!strcasecmp(name, "CUPS-Add-Printer"))
381 return (CUPS_ADD_MODIFY_PRINTER);
382
383 return ((ipp_op_t)-1);
384 }
385
386
387 /*
388 * 'ippPort()' - Return the default IPP port number.
389 */
390
391 int /* O - Port number */
392 ippPort(void)
393 {
394 const char *ipp_port; /* IPP_PORT environment variable */
395 struct servent *port; /* Port number info */
396 int portnum; /* Port number */
397 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
398
399
400 DEBUG_puts("ippPort()");
401
402 if (!cg->ipp_port)
403 {
404 /*
405 * See if the server definition includes the port number...
406 */
407
408 DEBUG_puts("ippPort: Not initialized...");
409
410 cupsServer();
411
412 #ifdef DEBUG
413 if (cg->ipp_port)
414 DEBUG_puts(("ippPort: Set via cupsServer()..."));
415 #endif /* DEBUG */
416 }
417
418 if (!cg->ipp_port)
419 {
420 if ((ipp_port = getenv("IPP_PORT")) != NULL)
421 {
422 DEBUG_puts("ippPort: Set via IPP_PORT...");
423 portnum = atoi(ipp_port);
424 }
425 else if ((port = getservbyname("ipp", NULL)) == NULL)
426 {
427 DEBUG_puts("ippPort: Set via CUPS_DEFAULT_IPP_PORT...");
428 portnum = CUPS_DEFAULT_IPP_PORT;
429 }
430 else
431 {
432 DEBUG_puts("ippPort: Set via ipp service entry...");
433 portnum = ntohs(port->s_port);
434 }
435
436 if (portnum > 0)
437 cg->ipp_port = portnum;
438 }
439
440 DEBUG_printf(("ippPort: Returning %d...\n", cg->ipp_port));
441
442 return (cg->ipp_port);
443 }
444
445
446 /*
447 * 'ippSetPort()' - Set the default port number.
448 */
449
450 void
451 ippSetPort(int p) /* I - Port number to use */
452 {
453 DEBUG_printf(("ippSetPort(p=%d)\n", p));
454
455 _cupsGlobals()->ipp_port = p;
456 }
457
458
459 /*
460 * 'ippTagString()' - Return the tag name corresponding to a tag value.
461 *
462 * The returned names are defined in RFC 2911 and 3382.
463 *
464 * @since CUPS 1.4@
465 */
466
467 const char * /* O - Tag name */
468 ippTagString(ipp_tag_t tag) /* I - Tag value */
469 {
470 tag &= IPP_TAG_MASK;
471
472 if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])))
473 return (ipp_tag_names[tag]);
474 else
475 return ("UNKNOWN");
476 }
477
478
479 /*
480 * 'ippTagValue()' - Return the tag value corresponding to a tag name.
481 *
482 * The tag names are defined in RFC 2911 and 3382.
483 *
484 * @since CUPS 1.4@
485 */
486
487 ipp_tag_t /* O - Tag value */
488 ippTagValue(const char *name) /* I - Tag name */
489 {
490 int i; /* Looping var */
491
492
493 for (i = 0; i < (sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])); i ++)
494 if (!strcasecmp(name, ipp_tag_names[i]))
495 return ((ipp_tag_t)i);
496
497 if (!strcasecmp(name, "operation"))
498 return (IPP_TAG_OPERATION);
499 else if (!strcasecmp(name, "job"))
500 return (IPP_TAG_JOB);
501 else if (!strcasecmp(name, "printer"))
502 return (IPP_TAG_PRINTER);
503 else if (!strcasecmp(name, "subscription"))
504 return (IPP_TAG_SUBSCRIPTION);
505 else if (!strcasecmp(name, "language"))
506 return (IPP_TAG_LANGUAGE);
507 else if (!strcasecmp(name, "mimetype"))
508 return (IPP_TAG_MIMETYPE);
509 else if (!strcasecmp(name, "name"))
510 return (IPP_TAG_NAME);
511 else if (!strcasecmp(name, "text"))
512 return (IPP_TAG_TEXT);
513 else
514 return (IPP_TAG_ZERO);
515 }
516
517
518 /*
519 * End of "$Id: ipp-support.c 7847 2008-08-19 04:22:14Z mike $".
520 */