/*
 * User-defined destination (and option) support for CUPS.
 *
 * Copyright © 2007-2019 by Apple Inc.
 * Copyright © 1997-2007 by Easy Software Products.
 *
 * Licensed under Apache License v2.0.  See the file "LICENSE" for more
 * information.
 */

/*
 * Include necessary headers...
 */

#include "cups-private.h"
#include "debug-internal.h"
#include <sys/stat.h>

#ifdef HAVE_NOTIFY_H
#  include <notify.h>
#endif /* HAVE_NOTIFY_H */

#ifdef HAVE_POLL
#  include <poll.h>
#endif /* HAVE_POLL */

#ifdef HAVE_DNSSD
#  include <dns_sd.h>
#endif /* HAVE_DNSSD */

#ifdef HAVE_AVAHI
#  include <avahi-client/client.h>
#  include <avahi-client/lookup.h>
#  include <avahi-common/simple-watch.h>
#  include <avahi-common/domain.h>
#  include <avahi-common/error.h>
#  include <avahi-common/malloc.h>
#define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX
#endif /* HAVE_AVAHI */


/*
 * Constants...
 */

#ifdef __APPLE__
#  if HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
#    include <SystemConfiguration/SystemConfiguration.h>
#    define _CUPS_LOCATION_DEFAULTS 1
#  endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */
#  define kCUPSPrintingPrefs	CFSTR("org.cups.PrintingPrefs")
#  define kDefaultPaperIDKey	CFSTR("DefaultPaperID")
#  define kLastUsedPrintersKey	CFSTR("LastUsedPrinters")
#  define kLocationNetworkKey	CFSTR("Network")
#  define kLocationPrinterIDKey	CFSTR("PrinterID")
#  define kUseLastPrinter	CFSTR("UseLastPrinter")
#endif /* __APPLE__ */

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
#  define _CUPS_DNSSD_GET_DESTS 250     /* Milliseconds for cupsGetDests */
#  define _CUPS_DNSSD_MAXTIME	50	/* Milliseconds for maximum quantum of time */
#else
#  define _CUPS_DNSSD_GET_DESTS 0       /* Milliseconds for cupsGetDests */
#endif /* HAVE_DNSSD || HAVE_AVAHI */


/*
 * Types...
 */

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
typedef enum _cups_dnssd_state_e	/* Enumerated device state */
{
  _CUPS_DNSSD_NEW,
  _CUPS_DNSSD_QUERY,
  _CUPS_DNSSD_PENDING,
  _CUPS_DNSSD_ACTIVE,
  _CUPS_DNSSD_INCOMPATIBLE,
  _CUPS_DNSSD_ERROR
} _cups_dnssd_state_t;

typedef struct _cups_dnssd_data_s	/* Enumeration data */
{
#  ifdef HAVE_DNSSD
  DNSServiceRef		main_ref;	/* Main service reference */
#  else /* HAVE_AVAHI */
  AvahiSimplePoll	*simple_poll;	/* Polling interface */
  AvahiClient		*client;	/* Client information */
  int			got_data;	/* Did we get data? */
  int			browsers;	/* How many browsers are running? */
#  endif /* HAVE_DNSSD */
  cups_dest_cb_t	cb;		/* Callback */
  void			*user_data;	/* User data pointer */
  cups_ptype_t		type,		/* Printer type filter */
			mask;		/* Printer type mask */
  cups_array_t		*devices;	/* Devices found so far */
  int			num_dests;	/* Number of lpoptions destinations */
  cups_dest_t		*dests;		/* lpoptions destinations */
  char			def_name[1024],	/* Default printer name, if any */
			*def_instance;	/* Default printer instance, if any */
} _cups_dnssd_data_t;

typedef struct _cups_dnssd_device_s	/* Enumerated device */
{
  _cups_dnssd_state_t	state;		/* State of device listing */
#  ifdef HAVE_DNSSD
  DNSServiceRef		ref;		/* Service reference for query */
#  else /* HAVE_AVAHI */
  AvahiRecordBrowser	*ref;		/* Browser for query */
#  endif /* HAVE_DNSSD */
  char			*fullName,	/* Full name */
			*regtype,	/* Registration type */
			*domain;	/* Domain name */
  cups_ptype_t		type;		/* Device registration type */
  cups_dest_t		dest;		/* Destination record */
} _cups_dnssd_device_t;

typedef struct _cups_dnssd_resolve_s	/* Data for resolving URI */
{
  int			*cancel;	/* Pointer to "cancel" variable */
  struct timeval	end_time;	/* Ending time */
} _cups_dnssd_resolve_t;
#endif /* HAVE_DNSSD */

typedef struct _cups_getdata_s
{
  int		num_dests;		/* Number of destinations */
  cups_dest_t	*dests;			/* Destinations */
  char		def_name[1024],		/* Default printer name, if any */
		*def_instance;		/* Default printer instance, if any */
} _cups_getdata_t;

typedef struct _cups_namedata_s
{
  const char  *name;                    /* Named destination */
  cups_dest_t *dest;                    /* Destination */
} _cups_namedata_t;


/*
 * Local functions...
 */

#if _CUPS_LOCATION_DEFAULTS
static CFArrayRef	appleCopyLocations(void);
static CFStringRef	appleCopyNetwork(void);
#endif /* _CUPS_LOCATION_DEFAULTS */
#ifdef __APPLE__
static char		*appleGetPaperSize(char *name, size_t namesize);
#endif /* __APPLE__ */
#if _CUPS_LOCATION_DEFAULTS
static CFStringRef	appleGetPrinter(CFArrayRef locations,
			                CFStringRef network, CFIndex *locindex);
#endif /* _CUPS_LOCATION_DEFAULTS */
static cups_dest_t	*cups_add_dest(const char *name, const char *instance,
				       int *num_dests, cups_dest_t **dests);
#ifdef __BLOCKS__
static int		cups_block_cb(cups_dest_block_t block, unsigned flags,
			              cups_dest_t *dest);
#endif /* __BLOCKS__ */
static int		cups_compare_dests(cups_dest_t *a, cups_dest_t *b);
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
#  ifdef HAVE_DNSSD
static void		cups_dnssd_browse_cb(DNSServiceRef sdRef,
					     DNSServiceFlags flags,
					     uint32_t interfaceIndex,
					     DNSServiceErrorType errorCode,
					     const char *serviceName,
					     const char *regtype,
					     const char *replyDomain,
					     void *context);
#  else /* HAVE_AVAHI */
static void		cups_dnssd_browse_cb(AvahiServiceBrowser *browser,
					     AvahiIfIndex interface,
					     AvahiProtocol protocol,
					     AvahiBrowserEvent event,
					     const char *serviceName,
					     const char *regtype,
					     const char *replyDomain,
					     AvahiLookupResultFlags flags,
					     void *context);
static void		cups_dnssd_client_cb(AvahiClient *client,
					     AvahiClientState state,
					     void *context);
#  endif /* HAVE_DNSSD */
static int		cups_dnssd_compare_devices(_cups_dnssd_device_t *a,
			                           _cups_dnssd_device_t *b);
static void		cups_dnssd_free_device(_cups_dnssd_device_t *device,
			                       _cups_dnssd_data_t *data);
static _cups_dnssd_device_t *
			cups_dnssd_get_device(_cups_dnssd_data_t *data,
					      const char *serviceName,
					      const char *regtype,
					      const char *replyDomain);
#  ifdef HAVE_DNSSD
static void		cups_dnssd_query_cb(DNSServiceRef sdRef,
					    DNSServiceFlags flags,
					    uint32_t interfaceIndex,
					    DNSServiceErrorType errorCode,
					    const char *fullName,
					    uint16_t rrtype, uint16_t rrclass,
					    uint16_t rdlen, const void *rdata,
					    uint32_t ttl, void *context);
#  else /* HAVE_AVAHI */
static int		cups_dnssd_poll_cb(struct pollfd *pollfds,
					   unsigned int num_pollfds,
					   int timeout, void *context);
static void		cups_dnssd_query_cb(AvahiRecordBrowser *browser,
					    AvahiIfIndex interface,
					    AvahiProtocol protocol,
					    AvahiBrowserEvent event,
					    const char *name, uint16_t rrclass,
					    uint16_t rrtype, const void *rdata,
					    size_t rdlen,
					    AvahiLookupResultFlags flags,
					    void *context);
#  endif /* HAVE_DNSSD */
static const char	*cups_dnssd_resolve(cups_dest_t *dest, const char *uri,
					    int msec, int *cancel,
					    cups_dest_cb_t cb, void *user_data);
static int		cups_dnssd_resolve_cb(void *context);
static void		cups_dnssd_unquote(char *dst, const char *src,
			                   size_t dstsize);
static int		cups_elapsed(struct timeval *t);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
static int              cups_enum_dests(http_t *http, unsigned flags, int msec, int *cancel, cups_ptype_t type, cups_ptype_t mask, cups_dest_cb_t cb, void *user_data);
static int		cups_find_dest(const char *name, const char *instance,
				       int num_dests, cups_dest_t *dests, int prev,
				       int *rdiff);
static int              cups_get_cb(_cups_getdata_t *data, unsigned flags, cups_dest_t *dest);
static char		*cups_get_default(const char *filename, char *namebuf,
					  size_t namesize, const char **instance);
static int		cups_get_dests(const char *filename, const char *match_name, const char *match_inst, int load_all, int user_default_set, int num_dests, cups_dest_t **dests);
static char		*cups_make_string(ipp_attribute_t *attr, char *buffer,
			                  size_t bufsize);
static int              cups_name_cb(_cups_namedata_t *data, unsigned flags, cups_dest_t *dest);
static void		cups_queue_name(char *name, const char *serviceName, size_t namesize);


/*
 * 'cupsAddDest()' - Add a destination to the list of destinations.
 *
 * This function cannot be used to add a new class or printer queue,
 * it only adds a new container of saved options for the named
 * destination or instance.
 *
 * If the named destination already exists, the destination list is
 * returned unchanged.  Adding a new instance of a destination creates
 * a copy of that destination's options.
 *
 * Use the @link cupsSaveDests@ function to save the updated list of
 * destinations to the user's lpoptions file.
 */

int					/* O  - New number of destinations */
cupsAddDest(const char  *name,		/* I  - Destination name */
            const char	*instance,	/* I  - Instance name or @code NULL@ for none/primary */
            int         num_dests,	/* I  - Number of destinations */
            cups_dest_t **dests)	/* IO - Destinations */
{
  int		i;			/* Looping var */
  cups_dest_t	*dest;			/* Destination pointer */
  cups_dest_t	*parent = NULL;		/* Parent destination */
  cups_option_t	*doption,		/* Current destination option */
		*poption;		/* Current parent option */


  if (!name || !dests)
    return (0);

  if (!cupsGetDest(name, instance, num_dests, *dests))
  {
    if (instance && !cupsGetDest(name, NULL, num_dests, *dests))
      return (num_dests);

    if ((dest = cups_add_dest(name, instance, &num_dests, dests)) == NULL)
      return (num_dests);

   /*
    * Find the base dest again now the array has been realloc'd.
    */

    parent = cupsGetDest(name, NULL, num_dests, *dests);

    if (instance && parent && parent->num_options > 0)
    {
     /*
      * Copy options from parent...
      */

      dest->options = calloc(sizeof(cups_option_t), (size_t)parent->num_options);

      if (dest->options)
      {
        dest->num_options = parent->num_options;

	for (i = dest->num_options, doption = dest->options,
	         poption = parent->options;
	     i > 0;
	     i --, doption ++, poption ++)
	{
	  doption->name  = _cupsStrRetain(poption->name);
	  doption->value = _cupsStrRetain(poption->value);
	}
      }
    }
  }

  return (num_dests);
}


#ifdef __APPLE__
/*
 * '_cupsAppleCopyDefaultPaperID()' - Get the default paper ID.
 */

CFStringRef				/* O - Default paper ID */
_cupsAppleCopyDefaultPaperID(void)
{
  return (CFPreferencesCopyAppValue(kDefaultPaperIDKey,
                                    kCUPSPrintingPrefs));
}


/*
 * '_cupsAppleCopyDefaultPrinter()' - Get the default printer at this location.
 */

CFStringRef				/* O - Default printer name */
_cupsAppleCopyDefaultPrinter(void)
{
#  if _CUPS_LOCATION_DEFAULTS
  CFStringRef	network;		/* Network location */
  CFArrayRef	locations;		/* Location array */
  CFStringRef	locprinter;		/* Current printer */


 /*
  * Use location-based defaults only if "use last printer" is selected in the
  * system preferences...
  */

  if (!_cupsAppleGetUseLastPrinter())
  {
    DEBUG_puts("1_cupsAppleCopyDefaultPrinter: Not using last printer as "
	       "default.");
    return (NULL);
  }

 /*
  * Get the current location...
  */

  if ((network = appleCopyNetwork()) == NULL)
  {
    DEBUG_puts("1_cupsAppleCopyDefaultPrinter: Unable to get current "
               "network.");
    return (NULL);
  }

 /*
  * Lookup the network in the preferences...
  */

  if ((locations = appleCopyLocations()) == NULL)
  {
   /*
    * Missing or bad location array, so no location-based default...
    */

    DEBUG_puts("1_cupsAppleCopyDefaultPrinter: Missing or bad last used "
	       "printer array.");

    CFRelease(network);

    return (NULL);
  }

  DEBUG_printf(("1_cupsAppleCopyDefaultPrinter: Got locations, %d entries.",
                (int)CFArrayGetCount(locations)));

  if ((locprinter = appleGetPrinter(locations, network, NULL)) != NULL)
    CFRetain(locprinter);

  CFRelease(network);
  CFRelease(locations);

  return (locprinter);

#  else
  return (NULL);
#  endif /* _CUPS_LOCATION_DEFAULTS */
}


/*
 * '_cupsAppleGetUseLastPrinter()' - Get whether to use the last used printer.
 */

int					/* O - 1 to use last printer, 0 otherwise */
_cupsAppleGetUseLastPrinter(void)
{
  Boolean	uselast,		/* Use last printer preference value */
		uselast_set;		/* Valid is set? */


  if (getenv("CUPS_DISABLE_APPLE_DEFAULT"))
    return (0);

  uselast = CFPreferencesGetAppBooleanValue(kUseLastPrinter,
                                            kCUPSPrintingPrefs,
					    &uselast_set);
  if (!uselast_set)
    return (1);
  else
    return (uselast);
}


/*
 * '_cupsAppleSetDefaultPaperID()' - Set the default paper id.
 */

void
_cupsAppleSetDefaultPaperID(
    CFStringRef name)			/* I - New paper ID */
{
  CFPreferencesSetAppValue(kDefaultPaperIDKey, name, kCUPSPrintingPrefs);
  CFPreferencesAppSynchronize(kCUPSPrintingPrefs);

#  ifdef HAVE_NOTIFY_POST
  notify_post("com.apple.printerPrefsChange");
#  endif /* HAVE_NOTIFY_POST */
}


/*
 * '_cupsAppleSetDefaultPrinter()' - Set the default printer for this location.
 */

void
_cupsAppleSetDefaultPrinter(
    CFStringRef name)			/* I - Default printer/class name */
{
#  if _CUPS_LOCATION_DEFAULTS
  CFStringRef		network;	/* Current network */
  CFArrayRef		locations;	/* Old locations array */
  CFIndex		locindex;	/* Index in locations array */
  CFStringRef		locprinter;	/* Current printer */
  CFMutableArrayRef	newlocations;	/* New locations array */
  CFMutableDictionaryRef newlocation;	/* New location */


 /*
  * Get the current location...
  */

  if ((network = appleCopyNetwork()) == NULL)
  {
    DEBUG_puts("1_cupsAppleSetDefaultPrinter: Unable to get current network...");
    return;
  }

 /*
  * Lookup the network in the preferences...
  */

  if ((locations = appleCopyLocations()) != NULL)
    locprinter = appleGetPrinter(locations, network, &locindex);
  else
  {
    locprinter = NULL;
    locindex   = -1;
  }

  if (!locprinter || CFStringCompare(locprinter, name, 0) != kCFCompareEqualTo)
  {
   /*
    * Need to change the locations array...
    */

    if (locations)
    {
      newlocations = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0,
                                              locations);

      if (locprinter)
        CFArrayRemoveValueAtIndex(newlocations, locindex);
    }
    else
      newlocations = CFArrayCreateMutable(kCFAllocatorDefault, 0,
					  &kCFTypeArrayCallBacks);

    newlocation = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
					    &kCFTypeDictionaryKeyCallBacks,
					    &kCFTypeDictionaryValueCallBacks);

    if (newlocation && newlocations)
    {
     /*
      * Put the new location at the front of the array...
      */

      CFDictionaryAddValue(newlocation, kLocationNetworkKey, network);
      CFDictionaryAddValue(newlocation, kLocationPrinterIDKey, name);
      CFArrayInsertValueAtIndex(newlocations, 0, newlocation);

     /*
      * Limit the number of locations to 10...
      */

      while (CFArrayGetCount(newlocations) > 10)
        CFArrayRemoveValueAtIndex(newlocations, 10);

     /*
      * Push the changes out...
      */

      CFPreferencesSetAppValue(kLastUsedPrintersKey, newlocations,
                               kCUPSPrintingPrefs);
      CFPreferencesAppSynchronize(kCUPSPrintingPrefs);

#  ifdef HAVE_NOTIFY_POST
      notify_post("com.apple.printerPrefsChange");
#  endif /* HAVE_NOTIFY_POST */
    }

    if (newlocations)
      CFRelease(newlocations);

    if (newlocation)
      CFRelease(newlocation);
  }

  if (locations)
    CFRelease(locations);

  CFRelease(network);

#  else
  (void)name;
#  endif /* _CUPS_LOCATION_DEFAULTS */
}


/*
 * '_cupsAppleSetUseLastPrinter()' - Set whether to use the last used printer.
 */

void
_cupsAppleSetUseLastPrinter(
    int uselast)			/* O - 1 to use last printer, 0 otherwise */
{
  CFPreferencesSetAppValue(kUseLastPrinter,
			   uselast ? kCFBooleanTrue : kCFBooleanFalse,
			   kCUPSPrintingPrefs);
  CFPreferencesAppSynchronize(kCUPSPrintingPrefs);

#  ifdef HAVE_NOTIFY_POST
  notify_post("com.apple.printerPrefsChange");
#  endif /* HAVE_NOTIFY_POST */
}
#endif /* __APPLE__ */


/*
 * 'cupsConnectDest()' - Open a connection to the destination.
 *
 * Connect to the destination, returning a new @code http_t@ connection object
 * and optionally the resource path to use for the destination.  These calls
 * will block until a connection is made, the timeout expires, the integer
 * pointed to by "cancel" is non-zero, or the callback function (or block)
 * returns 0.  The caller is responsible for calling @link httpClose@ on the
 * returned connection.
 *
 * Starting with CUPS 2.2.4, the caller can pass @code CUPS_DEST_FLAGS_DEVICE@
 * for the "flags" argument to connect directly to the device associated with
 * the destination.  Otherwise, the connection is made to the CUPS scheduler
 * associated with the destination.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

http_t *				/* O - Connection to destination or @code NULL@ */
cupsConnectDest(
    cups_dest_t    *dest,		/* I - Destination */
    unsigned       flags,		/* I - Connection flags */
    int            msec,		/* I - Timeout in milliseconds */
    int            *cancel,		/* I - Pointer to "cancel" variable */
    char           *resource,		/* I - Resource buffer */
    size_t         resourcesize,	/* I - Size of resource buffer */
    cups_dest_cb_t cb,			/* I - Callback function */
    void           *user_data)		/* I - User data pointer */
{
  const char	*uri;			/* Printer URI */
  char		scheme[32],		/* URI scheme */
		userpass[256],		/* Username and password (unused) */
		hostname[256],		/* Hostname */
		tempresource[1024];	/* Temporary resource buffer */
  int		port;			/* Port number */
  char		portstr[16];		/* Port number string */
  http_encryption_t encryption;		/* Encryption to use */
  http_addrlist_t *addrlist;		/* Address list for server */
  http_t	*http;			/* Connection to server */


  DEBUG_printf(("cupsConnectDest(dest=%p, flags=0x%x, msec=%d, cancel=%p(%d), resource=\"%s\", resourcesize=" CUPS_LLFMT ", cb=%p, user_data=%p)", (void *)dest, flags, msec, (void *)cancel, cancel ? *cancel : -1, resource, CUPS_LLCAST resourcesize, (void *)cb, user_data));

 /*
  * Range check input...
  */

  if (!dest)
  {
    if (resource)
      *resource = '\0';

    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

  if (!resource || resourcesize < 1)
  {
    resource     = tempresource;
    resourcesize = sizeof(tempresource);
  }

 /*
  * Grab the printer URI...
  */

  if (flags & CUPS_DEST_FLAGS_DEVICE)
  {
    if ((uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL)
    {
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
      if (strstr(uri, "._tcp"))
        uri = cups_dnssd_resolve(dest, uri, msec, cancel, cb, user_data);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
    }
  }
  else if ((uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options)) == NULL)
  {
    if ((uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL)
    {
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
      if (strstr(uri, "._tcp"))
        uri = cups_dnssd_resolve(dest, uri, msec, cancel, cb, user_data);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
    }

    if (uri)
      uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, uri, tempresource, sizeof(tempresource));

    if (uri)
    {
      dest->num_options = cupsAddOption("printer-uri-supported", uri, dest->num_options, &dest->options);

      uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
    }
  }

  if (!uri)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);

    if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);

    return (NULL);
  }

  if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
                      userpass, sizeof(userpass), hostname, sizeof(hostname),
                      &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad printer-uri."), 1);

    if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR,
            dest);

    return (NULL);
  }

 /*
  * Lookup the address for the server...
  */

  if (cb)
    (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_RESOLVING, dest);

  snprintf(portstr, sizeof(portstr), "%d", port);

  if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portstr)) == NULL)
  {
    if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);

    return (NULL);
  }

  if (cancel && *cancel)
  {
    httpAddrFreeList(addrlist);

    if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CANCELED, dest);

    return (NULL);
  }

 /*
  * Create the HTTP object pointing to the server referenced by the URI...
  */

  if (!strcmp(scheme, "ipps") || port == 443)
    encryption = HTTP_ENCRYPTION_ALWAYS;
  else
    encryption = HTTP_ENCRYPTION_IF_REQUESTED;

  http = httpConnect2(hostname, port, addrlist, AF_UNSPEC, encryption, 1, 0, NULL);
  httpAddrFreeList(addrlist);

 /*
  * Connect if requested...
  */

  if (flags & CUPS_DEST_FLAGS_UNCONNECTED)
  {
    if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED, dest);
  }
  else
  {
    if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CONNECTING, dest);

    if (!httpReconnect2(http, msec, cancel) && cb)
    {
      if (cancel && *cancel)
	(*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CONNECTING, dest);
      else
	(*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);
    }
    else if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_NONE, dest);
  }

  return (http);
}


#ifdef __BLOCKS__
/*
 * 'cupsConnectDestBlock()' - Open a connection to the destination.
 *
 * Connect to the destination, returning a new @code http_t@ connection object
 * and optionally the resource path to use for the destination.  These calls
 * will block until a connection is made, the timeout expires, the integer
 * pointed to by "cancel" is non-zero, or the block returns 0.  The caller is
 * responsible for calling @link httpClose@ on the returned connection.
 *
 * Starting with CUPS 2.2.4, the caller can pass  @code CUPS_DEST_FLAGS_DEVICE@
 * for the "flags" argument to connect directly to the device associated with
 * the destination.  Otherwise, the connection is made to the CUPS scheduler
 * associated with the destination.
 *
 * @since CUPS 1.6/macOS 10.8@ @exclude all@
 */

http_t *				/* O - Connection to destination or @code NULL@ */
cupsConnectDestBlock(
    cups_dest_t       *dest,		/* I - Destination */
    unsigned          flags,		/* I - Connection flags */
    int               msec,		/* I - Timeout in milliseconds */
    int               *cancel,		/* I - Pointer to "cancel" variable */
    char              *resource,	/* I - Resource buffer */
    size_t            resourcesize,	/* I - Size of resource buffer */
    cups_dest_block_t block)		/* I - Callback block */
{
  return (cupsConnectDest(dest, flags, msec, cancel, resource, resourcesize,
                          (cups_dest_cb_t)cups_block_cb, (void *)block));
}
#endif /* __BLOCKS__ */


/*
 * 'cupsCopyDest()' - Copy a destination.
 *
 * Make a copy of the destination to an array of destinations (or just a single
 * copy) - for use with the cupsEnumDests* functions. The caller is responsible
 * for calling cupsFreeDests() on the returned object(s).
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int                                     /* O  - New number of destinations */
cupsCopyDest(cups_dest_t *dest,         /* I  - Destination to copy */
             int         num_dests,     /* I  - Number of destinations */
             cups_dest_t **dests)       /* IO - Destination array */
{
  int		i;			/* Looping var */
  cups_dest_t	*new_dest;		/* New destination pointer */
  cups_option_t	*new_option,		/* Current destination option */
		*option;		/* Current parent option */


 /*
  * Range check input...
  */

  if (!dest || num_dests < 0 || !dests)
    return (num_dests);

 /*
  * See if the destination already exists...
  */

  if ((new_dest = cupsGetDest(dest->name, dest->instance, num_dests,
                              *dests)) != NULL)
  {
   /*
    * Protect against copying destination to itself...
    */

    if (new_dest == dest)
      return (num_dests);

   /*
    * Otherwise, free the options...
    */

    cupsFreeOptions(new_dest->num_options, new_dest->options);

    new_dest->num_options = 0;
    new_dest->options     = NULL;
  }
  else
    new_dest = cups_add_dest(dest->name, dest->instance, &num_dests, dests);

  if (new_dest)
  {
    new_dest->is_default = dest->is_default;

    if ((new_dest->options = calloc(sizeof(cups_option_t), (size_t)dest->num_options)) == NULL)
      return (cupsRemoveDest(dest->name, dest->instance, num_dests, dests));

    new_dest->num_options = dest->num_options;

    for (i = dest->num_options, option = dest->options,
	     new_option = new_dest->options;
	 i > 0;
	 i --, option ++, new_option ++)
    {
      new_option->name  = _cupsStrRetain(option->name);
      new_option->value = _cupsStrRetain(option->value);
    }
  }

  return (num_dests);
}


/*
 * '_cupsCreateDest()' - Create a local (temporary) queue.
 */

char *					/* O - Printer URI or @code NULL@ on error */
_cupsCreateDest(const char *name,	/* I - Printer name */
                const char *info,	/* I - Printer description of @code NULL@ */
		const char *device_id,	/* I - 1284 Device ID or @code NULL@ */
		const char *device_uri,	/* I - Device URI */
		char       *uri,	/* I - Printer URI buffer */
		size_t     urisize)	/* I - Size of URI buffer */
{
  http_t	*http;			/* Connection to server */
  ipp_t		*request,		/* CUPS-Create-Local-Printer request */
		*response;		/* CUPS-Create-Local-Printer response */
  ipp_attribute_t *attr;		/* printer-uri-supported attribute */
  ipp_pstate_t	state = IPP_PSTATE_STOPPED;
					/* printer-state value */


  if (!name || !device_uri || !uri || urisize < 32)
    return (NULL);

  if ((http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL)) == NULL)
    return (NULL);

  request = ippNewRequest(IPP_OP_CUPS_CREATE_LOCAL_PRINTER);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/");
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());

  ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, device_uri);
  ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL, name);
  if (info)
    ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", NULL, info);
  if (device_id)
    ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-device-id", NULL, device_id);

  response = cupsDoRequest(http, request, "/");

  if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
    strlcpy(uri, ippGetString(attr, 0, NULL), urisize);
  else
  {
    ippDelete(response);
    httpClose(http);
    return (NULL);
  }

  if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
    state = (ipp_pstate_t)ippGetInteger(attr, 0);

  while (state == IPP_PSTATE_STOPPED && cupsLastError() == IPP_STATUS_OK)
  {
    sleep(1);
    ippDelete(response);

    request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);

    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());
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-state");

    response = cupsDoRequest(http, request, "/");

    if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
      state = (ipp_pstate_t)ippGetInteger(attr, 0);
  }

  ippDelete(response);

  httpClose(http);

  return (uri);
}


/*
 * 'cupsEnumDests()' - Enumerate available destinations with a callback function.
 *
 * Destinations are enumerated from one or more sources.  The callback function
 * receives the @code user_data@ pointer and the destination pointer which can
 * be used as input to the @link cupsCopyDest@ function.  The function must
 * return 1 to continue enumeration or 0 to stop.
 *
 * The @code type@ and @code mask@ arguments allow the caller to filter the
 * destinations that are enumerated.  Passing 0 for both will enumerate all
 * printers.  The constant @code CUPS_PRINTER_DISCOVERED@ is used to filter on
 * destinations that are available but have not yet been added locally.
 *
 * Enumeration happens on the current thread and does not return until all
 * destinations have been enumerated or the callback function returns 0.
 *
 * Note: The callback function will likely receive multiple updates for the same
 * destinations - it is up to the caller to suppress any duplicate destinations.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 on success, 0 on failure */
cupsEnumDests(
  unsigned       flags,			/* I - Enumeration flags */
  int            msec,			/* I - Timeout in milliseconds, -1 for indefinite */
  int            *cancel,		/* I - Pointer to "cancel" variable */
  cups_ptype_t   type,			/* I - Printer type bits */
  cups_ptype_t   mask,			/* I - Mask for printer type bits */
  cups_dest_cb_t cb,			/* I - Callback function */
  void           *user_data)		/* I - User data */
{
  return (cups_enum_dests(CUPS_HTTP_DEFAULT, flags, msec, cancel, type, mask, cb, user_data));
}


#  ifdef __BLOCKS__
/*
 * 'cupsEnumDestsBlock()' - Enumerate available destinations with a block.
 *
 * Destinations are enumerated from one or more sources.  The block receives the
 * @code user_data@ pointer and the destination pointer which can be used as
 * input to the @link cupsCopyDest@ function.  The block must return 1 to
 * continue enumeration or 0 to stop.
 *
 * The @code type@ and @code mask@ arguments allow the caller to filter the
 * destinations that are enumerated.  Passing 0 for both will enumerate all
 * printers.  The constant @code CUPS_PRINTER_DISCOVERED@ is used to filter on
 * destinations that are available but have not yet been added locally.
 *
 * Enumeration happens on the current thread and does not return until all
 * destinations have been enumerated or the block returns 0.
 *
 * Note: The block will likely receive multiple updates for the same
 * destinations - it is up to the caller to suppress any duplicate destinations.
 *
 * @since CUPS 1.6/macOS 10.8@ @exclude all@
 */

int					/* O - 1 on success, 0 on failure */
cupsEnumDestsBlock(
    unsigned          flags,		/* I - Enumeration flags */
    int               timeout,		/* I - Timeout in milliseconds, 0 for indefinite */
    int               *cancel,		/* I - Pointer to "cancel" variable */
    cups_ptype_t      type,		/* I - Printer type bits */
    cups_ptype_t      mask,		/* I - Mask for printer type bits */
    cups_dest_block_t block)		/* I - Block */
{
  return (cupsEnumDests(flags, timeout, cancel, type, mask,
                        (cups_dest_cb_t)cups_block_cb, (void *)block));
}
#  endif /* __BLOCKS__ */


/*
 * 'cupsFreeDests()' - Free the memory used by the list of destinations.
 */

void
cupsFreeDests(int         num_dests,	/* I - Number of destinations */
              cups_dest_t *dests)	/* I - Destinations */
{
  int		i;			/* Looping var */
  cups_dest_t	*dest;			/* Current destination */


  if (num_dests == 0 || dests == NULL)
    return;

  for (i = num_dests, dest = dests; i > 0; i --, dest ++)
  {
    _cupsStrFree(dest->name);
    _cupsStrFree(dest->instance);

    cupsFreeOptions(dest->num_options, dest->options);
  }

  free(dests);
}


/*
 * 'cupsGetDest()' - Get the named destination from the list.
 *
 * Use the @link cupsEnumDests@ or @link cupsGetDests2@ functions to get a
 * list of supported destinations for the current user.
 */

cups_dest_t *				/* O - Destination pointer or @code NULL@ */
cupsGetDest(const char  *name,		/* I - Destination name or @code NULL@ for the default destination */
            const char	*instance,	/* I - Instance name or @code NULL@ */
            int         num_dests,	/* I - Number of destinations */
            cups_dest_t *dests)		/* I - Destinations */
{
  int	diff,				/* Result of comparison */
	match;				/* Matching index */


  if (num_dests <= 0 || !dests)
    return (NULL);

  if (!name)
  {
   /*
    * NULL name for default printer.
    */

    while (num_dests > 0)
    {
      if (dests->is_default)
        return (dests);

      num_dests --;
      dests ++;
    }
  }
  else
  {
   /*
    * Lookup name and optionally the instance...
    */

    match = cups_find_dest(name, instance, num_dests, dests, -1, &diff);

    if (!diff)
      return (dests + match);
  }

  return (NULL);
}


/*
 * '_cupsGetDestResource()' - Get the resource path and URI for a destination.
 */

const char *				/* O - URI */
_cupsGetDestResource(
    cups_dest_t *dest,			/* I - Destination */
    unsigned    flags,			/* I - Destination flags */
    char        *resource,		/* I - Resource buffer */
    size_t      resourcesize)		/* I - Size of resource buffer */
{
  const char	*uri,			/* URI */
		*device_uri,		/* Device URI */
		*printer_uri;		/* Printer URI */
  char		scheme[32],		/* URI scheme */
		userpass[256],		/* Username and password (unused) */
		hostname[256];		/* Hostname */
  int		port;			/* Port number */


  DEBUG_printf(("_cupsGetDestResource(dest=%p(%s), flags=%u, resource=%p, resourcesize=%d)", (void *)dest, dest->name, flags, (void *)resource, (int)resourcesize));

 /*
  * Range check input...
  */

  if (!dest || !resource || resourcesize < 1)
  {
    if (resource)
      *resource = '\0';

    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

 /*
  * Grab the printer and device URIs...
  */

  device_uri  = cupsGetOption("device-uri", dest->num_options, dest->options);
  printer_uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);

  DEBUG_printf(("1_cupsGetDestResource: device-uri=\"%s\", printer-uri-supported=\"%s\".", device_uri, printer_uri));

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
  if (((flags & CUPS_DEST_FLAGS_DEVICE) || !printer_uri) && strstr(device_uri, "._tcp"))
  {
    if ((device_uri = cups_dnssd_resolve(dest, device_uri, 5000, NULL, NULL, NULL)) != NULL)
    {
      DEBUG_printf(("1_cupsGetDestResource: Resolved device-uri=\"%s\".", device_uri));
    }
    else
    {
      DEBUG_puts("1_cupsGetDestResource: Unable to resolve device.");

      if (resource)
	*resource = '\0';

      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);

      return (NULL);
    }
  }
#endif /* HAVE_DNSSD || HAVE_AVAHI */

  if (flags & CUPS_DEST_FLAGS_DEVICE)
  {
    uri = device_uri;
  }
  else if (printer_uri)
  {
    uri = printer_uri;
  }
  else
  {
    uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, device_uri, resource, resourcesize);

    if (uri)
    {
      DEBUG_printf(("1_cupsGetDestResource: Local printer-uri-supported=\"%s\"", uri));

      dest->num_options = cupsAddOption("printer-uri-supported", uri, dest->num_options, &dest->options);

      uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
    }
  }

  if (!uri)
  {
    DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported or device-uri found.");

    if (resource)
      *resource = '\0';

    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);

    return (NULL);
  }
  else if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad URI."), 1);

    return (NULL);
  }

  DEBUG_printf(("1_cupsGetDestResource: resource=\"%s\"", resource));

  return (uri);
}


/*
 * 'cupsGetDestWithURI()' - Get a destination associated with a URI.
 *
 * "name" is the desired name for the printer. If @code NULL@, a name will be
 * created using the URI.
 *
 * "uri" is the "ipp" or "ipps" URI for the printer.
 *
 * @since CUPS 2.0/macOS 10.10@
 */

cups_dest_t *				/* O - Destination or @code NULL@ */
cupsGetDestWithURI(const char *name,	/* I - Desired printer name or @code NULL@ */
                   const char *uri)	/* I - URI for the printer */
{
  cups_dest_t	*dest;			/* New destination */
  char		temp[1024],		/* Temporary string */
		scheme[256],		/* Scheme from URI */
		userpass[256],		/* Username:password from URI */
		hostname[256],		/* Hostname from URI */
		resource[1024],		/* Resource path from URI */
		*ptr;			/* Pointer into string */
  const char	*info;			/* printer-info string */
  int		port;			/* Port number from URI */


 /*
  * Range check input...
  */

  if (!uri)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

  if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK ||
      (strncmp(uri, "ipp://", 6) && strncmp(uri, "ipps://", 7)))
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad printer-uri."), 1);

    return (NULL);
  }

  if (name)
  {
    info = name;
  }
  else
  {
   /*
    * Create the name from the URI...
    */

    if (strstr(hostname, "._tcp"))
    {
     /*
      * Use the service instance name...
      */

      if ((ptr = strstr(hostname, "._")) != NULL)
        *ptr = '\0';

      cups_queue_name(temp, hostname, sizeof(temp));
      name = temp;
      info = hostname;
    }
    else if (!strncmp(resource, "/classes/", 9))
    {
      snprintf(temp, sizeof(temp), "%s @ %s", resource + 9, hostname);
      name = resource + 9;
      info = temp;
    }
    else if (!strncmp(resource, "/printers/", 10))
    {
      snprintf(temp, sizeof(temp), "%s @ %s", resource + 10, hostname);
      name = resource + 10;
      info = temp;
    }
    else if (!strncmp(resource, "/ipp/print/", 11))
    {
      snprintf(temp, sizeof(temp), "%s @ %s", resource + 11, hostname);
      name = resource + 11;
      info = temp;
    }
    else
    {
      name = hostname;
      info = hostname;
    }
  }

 /*
  * Create the destination...
  */

  if ((dest = calloc(1, sizeof(cups_dest_t))) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
    return (NULL);
  }

  dest->name        = _cupsStrAlloc(name);
  dest->num_options = cupsAddOption("device-uri", uri, dest->num_options, &(dest->options));
  dest->num_options = cupsAddOption("printer-info", info, dest->num_options, &(dest->options));

  return (dest);
}


/*
 * '_cupsGetDests()' - Get destinations from a server.
 *
 * "op" is IPP_OP_CUPS_GET_PRINTERS to get a full list, IPP_OP_CUPS_GET_DEFAULT
 * to get the system-wide default printer, or IPP_OP_GET_PRINTER_ATTRIBUTES for
 * a known printer.
 *
 * "name" is the name of an existing printer and is only used when "op" is
 * IPP_OP_GET_PRINTER_ATTRIBUTES.
 *
 * "dest" is initialized to point to the array of destinations.
 *
 * 0 is returned if there are no printers, no default printer, or the named
 * printer does not exist, respectively.
 *
 * Free the memory used by the destination array using the @link cupsFreeDests@
 * function.
 *
 * Note: On macOS this function also gets the default paper from the system
 * preferences (~/L/P/org.cups.PrintingPrefs.plist) and includes it in the
 * options array for each destination that supports it.
 */

int					/* O  - Number of destinations */
_cupsGetDests(http_t       *http,	/* I  - Connection to server or
					 *      @code CUPS_HTTP_DEFAULT@ */
	      ipp_op_t     op,		/* I  - IPP operation */
	      const char   *name,	/* I  - Name of destination */
	      cups_dest_t  **dests,	/* IO - Destinations */
	      cups_ptype_t type,	/* I  - Printer type bits */
	      cups_ptype_t mask)	/* I  - Printer type mask */
{
  int		num_dests = 0;		/* Number of destinations */
  cups_dest_t	*dest;			/* Current destination */
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr;		/* Current attribute */
  const char	*printer_name;		/* printer-name attribute */
  char		uri[1024];		/* printer-uri value */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
#ifdef __APPLE__
  char		media_default[41];	/* Default paper size */
#endif /* __APPLE__ */
  char		optname[1024],		/* Option name */
		value[2048],		/* Option value */
		*ptr;			/* Pointer into name/value */
  static const char * const pattrs[] =	/* Attributes we're interested in */
		{
		  "auth-info-required",
		  "device-uri",
		  "job-sheets-default",
		  "marker-change-time",
		  "marker-colors",
		  "marker-high-levels",
		  "marker-levels",
		  "marker-low-levels",
		  "marker-message",
		  "marker-names",
		  "marker-types",
#ifdef __APPLE__
		  "media-supported",
#endif /* __APPLE__ */
		  "printer-commands",
		  "printer-defaults",
		  "printer-info",
		  "printer-is-accepting-jobs",
		  "printer-is-shared",
                  "printer-is-temporary",
		  "printer-location",
		  "printer-make-and-model",
		  "printer-mandatory-job-attributes",
		  "printer-name",
		  "printer-state",
		  "printer-state-change-time",
		  "printer-state-reasons",
		  "printer-type",
		  "printer-uri-supported"
		};


  DEBUG_printf(("_cupsGetDests(http=%p, op=%x(%s), name=\"%s\", dests=%p, type=%x, mask=%x)", (void *)http, op, ippOpString(op), name, (void *)dests, type, mask));

#ifdef __APPLE__
 /*
  * Get the default paper size...
  */

  appleGetPaperSize(media_default, sizeof(media_default));
  DEBUG_printf(("1_cupsGetDests: Default media is '%s'.", media_default));
#endif /* __APPLE__ */

 /*
  * Build a IPP_OP_CUPS_GET_PRINTERS or IPP_OP_GET_PRINTER_ATTRIBUTES request, which
  * require the following attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    requesting-user-name
  *    printer-uri [for IPP_OP_GET_PRINTER_ATTRIBUTES]
  */

  request = ippNewRequest(op);

  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
		NULL, pattrs);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
               "requesting-user-name", NULL, cupsUser());

  if (name && op != IPP_OP_CUPS_GET_DEFAULT)
  {
    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                     "localhost", ippPort(), "/printers/%s", name);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
                 uri);
  }
  else if (mask)
  {
    ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type", (int)type);
    ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", (int)mask);
  }

 /*
  * Do the request and get back a response...
  */

  if ((response = cupsDoRequest(http, request, "/")) != NULL)
  {
    for (attr = response->attrs; attr != NULL; attr = attr->next)
    {
     /*
      * Skip leading attributes until we hit a printer...
      */

      while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
        attr = attr->next;

      if (attr == NULL)
        break;

     /*
      * Pull the needed attributes from this printer...
      */

      printer_name = NULL;
      num_options  = 0;
      options      = NULL;

      for (; attr && attr->group_tag == IPP_TAG_PRINTER; attr = attr->next)
      {
	if (attr->value_tag != IPP_TAG_INTEGER &&
	    attr->value_tag != IPP_TAG_ENUM &&
	    attr->value_tag != IPP_TAG_BOOLEAN &&
	    attr->value_tag != IPP_TAG_TEXT &&
	    attr->value_tag != IPP_TAG_TEXTLANG &&
	    attr->value_tag != IPP_TAG_NAME &&
	    attr->value_tag != IPP_TAG_NAMELANG &&
	    attr->value_tag != IPP_TAG_KEYWORD &&
	    attr->value_tag != IPP_TAG_RANGE &&
	    attr->value_tag != IPP_TAG_URI)
          continue;

        if (!strcmp(attr->name, "auth-info-required") ||
	    !strcmp(attr->name, "device-uri") ||
	    !strcmp(attr->name, "marker-change-time") ||
	    !strcmp(attr->name, "marker-colors") ||
	    !strcmp(attr->name, "marker-high-levels") ||
	    !strcmp(attr->name, "marker-levels") ||
	    !strcmp(attr->name, "marker-low-levels") ||
	    !strcmp(attr->name, "marker-message") ||
	    !strcmp(attr->name, "marker-names") ||
	    !strcmp(attr->name, "marker-types") ||
	    !strcmp(attr->name, "printer-commands") ||
	    !strcmp(attr->name, "printer-info") ||
            !strcmp(attr->name, "printer-is-shared") ||
            !strcmp(attr->name, "printer-is-temporary") ||
	    !strcmp(attr->name, "printer-make-and-model") ||
	    !strcmp(attr->name, "printer-mandatory-job-attributes") ||
	    !strcmp(attr->name, "printer-state") ||
	    !strcmp(attr->name, "printer-state-change-time") ||
	    !strcmp(attr->name, "printer-type") ||
            !strcmp(attr->name, "printer-is-accepting-jobs") ||
            !strcmp(attr->name, "printer-location") ||
            !strcmp(attr->name, "printer-state-reasons") ||
	    !strcmp(attr->name, "printer-uri-supported"))
        {
	 /*
	  * Add a printer description attribute...
	  */

          num_options = cupsAddOption(attr->name,
	                              cups_make_string(attr, value,
				                       sizeof(value)),
				      num_options, &options);
	}
#ifdef __APPLE__
	else if (!strcmp(attr->name, "media-supported") && media_default[0])
	{
	 /*
	  * See if we can set a default media size...
	  */

          int	i;			/* Looping var */

	  for (i = 0; i < attr->num_values; i ++)
	    if (!_cups_strcasecmp(media_default, attr->values[i].string.text))
	    {
              DEBUG_printf(("1_cupsGetDests: Setting media to '%s'.", media_default));
	      num_options = cupsAddOption("media", media_default, num_options, &options);
              break;
	    }
	}
#endif /* __APPLE__ */
        else if (!strcmp(attr->name, "printer-name") &&
	         attr->value_tag == IPP_TAG_NAME)
	  printer_name = attr->values[0].string.text;
        else if (strncmp(attr->name, "notify-", 7) &&
                 strncmp(attr->name, "print-quality-", 14) &&
                 (attr->value_tag == IPP_TAG_BOOLEAN ||
		  attr->value_tag == IPP_TAG_ENUM ||
		  attr->value_tag == IPP_TAG_INTEGER ||
		  attr->value_tag == IPP_TAG_KEYWORD ||
		  attr->value_tag == IPP_TAG_NAME ||
		  attr->value_tag == IPP_TAG_RANGE) &&
		 (ptr = strstr(attr->name, "-default")) != NULL)
	{
	 /*
	  * Add a default option...
	  */

          strlcpy(optname, attr->name, sizeof(optname));
	  optname[ptr - attr->name] = '\0';

	  if (_cups_strcasecmp(optname, "media") || !cupsGetOption("media", num_options, options))
	    num_options = cupsAddOption(optname, cups_make_string(attr, value, sizeof(value)), num_options, &options);
	}
      }

     /*
      * See if we have everything needed...
      */

      if (!printer_name)
      {
        cupsFreeOptions(num_options, options);

        if (attr == NULL)
	  break;
	else
          continue;
      }

      if ((dest = cups_add_dest(printer_name, NULL, &num_dests, dests)) != NULL)
      {
        dest->num_options = num_options;
	dest->options     = options;
      }
      else
        cupsFreeOptions(num_options, options);

      if (attr == NULL)
	break;
    }

    ippDelete(response);
  }

 /*
  * Return the count...
  */

  return (num_dests);
}


/*
 * 'cupsGetDests()' - Get the list of destinations from the default server.
 *
 * Starting with CUPS 1.2, the returned list of destinations include the
 * "printer-info", "printer-is-accepting-jobs", "printer-is-shared",
 * "printer-make-and-model", "printer-state", "printer-state-change-time",
 * "printer-state-reasons", "printer-type", and "printer-uri-supported"
 * attributes as options.
 *
 * CUPS 1.4 adds the "marker-change-time", "marker-colors",
 * "marker-high-levels", "marker-levels", "marker-low-levels", "marker-message",
 * "marker-names", "marker-types", and "printer-commands" attributes as options.
 *
 * CUPS 2.2 adds accessible IPP printers to the list of destinations that can
 * be used.  The "printer-uri-supported" option will be present for those IPP
 * printers that have been recently used.
 *
 * Use the @link cupsFreeDests@ function to free the destination list and
 * the @link cupsGetDest@ function to find a particular destination.
 *
 * @exclude all@
 */

int					/* O - Number of destinations */
cupsGetDests(cups_dest_t **dests)	/* O - Destinations */
{
  return (cupsGetDests2(CUPS_HTTP_DEFAULT, dests));
}


/*
 * 'cupsGetDests2()' - Get the list of destinations from the specified server.
 *
 * Starting with CUPS 1.2, the returned list of destinations include the
 * "printer-info", "printer-is-accepting-jobs", "printer-is-shared",
 * "printer-make-and-model", "printer-state", "printer-state-change-time",
 * "printer-state-reasons", "printer-type", and "printer-uri-supported"
 * attributes as options.
 *
 * CUPS 1.4 adds the "marker-change-time", "marker-colors",
 * "marker-high-levels", "marker-levels", "marker-low-levels", "marker-message",
 * "marker-names", "marker-types", and "printer-commands" attributes as options.
 *
 * CUPS 2.2 adds accessible IPP printers to the list of destinations that can
 * be used.  The "printer-uri-supported" option will be present for those IPP
 * printers that have been recently used.
 *
 * Use the @link cupsFreeDests@ function to free the destination list and
 * the @link cupsGetDest@ function to find a particular destination.
 *
 * @since CUPS 1.1.21/macOS 10.4@
 */

int					/* O - Number of destinations */
cupsGetDests2(http_t      *http,	/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
              cups_dest_t **dests)	/* O - Destinations */
{
  _cups_getdata_t data;                 /* Enumeration data */


  DEBUG_printf(("cupsGetDests2(http=%p, dests=%p)", (void *)http, (void *)dests));

/*
  * Range check the input...
  */

  if (!dests)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad NULL dests pointer"), 1);
    DEBUG_puts("1cupsGetDests2: NULL dests pointer, returning 0.");
    return (0);
  }

 /*
  * Connect to the server as needed...
  */

  if (!http)
  {
    if ((http = _cupsConnect()) == NULL)
    {
      *dests = NULL;

      return (0);
    }
  }

 /*
  * Grab the printers and classes...
  */

  data.num_dests = 0;
  data.dests     = NULL;

  if (!httpAddrLocalhost(httpGetAddress(http)))
  {
   /*
    * When talking to a remote cupsd, just enumerate printers on the remote
    * cupsd.
    */

    cups_enum_dests(http, 0, _CUPS_DNSSD_GET_DESTS, NULL, 0, CUPS_PRINTER_DISCOVERED, (cups_dest_cb_t)cups_get_cb, &data);
  }
  else
  {
   /*
    * When talking to a local cupsd, enumerate both local printers and ones we
    * can find on the network...
    */

    cups_enum_dests(http, 0, _CUPS_DNSSD_GET_DESTS, NULL, 0, 0, (cups_dest_cb_t)cups_get_cb, &data);
  }

 /*
  * Return the number of destinations...
  */

  *dests = data.dests;

  if (data.num_dests > 0)
    _cupsSetError(IPP_STATUS_OK, NULL, 0);

  DEBUG_printf(("1cupsGetDests2: Returning %d destinations.", data.num_dests));

  return (data.num_dests);
}


/*
 * 'cupsGetNamedDest()' - Get options for the named destination.
 *
 * This function is optimized for retrieving a single destination and should
 * be used instead of @link cupsGetDests2@ and @link cupsGetDest@ when you
 * either know the name of the destination or want to print to the default
 * destination.  If @code NULL@ is returned, the destination does not exist or
 * there is no default destination.
 *
 * If "http" is @code CUPS_HTTP_DEFAULT@, the connection to the default print
 * server will be used.
 *
 * If "name" is @code NULL@, the default printer for the current user will be
 * returned.
 *
 * The returned destination must be freed using @link cupsFreeDests@ with a
 * "num_dests" value of 1.
 *
 * @since CUPS 1.4/macOS 10.6@
 */

cups_dest_t *				/* O - Destination or @code NULL@ */
cupsGetNamedDest(http_t     *http,	/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
                 const char *name,	/* I - Destination name or @code NULL@ for the default destination */
                 const char *instance)	/* I - Instance name or @code NULL@ */
{
  const char    *dest_name;             /* Working destination name */
  cups_dest_t	*dest;			/* Destination */
  char		filename[1024],		/* Path to lpoptions */
		defname[256];		/* Default printer name */
  int		set_as_default = 0;	/* Set returned destination as default */
  ipp_op_t	op = IPP_OP_GET_PRINTER_ATTRIBUTES;
					/* IPP operation to get server ops */
  _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */


  DEBUG_printf(("cupsGetNamedDest(http=%p, name=\"%s\", instance=\"%s\")", (void *)http, name, instance));

 /*
  * If "name" is NULL, find the default destination...
  */

  dest_name = name;

  if (!dest_name)
  {
    set_as_default = 1;
    dest_name      = _cupsUserDefault(defname, sizeof(defname));

    if (dest_name)
    {
      char	*ptr;			/* Temporary pointer... */

      if ((ptr = strchr(defname, '/')) != NULL)
      {
        *ptr++   = '\0';
	instance = ptr;
      }
      else
        instance = NULL;
    }
    else if (cg->home)
    {
     /*
      * No default in the environment, try the user's lpoptions files...
      */

      snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);

      dest_name = cups_get_default(filename, defname, sizeof(defname), &instance);

      if (dest_name)
        set_as_default = 2;
    }

    if (!dest_name)
    {
     /*
      * Still not there?  Try the system lpoptions file...
      */

      snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
      dest_name = cups_get_default(filename, defname, sizeof(defname), &instance);

      if (dest_name)
        set_as_default = 3;
    }

    if (!dest_name)
    {
     /*
      * No locally-set default destination, ask the server...
      */

      op             = IPP_OP_CUPS_GET_DEFAULT;
      set_as_default = 4;

      DEBUG_puts("1cupsGetNamedDest: Asking server for default printer...");
    }
    else
      DEBUG_printf(("1cupsGetNamedDest: Using name=\"%s\"...", name));
  }

 /*
  * Get the printer's attributes...
  */

  if (!_cupsGetDests(http, op, dest_name, &dest, 0, 0))
  {
    if (name)
    {
      _cups_namedata_t  data;           /* Callback data */

      DEBUG_puts("1cupsGetNamedDest: No queue found for printer, looking on network...");

      data.name = name;
      data.dest = NULL;

      cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_name_cb, &data);

      if (!data.dest)
        return (NULL);

      dest = data.dest;
    }
    else
    {
      switch (set_as_default)
      {
        default :
            break;

        case 1 : /* Set from env vars */
            if (getenv("LPDEST"))
              _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("LPDEST environment variable names default destination that does not exist."), 1);
	    else if (getenv("PRINTER"))
              _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("PRINTER environment variable names default destination that does not exist."), 1);
	    else
              _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("No default destination."), 1);
            break;

        case 2 : /* Set from ~/.cups/lpoptions */
	    _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("~/.cups/lpoptions file names default destination that does not exist."), 1);
            break;

        case 3 : /* Set from /etc/cups/lpoptions */
	    _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("/etc/cups/lpoptions file names default destination that does not exist."), 1);
            break;

        case 4 : /* Set from server */
	    _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("No default destination."), 1);
            break;
      }

      return (NULL);
    }
  }

  DEBUG_printf(("1cupsGetNamedDest: Got dest=%p", (void *)dest));

  if (instance)
    dest->instance = _cupsStrAlloc(instance);

  if (set_as_default)
    dest->is_default = 1;

 /*
  * Then add local options...
  */

  snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
  cups_get_dests(filename, dest_name, instance, 0, 1, 1, &dest);

  if (cg->home)
  {
    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);

    cups_get_dests(filename, dest_name, instance, 0, 1, 1, &dest);
  }

 /*
  * Return the result...
  */

  return (dest);
}


/*
 * 'cupsRemoveDest()' - Remove a destination from the destination list.
 *
 * Removing a destination/instance does not delete the class or printer
 * queue, merely the lpoptions for that destination/instance.  Use the
 * @link cupsSetDests@ or @link cupsSetDests2@ functions to save the new
 * options for the user.
 *
 * @since CUPS 1.3/macOS 10.5@
 */

int					/* O  - New number of destinations */
cupsRemoveDest(const char  *name,	/* I  - Destination name */
               const char  *instance,	/* I  - Instance name or @code NULL@ */
	       int         num_dests,	/* I  - Number of destinations */
	       cups_dest_t **dests)	/* IO - Destinations */
{
  int		i;			/* Index into destinations */
  cups_dest_t	*dest;			/* Pointer to destination */


 /*
  * Find the destination...
  */

  if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL)
    return (num_dests);

 /*
  * Free memory...
  */

  _cupsStrFree(dest->name);
  _cupsStrFree(dest->instance);
  cupsFreeOptions(dest->num_options, dest->options);

 /*
  * Remove the destination from the array...
  */

  num_dests --;

  i = (int)(dest - *dests);

  if (i < num_dests)
    memmove(dest, dest + 1, (size_t)(num_dests - i) * sizeof(cups_dest_t));

  return (num_dests);
}


/*
 * 'cupsSetDefaultDest()' - Set the default destination.
 *
 * @since CUPS 1.3/macOS 10.5@
 */

void
cupsSetDefaultDest(
    const char  *name,			/* I - Destination name */
    const char  *instance,		/* I - Instance name or @code NULL@ */
    int         num_dests,		/* I - Number of destinations */
    cups_dest_t *dests)			/* I - Destinations */
{
  int		i;			/* Looping var */
  cups_dest_t	*dest;			/* Current destination */


 /*
  * Range check input...
  */

  if (!name || num_dests <= 0 || !dests)
    return;

 /*
  * Loop through the array and set the "is_default" flag for the matching
  * destination...
  */

  for (i = num_dests, dest = dests; i > 0; i --, dest ++)
    dest->is_default = !_cups_strcasecmp(name, dest->name) &&
                       ((!instance && !dest->instance) ||
		        (instance && dest->instance &&
			 !_cups_strcasecmp(instance, dest->instance)));
}


/*
 * 'cupsSetDests()' - Save the list of destinations for the default server.
 *
 * This function saves the destinations to /etc/cups/lpoptions when run
 * as root and ~/.cups/lpoptions when run as a normal user.
 *
 * @exclude all@
 */

void
cupsSetDests(int         num_dests,	/* I - Number of destinations */
             cups_dest_t *dests)	/* I - Destinations */
{
  cupsSetDests2(CUPS_HTTP_DEFAULT, num_dests, dests);
}


/*
 * 'cupsSetDests2()' - Save the list of destinations for the specified server.
 *
 * This function saves the destinations to /etc/cups/lpoptions when run
 * as root and ~/.cups/lpoptions when run as a normal user.
 *
 * @since CUPS 1.1.21/macOS 10.4@
 */

int					/* O - 0 on success, -1 on error */
cupsSetDests2(http_t      *http,	/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
              int         num_dests,	/* I - Number of destinations */
              cups_dest_t *dests)	/* I - Destinations */
{
  int		i, j;			/* Looping vars */
  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 */
  char		filename[1024];		/* lpoptions file */
  int		num_temps;		/* Number of temporary destinations */
  cups_dest_t	*temps = NULL,		/* Temporary destinations */
		*temp;			/* Current temporary dest */
  const char	*val;			/* Value of temporary option */
  _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */


 /*
  * Range check the input...
  */

  if (!num_dests || !dests)
    return (-1);

 /*
  * Get the server destinations...
  */

  num_temps = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &temps, 0, 0);

  if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE)
  {
    cupsFreeDests(num_temps, temps);
    return (-1);
  }

 /*
  * Figure out which file to write to...
  */

  snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);

  if (cg->home)
  {
   /*
    * Create ~/.cups subdirectory...
    */

    snprintf(filename, sizeof(filename), "%s/.cups", cg->home);
    if (access(filename, 0))
      mkdir(filename, 0700);

    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);
  }

 /*
  * Try to open the file...
  */

  if ((fp = fopen(filename, "w")) == NULL)
  {
    cupsFreeDests(num_temps, temps);
    return (-1);
  }

#ifndef _WIN32
 /*
  * Set the permissions to 0644 when saving to the /etc/cups/lpoptions
  * file...
  */

  if (!getuid())
    fchmod(fileno(fp), 0644);
#endif /* !_WIN32 */

 /*
  * Write each printer; each line looks like:
  *
  *    Dest name[/instance] options
  *    Default name[/instance] options
  */

  for (i = num_dests, dest = dests; i > 0; i --, dest ++)
    if (dest->instance != NULL || dest->num_options != 0 || dest->is_default)
    {
      if (dest->is_default)
      {
	fprintf(fp, "Default %s", dest->name);
	if (dest->instance)
	  fprintf(fp, "/%s", dest->instance);

        wrote = 1;
      }
      else
        wrote = 0;

      temp = cupsGetDest(dest->name, NULL, num_temps, temps);

      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 options match these; if so, don't write 'em.
	*/

        if (temp && (val = cupsGetOption(option->name, temp->num_options, temp->options)) != NULL && !_cups_strcasecmp(val, option->value))
	  continue;

       /*
        * Options don't match, write to the file...
	*/

        if (!wrote)
	{
	  fprintf(fp, "Dest %s", dest->name);
	  if (dest->instance)
	    fprintf(fp, "/%s", dest->instance);
          wrote = 1;
	}

        if (option->value[0])
	{
	  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);
      }

      if (wrote)
        fputs("\n", fp);
    }

 /*
  * Free the temporary destinations and close the file...
  */

  cupsFreeDests(num_temps, temps);

  fclose(fp);

#ifdef __APPLE__
 /*
  * Set the default printer for this location - this allows command-line
  * and GUI applications to share the same default destination...
  */

  if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL)
  {
    CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, dest->name, kCFStringEncodingUTF8);
					/* Default printer name */

    if (name)
    {
      _cupsAppleSetDefaultPrinter(name);
      CFRelease(name);
    }
  }
#endif /* __APPLE__ */

#ifdef HAVE_NOTIFY_POST
 /*
  * Send a notification so that macOS applications can know about the
  * change, too.
  */

  notify_post("com.apple.printerListChange");
#endif /* HAVE_NOTIFY_POST */

  return (0);
}


/*
 * '_cupsUserDefault()' - Get the user default printer from environment
 *                        variables and location information.
 */

char *					/* O - Default printer or NULL */
_cupsUserDefault(char   *name,		/* I - Name buffer */
                 size_t namesize)	/* I - Size of name buffer */
{
  const char	*env;			/* LPDEST or PRINTER env variable */
#ifdef __APPLE__
  CFStringRef	locprinter;		/* Last printer as this location */
#endif /* __APPLE__ */


  if ((env = getenv("LPDEST")) == NULL)
    if ((env = getenv("PRINTER")) != NULL && !strcmp(env, "lp"))
      env = NULL;

  if (env)
  {
    strlcpy(name, env, namesize);
    return (name);
  }

#ifdef __APPLE__
 /*
  * Use location-based defaults if "use last printer" is selected in the
  * system preferences...
  */

  if (!getenv("CUPS_NO_APPLE_DEFAULT") && (locprinter = _cupsAppleCopyDefaultPrinter()) != NULL)
  {
    CFStringGetCString(locprinter, name, (CFIndex)namesize, kCFStringEncodingUTF8);
    CFRelease(locprinter);
  }
  else
    name[0] = '\0';

  DEBUG_printf(("1_cupsUserDefault: Returning \"%s\".", name));

  return (*name ? name : NULL);

#else
 /*
  * No location-based defaults on this platform...
  */

  name[0] = '\0';
  return (NULL);
#endif /* __APPLE__ */
}


#if _CUPS_LOCATION_DEFAULTS
/*
 * 'appleCopyLocations()' - Copy the location history array.
 */

static CFArrayRef			/* O - Location array or NULL */
appleCopyLocations(void)
{
  CFArrayRef	locations;		/* Location array */


 /*
  * Look up the location array in the preferences...
  */

  if ((locations = CFPreferencesCopyAppValue(kLastUsedPrintersKey,
                                             kCUPSPrintingPrefs)) == NULL)
    return (NULL);

  if (CFGetTypeID(locations) != CFArrayGetTypeID())
  {
    CFRelease(locations);
    return (NULL);
  }

  return (locations);
}


/*
 * 'appleCopyNetwork()' - Get the network ID for the current location.
 */

static CFStringRef			/* O - Network ID */
appleCopyNetwork(void)
{
  SCDynamicStoreRef	dynamicStore;	/* System configuration data */
  CFStringRef		key;		/* Current network configuration key */
  CFDictionaryRef	ip_dict;	/* Network configuration data */
  CFStringRef		network = NULL;	/* Current network ID */


  if ((dynamicStore = SCDynamicStoreCreate(NULL, CFSTR("libcups"), NULL,
                                           NULL)) != NULL)
  {
   /*
    * First use the IPv6 router address, if available, since that will generally
    * be a globally-unique link-local address.
    */

    if ((key = SCDynamicStoreKeyCreateNetworkGlobalEntity(
                   NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6)) != NULL)
    {
      if ((ip_dict = SCDynamicStoreCopyValue(dynamicStore, key)) != NULL)
      {
	if ((network = CFDictionaryGetValue(ip_dict,
	                                    kSCPropNetIPv6Router)) != NULL)
          CFRetain(network);

        CFRelease(ip_dict);
      }

      CFRelease(key);
    }

   /*
    * If that doesn't work, try the IPv4 router address. This isn't as unique
    * and will likely be a 10.x.y.z or 192.168.y.z address...
    */

    if (!network)
    {
      if ((key = SCDynamicStoreKeyCreateNetworkGlobalEntity(
		     NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4)) != NULL)
      {
	if ((ip_dict = SCDynamicStoreCopyValue(dynamicStore, key)) != NULL)
	{
	  if ((network = CFDictionaryGetValue(ip_dict,
					      kSCPropNetIPv4Router)) != NULL)
	    CFRetain(network);

	  CFRelease(ip_dict);
	}

	CFRelease(key);
      }
    }

    CFRelease(dynamicStore);
  }

  return (network);
}
#endif /* _CUPS_LOCATION_DEFAULTS */


#ifdef __APPLE__
/*
 * 'appleGetPaperSize()' - Get the default paper size.
 */

static char *				/* O - Default paper size */
appleGetPaperSize(char   *name,		/* I - Paper size name buffer */
                  size_t namesize)	/* I - Size of buffer */
{
  CFStringRef	defaultPaperID;		/* Default paper ID */
  pwg_media_t	*pwgmedia;		/* PWG media size */


  defaultPaperID = _cupsAppleCopyDefaultPaperID();
  if (!defaultPaperID ||
      CFGetTypeID(defaultPaperID) != CFStringGetTypeID() ||
      !CFStringGetCString(defaultPaperID, name, (CFIndex)namesize, kCFStringEncodingUTF8))
    name[0] = '\0';
  else if ((pwgmedia = pwgMediaForLegacy(name)) != NULL)
    strlcpy(name, pwgmedia->pwg, namesize);

  if (defaultPaperID)
    CFRelease(defaultPaperID);

  return (name);
}
#endif /* __APPLE__ */


#if _CUPS_LOCATION_DEFAULTS
/*
 * 'appleGetPrinter()' - Get a printer from the history array.
 */

static CFStringRef			/* O - Printer name or NULL */
appleGetPrinter(CFArrayRef  locations,	/* I - Location array */
                CFStringRef network,	/* I - Network name */
		CFIndex     *locindex)	/* O - Index in array */
{
  CFIndex		i,		/* Looping var */
			count;		/* Number of locations */
  CFDictionaryRef	location;	/* Current location */
  CFStringRef		locnetwork,	/* Current network */
			locprinter;	/* Current printer */


  for (i = 0, count = CFArrayGetCount(locations); i < count; i ++)
    if ((location = CFArrayGetValueAtIndex(locations, i)) != NULL &&
        CFGetTypeID(location) == CFDictionaryGetTypeID())
    {
      if ((locnetwork = CFDictionaryGetValue(location,
                                             kLocationNetworkKey)) != NULL &&
          CFGetTypeID(locnetwork) == CFStringGetTypeID() &&
	  CFStringCompare(network, locnetwork, 0) == kCFCompareEqualTo &&
	  (locprinter = CFDictionaryGetValue(location,
	                                     kLocationPrinterIDKey)) != NULL &&
	  CFGetTypeID(locprinter) == CFStringGetTypeID())
      {
        if (locindex)
	  *locindex = i;

	return (locprinter);
      }
    }

  return (NULL);
}
#endif /* _CUPS_LOCATION_DEFAULTS */


/*
 * 'cups_add_dest()' - Add a destination to the array.
 *
 * Unlike cupsAddDest(), this function does not check for duplicates.
 */

static cups_dest_t *			/* O  - New destination */
cups_add_dest(const char  *name,	/* I  - Name of destination */
              const char  *instance,	/* I  - Instance or NULL */
              int         *num_dests,	/* IO - Number of destinations */
	      cups_dest_t **dests)	/* IO - Destinations */
{
  int		insert,			/* Insertion point */
		diff;			/* Result of comparison */
  cups_dest_t	*dest;			/* Destination pointer */


 /*
  * Add new destination...
  */

  if (*num_dests == 0)
    dest = malloc(sizeof(cups_dest_t));
  else
    dest = realloc(*dests, sizeof(cups_dest_t) * (size_t)(*num_dests + 1));

  if (!dest)
    return (NULL);

  *dests = dest;

 /*
  * Find where to insert the destination...
  */

  if (*num_dests == 0)
    insert = 0;
  else
  {
    insert = cups_find_dest(name, instance, *num_dests, *dests, *num_dests - 1,
                            &diff);

    if (diff > 0)
      insert ++;
  }

 /*
  * Move the array elements as needed...
  */

  if (insert < *num_dests)
    memmove(*dests + insert + 1, *dests + insert, (size_t)(*num_dests - insert) * sizeof(cups_dest_t));

  (*num_dests) ++;

 /*
  * Initialize the destination...
  */

  dest              = *dests + insert;
  dest->name        = _cupsStrAlloc(name);
  dest->instance    = _cupsStrAlloc(instance);
  dest->is_default  = 0;
  dest->num_options = 0;
  dest->options     = (cups_option_t *)0;

  return (dest);
}


#  ifdef __BLOCKS__
/*
 * 'cups_block_cb()' - Enumeration callback for block API.
 */

static int				/* O - 1 to continue, 0 to stop */
cups_block_cb(
    cups_dest_block_t block,		/* I - Block */
    unsigned          flags,		/* I - Destination flags */
    cups_dest_t       *dest)		/* I - Destination */
{
  return ((block)(flags, dest));
}
#  endif /* __BLOCKS__ */


/*
 * 'cups_compare_dests()' - Compare two destinations.
 */

static int				/* O - Result of comparison */
cups_compare_dests(cups_dest_t *a,	/* I - First destination */
                   cups_dest_t *b)	/* I - Second destination */
{
  int	diff;				/* Difference */


  if ((diff = _cups_strcasecmp(a->name, b->name)) != 0)
    return (diff);
  else if (a->instance && b->instance)
    return (_cups_strcasecmp(a->instance, b->instance));
  else
    return ((a->instance && !b->instance) - (!a->instance && b->instance));
}


#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
#  ifdef HAVE_DNSSD
/*
 * 'cups_dnssd_browse_cb()' - Browse for printers.
 */

static void
cups_dnssd_browse_cb(
    DNSServiceRef       sdRef,		/* I - Service reference */
    DNSServiceFlags     flags,		/* I - Option flags */
    uint32_t            interfaceIndex,	/* I - Interface number */
    DNSServiceErrorType errorCode,	/* I - Error, if any */
    const char          *serviceName,	/* I - Name of service/device */
    const char          *regtype,	/* I - Type of service */
    const char          *replyDomain,	/* I - Service domain */
    void                *context)	/* I - Enumeration data */
{
  _cups_dnssd_data_t	*data = (_cups_dnssd_data_t *)context;
					/* Enumeration data */


  DEBUG_printf(("5cups_dnssd_browse_cb(sdRef=%p, flags=%x, interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\", context=%p)", (void *)sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain, context));

 /*
  * Don't do anything on error...
  */

  if (errorCode != kDNSServiceErr_NoError)
    return;

 /*
  * Get the device...
  */

  cups_dnssd_get_device(data, serviceName, regtype, replyDomain);
}


#  else /* HAVE_AVAHI */
/*
 * 'cups_dnssd_browse_cb()' - Browse for printers.
 */

static void
cups_dnssd_browse_cb(
    AvahiServiceBrowser    *browser,	/* I - Browser */
    AvahiIfIndex           interface,	/* I - Interface index (unused) */
    AvahiProtocol          protocol,	/* I - Network protocol (unused) */
    AvahiBrowserEvent      event,	/* I - What happened */
    const char             *name,	/* I - Service name */
    const char             *type,	/* I - Registration type */
    const char             *domain,	/* I - Domain */
    AvahiLookupResultFlags flags,	/* I - Flags */
    void                   *context)	/* I - Devices array */
{
#ifdef DEBUG
  AvahiClient		*client = avahi_service_browser_get_client(browser);
					/* Client information */
#endif /* DEBUG */
  _cups_dnssd_data_t	*data = (_cups_dnssd_data_t *)context;
					/* Enumeration data */


  (void)interface;
  (void)protocol;
  (void)context;

  DEBUG_printf(("cups_dnssd_browse_cb(..., name=\"%s\", type=\"%s\", domain=\"%s\", ...);", name, type, domain));

  switch (event)
  {
    case AVAHI_BROWSER_FAILURE:
	DEBUG_printf(("cups_dnssd_browse_cb: %s", avahi_strerror(avahi_client_errno(client))));
	avahi_simple_poll_quit(data->simple_poll);
	break;

    case AVAHI_BROWSER_NEW:
       /*
	* This object is new on the network.
	*/

	cups_dnssd_get_device(data, name, type, domain);
	break;

    case AVAHI_BROWSER_REMOVE :
    case AVAHI_BROWSER_CACHE_EXHAUSTED :
        break;

    case AVAHI_BROWSER_ALL_FOR_NOW :
        DEBUG_puts("cups_dnssd_browse_cb: ALL_FOR_NOW");
        data->browsers --;
        break;
  }
}


/*
 * 'cups_dnssd_client_cb()' - Avahi client callback function.
 */

static void
cups_dnssd_client_cb(
    AvahiClient      *client,		/* I - Client information (unused) */
    AvahiClientState state,		/* I - Current state */
    void             *context)		/* I - User data (unused) */
{
  _cups_dnssd_data_t	*data = (_cups_dnssd_data_t *)context;
					/* Enumeration data */


  (void)client;

  DEBUG_printf(("cups_dnssd_client_cb(client=%p, state=%d, context=%p)", client, state, context));

 /*
  * If the connection drops, quit.
  */

  if (state == AVAHI_CLIENT_FAILURE)
  {
    DEBUG_puts("cups_dnssd_client_cb: Avahi connection failed.");
    avahi_simple_poll_quit(data->simple_poll);
  }
}
#  endif /* HAVE_DNSSD */


/*
 * 'cups_dnssd_compare_device()' - Compare two devices.
 */

static int				/* O - Result of comparison */
cups_dnssd_compare_devices(
    _cups_dnssd_device_t *a,		/* I - First device */
    _cups_dnssd_device_t *b)		/* I - Second device */
{
  return (strcmp(a->dest.name, b->dest.name));
}


/*
 * 'cups_dnssd_free_device()' - Free the memory used by a device.
 */

static void
cups_dnssd_free_device(
    _cups_dnssd_device_t *device,	/* I - Device */
    _cups_dnssd_data_t   *data)		/* I - Enumeration data */
{
  DEBUG_printf(("5cups_dnssd_free_device(device=%p(%s), data=%p)", (void *)device, device->dest.name, (void *)data));

#  ifdef HAVE_DNSSD
  if (device->ref)
    DNSServiceRefDeallocate(device->ref);
#  else /* HAVE_AVAHI */
  if (device->ref)
    avahi_record_browser_free(device->ref);
#  endif /* HAVE_DNSSD */

  _cupsStrFree(device->domain);
  _cupsStrFree(device->fullName);
  _cupsStrFree(device->regtype);
  _cupsStrFree(device->dest.name);

  cupsFreeOptions(device->dest.num_options, device->dest.options);

  free(device);
}


/*
 * 'cups_dnssd_get_device()' - Lookup a device and create it as needed.
 */

static _cups_dnssd_device_t *		/* O - Device */
cups_dnssd_get_device(
    _cups_dnssd_data_t *data,		/* I - Enumeration data */
    const char         *serviceName,	/* I - Service name */
    const char         *regtype,	/* I - Registration type */
    const char         *replyDomain)	/* I - Domain name */
{
  _cups_dnssd_device_t	key,		/* Search key */
			*device;	/* Device */
  char			fullName[kDNSServiceMaxDomainName],
					/* Full name for query */
			name[128];	/* Queue name */


  DEBUG_printf(("5cups_dnssd_get_device(data=%p, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\")", (void *)data, serviceName, regtype, replyDomain));

 /*
  * See if this is an existing device...
  */

  cups_queue_name(name, serviceName, sizeof(name));

  key.dest.name = name;

  if ((device = cupsArrayFind(data->devices, &key)) != NULL)
  {
   /*
    * Yes, see if we need to do anything with this...
    */

    int	update = 0;			/* Non-zero if we need to update */

    if (!_cups_strcasecmp(replyDomain, "local.") &&
	_cups_strcasecmp(device->domain, replyDomain))
    {
     /*
      * Update the "global" listing to use the .local domain name instead.
      */

      _cupsStrFree(device->domain);
      device->domain = _cupsStrAlloc(replyDomain);

      DEBUG_printf(("6cups_dnssd_get_device: Updating '%s' to use local "
                    "domain.", device->dest.name));

      update = 1;
    }

    if (!_cups_strcasecmp(regtype, "_ipps._tcp") &&
	_cups_strcasecmp(device->regtype, regtype))
    {
     /*
      * Prefer IPPS over IPP.
      */

      _cupsStrFree(device->regtype);
      device->regtype = _cupsStrAlloc(regtype);

      DEBUG_printf(("6cups_dnssd_get_device: Updating '%s' to use IPPS.",
		    device->dest.name));

      update = 1;
    }

    if (!update)
    {
      DEBUG_printf(("6cups_dnssd_get_device: No changes to '%s'.",
                    device->dest.name));
      return (device);
    }
  }
  else
  {
   /*
    * No, add the device...
    */

    DEBUG_printf(("6cups_dnssd_get_device: Adding '%s' for %s with domain "
                  "'%s'.", serviceName,
                  !strcmp(regtype, "_ipps._tcp") ? "IPPS" : "IPP",
                  replyDomain));

    device            = calloc(sizeof(_cups_dnssd_device_t), 1);
    device->dest.name = _cupsStrAlloc(name);
    device->domain    = _cupsStrAlloc(replyDomain);
    device->regtype   = _cupsStrAlloc(regtype);

    device->dest.num_options = cupsAddOption("printer-info", serviceName, 0, &device->dest.options);

    cupsArrayAdd(data->devices, device);
  }

 /*
  * Set the "full name" of this service, which is used for queries...
  */

#  ifdef HAVE_DNSSD
  DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain);
#  else /* HAVE_AVAHI */
  avahi_service_name_join(fullName, kDNSServiceMaxDomainName, serviceName, regtype, replyDomain);
#  endif /* HAVE_DNSSD */

  _cupsStrFree(device->fullName);
  device->fullName = _cupsStrAlloc(fullName);

  if (device->ref)
  {
#  ifdef HAVE_DNSSD
    DNSServiceRefDeallocate(device->ref);
#  else /* HAVE_AVAHI */
    avahi_record_browser_free(device->ref);
#  endif /* HAVE_DNSSD */

    device->ref = 0;
  }

  if (device->state == _CUPS_DNSSD_ACTIVE)
  {
    DEBUG_printf(("6cups_dnssd_get_device: Remove callback for \"%s\".", device->dest.name));

    (*data->cb)(data->user_data, CUPS_DEST_FLAGS_REMOVED, &device->dest);
    device->state = _CUPS_DNSSD_NEW;
  }

  return (device);
}


#  ifdef HAVE_AVAHI
/*
 * 'cups_dnssd_poll_cb()' - Wait for input on the specified file descriptors.
 *
 * Note: This function is needed because avahi_simple_poll_iterate is broken
 *       and always uses a timeout of 0 (!) milliseconds.
 *       (https://github.com/lathiat/avahi/issues/127)
 *
 * @private@
 */

static int				/* O - Number of file descriptors matching */
cups_dnssd_poll_cb(
    struct pollfd *pollfds,		/* I - File descriptors */
    unsigned int  num_pollfds,		/* I - Number of file descriptors */
    int           timeout,		/* I - Timeout in milliseconds (unused) */
    void          *context)		/* I - User data (unused) */
{
  _cups_dnssd_data_t	*data = (_cups_dnssd_data_t *)context;
					/* Enumeration data */
  int			val;		/* Return value */


  DEBUG_printf(("cups_dnssd_poll_cb(pollfds=%p, num_pollfds=%d, timeout=%d, context=%p)", pollfds, num_pollfds, timeout, context));

  (void)timeout;

  val = poll(pollfds, num_pollfds, _CUPS_DNSSD_MAXTIME);

  DEBUG_printf(("cups_dnssd_poll_cb: poll() returned %d", val));

  if (val < 0)
  {
    DEBUG_printf(("cups_dnssd_poll_cb: %s", strerror(errno)));
  }
  else if (val > 0)
  {
    data->got_data = 1;
  }

  return (val);
}
#  endif /* HAVE_AVAHI */


/*
 * 'cups_dnssd_query_cb()' - Process query data.
 */

static void
cups_dnssd_query_cb(
#  ifdef HAVE_DNSSD
    DNSServiceRef       sdRef,		/* I - Service reference */
    DNSServiceFlags     flags,		/* I - Data flags */
    uint32_t            interfaceIndex,	/* I - Interface */
    DNSServiceErrorType errorCode,	/* I - Error, if any */
    const char          *fullName,	/* I - Full service name */
    uint16_t            rrtype,		/* I - Record type */
    uint16_t            rrclass,	/* I - Record class */
    uint16_t            rdlen,		/* I - Length of record data */
    const void          *rdata,		/* I - Record data */
    uint32_t            ttl,		/* I - Time-to-live */
#  else /* HAVE_AVAHI */
    AvahiRecordBrowser     *browser,	/* I - Record browser */
    AvahiIfIndex           interfaceIndex,
					/* I - Interface index (unused) */
    AvahiProtocol          protocol,	/* I - Network protocol (unused) */
    AvahiBrowserEvent      event,	/* I - What happened? */
    const char             *fullName,	/* I - Service name */
    uint16_t               rrclass,	/* I - Record class */
    uint16_t               rrtype,	/* I - Record type */
    const void             *rdata,	/* I - TXT record */
    size_t                 rdlen,	/* I - Length of TXT record */
    AvahiLookupResultFlags flags,	/* I - Flags */
#  endif /* HAVE_DNSSD */
    void                *context)	/* I - Enumeration data */
{
#  if defined(DEBUG) && defined(HAVE_AVAHI)
  AvahiClient		*client = avahi_record_browser_get_client(browser);
					/* Client information */
#  endif /* DEBUG && HAVE_AVAHI */
  _cups_dnssd_data_t	*data = (_cups_dnssd_data_t *)context;
					/* Enumeration data */
  char			serviceName[256],/* Service name */
			name[128],	/* Queue name */
			*ptr;		/* Pointer into string */
  _cups_dnssd_device_t	dkey,		/* Search key */
			*device;	/* Device */


#  ifdef HAVE_DNSSD
  DEBUG_printf(("5cups_dnssd_query_cb(sdRef=%p, flags=%x, interfaceIndex=%d, errorCode=%d, fullName=\"%s\", rrtype=%u, rrclass=%u, rdlen=%u, rdata=%p, ttl=%u, context=%p)", (void *)sdRef, flags, interfaceIndex, errorCode, fullName, rrtype, rrclass, rdlen, rdata, ttl, context));

 /*
  * Only process "add" data...
  */

  if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd))
    return;

#  else /* HAVE_AVAHI */
  DEBUG_printf(("cups_dnssd_query_cb(browser=%p, interfaceIndex=%d, protocol=%d, event=%d, fullName=\"%s\", rrclass=%u, rrtype=%u, rdata=%p, rdlen=%u, flags=%x, context=%p)", browser, interfaceIndex, protocol, event, fullName, rrclass, rrtype, rdata, (unsigned)rdlen, flags, context));

 /*
  * Only process "add" data...
  */

  if (event != AVAHI_BROWSER_NEW)
  {
    if (event == AVAHI_BROWSER_FAILURE)
      DEBUG_printf(("cups_dnssd_query_cb: %s", avahi_strerror(avahi_client_errno(client))));

    return;
  }
#  endif /* HAVE_DNSSD */

 /*
  * Lookup the service in the devices array.
  */

  cups_dnssd_unquote(serviceName, fullName, sizeof(serviceName));

  if ((ptr = strstr(serviceName, "._")) != NULL)
    *ptr = '\0';

  cups_queue_name(name, serviceName, sizeof(name));

  dkey.dest.name = name;

  if ((device = cupsArrayFind(data->devices, &dkey)) != NULL && device->state == _CUPS_DNSSD_NEW)
  {
   /*
    * Found it, pull out the make and model from the TXT record and save it...
    */

    const uint8_t	*txt,		/* Pointer into data */
			*txtnext,	/* Next key/value pair */
			*txtend;	/* End of entire TXT record */
    uint8_t		txtlen;		/* Length of current key/value pair */
    char		key[256],	/* Key string */
			value[256],	/* Value string */
			make_and_model[512],
					/* Manufacturer and model */
			model[256],	/* Model */
			uriname[1024],	/* Name for URI */
			uri[1024];	/* Printer URI */
    cups_ptype_t	type = CUPS_PRINTER_DISCOVERED | CUPS_PRINTER_BW;
					/* Printer type */
    int			saw_printer_type = 0;
					/* Did we see a printer-type key? */

    device->state     = _CUPS_DNSSD_PENDING;
    make_and_model[0] = '\0';

    strlcpy(model, "Unknown", sizeof(model));

    for (txt = rdata, txtend = txt + rdlen;
	 txt < txtend;
	 txt = txtnext)
    {
     /*
      * Read a key/value pair starting with an 8-bit length.  Since the
      * length is 8 bits and the size of the key/value buffers is 256, we
      * don't need to check for overflow...
      */

      txtlen = *txt++;

      if (!txtlen || (txt + txtlen) > txtend)
	break;

      txtnext = txt + txtlen;

      for (ptr = key; txt < txtnext && *txt != '='; txt ++)
	*ptr++ = (char)*txt;
      *ptr = '\0';

      if (txt < txtnext && *txt == '=')
      {
	txt ++;

	if (txt < txtnext)
	  memcpy(value, txt, (size_t)(txtnext - txt));
	value[txtnext - txt] = '\0';

	DEBUG_printf(("6cups_dnssd_query_cb: %s=%s", key, value));
      }
      else
      {
	DEBUG_printf(("6cups_dnssd_query_cb: '%s' with no value.", key));
	continue;
      }

      if (!_cups_strcasecmp(key, "usb_MFG") ||
          !_cups_strcasecmp(key, "usb_MANU") ||
	  !_cups_strcasecmp(key, "usb_MANUFACTURER"))
	strlcpy(make_and_model, value, sizeof(make_and_model));
      else if (!_cups_strcasecmp(key, "usb_MDL") ||
               !_cups_strcasecmp(key, "usb_MODEL"))
	strlcpy(model, value, sizeof(model));
      else if (!_cups_strcasecmp(key, "product") && !strstr(value, "Ghostscript"))
      {
	if (value[0] == '(')
	{
	 /*
	  * Strip parenthesis...
	  */

	  if ((ptr = value + strlen(value) - 1) > value && *ptr == ')')
	    *ptr = '\0';

	  strlcpy(model, value + 1, sizeof(model));
	}
	else
	  strlcpy(model, value, sizeof(model));
      }
      else if (!_cups_strcasecmp(key, "ty"))
      {
	strlcpy(model, value, sizeof(model));

	if ((ptr = strchr(model, ',')) != NULL)
	  *ptr = '\0';
      }
      else if (!_cups_strcasecmp(key, "note"))
        device->dest.num_options = cupsAddOption("printer-location", value,
						 device->dest.num_options,
						 &device->dest.options);
      else if (!_cups_strcasecmp(key, "pdl"))
      {
       /*
        * Look for PDF-capable printers; only PDF-capable printers are shown.
        */

        const char	*start, *next;	/* Pointer into value */
        int		have_pdf = 0,	/* Have PDF? */
			have_raster = 0;/* Have raster format support? */

        for (start = value; start && *start; start = next)
        {
          if (!_cups_strncasecmp(start, "application/pdf", 15) && (!start[15] || start[15] == ','))
          {
            have_pdf = 1;
            break;
          }
          else if ((!_cups_strncasecmp(start, "image/pwg-raster", 16) && (!start[16] || start[16] == ',')) ||
		   (!_cups_strncasecmp(start, "image/urf", 9) && (!start[9] || start[9] == ',')))
          {
            have_raster = 1;
            break;
          }

          if ((next = strchr(start, ',')) != NULL)
            next ++;
        }

        if (!have_pdf && !have_raster)
          device->state = _CUPS_DNSSD_INCOMPATIBLE;
      }
      else if (!_cups_strcasecmp(key, "printer-type"))
      {
       /*
        * Value is either NNNN or 0xXXXX
        */

	saw_printer_type = 1;
        type             = (cups_ptype_t)strtol(value, NULL, 0) | CUPS_PRINTER_DISCOVERED;
      }
      else if (!saw_printer_type)
      {
	if (!_cups_strcasecmp(key, "air") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_AUTHENTICATED;
	else if (!_cups_strcasecmp(key, "bind") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_BIND;
	else if (!_cups_strcasecmp(key, "collate") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_COLLATE;
	else if (!_cups_strcasecmp(key, "color") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_COLOR;
	else if (!_cups_strcasecmp(key, "copies") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_COPIES;
	else if (!_cups_strcasecmp(key, "duplex") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_DUPLEX;
	else if (!_cups_strcasecmp(key, "fax") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_MFP;
	else if (!_cups_strcasecmp(key, "papercustom") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_VARIABLE;
	else if (!_cups_strcasecmp(key, "papermax"))
	{
	  if (!_cups_strcasecmp(value, "legal-a4"))
	    type |= CUPS_PRINTER_SMALL;
	  else if (!_cups_strcasecmp(value, "isoc-a2"))
	    type |= CUPS_PRINTER_MEDIUM;
	  else if (!_cups_strcasecmp(value, ">isoc-a2"))
	    type |= CUPS_PRINTER_LARGE;
	}
	else if (!_cups_strcasecmp(key, "punch") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_PUNCH;
	else if (!_cups_strcasecmp(key, "scan") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_MFP;
	else if (!_cups_strcasecmp(key, "sort") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_SORT;
	else if (!_cups_strcasecmp(key, "staple") &&
		 !_cups_strcasecmp(value, "t"))
	  type |= CUPS_PRINTER_STAPLE;
      }
    }

   /*
    * Save the printer-xxx values...
    */

    if (make_and_model[0])
    {
      strlcat(make_and_model, " ", sizeof(make_and_model));
      strlcat(make_and_model, model, sizeof(make_and_model));

      device->dest.num_options = cupsAddOption("printer-make-and-model", make_and_model, device->dest.num_options, &device->dest.options);
    }
    else
      device->dest.num_options = cupsAddOption("printer-make-and-model", model, device->dest.num_options, &device->dest.options);

    device->type = type;
    snprintf(value, sizeof(value), "%u", type);
    device->dest.num_options = cupsAddOption("printer-type", value, device->dest.num_options, &device->dest.options);

   /*
    * Save the URI...
    */

    cups_dnssd_unquote(uriname, device->fullName, sizeof(uriname));
    httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri),
                    !strcmp(device->regtype, "_ipps._tcp") ? "ipps" : "ipp",
                    NULL, uriname, 0, saw_printer_type ? "/cups" : "/");

    DEBUG_printf(("6cups_dnssd_query: device-uri=\"%s\"", uri));

    device->dest.num_options = cupsAddOption("device-uri", uri, device->dest.num_options, &device->dest.options);
  }
  else
    DEBUG_printf(("6cups_dnssd_query: Ignoring TXT record for '%s'.",
                  fullName));
}


/*
 * 'cups_dnssd_resolve()' - Resolve a Bonjour printer URI.
 */

static const char *			/* O - Resolved URI or NULL */
cups_dnssd_resolve(
    cups_dest_t    *dest,		/* I - Destination */
    const char     *uri,		/* I - Current printer URI */
    int            msec,		/* I - Time in milliseconds */
    int            *cancel,		/* I - Pointer to "cancel" variable */
    cups_dest_cb_t cb,			/* I - Callback */
    void           *user_data)		/* I - User data for callback */
{
  char			tempuri[1024];	/* Temporary URI buffer */
  _cups_dnssd_resolve_t	resolve;	/* Resolve data */


 /*
  * Resolve the URI...
  */

  resolve.cancel = cancel;
  gettimeofday(&resolve.end_time, NULL);
  if (msec > 0)
  {
    resolve.end_time.tv_sec  += msec / 1000;
    resolve.end_time.tv_usec += (msec % 1000) * 1000;

    while (resolve.end_time.tv_usec >= 1000000)
    {
      resolve.end_time.tv_sec ++;
      resolve.end_time.tv_usec -= 1000000;
    }
  }
  else
    resolve.end_time.tv_sec += 75;

  if (cb)
    (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_RESOLVING, dest);

  if ((uri = _httpResolveURI(uri, tempuri, sizeof(tempuri), _HTTP_RESOLVE_DEFAULT, cups_dnssd_resolve_cb, &resolve)) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to resolve printer-uri."), 1);

    if (cb)
      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);

    return (NULL);
  }

 /*
  * Save the resolved URI...
  */

  dest->num_options = cupsAddOption("device-uri", uri, dest->num_options, &dest->options);

  return (cupsGetOption("device-uri", dest->num_options, dest->options));
}


/*
 * 'cups_dnssd_resolve_cb()' - See if we should continue resolving.
 */

static int				/* O - 1 to continue, 0 to stop */
cups_dnssd_resolve_cb(void *context)	/* I - Resolve data */
{
  _cups_dnssd_resolve_t	*resolve = (_cups_dnssd_resolve_t *)context;
					/* Resolve data */
  struct timeval	curtime;	/* Current time */


 /*
  * If the cancel variable is set, return immediately.
  */

  if (resolve->cancel && *(resolve->cancel))
  {
    DEBUG_puts("4cups_dnssd_resolve_cb: Canceled.");
    return (0);
  }

 /*
  * Otherwise check the end time...
  */

  gettimeofday(&curtime, NULL);

  DEBUG_printf(("4cups_dnssd_resolve_cb: curtime=%d.%06d, end_time=%d.%06d", (int)curtime.tv_sec, (int)curtime.tv_usec, (int)resolve->end_time.tv_sec, (int)resolve->end_time.tv_usec));

  return (curtime.tv_sec < resolve->end_time.tv_sec ||
          (curtime.tv_sec == resolve->end_time.tv_sec &&
           curtime.tv_usec < resolve->end_time.tv_usec));
}


/*
 * 'cups_dnssd_unquote()' - Unquote a name string.
 */

static void
cups_dnssd_unquote(char       *dst,	/* I - Destination buffer */
                   const char *src,	/* I - Source string */
		   size_t     dstsize)	/* I - Size of destination buffer */
{
  char	*dstend = dst + dstsize - 1;	/* End of destination buffer */


  while (*src && dst < dstend)
  {
    if (*src == '\\')
    {
      src ++;
      if (isdigit(src[0] & 255) && isdigit(src[1] & 255) &&
          isdigit(src[2] & 255))
      {
        *dst++ = ((((src[0] - '0') * 10) + src[1] - '0') * 10) + src[2] - '0';
	src += 3;
      }
      else
        *dst++ = *src++;
    }
    else
      *dst++ = *src ++;
  }

  *dst = '\0';
}
#endif /* HAVE_DNSSD */


#if defined(HAVE_AVAHI) || defined(HAVE_DNSSD)
/*
 * 'cups_elapsed()' - Return the elapsed time in milliseconds.
 */

static int				/* O  - Elapsed time in milliseconds */
cups_elapsed(struct timeval *t)		/* IO - Previous time */
{
  int			msecs;		/* Milliseconds */
  struct timeval	nt;		/* New time */


  gettimeofday(&nt, NULL);

  msecs = (int)(1000 * (nt.tv_sec - t->tv_sec) + (nt.tv_usec - t->tv_usec) / 1000);

  *t = nt;

  return (msecs);
}
#endif /* HAVE_AVAHI || HAVE_DNSSD */


/*
 * 'cups_enum_dests()' - Enumerate destinations from a specific server.
 */

static int                              /* O - 1 on success, 0 on failure */
cups_enum_dests(
  http_t         *http,                 /* I - Connection to scheduler */
  unsigned       flags,                 /* I - Enumeration flags */
  int            msec,                  /* I - Timeout in milliseconds, -1 for indefinite */
  int            *cancel,               /* I - Pointer to "cancel" variable */
  cups_ptype_t   type,                  /* I - Printer type bits */
  cups_ptype_t   mask,                  /* I - Mask for printer type bits */
  cups_dest_cb_t cb,                    /* I - Callback function */
  void           *user_data)            /* I - User data */
{
  int           i, j,			/* Looping vars */
                num_dests;              /* Number of destinations */
  cups_dest_t   *dests = NULL,          /* Destinations */
                *dest;			/* Current destination */
  cups_option_t	*option;		/* Current option */
  const char	*user_default;		/* Default printer from environment */
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
  int           count,                  /* Number of queries started */
                completed,              /* Number of completed queries */
                remaining;              /* Remainder of timeout */
  struct timeval curtime;               /* Current time */
  _cups_dnssd_data_t data;		/* Data for callback */
  _cups_dnssd_device_t *device;         /* Current device */
#  ifdef HAVE_DNSSD
  int           nfds,                   /* Number of files responded */
                main_fd;                /* File descriptor for lookups */
  DNSServiceRef ipp_ref = NULL;		/* IPP browser */
#    ifdef HAVE_SSL
  DNSServiceRef ipps_ref = NULL;	/* IPPS browser */
#    endif /* HAVE_SSL */
#    ifdef HAVE_POLL
  struct pollfd pfd;                    /* Polling data */
#    else
  fd_set        input;                  /* Input set for select() */
  struct timeval timeout;               /* Timeout for select() */
#    endif /* HAVE_POLL */
#  else /* HAVE_AVAHI */
  int           error;                  /* Error value */
  AvahiServiceBrowser *ipp_ref = NULL;  /* IPP browser */
#    ifdef HAVE_SSL
  AvahiServiceBrowser *ipps_ref = NULL; /* IPPS browser */
#    endif /* HAVE_SSL */
#  endif /* HAVE_DNSSD */
#else
  _cups_getdata_t data;			/* Data for callback */
#endif /* HAVE_DNSSD || HAVE_AVAHI */
  char		filename[1024];		/* Local lpoptions file */
  _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */


  DEBUG_printf(("cups_enum_dests(flags=%x, msec=%d, cancel=%p, type=%x, mask=%x, cb=%p, user_data=%p)", flags, msec, (void *)cancel, type, mask, (void *)cb, (void *)user_data));

 /*
  * Range check input...
  */

  (void)flags;

  if (!cb)
  {
    DEBUG_puts("1cups_enum_dests: No callback, returning 0.");
    return (0);
  }

 /*
  * Load the /etc/cups/lpoptions and ~/.cups/lpoptions files...
  */

  memset(&data, 0, sizeof(data));

  user_default = _cupsUserDefault(data.def_name, sizeof(data.def_name));

  snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
  data.num_dests = cups_get_dests(filename, NULL, NULL, 1, user_default != NULL, data.num_dests, &data.dests);

  if (cg->home)
  {
    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);

    data.num_dests = cups_get_dests(filename, NULL, NULL, 1, user_default != NULL, data.num_dests, &data.dests);
  }

  if (!user_default && (dest = cupsGetDest(NULL, NULL, data.num_dests, data.dests)) != NULL)
  {
   /*
    * Use an lpoptions default printer...
    */

    if (dest->instance)
      snprintf(data.def_name, sizeof(data.def_name), "%s/%s", dest->name, dest->instance);
    else
      strlcpy(data.def_name, dest->name, sizeof(data.def_name));
  }
  else
  {
    const char	*default_printer;	/* Server default printer */

    if ((default_printer = cupsGetDefault2(http)) != NULL)
      strlcpy(data.def_name, default_printer, sizeof(data.def_name));
  }

  if (data.def_name[0])
  {
   /*
    * Separate printer and instance name...
    */

    if ((data.def_instance = strchr(data.def_name, '/')) != NULL)
      *data.def_instance++ = '\0';
  }

  DEBUG_printf(("1cups_enum_dests: def_name=\"%s\", def_instance=\"%s\"", data.def_name, data.def_instance));

 /*
  * Get ready to enumerate...
  */

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
  data.type      = type;
  data.mask      = mask;
  data.cb        = cb;
  data.user_data = user_data;
  data.devices   = cupsArrayNew3((cups_array_func_t)cups_dnssd_compare_devices, NULL, NULL, 0, NULL, (cups_afree_func_t)cups_dnssd_free_device);
#endif /* HAVE_DNSSD || HAVE_AVAHI */

  if (!(mask & CUPS_PRINTER_DISCOVERED) || !(type & CUPS_PRINTER_DISCOVERED))
  {
   /*
    * Get the list of local printers and pass them to the callback function...
    */

    num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &dests, type, mask);

    if (data.def_name[0])
    {
     /*
      * Lookup the named default printer and instance and make it the default...
      */

      if ((dest = cupsGetDest(data.def_name, data.def_instance, num_dests, dests)) != NULL)
      {
	DEBUG_printf(("1cups_enum_dests: Setting is_default on \"%s/%s\".", dest->name, dest->instance));
        dest->is_default = 1;
      }
    }

    for (i = num_dests, dest = dests;
         i > 0 && (!cancel || !*cancel);
         i --, dest ++)
    {
      cups_dest_t	*user_dest;	/* Destination from lpoptions */
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
      const char	*device_uri;	/* Device URI */
#endif /* HAVE_DNSSD || HAVE_AVAHI */

      if ((user_dest = cupsGetDest(dest->name, dest->instance, data.num_dests, data.dests)) != NULL)
      {
       /*
        * Apply user defaults to this destination...
        */

        for (j = user_dest->num_options, option = user_dest->options; j > 0; j --, option ++)
          dest->num_options = cupsAddOption(option->name, option->value, dest->num_options, &dest->options);
      }

      if (!(*cb)(user_data, i > 1 ? CUPS_DEST_FLAGS_MORE : CUPS_DEST_FLAGS_NONE, dest))
        break;

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
      if (!dest->instance && (device_uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL && !strncmp(device_uri, "dnssd://", 8))
      {
       /*
        * Add existing queue using service name, etc. so we don't list it again...
        */

        char    scheme[32],             /* URI scheme */
                userpass[32],           /* Username:password */
                serviceName[256],       /* Service name (host field) */
                resource[256],          /* Resource (options) */
                *regtype,               /* Registration type */
                *replyDomain;           /* Registration domain */
        int     port;                   /* Port number (not used) */

        if (httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), serviceName, sizeof(serviceName), &port, resource, sizeof(resource)) >= HTTP_URI_STATUS_OK)
        {
          if ((regtype = strstr(serviceName, "._ipp")) != NULL)
          {
            *regtype++ = '\0';

            if ((replyDomain = strstr(regtype, "._tcp.")) != NULL)
            {
              replyDomain[5] = '\0';
              replyDomain += 6;

              if ((device = cups_dnssd_get_device(&data, serviceName, regtype, replyDomain)) != NULL)
                device->state = _CUPS_DNSSD_ACTIVE;
            }
          }
        }
      }
#endif /* HAVE_DNSSD || HAVE_AVAHI */
    }

    cupsFreeDests(num_dests, dests);

    if (i > 0 || msec == 0)
      goto enum_finished;
  }

 /*
  * Return early if the caller doesn't want to do discovery...
  */

  if ((mask & CUPS_PRINTER_DISCOVERED) && !(type & CUPS_PRINTER_DISCOVERED))
    goto enum_finished;

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
 /*
  * Get Bonjour-shared printers...
  */

  gettimeofday(&curtime, NULL);

#  ifdef HAVE_DNSSD
  if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError)
  {
    DEBUG_puts("1cups_enum_dests: Unable to create service browser, returning 0.");

    cupsFreeDests(data.num_dests, data.dests);

    return (0);
  }

  main_fd = DNSServiceRefSockFD(data.main_ref);

  ipp_ref = data.main_ref;
  if (DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data) != kDNSServiceErr_NoError)
  {
    DEBUG_puts("1cups_enum_dests: Unable to create IPP browser, returning 0.");
    DNSServiceRefDeallocate(data.main_ref);

    cupsFreeDests(data.num_dests, data.dests);

    return (0);
  }

#    ifdef HAVE_SSL
  ipps_ref = data.main_ref;
  if (DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, "_ipps._tcp", NULL, (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data) != kDNSServiceErr_NoError)
  {
    DEBUG_puts("1cups_enum_dests: Unable to create IPPS browser, returning 0.");
    DNSServiceRefDeallocate(data.main_ref);

    cupsFreeDests(data.num_dests, data.dests);

    return (0);
  }
#    endif /* HAVE_SSL */

#  else /* HAVE_AVAHI */
  if ((data.simple_poll = avahi_simple_poll_new()) == NULL)
  {
    DEBUG_puts("1cups_enum_dests: Unable to create Avahi poll, returning 0.");

    cupsFreeDests(data.num_dests, data.dests);

    return (0);
  }

  avahi_simple_poll_set_func(data.simple_poll, cups_dnssd_poll_cb, &data);

  data.client = avahi_client_new(avahi_simple_poll_get(data.simple_poll),
         0, cups_dnssd_client_cb, &data,
         &error);
  if (!data.client)
  {
    DEBUG_puts("1cups_enum_dests: Unable to create Avahi client, returning 0.");
    avahi_simple_poll_free(data.simple_poll);

    cupsFreeDests(data.num_dests, data.dests);

    return (0);
  }

  data.browsers = 1;
  if ((ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, cups_dnssd_browse_cb, &data)) == NULL)
  {
    DEBUG_puts("1cups_enum_dests: Unable to create Avahi IPP browser, returning 0.");

    avahi_client_free(data.client);
    avahi_simple_poll_free(data.simple_poll);

    cupsFreeDests(data.num_dests, data.dests);

    return (0);
  }

#    ifdef HAVE_SSL
  data.browsers ++;
  if ((ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data)) == NULL)
  {
    DEBUG_puts("1cups_enum_dests: Unable to create Avahi IPPS browser, returning 0.");

    avahi_service_browser_free(ipp_ref);
    avahi_client_free(data.client);
    avahi_simple_poll_free(data.simple_poll);

    cupsFreeDests(data.num_dests, data.dests);

    return (0);
  }
#    endif /* HAVE_SSL */
#  endif /* HAVE_DNSSD */

  if (msec < 0)
    remaining = INT_MAX;
  else
    remaining = msec;

  while (remaining > 0 && (!cancel || !*cancel))
  {
   /*
    * Check for input...
    */

    DEBUG_printf(("1cups_enum_dests: remaining=%d", remaining));

    cups_elapsed(&curtime);

#  ifdef HAVE_DNSSD
#    ifdef HAVE_POLL
    pfd.fd     = main_fd;
    pfd.events = POLLIN;

    nfds = poll(&pfd, 1, remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining);

#    else
    FD_ZERO(&input);
    FD_SET(main_fd, &input);

    timeout.tv_sec  = 0;
    timeout.tv_usec = 1000 * (remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining);

    nfds = select(main_fd + 1, &input, NULL, NULL, &timeout);
#    endif /* HAVE_POLL */

    if (nfds > 0)
      DNSServiceProcessResult(data.main_ref);
    else if (nfds < 0 && errno != EINTR && errno != EAGAIN)
      break;

#  else /* HAVE_AVAHI */
    data.got_data = 0;

    if ((error = avahi_simple_poll_iterate(data.simple_poll, _CUPS_DNSSD_MAXTIME)) > 0)
    {
     /*
      * We've been told to exit the loop.  Perhaps the connection to
      * Avahi failed.
      */

      break;
    }

    DEBUG_printf(("1cups_enum_dests: got_data=%d", data.got_data));
#  endif /* HAVE_DNSSD */

    remaining -= cups_elapsed(&curtime);

    for (device = (_cups_dnssd_device_t *)cupsArrayFirst(data.devices),
             count = 0, completed = 0;
         device;
         device = (_cups_dnssd_device_t *)cupsArrayNext(data.devices))
    {
      if (device->ref)
        count ++;

      if (device->state == _CUPS_DNSSD_ACTIVE)
        completed ++;

      if (!device->ref && device->state == _CUPS_DNSSD_NEW)
      {
        DEBUG_printf(("1cups_enum_dests: Querying '%s'.", device->fullName));

#  ifdef HAVE_DNSSD
        device->ref = data.main_ref;

        if (DNSServiceQueryRecord(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->fullName, kDNSServiceType_TXT, kDNSServiceClass_IN, (DNSServiceQueryRecordReply)cups_dnssd_query_cb, &data) == kDNSServiceErr_NoError)
        {
          count ++;
        }
        else
        {
          device->ref   = 0;
          device->state = _CUPS_DNSSD_ERROR;

          DEBUG_puts("1cups_enum_dests: Query failed.");
        }

#  else /* HAVE_AVAHI */
        if ((device->ref = avahi_record_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, cups_dnssd_query_cb, &data)) != NULL)
        {
          DEBUG_printf(("1cups_enum_dests: Query ref=%p", device->ref));
          count ++;
        }
        else
        {
          device->state = _CUPS_DNSSD_ERROR;

          DEBUG_printf(("1cups_enum_dests: Query failed: %s", avahi_strerror(avahi_client_errno(data.client))));
        }
#  endif /* HAVE_DNSSD */
      }
      else if (device->ref && device->state == _CUPS_DNSSD_PENDING)
      {
        completed ++;

        DEBUG_printf(("1cups_enum_dests: Query for \"%s\" is complete.", device->fullName));

        if ((device->type & mask) == type)
        {
          cups_dest_t	*user_dest;	/* Destination from lpoptions */

          dest = &device->dest;

	  if ((user_dest = cupsGetDest(dest->name, dest->instance, data.num_dests, data.dests)) != NULL)
	  {
	   /*
	    * Apply user defaults to this destination...
	    */

	    for (j = user_dest->num_options, option = user_dest->options; j > 0; j --, option ++)
	      dest->num_options = cupsAddOption(option->name, option->value, dest->num_options, &dest->options);
	  }

          if (!strcasecmp(dest->name, data.def_name) && !data.def_instance)
	  {
	    DEBUG_printf(("1cups_enum_dests: Setting is_default on discovered \"%s\".", dest->name));
            dest->is_default = 1;
	  }

          DEBUG_printf(("1cups_enum_dests: Add callback for \"%s\".", device->dest.name));
          if (!(*cb)(user_data, CUPS_DEST_FLAGS_NONE, dest))
          {
            remaining = -1;
            break;
          }
        }

        device->state = _CUPS_DNSSD_ACTIVE;
      }
    }

#  ifdef HAVE_AVAHI
    DEBUG_printf(("1cups_enum_dests: remaining=%d, browsers=%d, completed=%d, count=%d, devices count=%d", remaining, data.browsers, completed, count, cupsArrayCount(data.devices)));

    if (data.browsers == 0 && completed == cupsArrayCount(data.devices))
      break;
#  else
    DEBUG_printf(("1cups_enum_dests: remaining=%d, completed=%d, count=%d, devices count=%d", remaining, completed, count, cupsArrayCount(data.devices)));

    if (completed == cupsArrayCount(data.devices))
      break;
#  endif /* HAVE_AVAHI */
  }
#endif /* HAVE_DNSSD || HAVE_AVAHI */

 /*
  * Return...
  */

  enum_finished:

  cupsFreeDests(data.num_dests, data.dests);

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
  cupsArrayDelete(data.devices);

#  ifdef HAVE_DNSSD
  if (ipp_ref)
    DNSServiceRefDeallocate(ipp_ref);

#    ifdef HAVE_SSL
  if (ipps_ref)
    DNSServiceRefDeallocate(ipps_ref);
#    endif /* HAVE_SSL */

  if (data.main_ref)
    DNSServiceRefDeallocate(data.main_ref);

#  else /* HAVE_AVAHI */
  if (ipp_ref)
    avahi_service_browser_free(ipp_ref);
#    ifdef HAVE_SSL
  if (ipps_ref)
    avahi_service_browser_free(ipps_ref);
#    endif /* HAVE_SSL */

  if (data.client)
    avahi_client_free(data.client);
  if (data.simple_poll)
    avahi_simple_poll_free(data.simple_poll);
#  endif /* HAVE_DNSSD */
#endif /* HAVE_DNSSD || HAVE_AVAHI */

  DEBUG_puts("1cups_enum_dests: Returning 1.");

  return (1);
}


/*
 * 'cups_find_dest()' - Find a destination using a binary search.
 */

static int				/* O - Index of match */
cups_find_dest(const char  *name,	/* I - Destination name */
               const char  *instance,	/* I - Instance or NULL */
               int         num_dests,	/* I - Number of destinations */
	       cups_dest_t *dests,	/* I - Destinations */
	       int         prev,	/* I - Previous index */
	       int         *rdiff)	/* O - Difference of match */
{
  int		left,			/* Low mark for binary search */
		right,			/* High mark for binary search */
		current,		/* Current index */
		diff;			/* Result of comparison */
  cups_dest_t	key;			/* Search key */


  key.name     = (char *)name;
  key.instance = (char *)instance;

  if (prev >= 0)
  {
   /*
    * Start search on either side of previous...
    */

    if ((diff = cups_compare_dests(&key, dests + prev)) == 0 ||
        (diff < 0 && prev == 0) ||
	(diff > 0 && prev == (num_dests - 1)))
    {
      *rdiff = diff;
      return (prev);
    }
    else if (diff < 0)
    {
     /*
      * Start with previous on right side...
      */

      left  = 0;
      right = prev;
    }
    else
    {
     /*
      * Start wih previous on left side...
      */

      left  = prev;
      right = num_dests - 1;
    }
  }
  else
  {
   /*
    * Start search in the middle...
    */

    left  = 0;
    right = num_dests - 1;
  }

  do
  {
    current = (left + right) / 2;
    diff    = cups_compare_dests(&key, dests + current);

    if (diff == 0)
      break;
    else if (diff < 0)
      right = current;
    else
      left = current;
  }
  while ((right - left) > 1);

  if (diff != 0)
  {
   /*
    * Check the last 1 or 2 elements...
    */

    if ((diff = cups_compare_dests(&key, dests + left)) <= 0)
      current = left;
    else
    {
      diff    = cups_compare_dests(&key, dests + right);
      current = right;
    }
  }

 /*
  * Return the closest destination and the difference...
  */

  *rdiff = diff;

  return (current);
}


/*
 * 'cups_get_cb()' - Collect enumerated destinations.
 */

static int                              /* O - 1 to continue, 0 to stop */
cups_get_cb(_cups_getdata_t *data,      /* I - Data from cupsGetDests */
            unsigned        flags,      /* I - Enumeration flags */
            cups_dest_t     *dest)      /* I - Destination */
{
  if (flags & CUPS_DEST_FLAGS_REMOVED)
  {
   /*
    * Remove destination from array...
    */

    data->num_dests = cupsRemoveDest(dest->name, dest->instance, data->num_dests, &data->dests);
  }
  else
  {
   /*
    * Add destination to array...
    */

    data->num_dests = cupsCopyDest(dest, data->num_dests, &data->dests);
  }

  return (1);
}


/*
 * 'cups_get_default()' - Get the default destination from an lpoptions file.
 */

static char *				/* O - Default destination or NULL */
cups_get_default(const char *filename,	/* I - File to read */
                 char       *namebuf,	/* I - Name buffer */
		 size_t     namesize,	/* I - Size of name buffer */
		 const char **instance)	/* I - Instance */
{
  cups_file_t	*fp;			/* lpoptions file */
  char		line[8192],		/* Line from file */
		*value,			/* Value for line */
		*nameptr;		/* Pointer into name */
  int		linenum;		/* Current line */


  *namebuf = '\0';

  if ((fp = cupsFileOpen(filename, "r")) != NULL)
  {
    linenum  = 0;

    while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
    {
      if (!_cups_strcasecmp(line, "default") && value)
      {
        strlcpy(namebuf, value, namesize);

	if ((nameptr = strchr(namebuf, ' ')) != NULL)
	  *nameptr = '\0';
	if ((nameptr = strchr(namebuf, '\t')) != NULL)
	  *nameptr = '\0';

	if ((nameptr = strchr(namebuf, '/')) != NULL)
	  *nameptr++ = '\0';

        *instance = nameptr;
	break;
      }
    }

    cupsFileClose(fp);
  }

  return (*namebuf ? namebuf : NULL);
}


/*
 * 'cups_get_dests()' - Get destinations from a file.
 */

static int				/* O - Number of destinations */
cups_get_dests(
    const char  *filename,		/* I - File to read from */
    const char  *match_name,		/* I - Destination name we want */
    const char  *match_inst,		/* I - Instance name we want */
    int         load_all,		/* I - Load all saved destinations? */
    int         user_default_set,	/* I - User default printer set? */
    int         num_dests,		/* I - Number of destinations */
    cups_dest_t **dests)		/* IO - Destinations */
{
  int		i;			/* Looping var */
  cups_dest_t	*dest;			/* Current destination */
  cups_file_t	*fp;			/* File pointer */
  char		line[8192],		/* Line from file */
		*lineptr,		/* Pointer into line */
		*name,			/* Name of destination/option */
		*instance;		/* Instance of destination */
  int		linenum;		/* Current line number */


  DEBUG_printf(("7cups_get_dests(filename=\"%s\", match_name=\"%s\", match_inst=\"%s\", load_all=%d, user_default_set=%d, num_dests=%d, dests=%p)", filename, match_name, match_inst, load_all, user_default_set, num_dests, (void *)dests));

 /*
  * Try to open the file...
  */

  if ((fp = cupsFileOpen(filename, "r")) == NULL)
    return (num_dests);

 /*
  * Read each printer; each line looks like:
  *
  *    Dest name[/instance] options
  *    Default name[/instance] options
  */

  linenum = 0;

  while (cupsFileGetConf(fp, line, sizeof(line), &lineptr, &linenum))
  {
   /*
    * See what type of line it is...
    */

    DEBUG_printf(("9cups_get_dests: linenum=%d line=\"%s\" lineptr=\"%s\"",
                  linenum, line, lineptr));

    if ((_cups_strcasecmp(line, "dest") && _cups_strcasecmp(line, "default")) || !lineptr)
    {
      DEBUG_puts("9cups_get_dests: Not a dest or default line...");
      continue;
    }

    name = lineptr;

   /*
    * Search for an instance...
    */

    while (!isspace(*lineptr & 255) && *lineptr && *lineptr != '/')
      lineptr ++;

    if (*lineptr == '/')
    {
     /*
      * Found an instance...
      */

      *lineptr++ = '\0';
      instance = lineptr;

     /*
      * Search for an instance...
      */

      while (!isspace(*lineptr & 255) && *lineptr)
	lineptr ++;
    }
    else
      instance = NULL;

    if (*lineptr)
      *lineptr++ = '\0';

    DEBUG_printf(("9cups_get_dests: name=\"%s\", instance=\"%s\"", name,
                  instance));

   /*
    * Match and/or ignore missing destinations...
    */

    if (match_name)
    {
      if (_cups_strcasecmp(name, match_name) ||
          (!instance && match_inst) ||
	  (instance && !match_inst) ||
	  (instance && _cups_strcasecmp(instance, match_inst)))
	continue;

      dest = *dests;
    }
    else if (!load_all && cupsGetDest(name, NULL, num_dests, *dests) == NULL)
    {
      DEBUG_puts("9cups_get_dests: Not found!");
      continue;
    }
    else
    {
     /*
      * Add the destination...
      */

      num_dests = cupsAddDest(name, instance, num_dests, dests);

      if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL)
      {
       /*
	* Out of memory!
	*/

        DEBUG_puts("9cups_get_dests: Out of memory!");
        break;
      }
    }

   /*
    * Add options until we hit the end of the line...
    */

    dest->num_options = cupsParseOptions(lineptr, dest->num_options, &(dest->options));

   /*
    * If we found what we were looking for, stop now...
    */

    if (match_name)
      break;

   /*
    * Set this as default if needed...
    */

    if (!user_default_set && !_cups_strcasecmp(line, "default"))
    {
      DEBUG_puts("9cups_get_dests: Setting as default...");

      for (i = 0; i < num_dests; i ++)
        (*dests)[i].is_default = 0;

      dest->is_default = 1;
    }
  }

 /*
  * Close the file and return...
  */

  cupsFileClose(fp);

  return (num_dests);
}


/*
 * 'cups_make_string()' - Make a comma-separated string of values from an IPP
 *                        attribute.
 */

static char *				/* O - New string */
cups_make_string(
    ipp_attribute_t *attr,		/* I - Attribute to convert */
    char            *buffer,		/* I - Buffer */
    size_t          bufsize)		/* I - Size of buffer */
{
  int		i;			/* Looping var */
  char		*ptr,			/* Pointer into buffer */
		*end,			/* Pointer to end of buffer */
		*valptr;		/* Pointer into string attribute */


 /*
  * Return quickly if we have a single string value...
  */

  if (attr->num_values == 1 &&
      attr->value_tag != IPP_TAG_INTEGER &&
      attr->value_tag != IPP_TAG_ENUM &&
      attr->value_tag != IPP_TAG_BOOLEAN &&
      attr->value_tag != IPP_TAG_RANGE)
    return (attr->values[0].string.text);

 /*
  * Copy the values to the string, separating with commas and escaping strings
  * as needed...
  */

  end = buffer + bufsize - 1;

  for (i = 0, ptr = buffer; i < attr->num_values && ptr < end; i ++)
  {
    if (i)
      *ptr++ = ',';

    switch (attr->value_tag)
    {
      case IPP_TAG_INTEGER :
      case IPP_TAG_ENUM :
	  snprintf(ptr, (size_t)(end - ptr + 1), "%d", attr->values[i].integer);
	  break;

      case IPP_TAG_BOOLEAN :
	  if (attr->values[i].boolean)
	    strlcpy(ptr, "true", (size_t)(end - ptr + 1));
	  else
	    strlcpy(ptr, "false", (size_t)(end - ptr + 1));
	  break;

      case IPP_TAG_RANGE :
	  if (attr->values[i].range.lower == attr->values[i].range.upper)
	    snprintf(ptr, (size_t)(end - ptr + 1), "%d", attr->values[i].range.lower);
	  else
	    snprintf(ptr, (size_t)(end - ptr + 1), "%d-%d", attr->values[i].range.lower, attr->values[i].range.upper);
	  break;

      default :
	  for (valptr = attr->values[i].string.text;
	       *valptr && ptr < end;)
	  {
	    if (strchr(" \t\n\\\'\"", *valptr))
	    {
	      if (ptr >= (end - 1))
	        break;

	      *ptr++ = '\\';
	    }

	    *ptr++ = *valptr++;
	  }

	  *ptr = '\0';
	  break;
    }

    ptr += strlen(ptr);
  }

  *ptr = '\0';

  return (buffer);
}


/*
 * 'cups_name_cb()' - Find an enumerated destination.
 */

static int                              /* O - 1 to continue, 0 to stop */
cups_name_cb(_cups_namedata_t *data,    /* I - Data from cupsGetNamedDest */
             unsigned         flags,    /* I - Enumeration flags */
             cups_dest_t      *dest)    /* I - Destination */
{
  DEBUG_printf(("2cups_name_cb(data=%p(%s), flags=%x, dest=%p(%s)", (void *)data, data->name, flags, (void *)dest, dest->name));

  if (!(flags & CUPS_DEST_FLAGS_REMOVED) && !dest->instance && !strcasecmp(data->name, dest->name))
  {
   /*
    * Copy destination and stop enumeration...
    */

    cupsCopyDest(dest, 0, &data->dest);
    return (0);
  }

  return (1);
}


/*
 * 'cups_queue_name()' - Create a local queue name based on the service name.
 */

static void
cups_queue_name(
    char       *name,			/* I - Name buffer */
    const char *serviceName,		/* I - Service name */
    size_t     namesize)		/* I - Size of name buffer */
{
  const char	*ptr;			/* Pointer into serviceName */
  char		*nameptr;		/* Pointer into name */


  for (nameptr = name, ptr = serviceName; *ptr && nameptr < (name + namesize - 1); ptr ++)
  {
   /*
    * Sanitize the printer name...
    */

    if (_cups_isalnum(*ptr))
      *nameptr++ = *ptr;
    else if (nameptr == name || nameptr[-1] != '_')
      *nameptr++ = '_';
  }

  *nameptr = '\0';
}
