/*
 * Destination option/media support for CUPS.
 *
 * Copyright © 2012-2019 by Apple Inc.
 *
 * Licensed under Apache License v2.0.  See the file "LICENSE" for more
 * information.
 */

/*
 * Include necessary headers...
 */

#include "cups-private.h"
#include "debug-internal.h"


/*
 * Local constants...
 */

#define _CUPS_MEDIA_READY_TTL	30	/* Life of xxx-ready values */


/*
 * Local functions...
 */

static void		cups_add_dconstres(cups_array_t *a, ipp_t *collection);
static int		cups_collection_contains(ipp_t *test, ipp_t *match);
static size_t		cups_collection_string(ipp_attribute_t *attr, char *buffer, size_t bufsize) _CUPS_NONNULL((1,2));
static int		cups_compare_dconstres(_cups_dconstres_t *a,
			                       _cups_dconstres_t *b);
static int		cups_compare_media_db(_cups_media_db_t *a,
			                      _cups_media_db_t *b);
static _cups_media_db_t	*cups_copy_media_db(_cups_media_db_t *mdb);
static void		cups_create_cached(http_t *http, cups_dinfo_t *dinfo,
			                   unsigned flags);
static void		cups_create_constraints(cups_dinfo_t *dinfo);
static void		cups_create_defaults(cups_dinfo_t *dinfo);
static void		cups_create_media_db(cups_dinfo_t *dinfo,
			                     unsigned flags);
static void		cups_free_media_db(_cups_media_db_t *mdb);
static int		cups_get_media_db(http_t *http, cups_dinfo_t *dinfo,
			                  pwg_media_t *pwg, unsigned flags,
			                  cups_size_t *size);
static int		cups_is_close_media_db(_cups_media_db_t *a,
			                       _cups_media_db_t *b);
static cups_array_t	*cups_test_constraints(cups_dinfo_t *dinfo,
					       const char *new_option,
					       const char *new_value,
					       int num_options,
					       cups_option_t *options,
					       int *num_conflicts,
					       cups_option_t **conflicts);
static void		cups_update_ready(http_t *http, cups_dinfo_t *dinfo);


/*
 * 'cupsAddDestMediaOptions()' - Add the option corresponding to the specified media size.
 *
 * @since CUPS 2.3/macOS 10.14@
 */

int					/* O  - New number of options */
cupsAddDestMediaOptions(
    http_t        *http,		/* I  - Connection to destination */
    cups_dest_t   *dest,		/* I  - Destination */
    cups_dinfo_t  *dinfo,		/* I  - Destination information */
    unsigned      flags,		/* I  - Media matching flags */
    cups_size_t   *size,		/* I  - Media size */
    int           num_options,		/* I  - Current number of options */
    cups_option_t **options)		/* IO - Options */
{
  cups_array_t		*db;		/* Media database */
  _cups_media_db_t	*mdb;		/* Media database entry */
  char			value[2048];	/* Option value */


 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !size || !options)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (num_options);
  }

 /*
  * Find the matching media size...
  */

  if (flags & CUPS_MEDIA_FLAGS_READY)
    db = dinfo->ready_db;
  else
    db = dinfo->media_db;

  DEBUG_printf(("1cupsAddDestMediaOptions: size->media=\"%s\"", size->media));

  for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
  {
    if (mdb->key && !strcmp(mdb->key, size->media))
      break;
    else if (mdb->size_name && !strcmp(mdb->size_name, size->media))
      break;
  }

  if (!mdb)
  {
    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
    {
      if (mdb->width == size->width && mdb->length == size->length && mdb->bottom == size->bottom && mdb->left == size->left && mdb->right == size->right && mdb->top == size->top)
	break;
    }
  }

  if (!mdb)
  {
    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
    {
      if (mdb->width == size->width && mdb->length == size->length)
	break;
    }
  }

  if (!mdb)
  {
    DEBUG_puts("1cupsAddDestMediaOptions: Unable to find matching size.");
    return (num_options);
  }

  DEBUG_printf(("1cupsAddDestMediaOptions: MATCH mdb%p [key=\"%s\" size_name=\"%s\" source=\"%s\" type=\"%s\" width=%d length=%d B%d L%d R%d T%d]", (void *)mdb, mdb->key, mdb->size_name, mdb->source, mdb->type, mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top));

  if (mdb->source)
  {
    if (mdb->type)
      snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-source=\"%s\" media-type=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->source, mdb->type);
    else
      snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-source=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->source);
  }
  else if (mdb->type)
  {
    snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-type=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->type);
  }
  else
  {
    snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top);
  }

  num_options = cupsAddOption("media-col", value, num_options, options);

  return (num_options);
}


/*
 * 'cupsCheckDestSupported()' - Check that the option and value are supported
 *                              by the destination.
 *
 * Returns 1 if supported, 0 otherwise.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 if supported, 0 otherwise */
cupsCheckDestSupported(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option,		/* I - Option */
    const char   *value)		/* I - Value or @code NULL@ */
{
  int			i;		/* Looping var */
  char			temp[1024];	/* Temporary string */
  int			int_value;	/* Integer value */
  int			xres_value,	/* Horizontal resolution */
			yres_value;	/* Vertical resolution */
  ipp_res_t		units_value;	/* Resolution units */
  ipp_attribute_t	*attr;		/* Attribute */
  _ipp_value_t		*attrval;	/* Current attribute value */
  _ipp_option_t		*map;		/* Option mapping information */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
    return (0);

 /*
  * Lookup the attribute...
  */

  if (strstr(option, "-supported"))
    attr = ippFindAttribute(dinfo->attrs, option, IPP_TAG_ZERO);
  else
  {
    snprintf(temp, sizeof(temp), "%s-supported", option);
    attr = ippFindAttribute(dinfo->attrs, temp, IPP_TAG_ZERO);
  }

  if (!attr)
    return (0);

  if (!value)
    return (1);

/*
  * Compare values...
  */

  if (!strcmp(option, "media") && !strncmp(value, "custom_", 7))
  {
   /*
    * Check range of custom media sizes...
    */

    pwg_media_t	*pwg;		/* Current PWG media size info */
    int		min_width,	/* Minimum width */
		min_length,	/* Minimum length */
		max_width,	/* Maximum width */
		max_length;	/* Maximum length */

   /*
    * Get the minimum and maximum size...
    */

    min_width = min_length = INT_MAX;
    max_width = max_length = 0;

    for (i = attr->num_values, attrval = attr->values;
	 i > 0;
	 i --, attrval ++)
    {
      if (!strncmp(attrval->string.text, "custom_min_", 11) &&
          (pwg = pwgMediaForPWG(attrval->string.text)) != NULL)
      {
        min_width  = pwg->width;
        min_length = pwg->length;
      }
      else if (!strncmp(attrval->string.text, "custom_max_", 11) &&
	       (pwg = pwgMediaForPWG(attrval->string.text)) != NULL)
      {
        max_width  = pwg->width;
        max_length = pwg->length;
      }
    }

   /*
    * Check the range...
    */

    if (min_width < INT_MAX && max_width > 0 &&
        (pwg = pwgMediaForPWG(value)) != NULL &&
        pwg->width >= min_width && pwg->width <= max_width &&
        pwg->length >= min_length && pwg->length <= max_length)
      return (1);
  }
  else
  {
   /*
    * Check literal values...
    */

    map = _ippFindOption(option);

    switch (attr->value_tag)
    {
      case IPP_TAG_INTEGER :
          if (map && map->value_tag == IPP_TAG_STRING)
            return (strlen(value) <= (size_t)attr->values[0].integer);

      case IPP_TAG_ENUM :
          int_value = atoi(value);

          for (i = 0; i < attr->num_values; i ++)
            if (attr->values[i].integer == int_value)
              return (1);
          break;

      case IPP_TAG_BOOLEAN :
          return (attr->values[0].boolean);

      case IPP_TAG_RANGE :
          if (map && map->value_tag == IPP_TAG_STRING)
            int_value = (int)strlen(value);
          else
            int_value = atoi(value);

          for (i = 0; i < attr->num_values; i ++)
            if (int_value >= attr->values[i].range.lower &&
                int_value <= attr->values[i].range.upper)
              return (1);
          break;

      case IPP_TAG_RESOLUTION :
          if (sscanf(value, "%dx%d%15s", &xres_value, &yres_value, temp) != 3)
          {
            if (sscanf(value, "%d%15s", &xres_value, temp) != 2)
              return (0);

            yres_value = xres_value;
          }

          if (!strcmp(temp, "dpi"))
            units_value = IPP_RES_PER_INCH;
          else if (!strcmp(temp, "dpc") || !strcmp(temp, "dpcm"))
            units_value = IPP_RES_PER_CM;
          else
            return (0);

          for (i = attr->num_values, attrval = attr->values;
               i > 0;
               i --, attrval ++)
          {
            if (attrval->resolution.xres == xres_value &&
                attrval->resolution.yres == yres_value &&
                attrval->resolution.units == units_value)
              return (1);
          }
          break;

      case IPP_TAG_TEXT :
      case IPP_TAG_NAME :
      case IPP_TAG_KEYWORD :
      case IPP_TAG_CHARSET :
      case IPP_TAG_URI :
      case IPP_TAG_URISCHEME :
      case IPP_TAG_MIMETYPE :
      case IPP_TAG_LANGUAGE :
      case IPP_TAG_TEXTLANG :
      case IPP_TAG_NAMELANG :
          for (i = 0; i < attr->num_values; i ++)
            if (!strcmp(attr->values[i].string.text, value))
              return (1);
          break;

      default :
          break;
    }
  }

 /*
  * If we get there the option+value is not supported...
  */

  return (0);
}


/*
 * 'cupsCopyDestConflicts()' - Get conflicts and resolutions for a new
 *                             option/value pair.
 *
 * "num_options" and "options" represent the currently selected options by the
 * user.  "new_option" and "new_value" are the setting the user has just
 * changed.
 *
 * Returns 1 if there is a conflict, 0 if there are no conflicts, and -1 if
 * there was an unrecoverable error such as a resolver loop.
 *
 * If "num_conflicts" and "conflicts" are not @code NULL@, they are set to
 * contain the list of conflicting option/value pairs.  Similarly, if
 * "num_resolved" and "resolved" are not @code NULL@ they will be set to the
 * list of changes needed to resolve the conflict.
 *
 * If cupsCopyDestConflicts returns 1 but "num_resolved" and "resolved" are set
 * to 0 and @code NULL@, respectively, then the conflict cannot be resolved.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 if there is a conflict, 0 if none, -1 on error */
cupsCopyDestConflicts(
    http_t        *http,		/* I - Connection to destination */
    cups_dest_t   *dest,		/* I - Destination */
    cups_dinfo_t  *dinfo,		/* I - Destination information */
    int           num_options,		/* I - Number of current options */
    cups_option_t *options,		/* I - Current options */
    const char    *new_option,		/* I - New option */
    const char    *new_value,		/* I - New value */
    int           *num_conflicts,	/* O - Number of conflicting options */
    cups_option_t **conflicts,		/* O - Conflicting options */
    int           *num_resolved,	/* O - Number of options to resolve */
    cups_option_t **resolved)		/* O - Resolved options */
{
  int		i,			/* Looping var */
		have_conflicts = 0,	/* Do we have conflicts? */
		changed,		/* Did we change something? */
		tries,			/* Number of tries for resolution */
		num_myconf = 0,		/* My number of conflicting options */
		num_myres = 0;		/* My number of resolved options */
  cups_option_t	*myconf = NULL,		/* My conflicting options */
		*myres = NULL,		/* My resolved options */
		*myoption,		/* My current option */
		*option;		/* Current option */
  cups_array_t	*active = NULL,		/* Active conflicts */
		*pass = NULL,		/* Resolvers for this pass */
		*resolvers = NULL,	/* Resolvers we have used */
		*test;			/* Test array for conflicts */
  _cups_dconstres_t *c,			/* Current constraint */
		*r;			/* Current resolver */
  ipp_attribute_t *attr;		/* Current attribute */
  char		value[2048];		/* Current attribute value as string */
  const char	*myvalue;		/* Current value of an option */


 /*
  * Clear returned values...
  */

  if (num_conflicts)
    *num_conflicts = 0;

  if (conflicts)
    *conflicts = NULL;

  if (num_resolved)
    *num_resolved = 0;

  if (resolved)
    *resolved = NULL;

 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo ||
      (num_conflicts != NULL) != (conflicts != NULL) ||
      (num_resolved != NULL) != (resolved != NULL))
    return (0);

 /*
  * Load constraints as needed...
  */

  if (!dinfo->constraints)
    cups_create_constraints(dinfo);

  if (cupsArrayCount(dinfo->constraints) == 0)
    return (0);

  if (!dinfo->num_defaults)
    cups_create_defaults(dinfo);

 /*
  * If we are resolving, create a shadow array...
  */

  if (num_resolved)
  {
    for (i = num_options, option = options; i > 0; i --, option ++)
      num_myres = cupsAddOption(option->name, option->value, num_myres, &myres);

    if (new_option && new_value)
      num_myres = cupsAddOption(new_option, new_value, num_myres, &myres);
  }
  else
  {
    num_myres = num_options;
    myres     = options;
  }

 /*
  * Check for any conflicts...
  */

  if (num_resolved)
    pass = cupsArrayNew((cups_array_func_t)cups_compare_dconstres, NULL);

  for (tries = 0; tries < 100; tries ++)
  {
   /*
    * Check for any conflicts...
    */

    if (num_conflicts || num_resolved)
    {
      cupsFreeOptions(num_myconf, myconf);

      num_myconf = 0;
      myconf     = NULL;
      active     = cups_test_constraints(dinfo, new_option, new_value,
                                         num_myres, myres, &num_myconf,
                                         &myconf);
    }
    else
      active = cups_test_constraints(dinfo, new_option, new_value, num_myres,
				     myres, NULL, NULL);

    have_conflicts = (active != NULL);

    if (!active || !num_resolved)
      break;				/* All done */

   /*
    * Scan the constraints that were triggered to apply resolvers...
    */

    if (!resolvers)
      resolvers = cupsArrayNew((cups_array_func_t)cups_compare_dconstres, NULL);

    for (c = (_cups_dconstres_t *)cupsArrayFirst(active), changed = 0;
         c;
         c = (_cups_dconstres_t *)cupsArrayNext(active))
    {
      if (cupsArrayFind(pass, c))
        continue;			/* Already applied this resolver... */

      if (cupsArrayFind(resolvers, c))
      {
        DEBUG_printf(("1cupsCopyDestConflicts: Resolver loop with %s.",
                      c->name));
        have_conflicts = -1;
        goto cleanup;
      }

      if ((r = cupsArrayFind(dinfo->resolvers, c)) == NULL)
      {
        DEBUG_printf(("1cupsCopyDestConflicts: Resolver %s not found.",
                      c->name));
        have_conflicts = -1;
        goto cleanup;
      }

     /*
      * Add the options from the resolver...
      */

      cupsArrayAdd(pass, r);
      cupsArrayAdd(resolvers, r);

      for (attr = ippFirstAttribute(r->collection);
           attr;
           attr = ippNextAttribute(r->collection))
      {
        if (new_option && !strcmp(attr->name, new_option))
          continue;			/* Ignore this if we just changed it */

        if (ippAttributeString(attr, value, sizeof(value)) >= sizeof(value))
          continue;			/* Ignore if the value is too long */

        if ((test = cups_test_constraints(dinfo, attr->name, value, num_myres,
                                          myres, NULL, NULL)) == NULL)
        {
         /*
          * That worked, flag it...
          */

          changed = 1;
        }
        else
          cupsArrayDelete(test);

       /*
	* Add the option/value from the resolver regardless of whether it
	* worked; this makes sure that we can cascade several changes to
	* make things resolve...
	*/

	num_myres = cupsAddOption(attr->name, value, num_myres, &myres);
      }
    }

    if (!changed)
    {
      DEBUG_puts("1cupsCopyDestConflicts: Unable to resolve constraints.");
      have_conflicts = -1;
      goto cleanup;
    }

    cupsArrayClear(pass);

    cupsArrayDelete(active);
    active = NULL;
  }

  if (tries >= 100)
  {
    DEBUG_puts("1cupsCopyDestConflicts: Unable to resolve after 100 tries.");
    have_conflicts = -1;
    goto cleanup;
  }

 /*
  * Copy resolved options as needed...
  */

  if (num_resolved)
  {
    for (i = num_myres, myoption = myres; i > 0; i --, myoption ++)
    {
      if ((myvalue = cupsGetOption(myoption->name, num_options,
                                   options)) == NULL ||
          strcmp(myvalue, myoption->value))
      {
        if (new_option && !strcmp(new_option, myoption->name) &&
            new_value && !strcmp(new_value, myoption->value))
          continue;

        *num_resolved = cupsAddOption(myoption->name, myoption->value,
                                      *num_resolved, resolved);
      }
    }
  }

 /*
  * Clean up...
  */

  cleanup:

  cupsArrayDelete(active);
  cupsArrayDelete(pass);
  cupsArrayDelete(resolvers);

  if (num_resolved)
  {
   /*
    * Free shadow copy of options...
    */

    cupsFreeOptions(num_myres, myres);
  }

  if (num_conflicts)
  {
   /*
    * Return conflicting options to caller...
    */

    *num_conflicts = num_myconf;
    *conflicts     = myconf;
  }
  else
  {
   /*
    * Free conflicting options...
    */

    cupsFreeOptions(num_myconf, myconf);
  }

  return (have_conflicts);
}


/*
 * 'cupsCopyDestInfo()' - Get the supported values/capabilities for the
 *                        destination.
 *
 * The caller is responsible for calling @link cupsFreeDestInfo@ on the return
 * value. @code NULL@ is returned on error.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

cups_dinfo_t *				/* O - Destination information */
cupsCopyDestInfo(
    http_t      *http,			/* I - Connection to destination */
    cups_dest_t *dest)			/* I - Destination */
{
  cups_dinfo_t	*dinfo;			/* Destination information */
  unsigned	dflags;			/* Destination flags */
  ipp_t		*request,		/* Get-Printer-Attributes request */
		*response;		/* Supported attributes */
  int		tries,			/* Number of tries so far */
		delay,			/* Current retry delay */
		prev_delay;		/* Next retry delay */
  const char	*uri;			/* Printer URI */
  char		resource[1024];		/* Resource path */
  int		version;		/* IPP version */
  ipp_status_t	status;			/* Status of request */
  _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */
  static const char * const requested_attrs[] =
  {					/* Requested attributes */
    "job-template",
    "media-col-database",
    "printer-description"
  };


  DEBUG_printf(("cupsCopyDestInfo(http=%p, dest=%p(%s))", (void *)http, (void *)dest, dest ? dest->name : ""));

 /*
  * Get the default connection as needed...
  */

  if (!http)
  {
    DEBUG_puts("1cupsCopyDestInfo: Default server connection.");
    http   = _cupsConnect();
    dflags = CUPS_DEST_FLAGS_NONE;
  }
#ifdef AF_LOCAL
  else if (httpAddrFamily(http->hostaddr) == AF_LOCAL)
  {
    DEBUG_puts("1cupsCopyDestInfo: Connection to server (domain socket).");
    dflags = CUPS_DEST_FLAGS_NONE;
  }
#endif /* AF_LOCAL */
  else if ((strcmp(http->hostname, cg->server) && cg->server[0] != '/') || cg->ipp_port != httpAddrPort(http->hostaddr))
  {
    DEBUG_printf(("1cupsCopyDestInfo: Connection to device (%s).", http->hostname));
    dflags = CUPS_DEST_FLAGS_DEVICE;
  }
  else
  {
    DEBUG_printf(("1cupsCopyDestInfo: Connection to server (%s).", http->hostname));
    dflags = CUPS_DEST_FLAGS_NONE;
  }

 /*
  * Range check input...
  */

  if (!http || !dest)
    return (NULL);

 /*
  * Get the printer URI and resource path...
  */

  if ((uri = _cupsGetDestResource(dest, dflags, resource, sizeof(resource))) == NULL)
  {
    DEBUG_puts("1cupsCopyDestInfo: Unable to get resource.");
    return (NULL);
  }

 /*
  * Get the supported attributes...
  */

  delay      = 1;
  prev_delay = 1;
  tries      = 0;
  version    = 20;

  do
  {
   /*
    * Send a Get-Printer-Attributes request...
    */

    request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);

    ippSetVersion(request, version / 10, version % 10);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
    ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(requested_attrs) / sizeof(requested_attrs[0])), NULL, requested_attrs);
    response = cupsDoRequest(http, request, resource);
    status   = cupsLastError();

    if (status > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
    {
      DEBUG_printf(("1cupsCopyDestInfo: Get-Printer-Attributes for '%s' returned %s (%s)", dest->name, ippErrorString(status), cupsLastErrorString()));

      ippDelete(response);
      response = NULL;

      if ((status == IPP_STATUS_ERROR_BAD_REQUEST || status == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED) && version > 11)
      {
        version = 11;
      }
      else if (status == IPP_STATUS_ERROR_BUSY)
      {
        sleep((unsigned)delay);

        delay = _cupsNextDelay(delay, &prev_delay);
      }
      else
        return (NULL);
    }

    tries ++;
  }
  while (!response && tries < 10);

  if (!response)
  {
    DEBUG_puts("1cupsCopyDestInfo: Unable to get printer attributes.");
    return (NULL);
  }

 /*
  * Allocate a cups_dinfo_t structure and return it...
  */

  if ((dinfo = calloc(1, sizeof(cups_dinfo_t))) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
    ippDelete(response);
    return (NULL);
  }

  DEBUG_printf(("1cupsCopyDestInfo: version=%d, uri=\"%s\", resource=\"%s\".", version, uri, resource));

  dinfo->version  = version;
  dinfo->uri      = uri;
  dinfo->resource = _cupsStrAlloc(resource);
  dinfo->attrs    = response;

  return (dinfo);
}


/*
 * 'cupsFindDestDefault()' - Find the default value(s) for the given option.
 *
 * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
 * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
 * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
 * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
 * functions to inspect the default value(s) as needed.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

ipp_attribute_t	*			/* O - Default attribute or @code NULL@ for none */
cupsFindDestDefault(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option)		/* I - Option/attribute name */
{
  char	name[IPP_MAX_NAME];		/* Attribute name */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

 /*
  * Find and return the attribute...
  */

  snprintf(name, sizeof(name), "%s-default", option);
  return (ippFindAttribute(dinfo->attrs, name, IPP_TAG_ZERO));
}


/*
 * 'cupsFindDestReady()' - Find the default value(s) for the given option.
 *
 * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
 * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
 * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
 * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
 * functions to inspect the default value(s) as needed.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

ipp_attribute_t	*			/* O - Default attribute or @code NULL@ for none */
cupsFindDestReady(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option)		/* I - Option/attribute name */
{
  char	name[IPP_MAX_NAME];		/* Attribute name */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

 /*
  * Find and return the attribute...
  */

  cups_update_ready(http, dinfo);

  snprintf(name, sizeof(name), "%s-ready", option);
  return (ippFindAttribute(dinfo->ready_attrs, name, IPP_TAG_ZERO));
}


/*
 * 'cupsFindDestSupported()' - Find the default value(s) for the given option.
 *
 * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
 * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
 * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
 * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
 * functions to inspect the default value(s) as needed.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

ipp_attribute_t	*			/* O - Default attribute or @code NULL@ for none */
cupsFindDestSupported(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option)		/* I - Option/attribute name */
{
  char	name[IPP_MAX_NAME];		/* Attribute name */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

 /*
  * Find and return the attribute...
  */

  snprintf(name, sizeof(name), "%s-supported", option);
  return (ippFindAttribute(dinfo->attrs, name, IPP_TAG_ZERO));
}


/*
 * 'cupsFreeDestInfo()' - Free destination information obtained using
 *                        @link cupsCopyDestInfo@.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

void
cupsFreeDestInfo(cups_dinfo_t *dinfo)	/* I - Destination information */
{
 /*
  * Range check input...
  */

  if (!dinfo)
    return;

 /*
  * Free memory and return...
  */

  _cupsStrFree(dinfo->resource);

  cupsArrayDelete(dinfo->constraints);
  cupsArrayDelete(dinfo->resolvers);

  cupsArrayDelete(dinfo->localizations);

  cupsArrayDelete(dinfo->media_db);

  cupsArrayDelete(dinfo->cached_db);

  ippDelete(dinfo->ready_attrs);
  cupsArrayDelete(dinfo->ready_db);

  ippDelete(dinfo->attrs);

  free(dinfo);
}


/*
 * 'cupsGetDestMediaByIndex()' - Get a media name, dimension, and margins for a
 *                               specific size.
 *
 * The @code flags@ parameter determines which set of media are indexed.  For
 * example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will get the Nth
 * borderless size supported by the printer.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

int					/* O - 1 on success, 0 on failure */
cupsGetDestMediaByIndex(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    int          n,			/* I - Media size number (0-based) */
    unsigned     flags,			/* I - Media flags */
    cups_size_t  *size)			/* O - Media size information */
{
  _cups_media_db_t	*nsize;		/* Size for N */
  pwg_media_t		*pwg;		/* PWG media name for size */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || n < 0 || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Load media list as needed...
  */

  if (flags & CUPS_MEDIA_FLAGS_READY)
    cups_update_ready(http, dinfo);

  if (!dinfo->cached_db || dinfo->cached_flags != flags)
    cups_create_cached(http, dinfo, flags);

 /*
  * Copy the size over and return...
  */

  if ((nsize = (_cups_media_db_t *)cupsArrayIndex(dinfo->cached_db, n)) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

  if (nsize->key)
    strlcpy(size->media, nsize->key, sizeof(size->media));
  else if (nsize->size_name)
    strlcpy(size->media, nsize->size_name, sizeof(size->media));
  else if ((pwg = pwgMediaForSize(nsize->width, nsize->length)) != NULL)
    strlcpy(size->media, pwg->pwg, sizeof(size->media));
  else
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

  size->width  = nsize->width;
  size->length = nsize->length;
  size->bottom = nsize->bottom;
  size->left   = nsize->left;
  size->right  = nsize->right;
  size->top    = nsize->top;

  return (1);
}


/*
 * 'cupsGetDestMediaByName()' - Get media names, dimensions, and margins.
 *
 * The "media" string is a PWG media name.  "Flags" provides some matching
 * guidance (multiple flags can be combined):
 *
 * CUPS_MEDIA_FLAGS_DEFAULT    = find the closest size supported by the printer,
 * CUPS_MEDIA_FLAGS_BORDERLESS = find a borderless size,
 * CUPS_MEDIA_FLAGS_DUPLEX     = find a size compatible with 2-sided printing,
 * CUPS_MEDIA_FLAGS_EXACT      = find an exact match for the size, and
 * CUPS_MEDIA_FLAGS_READY      = if the printer supports media sensing, find the
 *                               size amongst the "ready" media.
 *
 * The matching result (if any) is returned in the "cups_size_t" structure.
 *
 * Returns 1 when there is a match and 0 if there is not a match.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 on match, 0 on failure */
cupsGetDestMediaByName(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *media,		/* I - Media name */
    unsigned     flags,			/* I - Media matching flags */
    cups_size_t  *size)			/* O - Media size information */
{
  pwg_media_t		*pwg;		/* PWG media info */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || !media || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Lookup the media size name...
  */

  if ((pwg = pwgMediaForPWG(media)) == NULL)
    if ((pwg = pwgMediaForLegacy(media)) == NULL)
    {
      DEBUG_printf(("1cupsGetDestMediaByName: Unknown size '%s'.", media));
      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown media size name."), 1);
      return (0);
    }

 /*
  * Lookup the size...
  */

  return (cups_get_media_db(http, dinfo, pwg, flags, size));
}


/*
 * 'cupsGetDestMediaBySize()' - Get media names, dimensions, and margins.
 *
 * "Width" and "length" are the dimensions in hundredths of millimeters.
 * "Flags" provides some matching guidance (multiple flags can be combined):
 *
 * CUPS_MEDIA_FLAGS_DEFAULT    = find the closest size supported by the printer,
 * CUPS_MEDIA_FLAGS_BORDERLESS = find a borderless size,
 * CUPS_MEDIA_FLAGS_DUPLEX     = find a size compatible with 2-sided printing,
 * CUPS_MEDIA_FLAGS_EXACT      = find an exact match for the size, and
 * CUPS_MEDIA_FLAGS_READY      = if the printer supports media sensing, find the
 *                               size amongst the "ready" media.
 *
 * The matching result (if any) is returned in the "cups_size_t" structure.
 *
 * Returns 1 when there is a match and 0 if there is not a match.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 on match, 0 on failure */
cupsGetDestMediaBySize(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    int         width,			/* I - Media width in hundredths of
					 *     of millimeters */
    int         length,			/* I - Media length in hundredths of
					 *     of millimeters */
    unsigned     flags,			/* I - Media matching flags */
    cups_size_t  *size)			/* O - Media size information */
{
  pwg_media_t		*pwg;		/* PWG media info */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || width <= 0 || length <= 0 || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Lookup the media size name...
  */

  if ((pwg = pwgMediaForSize(width, length)) == NULL)
  {
    DEBUG_printf(("1cupsGetDestMediaBySize: Invalid size %dx%d.", width,
                  length));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid media size."), 1);
    return (0);
  }

 /*
  * Lookup the size...
  */

  return (cups_get_media_db(http, dinfo, pwg, flags, size));
}


/*
 * 'cupsGetDestMediaCount()' - Get the number of sizes supported by a
 *                             destination.
 *
 * The @code flags@ parameter determines the set of media sizes that are
 * counted.  For example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will return
 * the number of borderless sizes.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

int					/* O - Number of sizes */
cupsGetDestMediaCount(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    unsigned     flags)			/* I - Media flags */
{
 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Load media list as needed...
  */

  if (flags & CUPS_MEDIA_FLAGS_READY)
    cups_update_ready(http, dinfo);

  if (!dinfo->cached_db || dinfo->cached_flags != flags)
    cups_create_cached(http, dinfo, flags);

  return (cupsArrayCount(dinfo->cached_db));
}


/*
 * 'cupsGetDestMediaDefault()' - Get the default size for a destination.
 *
 * The @code flags@ parameter determines which default size is returned.  For
 * example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will return the default
 * borderless size, typically US Letter or A4, but sometimes 4x6 photo media.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

int					/* O - 1 on success, 0 on failure */
cupsGetDestMediaDefault(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    unsigned     flags,			/* I - Media flags */
    cups_size_t  *size)			/* O - Media size information */
{
  const char	*media;			/* Default media size */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Get the default media size, if any...
  */

  if ((media = cupsGetOption("media", dest->num_options, dest->options)) == NULL)
    media = "na_letter_8.5x11in";

  if (cupsGetDestMediaByName(http, dest, dinfo, media, flags, size))
    return (1);

  if (strcmp(media, "na_letter_8.5x11in") && cupsGetDestMediaByName(http, dest, dinfo, "iso_a4_210x297mm", flags, size))
    return (1);

  if (strcmp(media, "iso_a4_210x297mm") && cupsGetDestMediaByName(http, dest, dinfo, "na_letter_8.5x11in", flags, size))
    return (1);

  if ((flags & CUPS_MEDIA_FLAGS_BORDERLESS) && cupsGetDestMediaByName(http, dest, dinfo, "na_index_4x6in", flags, size))
    return (1);

 /*
  * Fall back to the first matching media size...
  */

  return (cupsGetDestMediaByIndex(http, dest, dinfo, 0, flags, size));
}


/*
 * 'cups_add_dconstres()' - Add a constraint or resolver to an array.
 */

static void
cups_add_dconstres(
    cups_array_t *a,			/* I - Array */
    ipp_t        *collection)		/* I - Collection value */
{
  ipp_attribute_t	*attr;		/* Attribute */
  _cups_dconstres_t	*temp;		/* Current constraint/resolver */


  if ((attr = ippFindAttribute(collection, "resolver-name",
                               IPP_TAG_NAME)) == NULL)
    return;

  if ((temp = calloc(1, sizeof(_cups_dconstres_t))) == NULL)
    return;

  temp->name       = attr->values[0].string.text;
  temp->collection = collection;

  cupsArrayAdd(a, temp);
}


/*
 * 'cups_collection_contains()' - Check whether test collection is contained in the matching collection.
 */

static int				/* O - 1 on a match, 0 on a non-match */
cups_collection_contains(ipp_t *test,	/* I - Collection to test */
                         ipp_t *match)	/* I - Matching values */
{
  int			i, j,		/* Looping vars */
			mcount,		/* Number of match values */
			tcount;		/* Number of test values */
  ipp_attribute_t	*tattr,		/* Testing attribute */
			*mattr;		/* Matching attribute */
  const char		*tval;		/* Testing string value */


  for (mattr = ippFirstAttribute(match); mattr; mattr = ippNextAttribute(match))
  {
    if ((tattr = ippFindAttribute(test, ippGetName(mattr), IPP_TAG_ZERO)) == NULL)
      return (0);

    tcount = ippGetCount(tattr);

    switch (ippGetValueTag(mattr))
    {
      case IPP_TAG_INTEGER :
      case IPP_TAG_ENUM :
          if (ippGetValueTag(tattr) != ippGetValueTag(mattr))
            return (0);

          for (i = 0; i < tcount; i ++)
          {
            if (!ippContainsInteger(mattr, ippGetInteger(tattr, i)))
              return (0);
          }
          break;

      case IPP_TAG_RANGE :
          if (ippGetValueTag(tattr) != IPP_TAG_INTEGER)
            return (0);

          for (i = 0; i < tcount; i ++)
          {
            if (!ippContainsInteger(mattr, ippGetInteger(tattr, i)))
              return (0);
          }
          break;

      case IPP_TAG_BOOLEAN :
          if (ippGetValueTag(tattr) != IPP_TAG_BOOLEAN || ippGetBoolean(tattr, 0) != ippGetBoolean(mattr, 0))
            return (0);
          break;

      case IPP_TAG_TEXTLANG :
      case IPP_TAG_NAMELANG :
      case IPP_TAG_TEXT :
      case IPP_TAG_NAME :
      case IPP_TAG_KEYWORD :
      case IPP_TAG_URI :
      case IPP_TAG_URISCHEME :
      case IPP_TAG_CHARSET :
      case IPP_TAG_LANGUAGE :
      case IPP_TAG_MIMETYPE :
          for (i = 0; i < tcount; i ++)
          {
            if ((tval = ippGetString(tattr, i, NULL)) == NULL || !ippContainsString(mattr, tval))
              return (0);
          }
          break;

      case IPP_TAG_BEGIN_COLLECTION :
          for (i = 0; i < tcount; i ++)
          {
            ipp_t *tcol = ippGetCollection(tattr, i);
					/* Testing collection */

            for (j = 0, mcount = ippGetCount(mattr); j < mcount; j ++)
              if (!cups_collection_contains(tcol, ippGetCollection(mattr, j)))
                return (0);
          }
          break;

      default :
          return (0);
    }
  }

  return (1);
}


/*
 * 'cups_collection_string()' - Convert an IPP collection to an option string.
 */

static size_t				/* O - Number of bytes needed */
cups_collection_string(
    ipp_attribute_t *attr,		/* I - Collection attribute */
    char            *buffer,		/* I - String buffer */
    size_t          bufsize)		/* I - Size of buffer */
{
  int			i, j,		/* Looping vars */
			count,		/* Number of collection values */
			mcount;		/* Number of member values */
  ipp_t			*col;		/* Collection */
  ipp_attribute_t	*first,		/* First member attribute */
			*member;	/* Member attribute */
  char			*bufptr,	/* Pointer into buffer */
			*bufend,	/* End of buffer */
			temp[100];	/* Temporary string */
  const char		*mptr;		/* Pointer into member value */
  int			mlen;		/* Length of octetString */


  bufptr = buffer;
  bufend = buffer + bufsize - 1;

  for (i = 0, count = ippGetCount(attr); i < count; i ++)
  {
    col = ippGetCollection(attr, i);

    if (i)
    {
      if (bufptr < bufend)
        *bufptr++ = ',';
      else
        bufptr ++;
    }

    if (bufptr < bufend)
      *bufptr++ = '{';
    else
      bufptr ++;

    for (member = first = ippFirstAttribute(col); member; member = ippNextAttribute(col))
    {
      const char *mname = ippGetName(member);

      if (member != first)
      {
	if (bufptr < bufend)
	  *bufptr++ = ' ';
	else
	  bufptr ++;
      }

      if (ippGetValueTag(member) == IPP_TAG_BOOLEAN)
      {
        if (!ippGetBoolean(member, 0))
        {
	  if (bufptr < bufend)
	    strlcpy(bufptr, "no", (size_t)(bufend - bufptr + 1));
	  bufptr += 2;
        }

	if (bufptr < bufend)
	  strlcpy(bufptr, mname, (size_t)(bufend - bufptr + 1));
	bufptr += strlen(mname);
        continue;
      }

      if (bufptr < bufend)
        strlcpy(bufptr, mname, (size_t)(bufend - bufptr + 1));
      bufptr += strlen(mname);

      if (bufptr < bufend)
        *bufptr++ = '=';
      else
        bufptr ++;

      if (ippGetValueTag(member) == IPP_TAG_BEGIN_COLLECTION)
      {
       /*
	* Convert sub-collection...
	*/

	bufptr += cups_collection_string(member, bufptr, bufptr < bufend ? (size_t)(bufend - bufptr + 1) : 0);
      }
      else
      {
       /*
        * Convert simple type...
        */

	for (j = 0, mcount = ippGetCount(member); j < mcount; j ++)
	{
	  if (j)
	  {
	    if (bufptr < bufend)
	      *bufptr++ = ',';
	    else
	      bufptr ++;
	  }

          switch (ippGetValueTag(member))
          {
            case IPP_TAG_INTEGER :
            case IPP_TAG_ENUM :
                bufptr += snprintf(bufptr, bufptr < bufend ? (size_t)(bufend - bufptr + 1) : 0, "%d", ippGetInteger(member, j));
                break;

	    case IPP_TAG_STRING :
		if (bufptr < bufend)
		  *bufptr++ = '\"';
		else
		  bufptr ++;

	        for (mptr = (const char *)ippGetOctetString(member, j, &mlen); mlen > 0; mlen --, mptr ++)
	        {
	          if (*mptr == '\"' || *mptr == '\\')
	          {
		    if (bufptr < bufend)
		      *bufptr++ = '\\';
		    else
		      bufptr ++;
		  }

		  if (bufptr < bufend)
		    *bufptr++ = *mptr;
		  else
		    bufptr ++;
                }

		if (bufptr < bufend)
		  *bufptr++ = '\"';
		else
		  bufptr ++;
	        break;

            case IPP_TAG_DATE :
		{
		  unsigned year;	/* Year */
		  const ipp_uchar_t *date = ippGetDate(member, j);
					/* Date value */

		  year = ((unsigned)date[0] << 8) + (unsigned)date[1];

		  if (date[9] == 0 && date[10] == 0)
		    snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ", year, date[2], date[3], date[4], date[5], date[6]);
		  else
		    snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u", year, date[2], date[3], date[4], date[5], date[6], date[8], date[9], date[10]);

		  if (bufptr < bufend)
		    strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));

		  bufptr += strlen(temp);
		}
                break;

            case IPP_TAG_RESOLUTION :
                {
                  int		xres,	/* Horizontal resolution */
				yres;	/* Vertical resolution */
                  ipp_res_t	units;	/* Resolution units */

                  xres = ippGetResolution(member, j, &yres, &units);

                  if (xres == yres)
                    snprintf(temp, sizeof(temp), "%d%s", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
		  else
                    snprintf(temp, sizeof(temp), "%dx%d%s", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");

		  if (bufptr < bufend)
		    strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));

		  bufptr += strlen(temp);
                }
                break;

            case IPP_TAG_RANGE :
                {
                  int		lower,	/* Lower bound */
				upper;	/* Upper bound */

                  lower = ippGetRange(member, j, &upper);

		  snprintf(temp, sizeof(temp), "%d-%d", lower, upper);

		  if (bufptr < bufend)
		    strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));

		  bufptr += strlen(temp);
                }
                break;

            case IPP_TAG_TEXTLANG :
            case IPP_TAG_NAMELANG :
            case IPP_TAG_TEXT :
            case IPP_TAG_NAME :
            case IPP_TAG_KEYWORD :
            case IPP_TAG_URI :
            case IPP_TAG_URISCHEME :
            case IPP_TAG_CHARSET :
            case IPP_TAG_LANGUAGE :
            case IPP_TAG_MIMETYPE :
		if (bufptr < bufend)
		  *bufptr++ = '\"';
		else
		  bufptr ++;

	        for (mptr = ippGetString(member, j, NULL); *mptr; mptr ++)
	        {
	          if (*mptr == '\"' || *mptr == '\\')
	          {
		    if (bufptr < bufend)
		      *bufptr++ = '\\';
		    else
		      bufptr ++;
		  }

		  if (bufptr < bufend)
		    *bufptr++ = *mptr;
		  else
		    bufptr ++;
                }

		if (bufptr < bufend)
		  *bufptr++ = '\"';
		else
		  bufptr ++;
                break;

            default :
                break;
          }
	}
      }
    }

    if (bufptr < bufend)
      *bufptr++ = '}';
    else
      bufptr ++;
  }

  *bufptr = '\0';
  return ((size_t)(bufptr - buffer + 1));
}


/*
 * 'cups_compare_dconstres()' - Compare to resolver entries.
 */

static int				/* O - Result of comparison */
cups_compare_dconstres(
    _cups_dconstres_t *a,		/* I - First resolver */
    _cups_dconstres_t *b)		/* I - Second resolver */
{
  return (strcmp(a->name, b->name));
}


/*
 * 'cups_compare_media_db()' - Compare two media entries.
 */

static int				/* O - Result of comparison */
cups_compare_media_db(
    _cups_media_db_t *a,		/* I - First media entries */
    _cups_media_db_t *b)		/* I - Second media entries */
{
  int	result;				/* Result of comparison */


  if ((result = a->width - b->width) == 0)
    result = a->length - b->length;

  return (result);
}


/*
 * 'cups_copy_media_db()' - Copy a media entry.
 */

static _cups_media_db_t *		/* O - New media entry */
cups_copy_media_db(
    _cups_media_db_t *mdb)		/* I - Media entry to copy */
{
  _cups_media_db_t *temp;		/* New media entry */


  if ((temp = calloc(1, sizeof(_cups_media_db_t))) == NULL)
    return (NULL);

  if (mdb->color)
    temp->color = _cupsStrAlloc(mdb->color);
  if (mdb->key)
    temp->key = _cupsStrAlloc(mdb->key);
  if (mdb->info)
    temp->info = _cupsStrAlloc(mdb->info);
  if (mdb->size_name)
    temp->size_name = _cupsStrAlloc(mdb->size_name);
  if (mdb->source)
    temp->source = _cupsStrAlloc(mdb->source);
  if (mdb->type)
    temp->type = _cupsStrAlloc(mdb->type);

  temp->width  = mdb->width;
  temp->length = mdb->length;
  temp->bottom = mdb->bottom;
  temp->left   = mdb->left;
  temp->right  = mdb->right;
  temp->top    = mdb->top;

  return (temp);
}


/*
 * 'cups_create_cached()' - Create the media selection cache.
 */

static void
cups_create_cached(http_t       *http,	/* I - Connection to destination */
                   cups_dinfo_t *dinfo,	/* I - Destination information */
                   unsigned     flags)	/* I - Media selection flags */
{
  cups_array_t		*db;		/* Media database array to use */
  _cups_media_db_t	*mdb,		/* Media database entry */
			*first;		/* First entry this size */


  DEBUG_printf(("3cups_create_cached(http=%p, dinfo=%p, flags=%u)", (void *)http, (void *)dinfo, flags));

  if (dinfo->cached_db)
    cupsArrayDelete(dinfo->cached_db);

  dinfo->cached_db    = cupsArrayNew(NULL, NULL);
  dinfo->cached_flags = flags;

  if (flags & CUPS_MEDIA_FLAGS_READY)
  {
    DEBUG_puts("4cups_create_cached: ready media");

    cups_update_ready(http, dinfo);
    db = dinfo->ready_db;
  }
  else
  {
    DEBUG_puts("4cups_create_cached: supported media");

    if (!dinfo->media_db)
      cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_DEFAULT);

    db = dinfo->media_db;
  }

  for (mdb = (_cups_media_db_t *)cupsArrayFirst(db), first = mdb;
       mdb;
       mdb = (_cups_media_db_t *)cupsArrayNext(db))
  {
    DEBUG_printf(("4cups_create_cached: %p key=\"%s\", type=\"%s\", %dx%d, B%d L%d R%d T%d", (void *)mdb, mdb->key, mdb->type, mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top));

    if (flags & CUPS_MEDIA_FLAGS_BORDERLESS)
    {
      if (!mdb->left && !mdb->right && !mdb->top && !mdb->bottom)
      {
        DEBUG_printf(("4cups_create_cached: add %p", (void *)mdb));
        cupsArrayAdd(dinfo->cached_db, mdb);
      }
    }
    else if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
    {
      if (first->width != mdb->width || first->length != mdb->length)
      {
	DEBUG_printf(("4cups_create_cached: add %p", (void *)first));
        cupsArrayAdd(dinfo->cached_db, first);
        first = mdb;
      }
      else if (mdb->left >= first->left && mdb->right >= first->right && mdb->top >= first->top && mdb->bottom >= first->bottom &&
	       (mdb->left != first->left || mdb->right != first->right || mdb->top != first->top || mdb->bottom != first->bottom))
        first = mdb;
    }
    else
    {
      DEBUG_printf(("4cups_create_cached: add %p", (void *)mdb));
      cupsArrayAdd(dinfo->cached_db, mdb);
    }
  }

  if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
  {
    DEBUG_printf(("4cups_create_cached: add %p", (void *)first));
    cupsArrayAdd(dinfo->cached_db, first);
  }
}


/*
 * 'cups_create_constraints()' - Create the constraints and resolvers arrays.
 */

static void
cups_create_constraints(
    cups_dinfo_t *dinfo)		/* I - Destination information */
{
  int			i;		/* Looping var */
  ipp_attribute_t	*attr;		/* Attribute */
  _ipp_value_t		*val;		/* Current value */


  dinfo->constraints = cupsArrayNew3(NULL, NULL, NULL, 0, NULL,
                                     (cups_afree_func_t)free);
  dinfo->resolvers   = cupsArrayNew3((cups_array_func_t)cups_compare_dconstres,
				     NULL, NULL, 0, NULL,
                                     (cups_afree_func_t)free);

  if ((attr = ippFindAttribute(dinfo->attrs, "job-constraints-supported",
			       IPP_TAG_BEGIN_COLLECTION)) != NULL)
  {
    for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
      cups_add_dconstres(dinfo->constraints, val->collection);
  }

  if ((attr = ippFindAttribute(dinfo->attrs, "job-resolvers-supported",
			       IPP_TAG_BEGIN_COLLECTION)) != NULL)
  {
    for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
      cups_add_dconstres(dinfo->resolvers, val->collection);
  }
}


/*
 * 'cups_create_defaults()' - Create the -default option array.
 */

static void
cups_create_defaults(
    cups_dinfo_t *dinfo)		/* I - Destination information */
{
  ipp_attribute_t	*attr;		/* Current attribute */
  char			name[IPP_MAX_NAME + 1],
					/* Current name */
			*nameptr,	/* Pointer into current name */
			value[2048];	/* Current value */


 /*
  * Iterate through the printer attributes looking for xxx-default and adding
  * xxx=value to the defaults option array.
  */

  for (attr = ippFirstAttribute(dinfo->attrs); attr; attr = ippNextAttribute(dinfo->attrs))
  {
    if (!ippGetName(attr) || ippGetGroupTag(attr) != IPP_TAG_PRINTER)
      continue;

    strlcpy(name, ippGetName(attr), sizeof(name));
    if ((nameptr = name + strlen(name) - 8) <= name || strcmp(nameptr, "-default"))
      continue;

    *nameptr = '\0';

    if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION)
    {
      if (cups_collection_string(attr, value, sizeof(value)) >= sizeof(value))
        continue;
    }
    else if (ippAttributeString(attr, value, sizeof(value)) >= sizeof(value))
      continue;

    dinfo->num_defaults = cupsAddOption(name, value, dinfo->num_defaults, &dinfo->defaults);
  }
}


/*
 * 'cups_create_media_db()' - Create the media database.
 */

static void
cups_create_media_db(
    cups_dinfo_t *dinfo,		/* I - Destination information */
    unsigned     flags)			/* I - Media flags */
{
  int			i;		/* Looping var */
  _ipp_value_t		*val;		/* Current value */
  ipp_attribute_t	*media_col_db,	/* media-col-database */
			*media_attr,	/* media-xxx */
			*x_dimension,	/* x-dimension */
			*y_dimension;	/* y-dimension */
  pwg_media_t		*pwg;		/* PWG media info */
  cups_array_t		*db;		/* New media database array */
  _cups_media_db_t	mdb;		/* Media entry */
  char			media_key[256];	/* Synthesized media-key value */


  db = cupsArrayNew3((cups_array_func_t)cups_compare_media_db,
		     NULL, NULL, 0,
		     (cups_acopy_func_t)cups_copy_media_db,
		     (cups_afree_func_t)cups_free_media_db);

  if (flags == CUPS_MEDIA_FLAGS_READY)
  {
    dinfo->ready_db = db;

    media_col_db = ippFindAttribute(dinfo->ready_attrs, "media-col-ready",
				    IPP_TAG_BEGIN_COLLECTION);
    media_attr   = ippFindAttribute(dinfo->ready_attrs, "media-ready",
				    IPP_TAG_ZERO);
  }
  else
  {
    dinfo->media_db        = db;
    dinfo->min_size.width  = INT_MAX;
    dinfo->min_size.length = INT_MAX;
    dinfo->max_size.width  = 0;
    dinfo->max_size.length = 0;

    media_col_db = ippFindAttribute(dinfo->attrs, "media-col-database",
				    IPP_TAG_BEGIN_COLLECTION);
    media_attr   = ippFindAttribute(dinfo->attrs, "media-supported",
				    IPP_TAG_ZERO);
  }

  if (media_col_db)
  {
    _ipp_value_t	*custom = NULL;	/* Custom size range value */

    for (i = media_col_db->num_values, val = media_col_db->values;
         i > 0;
         i --, val ++)
    {
      memset(&mdb, 0, sizeof(mdb));

      if ((media_attr = ippFindAttribute(val->collection, "media-size",
                                         IPP_TAG_BEGIN_COLLECTION)) != NULL)
      {
        ipp_t	*media_size = media_attr->values[0].collection;
					/* media-size collection value */

        if ((x_dimension = ippFindAttribute(media_size, "x-dimension",
                                            IPP_TAG_INTEGER)) != NULL &&
	    (y_dimension = ippFindAttribute(media_size, "y-dimension",
					    IPP_TAG_INTEGER)) != NULL)
	{
	 /*
	  * Fixed size...
	  */

	  mdb.width  = x_dimension->values[0].integer;
	  mdb.length = y_dimension->values[0].integer;
	}
	else if ((x_dimension = ippFindAttribute(media_size, "x-dimension",
						 IPP_TAG_INTEGER)) != NULL &&
		 (y_dimension = ippFindAttribute(media_size, "y-dimension",
						 IPP_TAG_RANGE)) != NULL)
	{
	 /*
	  * Roll limits...
	  */

	  mdb.width  = x_dimension->values[0].integer;
	  mdb.length = y_dimension->values[0].range.upper;
	}
        else if (flags != CUPS_MEDIA_FLAGS_READY &&
                 (x_dimension = ippFindAttribute(media_size, "x-dimension",
					         IPP_TAG_RANGE)) != NULL &&
		 (y_dimension = ippFindAttribute(media_size, "y-dimension",
						 IPP_TAG_RANGE)) != NULL)
	{
	 /*
	  * Custom size range; save this as the custom size value with default
	  * margins, then continue; we'll capture the real margins below...
	  */

	  custom = val;

	  dinfo->min_size.width  = x_dimension->values[0].range.lower;
	  dinfo->min_size.length = y_dimension->values[0].range.lower;
	  dinfo->min_size.left   =
	  dinfo->min_size.right  = 635; /* Default 1/4" side margins */
	  dinfo->min_size.top    =
	  dinfo->min_size.bottom = 1270; /* Default 1/2" top/bottom margins */

	  dinfo->max_size.width  = x_dimension->values[0].range.upper;
	  dinfo->max_size.length = y_dimension->values[0].range.upper;
	  dinfo->max_size.left   =
	  dinfo->max_size.right  = 635; /* Default 1/4" side margins */
	  dinfo->max_size.top    =
	  dinfo->max_size.bottom = 1270; /* Default 1/2" top/bottom margins */
	  continue;
	}
      }

      if ((media_attr = ippFindAttribute(val->collection, "media-color", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.color = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-info", IPP_TAG_TEXT)) != NULL)
        mdb.info = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-key", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.key = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-size-name", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.size_name = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-source", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.source = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-type", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.type = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-bottom-margin", IPP_TAG_INTEGER)) != NULL)
        mdb.bottom = media_attr->values[0].integer;

      if ((media_attr = ippFindAttribute(val->collection, "media-left-margin", IPP_TAG_INTEGER)) != NULL)
        mdb.left = media_attr->values[0].integer;

      if ((media_attr = ippFindAttribute(val->collection, "media-right-margin", IPP_TAG_INTEGER)) != NULL)
        mdb.right = media_attr->values[0].integer;

      if ((media_attr = ippFindAttribute(val->collection, "media-top-margin", IPP_TAG_INTEGER)) != NULL)
        mdb.top = media_attr->values[0].integer;

      if (!mdb.key)
      {
        if (!mdb.size_name && (pwg = pwgMediaForSize(mdb.width, mdb.length)) != NULL)
	  mdb.size_name = (char *)pwg->pwg;

        if (!mdb.size_name)
        {
         /*
          * Use a CUPS-specific identifier if we don't have a size name...
          */

	  if (flags & CUPS_MEDIA_FLAGS_READY)
	    snprintf(media_key, sizeof(media_key), "cups-media-ready-%d", i + 1);
	  else
	    snprintf(media_key, sizeof(media_key), "cups-media-%d", i + 1);
        }
        else if (mdb.source)
        {
         /*
          * Generate key using size name, source, and type (if set)...
          */

          if (mdb.type)
            snprintf(media_key, sizeof(media_key), "%s_%s_%s", mdb.size_name, mdb.source, mdb.type);
	  else
            snprintf(media_key, sizeof(media_key), "%s_%s", mdb.size_name, mdb.source);
        }
        else if (mdb.type)
        {
         /*
          * Generate key using size name and type...
          */

	  snprintf(media_key, sizeof(media_key), "%s_%s", mdb.size_name, mdb.type);
        }
        else
        {
         /*
          * Key is just the size name...
          */

          strlcpy(media_key, mdb.size_name, sizeof(media_key));
        }

       /*
        * Append "_borderless" for borderless media...
        */

        if (!mdb.bottom && !mdb.left && !mdb.right && !mdb.top)
          strlcat(media_key, "_borderless", sizeof(media_key));

        mdb.key = media_key;
      }

      DEBUG_printf(("1cups_create_media_db: Adding media: key=\"%s\", width=%d, length=%d, source=\"%s\", type=\"%s\".", mdb.key, mdb.width, mdb.length, mdb.source, mdb.type));

      cupsArrayAdd(db, &mdb);
    }

    if (custom)
    {
      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-bottom-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.top =
        dinfo->max_size.top = media_attr->values[0].integer;
      }

      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-left-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.left =
        dinfo->max_size.left = media_attr->values[0].integer;
      }

      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-right-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.right =
        dinfo->max_size.right = media_attr->values[0].integer;
      }

      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-top-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.top =
        dinfo->max_size.top = media_attr->values[0].integer;
      }
    }
  }
  else if (media_attr &&
           (media_attr->value_tag == IPP_TAG_NAME ||
            media_attr->value_tag == IPP_TAG_NAMELANG ||
            media_attr->value_tag == IPP_TAG_KEYWORD))
  {
    memset(&mdb, 0, sizeof(mdb));

    mdb.left   =
    mdb.right  = 635; /* Default 1/4" side margins */
    mdb.top    =
    mdb.bottom = 1270; /* Default 1/2" top/bottom margins */

    for (i = media_attr->num_values, val = media_attr->values;
         i > 0;
         i --, val ++)
    {
      if ((pwg = pwgMediaForPWG(val->string.text)) == NULL)
        if ((pwg = pwgMediaForLegacy(val->string.text)) == NULL)
	{
	  DEBUG_printf(("3cups_create_media_db: Ignoring unknown size '%s'.",
			val->string.text));
	  continue;
	}

      mdb.width  = pwg->width;
      mdb.length = pwg->length;

      if (flags != CUPS_MEDIA_FLAGS_READY &&
          !strncmp(val->string.text, "custom_min_", 11))
      {
        mdb.size_name   = NULL;
        dinfo->min_size = mdb;
      }
      else if (flags != CUPS_MEDIA_FLAGS_READY &&
	       !strncmp(val->string.text, "custom_max_", 11))
      {
        mdb.size_name   = NULL;
        dinfo->max_size = mdb;
      }
      else
      {
        mdb.size_name = val->string.text;

        cupsArrayAdd(db, &mdb);
      }
    }
  }
}


/*
 * 'cups_free_media_cb()' - Free a media entry.
 */

static void
cups_free_media_db(
    _cups_media_db_t *mdb)		/* I - Media entry to free */
{
  if (mdb->color)
    _cupsStrFree(mdb->color);
  if (mdb->key)
    _cupsStrFree(mdb->key);
  if (mdb->info)
    _cupsStrFree(mdb->info);
  if (mdb->size_name)
    _cupsStrFree(mdb->size_name);
  if (mdb->source)
    _cupsStrFree(mdb->source);
  if (mdb->type)
    _cupsStrFree(mdb->type);

  free(mdb);
}


/*
 * 'cups_get_media_db()' - Lookup the media entry for a given size.
 */

static int				/* O - 1 on match, 0 on failure */
cups_get_media_db(http_t       *http,	/* I - Connection to destination */
                  cups_dinfo_t *dinfo,	/* I - Destination information */
                  pwg_media_t  *pwg,	/* I - PWG media info */
                  unsigned     flags,	/* I - Media matching flags */
                  cups_size_t  *size)	/* O - Media size/margin/name info */
{
  cups_array_t		*db;		/* Which media database to query */
  _cups_media_db_t	*mdb,		/* Current media database entry */
			*best = NULL,	/* Best matching entry */
			key;		/* Search key */


 /*
  * Create the media database as needed...
  */

  if (flags & CUPS_MEDIA_FLAGS_READY)
  {
    cups_update_ready(http, dinfo);
    db = dinfo->ready_db;
  }
  else
  {
    if (!dinfo->media_db)
      cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_DEFAULT);

    db = dinfo->media_db;
  }

 /*
  * Find a match...
  */

  memset(&key, 0, sizeof(key));
  key.width  = pwg->width;
  key.length = pwg->length;

  if ((mdb = cupsArrayFind(db, &key)) != NULL)
  {
   /*
    * Found an exact match, let's figure out the best margins for the flags
    * supplied...
    */

    best = mdb;

    if (flags & CUPS_MEDIA_FLAGS_BORDERLESS)
    {
     /*
      * Look for the smallest margins...
      */

      if (best->left != 0 || best->right != 0 || best->top != 0 || best->bottom != 0)
      {
	for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	     mdb && !cups_compare_media_db(mdb, &key);
	     mdb = (_cups_media_db_t *)cupsArrayNext(db))
	{
	  if (mdb->left <= best->left && mdb->right <= best->right &&
	      mdb->top <= best->top && mdb->bottom <= best->bottom)
	  {
	    best = mdb;
	    if (mdb->left == 0 && mdb->right == 0 && mdb->bottom == 0 &&
		mdb->top == 0)
	      break;
	  }
	}
      }

     /*
      * If we need an exact match, return no-match if the size is not
      * borderless.
      */

      if ((flags & CUPS_MEDIA_FLAGS_EXACT) &&
          (best->left || best->right || best->top || best->bottom))
        return (0);
    }
    else if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
    {
     /*
      * Look for the largest margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && !cups_compare_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (mdb->left >= best->left && mdb->right >= best->right &&
	    mdb->top >= best->top && mdb->bottom >= best->bottom &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
    else
    {
     /*
      * Look for the smallest non-zero margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && !cups_compare_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (((mdb->left > 0 && mdb->left <= best->left) || best->left == 0) &&
	    ((mdb->right > 0 && mdb->right <= best->right) || best->right == 0) &&
	    ((mdb->top > 0 && mdb->top <= best->top) || best->top == 0) &&
	    ((mdb->bottom > 0 && mdb->bottom <= best->bottom) || best->bottom == 0) &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
  }
  else if (flags & CUPS_MEDIA_FLAGS_EXACT)
  {
   /*
    * See if we can do this as a custom size...
    */

    if (pwg->width < dinfo->min_size.width ||
        pwg->width > dinfo->max_size.width ||
        pwg->length < dinfo->min_size.length ||
        pwg->length > dinfo->max_size.length)
      return (0);			/* Out of range */

    if ((flags & CUPS_MEDIA_FLAGS_BORDERLESS) &&
        (dinfo->min_size.left > 0 || dinfo->min_size.right > 0 ||
         dinfo->min_size.top > 0 || dinfo->min_size.bottom > 0))
      return (0);			/* Not borderless */

    key.size_name = (char *)pwg->pwg;
    key.bottom    = dinfo->min_size.bottom;
    key.left      = dinfo->min_size.left;
    key.right     = dinfo->min_size.right;
    key.top       = dinfo->min_size.top;

    best = &key;
  }
  else if (pwg->width >= dinfo->min_size.width &&
	   pwg->width <= dinfo->max_size.width &&
	   pwg->length >= dinfo->min_size.length &&
	   pwg->length <= dinfo->max_size.length)
  {
   /*
    * Map to custom size...
    */

    key.size_name = (char *)pwg->pwg;
    key.bottom    = dinfo->min_size.bottom;
    key.left      = dinfo->min_size.left;
    key.right     = dinfo->min_size.right;
    key.top       = dinfo->min_size.top;

    best = &key;
  }
  else
  {
   /*
    * Find a close size...
    */

    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db);
         mdb;
         mdb = (_cups_media_db_t *)cupsArrayNext(db))
      if (cups_is_close_media_db(mdb, &key))
        break;

    if (!mdb)
      return (0);

    best = mdb;

    if (flags & CUPS_MEDIA_FLAGS_BORDERLESS)
    {
     /*
      * Look for the smallest margins...
      */

      if (best->left != 0 || best->right != 0 || best->top != 0 ||
          best->bottom != 0)
      {
	for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	     mdb && cups_is_close_media_db(mdb, &key);
	     mdb = (_cups_media_db_t *)cupsArrayNext(db))
	{
	  if (mdb->left <= best->left && mdb->right <= best->right &&
	      mdb->top <= best->top && mdb->bottom <= best->bottom &&
	      (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  {
	    best = mdb;
	    if (mdb->left == 0 && mdb->right == 0 && mdb->bottom == 0 &&
		mdb->top == 0)
	      break;
	  }
	}
      }
    }
    else if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
    {
     /*
      * Look for the largest margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && cups_is_close_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (mdb->left >= best->left && mdb->right >= best->right &&
	    mdb->top >= best->top && mdb->bottom >= best->bottom &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
    else
    {
     /*
      * Look for the smallest non-zero margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && cups_is_close_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (((mdb->left > 0 && mdb->left <= best->left) || best->left == 0) &&
	    ((mdb->right > 0 && mdb->right <= best->right) ||
	     best->right == 0) &&
	    ((mdb->top > 0 && mdb->top <= best->top) || best->top == 0) &&
	    ((mdb->bottom > 0 && mdb->bottom <= best->bottom) ||
	     best->bottom == 0) &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
  }

  if (best)
  {
   /*
    * Return the matching size...
    */

    if (best->key)
      strlcpy(size->media, best->key, sizeof(size->media));
    else if (best->size_name)
      strlcpy(size->media, best->size_name, sizeof(size->media));
    else if (pwg && pwg->pwg)
      strlcpy(size->media, pwg->pwg, sizeof(size->media));
    else
      strlcpy(size->media, "unknown", sizeof(size->media));

    size->width  = best->width;
    size->length = best->length;
    size->bottom = best->bottom;
    size->left   = best->left;
    size->right  = best->right;
    size->top    = best->top;

    return (1);
  }

  return (0);
}


/*
 * 'cups_is_close_media_db()' - Compare two media entries to see if they are
 *                              close to the same size.
 *
 * Currently we use 5 points (from PostScript) as the matching range...
 */

static int				/* O - 1 if the sizes are close */
cups_is_close_media_db(
    _cups_media_db_t *a,		/* I - First media entries */
    _cups_media_db_t *b)		/* I - Second media entries */
{
  int	dwidth,				/* Difference in width */
	dlength;			/* Difference in length */


  dwidth  = a->width - b->width;
  dlength = a->length - b->length;

  return (dwidth >= -176 && dwidth <= 176 &&
          dlength >= -176 && dlength <= 176);
}


/*
 * 'cups_test_constraints()' - Test constraints.
 */

static cups_array_t *			/* O - Active constraints */
cups_test_constraints(
    cups_dinfo_t  *dinfo,		/* I - Destination information */
    const char    *new_option,		/* I - Newly selected option */
    const char    *new_value,		/* I - Newly selected value */
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    int           *num_conflicts,	/* O - Number of conflicting options */
    cups_option_t **conflicts)		/* O - Conflicting options */
{
  int			i,		/* Looping var */
			count,		/* Number of values */
			match;		/* Value matches? */
  int			num_matching;	/* Number of matching options */
  cups_option_t		*matching;	/* Matching options */
  _cups_dconstres_t	*c;		/* Current constraint */
  cups_array_t		*active = NULL;	/* Active constraints */
  ipp_t			*col;		/* Collection value */
  ipp_attribute_t	*attr;		/* Current attribute */
  _ipp_value_t		*attrval;	/* Current attribute value */
  const char		*value;		/* Current value */
  char			temp[1024];	/* Temporary string */
  int			int_value;	/* Integer value */
  int			xres_value,	/* Horizontal resolution */
			yres_value;	/* Vertical resolution */
  ipp_res_t		units_value;	/* Resolution units */


  for (c = (_cups_dconstres_t *)cupsArrayFirst(dinfo->constraints);
       c;
       c = (_cups_dconstres_t *)cupsArrayNext(dinfo->constraints))
  {
    num_matching = 0;
    matching     = NULL;

    for (attr = ippFirstAttribute(c->collection);
         attr;
         attr = ippNextAttribute(c->collection))
    {
     /*
      * Get the value for the current attribute in the constraint...
      */

      if (new_option && new_value && !strcmp(attr->name, new_option))
        value = new_value;
      else if ((value = cupsGetOption(attr->name, num_options, options)) == NULL)
        value = cupsGetOption(attr->name, dinfo->num_defaults, dinfo->defaults);

      if (!value)
      {
       /*
        * Not set so this constraint does not apply...
        */

        break;
      }

      match = 0;

      switch (attr->value_tag)
      {
        case IPP_TAG_INTEGER :
        case IPP_TAG_ENUM :
	    int_value = atoi(value);

	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (attrval->integer == int_value)
	      {
		match = 1;
		break;
	      }
            }
            break;

        case IPP_TAG_BOOLEAN :
	    int_value = !strcmp(value, "true");

	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (attrval->boolean == int_value)
	      {
		match = 1;
		break;
	      }
            }
            break;

        case IPP_TAG_RANGE :
	    int_value = atoi(value);

	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (int_value >= attrval->range.lower &&
	          int_value <= attrval->range.upper)
	      {
		match = 1;
		break;
	      }
            }
            break;

        case IPP_TAG_RESOLUTION :
	    if (sscanf(value, "%dx%d%15s", &xres_value, &yres_value, temp) != 3)
	    {
	      if (sscanf(value, "%d%15s", &xres_value, temp) != 2)
		break;

	      yres_value = xres_value;
	    }

	    if (!strcmp(temp, "dpi"))
	      units_value = IPP_RES_PER_INCH;
	    else if (!strcmp(temp, "dpc") || !strcmp(temp, "dpcm"))
	      units_value = IPP_RES_PER_CM;
	    else
	      break;

	    for (i = attr->num_values, attrval = attr->values;
		 i > 0;
		 i --, attrval ++)
	    {
	      if (attrval->resolution.xres == xres_value &&
		  attrval->resolution.yres == yres_value &&
		  attrval->resolution.units == units_value)
	      {
	      	match = 1;
		break;
	      }
	    }
            break;

	case IPP_TAG_TEXT :
	case IPP_TAG_NAME :
	case IPP_TAG_KEYWORD :
	case IPP_TAG_CHARSET :
	case IPP_TAG_URI :
	case IPP_TAG_URISCHEME :
	case IPP_TAG_MIMETYPE :
	case IPP_TAG_LANGUAGE :
	case IPP_TAG_TEXTLANG :
	case IPP_TAG_NAMELANG :
	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (!strcmp(attrval->string.text, value))
	      {
		match = 1;
		break;
	      }
            }
	    break;

        case IPP_TAG_BEGIN_COLLECTION :
            col = ippNew();
            _cupsEncodeOption(col, IPP_TAG_ZERO, NULL, ippGetName(attr), value);

            for (i = 0, count = ippGetCount(attr); i < count; i ++)
            {
              if (cups_collection_contains(col, ippGetCollection(attr, i)))
              {
                match = 1;
                break;
	      }
            }

            ippDelete(col);
            break;

        default :
            break;
      }

      if (!match)
        break;

      num_matching = cupsAddOption(attr->name, value, num_matching, &matching);
    }

    if (!attr)
    {
      if (!active)
        active = cupsArrayNew(NULL, NULL);

      cupsArrayAdd(active, c);

      if (num_conflicts && conflicts)
      {
        cups_option_t	*moption;	/* Matching option */

        for (i = num_matching, moption = matching; i > 0; i --, moption ++)
          *num_conflicts = cupsAddOption(moption->name, moption->value, *num_conflicts, conflicts);
      }
    }

    cupsFreeOptions(num_matching, matching);
  }

  return (active);
}


/*
 * 'cups_update_ready()' - Update xxx-ready attributes for the printer.
 */

static void
cups_update_ready(http_t       *http,	/* I - Connection to destination */
                  cups_dinfo_t *dinfo)	/* I - Destination information */
{
  ipp_t	*request;			/* Get-Printer-Attributes request */
  static const char * const pattrs[] =	/* Printer attributes we want */
  {
    "finishings-col-ready",
    "finishings-ready",
    "job-finishings-col-ready",
    "job-finishings-ready",
    "media-col-ready",
    "media-ready"
  };


 /*
  * Don't update more than once every 30 seconds...
  */

  if ((time(NULL) - dinfo->ready_time) < _CUPS_MEDIA_READY_TTL)
    return;

 /*
  * Free any previous results...
  */

  if (dinfo->cached_flags & CUPS_MEDIA_FLAGS_READY)
  {
    cupsArrayDelete(dinfo->cached_db);
    dinfo->cached_db    = NULL;
    dinfo->cached_flags = CUPS_MEDIA_FLAGS_DEFAULT;
  }

  ippDelete(dinfo->ready_attrs);
  dinfo->ready_attrs = NULL;

  cupsArrayDelete(dinfo->ready_db);
  dinfo->ready_db = NULL;

 /*
  * Query the xxx-ready values...
  */

  request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
  ippSetVersion(request, dinfo->version / 10, dinfo->version % 10);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
               dinfo->uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());
  ippAddStrings(request, IPP_TAG_OPERATION, IPP_CONST_TAG(IPP_TAG_KEYWORD), "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);

  dinfo->ready_attrs = cupsDoRequest(http, request, dinfo->resource);

 /*
  * Update the ready media database...
  */

  cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_READY);

 /*
  * Update last lookup time and return...
  */

  dinfo->ready_time = time(NULL);
}
