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