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