Index: dest.c =================================================================== --- dest.c (revision 5743) +++ dest.c (working copy) @@ -456,6 +456,7 @@ int wrote; /* Wrote definition? */ cups_dest_t *dest; /* Current destination */ cups_option_t *option; /* Current option */ + _ipp_option_t *match; /* Matching attribute for option */ FILE *fp; /* File pointer */ const char *home; /* HOME environment variable */ char filename[1024]; /* lpoptions file */ @@ -568,16 +569,23 @@ for (j = dest->num_options, option = dest->options; j > 0; j --, option ++) { /* + * See if this option is a printer attribute; if so, skip it... + */ + + if ((match = _ippFindOption(option->name)) != NULL && + match->group_tag == IPP_TAG_PRINTER) + continue; + + /* * See if the server/global options match these; if so, don't * write 'em. */ - if (temp && (val = cupsGetOption(option->name, temp->num_options, - temp->options)) != NULL) - { - if (!strcasecmp(val, option->value)) - continue; - } + if (temp && + (val = cupsGetOption(option->name, temp->num_options, + temp->options)) != NULL && + !strcasecmp(val, option->value)) + continue; /* * Options don't match, write to the file... @@ -593,10 +601,35 @@ if (option->value[0]) { - if (strchr(option->value, ' ') != NULL) - fprintf(fp, " %s=\"%s\"", option->name, option->value); - else + if (strchr(option->value, ' ') || + strchr(option->value, '\\') || + strchr(option->value, '\"') || + strchr(option->value, '\'')) + { + /* + * Quote the value... + */ + + fprintf(fp, " %s=\"", option->name); + + for (val = option->value; *val; val ++) + { + if (strchr("\"\'\\", *val)) + putc('\\', fp); + + putc(*val, fp); + } + + putc('\"', fp); + } + else + { + /* + * Store the literal value... + */ + fprintf(fp, " %s=%s", option->name, option->value); + } } else fprintf(fp, " %s", option->name); Index: encode.c =================================================================== --- encode.c (revision 5743) +++ encode.c (working copy) @@ -28,6 +28,7 @@ * cupsEncodeOptions() - Encode printer options into IPP attributes. * cupsEncodeOptions2() - Encode printer options into IPP attributes for * a group. + * _ippFindOption() - Find the attribute information for an option. * compare_ipp_options() - Compare two IPP options. */ @@ -49,13 +50,6 @@ * **** THIS LIST MUST BE SORTED **** */ -typedef struct -{ - const char *name; - ipp_tag_t value_tag; - ipp_tag_t group_tag; -} _ipp_option_t; - static const _ipp_option_t ipp_options[] = { { "blackplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, @@ -116,6 +110,8 @@ { "ppi-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "prettyprint", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, { "prettyprint-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { "print-quality", IPP_TAG_ENUM, IPP_TAG_JOB }, + { "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { "printer-error-policy", IPP_TAG_NAME, IPP_TAG_PRINTER }, { "printer-info", IPP_TAG_TEXT, IPP_TAG_PRINTER }, { "printer-is-accepting-jobs",IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, @@ -129,14 +125,12 @@ { "printer-state-reasons", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { "printer-type", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { "printer-uri", IPP_TAG_URI, IPP_TAG_OPERATION }, - { "print-quality", IPP_TAG_ENUM, IPP_TAG_JOB }, - { "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { "queued-job-count", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "raw", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION }, + { "requesting-user-name-allowed", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { "requesting-user-name-denied", IPP_TAG_NAME, IPP_TAG_PRINTER }, { "resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB }, { "resolution-default", IPP_TAG_RESOLUTION, IPP_TAG_PRINTER }, - { "requesting-user-name-allowed", IPP_TAG_NAME, IPP_TAG_PRINTER }, - { "requesting-user-name-denied", IPP_TAG_NAME, IPP_TAG_PRINTER }, { "saturation", IPP_TAG_INTEGER, IPP_TAG_JOB }, { "saturation-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "scaling", IPP_TAG_INTEGER, IPP_TAG_JOB }, @@ -245,8 +239,7 @@ for (i = num_options, option = options; i > 0; i --, option ++) { - _ipp_option_t key, /* Search key */ - *match; /* Matching attribute */ + _ipp_option_t *match; /* Matching attribute */ /* @@ -262,16 +255,7 @@ * Figure out the proper value and group tags for this option... */ - key.name = option->name; - match = (_ipp_option_t *)bsearch(&key, ipp_options, - sizeof(ipp_options) / - sizeof(ipp_options[0]), - sizeof(ipp_options[0]), - (int (*)(const void *, - const void *)) - compare_ipp_options); - - if (match) + if ((match = _ippFindOption(option->name)) != NULL) { if (match->group_tag != group_tag) continue; @@ -549,6 +533,30 @@ /* + * '_ippFindOption()' - Find the attribute information for an option. + */ + +_ipp_option_t * /* O - Attribute information */ +_ippFindOption(const char *name) /* I - Option/attribute name */ +{ + _ipp_option_t key; /* Search key */ + + + /* + * Lookup the proper value and group tags for this option... + */ + + key.name = name; + + return ((_ipp_option_t *)bsearch(&key, ipp_options, + sizeof(ipp_options) / sizeof(ipp_options[0]), + sizeof(ipp_options[0]), + (int (*)(const void *, const void *)) + compare_ipp_options)); +} + + +/* * 'compare_ipp_options()' - Compare two IPP options. */ Index: ipp-private.h =================================================================== --- ipp-private.h (revision 5743) +++ ipp-private.h (working copy) @@ -44,10 +44,23 @@ /* + * Structures... + */ + +typedef struct /**** Attribute mapping data ****/ +{ + const char *name; /* Option/attribute name */ + ipp_tag_t value_tag; /* Value tag for this attribute */ + ipp_tag_t group_tag; /* Group tag for this attribute */ +} _ipp_option_t; + + +/* * Prototypes for private functions... */ extern ipp_attribute_t *_ippAddAttr(ipp_t *, int); +extern _ipp_option_t *_ippFindOption(const char *name); extern void _ippFreeAttr(ipp_attribute_t *); Index: testipp.c =================================================================== --- testipp.c (revision 5743) +++ testipp.c (working copy) @@ -36,7 +36,7 @@ #include #include #include -#include "ipp.h" +#include "ipp-private.h" #ifdef WIN32 # include #else @@ -283,6 +283,19 @@ ippDelete(request); /* + * Test _ippFindOption() private API... + */ + + fputs("_ippFindOption(\"printer-type\"): ", stdout); + if (_ippFindOption("printer-type")) + puts("PASS"); + else + { + puts("FAIL"); + status = 1; + } + + /* * Summarize... */