Zdenek Dohnal d4e17e
diff -up cups-2.2.4/cups/cups.h.cupsenumdests2 cups-2.2.4/cups/cups.h
Zdenek Dohnal d4e17e
--- cups-2.2.4/cups/cups.h.cupsenumdests2	2017-06-30 17:44:38.000000000 +0200
Zdenek Dohnal d4e17e
+++ cups-2.2.4/cups/cups.h	2017-10-04 15:31:45.358029517 +0200
Zdenek Dohnal d4e17e
@@ -527,11 +527,20 @@ extern int		cupsEnumDests(unsigned flags
Zdenek Dohnal d4e17e
 				      cups_ptype_t type, cups_ptype_t mask,
Zdenek Dohnal d4e17e
 				      cups_dest_cb_t cb, void *user_data)
Zdenek Dohnal d4e17e
 				      _CUPS_API_1_6;
Zdenek Dohnal d4e17e
+extern int		cupsEnumDests2(http_t *http, unsigned flags, int msec, int *cancel,
Zdenek Dohnal d4e17e
+				      cups_ptype_t type, cups_ptype_t mask,
Zdenek Dohnal d4e17e
+				      cups_dest_cb_t cb, void *user_data)
Zdenek Dohnal d4e17e
+				      _CUPS_API_1_6;
Zdenek Dohnal d4e17e
 #  ifdef __BLOCKS__
Zdenek Dohnal d4e17e
 extern int		cupsEnumDestsBlock(unsigned flags, int msec,
Zdenek Dohnal d4e17e
 					   int *cancel, cups_ptype_t type,
Zdenek Dohnal d4e17e
 					   cups_ptype_t mask,
Zdenek Dohnal d4e17e
 					   cups_dest_block_t block)
Zdenek Dohnal d4e17e
+					   _CUPS_API_1_6;
Zdenek Dohnal d4e17e
+extern int		cupsEnumDestsBlock2(http_t *http, unsigned flags, int msec,
Zdenek Dohnal d4e17e
+					   int *cancel, cups_ptype_t type,
Zdenek Dohnal d4e17e
+					   cups_ptype_t mask,
Zdenek Dohnal d4e17e
+					   cups_dest_block_t block)
Zdenek Dohnal d4e17e
 					   _CUPS_API_1_6;
Zdenek Dohnal d4e17e
 #  endif /* __BLOCKS__ */
Zdenek Dohnal d4e17e
 extern ipp_status_t	cupsFinishDestDocument(http_t *http,
Zdenek Dohnal d4e17e
diff -up cups-2.2.4/cups/dest.c.cupsenumdests2 cups-2.2.4/cups/dest.c
Zdenek Dohnal d4e17e
--- cups-2.2.4/cups/dest.c.cupsenumdests2	2017-10-04 15:31:45.356029534 +0200
Zdenek Dohnal d4e17e
+++ cups-2.2.4/cups/dest.c	2017-10-04 15:31:45.359029509 +0200
Zdenek Dohnal d4e17e
@@ -1377,6 +1377,423 @@ cupsEnumDests(
Zdenek Dohnal d4e17e
   return (1);
Zdenek Dohnal d4e17e
 }
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
+/*
Zdenek Dohnal d4e17e
+ * 'cupsEnumDests2()' - same as cupsEnumDests(), but for not default http connection
Zdenek Dohnal d4e17e
+ */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+int					/* O - 1 on success, 0 on failure */
Zdenek Dohnal d4e17e
+cupsEnumDests2(
Zdenek Dohnal d4e17e
+  http_t         *http,			/* I - Connection to server */
Zdenek Dohnal d4e17e
+  unsigned       flags,			/* I - Enumeration flags */
Zdenek Dohnal d4e17e
+  int            msec,			/* I - Timeout in milliseconds, -1 for indefinite */
Zdenek Dohnal d4e17e
+  int            *cancel,		/* I - Pointer to "cancel" variable */
Zdenek Dohnal d4e17e
+  cups_ptype_t   type,			/* I - Printer type bits */
Zdenek Dohnal d4e17e
+  cups_ptype_t   mask,			/* I - Mask for printer type bits */
Zdenek Dohnal d4e17e
+  cups_dest_cb_t cb,			/* I - Callback function */
Zdenek Dohnal d4e17e
+  void           *user_data)		/* I - User data */
Zdenek Dohnal d4e17e
+{
Zdenek Dohnal d4e17e
+  int			i,		/* Looping var */
Zdenek Dohnal d4e17e
+			num_dests;	/* Number of destinations */
Zdenek Dohnal d4e17e
+  cups_dest_t		*dests = NULL,	/* Destinations */
Zdenek Dohnal d4e17e
+			*dest;		/* Current destination */
Zdenek Dohnal d4e17e
+  const char		*defprinter;	/* Default printer */
Zdenek Dohnal d4e17e
+  char			name[1024],	/* Copy of printer name */
Zdenek Dohnal d4e17e
+			*instance,	/* Pointer to instance name */
Zdenek Dohnal d4e17e
+			*user_default;	/* User default printer */
Zdenek Dohnal d4e17e
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
Zdenek Dohnal d4e17e
+  int			count,		/* Number of queries started */
Zdenek Dohnal d4e17e
+			completed,	/* Number of completed queries */
Zdenek Dohnal d4e17e
+			remaining;	/* Remainder of timeout */
Zdenek Dohnal d4e17e
+  struct timeval	curtime;	/* Current time */
Zdenek Dohnal d4e17e
+  _cups_dnssd_data_t	data;		/* Data for callback */
Zdenek Dohnal d4e17e
+  _cups_dnssd_device_t	*device;	/* Current device */
Zdenek Dohnal d4e17e
+#  ifdef HAVE_DNSSD
Zdenek Dohnal d4e17e
+  int			nfds,		/* Number of files responded */
Zdenek Dohnal d4e17e
+			main_fd;	/* File descriptor for lookups */
Zdenek Dohnal d4e17e
+  DNSServiceRef		ipp_ref = NULL,	/* IPP browser */
Zdenek Dohnal d4e17e
+			local_ipp_ref = NULL; /* Local IPP browser */
Zdenek Dohnal d4e17e
+#    ifdef HAVE_SSL
Zdenek Dohnal d4e17e
+  DNSServiceRef		ipps_ref = NULL,/* IPPS browser */
Zdenek Dohnal d4e17e
+			local_ipps_ref = NULL; /* Local IPPS browser */
Zdenek Dohnal d4e17e
+#    endif /* HAVE_SSL */
Zdenek Dohnal d4e17e
+#    ifdef HAVE_POLL
Zdenek Dohnal d4e17e
+  struct pollfd		pfd;		/* Polling data */
Zdenek Dohnal d4e17e
+#    else
Zdenek Dohnal d4e17e
+  fd_set		input;		/* Input set for select() */
Zdenek Dohnal d4e17e
+  struct timeval	timeout;	/* Timeout for select() */
Zdenek Dohnal d4e17e
+#    endif /* HAVE_POLL */
Zdenek Dohnal d4e17e
+#  else /* HAVE_AVAHI */
Zdenek Dohnal d4e17e
+  int			error;		/* Error value */
Zdenek Dohnal d4e17e
+  AvahiServiceBrowser	*ipp_ref = NULL;/* IPP browser */
Zdenek Dohnal d4e17e
+#    ifdef HAVE_SSL
Zdenek Dohnal d4e17e
+  AvahiServiceBrowser	*ipps_ref = NULL; /* IPPS browser */
Zdenek Dohnal d4e17e
+#    endif /* HAVE_SSL */
Zdenek Dohnal d4e17e
+#  endif /* HAVE_DNSSD */
Zdenek Dohnal d4e17e
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+ /*
Zdenek Dohnal d4e17e
+  * Range check input...
Zdenek Dohnal d4e17e
+  */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  (void)flags;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if (!cb)
Zdenek Dohnal d4e17e
+    return (0);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+ /*
Zdenek Dohnal d4e17e
+  * Get ready to enumerate...
Zdenek Dohnal d4e17e
+  */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
Zdenek Dohnal d4e17e
+  memset(&data, 0, sizeof(data));
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  data.type      = type;
Zdenek Dohnal d4e17e
+  data.mask      = mask;
Zdenek Dohnal d4e17e
+  data.cb        = cb;
Zdenek Dohnal d4e17e
+  data.user_data = user_data;
Zdenek Dohnal d4e17e
+  data.devices   = cupsArrayNew3((cups_array_func_t)cups_dnssd_compare_devices, NULL, NULL, 0, NULL, (cups_afree_func_t)cups_dnssd_free_device);
Zdenek Dohnal d4e17e
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if (!(mask & CUPS_PRINTER_DISCOVERED) || !(type & CUPS_PRINTER_DISCOVERED))
Zdenek Dohnal d4e17e
+  {
Zdenek Dohnal d4e17e
+   /*
Zdenek Dohnal d4e17e
+    * Get the list of local printers and pass them to the callback function...
Zdenek Dohnal d4e17e
+    */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL,
Zdenek Dohnal d4e17e
+                              &dests, type, mask);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    if ((user_default = _cupsUserDefault(name, sizeof(name))) != NULL)
Zdenek Dohnal d4e17e
+      defprinter = name;
Zdenek Dohnal d4e17e
+    else if ((defprinter = cupsGetDefault2(http)) != NULL)
Zdenek Dohnal d4e17e
+    {
Zdenek Dohnal d4e17e
+      strlcpy(name, defprinter, sizeof(name));
Zdenek Dohnal d4e17e
+      defprinter = name;
Zdenek Dohnal d4e17e
+    }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    if (defprinter)
Zdenek Dohnal d4e17e
+    {
Zdenek Dohnal d4e17e
+     /*
Zdenek Dohnal d4e17e
+      * Separate printer and instance name...
Zdenek Dohnal d4e17e
+      */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+      if ((instance = strchr(name, '/')) != NULL)
Zdenek Dohnal d4e17e
+        *instance++ = '\0';
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+     /*
Zdenek Dohnal d4e17e
+      * Lookup the printer and instance and make it the default...
Zdenek Dohnal d4e17e
+      */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+      if ((dest = cupsGetDest(name, instance, num_dests, dests)) != NULL)
Zdenek Dohnal d4e17e
+        dest->is_default = 1;
Zdenek Dohnal d4e17e
+    }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    for (i = num_dests, dest = dests;
Zdenek Dohnal d4e17e
+         i > 0 && (!cancel || !*cancel);
Zdenek Dohnal d4e17e
+         i --, dest ++)
Zdenek Dohnal d4e17e
+    {
Zdenek Dohnal d4e17e
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
Zdenek Dohnal d4e17e
+      const char *device_uri;		/* Device URI */
Zdenek Dohnal d4e17e
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+      if (!(*cb)(user_data, i > 1 ? CUPS_DEST_FLAGS_MORE : CUPS_DEST_FLAGS_NONE,
Zdenek Dohnal d4e17e
+                 dest))
Zdenek Dohnal d4e17e
+        break;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
Zdenek Dohnal d4e17e
+      if (!dest->instance && (device_uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL && !strncmp(device_uri, "dnssd://", 8))
Zdenek Dohnal d4e17e
+      {
Zdenek Dohnal d4e17e
+       /*
Zdenek Dohnal d4e17e
+        * Add existing queue using service name, etc. so we don't list it again...
Zdenek Dohnal d4e17e
+        */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+        char	scheme[32],		/* URI scheme */
Zdenek Dohnal d4e17e
+                userpass[32],           /* Username:password */
Zdenek Dohnal d4e17e
+                serviceName[256],       /* Service name (host field) */
Zdenek Dohnal d4e17e
+                resource[256],          /* Resource (options) */
Zdenek Dohnal d4e17e
+                *regtype,               /* Registration type */
Zdenek Dohnal d4e17e
+                *replyDomain;           /* Registration domain */
Zdenek Dohnal d4e17e
+        int	port;			/* Port number (not used) */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+        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)
Zdenek Dohnal d4e17e
+        {
Zdenek Dohnal d4e17e
+          if ((regtype = strstr(serviceName, "._ipp")) != NULL)
Zdenek Dohnal d4e17e
+          {
Zdenek Dohnal d4e17e
+            *regtype++ = '\0';
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+            if ((replyDomain = strstr(regtype, "._tcp.")) != NULL)
Zdenek Dohnal d4e17e
+            {
Zdenek Dohnal d4e17e
+              replyDomain[5] = '\0';
Zdenek Dohnal d4e17e
+              replyDomain += 6;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+              if ((device = cups_dnssd_get_device(&data, serviceName, regtype, replyDomain)) != NULL)
Zdenek Dohnal d4e17e
+                device->state = _CUPS_DNSSD_ACTIVE;
Zdenek Dohnal d4e17e
+            }
Zdenek Dohnal d4e17e
+          }
Zdenek Dohnal d4e17e
+        }
Zdenek Dohnal d4e17e
+      }
Zdenek Dohnal d4e17e
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
Zdenek Dohnal d4e17e
+    }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    cupsFreeDests(num_dests, dests);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    if (i > 0 || msec == 0)
Zdenek Dohnal d4e17e
+      goto enum_finished;
Zdenek Dohnal d4e17e
+  }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+ /*
Zdenek Dohnal d4e17e
+  * Return early if the caller doesn't want to do discovery...
Zdenek Dohnal d4e17e
+  */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if ((mask & CUPS_PRINTER_DISCOVERED) && !(type & CUPS_PRINTER_DISCOVERED))
Zdenek Dohnal d4e17e
+    goto enum_finished;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
Zdenek Dohnal d4e17e
+ /*
Zdenek Dohnal d4e17e
+  * Get Bonjour-shared printers...
Zdenek Dohnal d4e17e
+  */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  gettimeofday(&curtime, NULL);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  ifdef HAVE_DNSSD
Zdenek Dohnal d4e17e
+  if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError)
Zdenek Dohnal d4e17e
+    return (0);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  main_fd = DNSServiceRefSockFD(data.main_ref);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  ipp_ref = data.main_ref;
Zdenek Dohnal d4e17e
+  DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0,
Zdenek Dohnal d4e17e
+                   "_ipp._tcp", NULL,
Zdenek Dohnal d4e17e
+                   (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  local_ipp_ref = data.main_ref;
Zdenek Dohnal d4e17e
+  DNSServiceBrowse(&local_ipp_ref, kDNSServiceFlagsShareConnection,
Zdenek Dohnal d4e17e
+                   kDNSServiceInterfaceIndexLocalOnly,
Zdenek Dohnal d4e17e
+                   "_ipp._tcp", NULL,
Zdenek Dohnal d4e17e
+                   (DNSServiceBrowseReply)cups_dnssd_local_cb, &data);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#    ifdef HAVE_SSL
Zdenek Dohnal d4e17e
+  ipps_ref = data.main_ref;
Zdenek Dohnal d4e17e
+  DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0,
Zdenek Dohnal d4e17e
+                   "_ipps._tcp", NULL,
Zdenek Dohnal d4e17e
+                   (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  local_ipps_ref = data.main_ref;
Zdenek Dohnal d4e17e
+  DNSServiceBrowse(&local_ipps_ref, kDNSServiceFlagsShareConnection,
Zdenek Dohnal d4e17e
+                   kDNSServiceInterfaceIndexLocalOnly,
Zdenek Dohnal d4e17e
+                   "_ipps._tcp", NULL,
Zdenek Dohnal d4e17e
+                   (DNSServiceBrowseReply)cups_dnssd_local_cb, &data);
Zdenek Dohnal d4e17e
+#    endif /* HAVE_SSL */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  else /* HAVE_AVAHI */
Zdenek Dohnal d4e17e
+  if ((data.simple_poll = avahi_simple_poll_new()) == NULL)
Zdenek Dohnal d4e17e
+  {
Zdenek Dohnal d4e17e
+    DEBUG_puts("cupsEnumDests2: Unable to create Avahi simple poll object.");
Zdenek Dohnal d4e17e
+    return (1);
Zdenek Dohnal d4e17e
+  }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  avahi_simple_poll_set_func(data.simple_poll, cups_dnssd_poll_cb, &data);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  data.client = avahi_client_new(avahi_simple_poll_get(data.simple_poll),
Zdenek Dohnal d4e17e
+				 0, cups_dnssd_client_cb, &data,
Zdenek Dohnal d4e17e
+				 &error);
Zdenek Dohnal d4e17e
+  if (!data.client)
Zdenek Dohnal d4e17e
+  {
Zdenek Dohnal d4e17e
+    DEBUG_puts("cupsEnumDests2: Unable to create Avahi client.");
Zdenek Dohnal d4e17e
+    avahi_simple_poll_free(data.simple_poll);
Zdenek Dohnal d4e17e
+    return (1);
Zdenek Dohnal d4e17e
+  }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  data.browsers = 1;
Zdenek Dohnal d4e17e
+  ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, cups_dnssd_browse_cb, &data);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#    ifdef HAVE_SSL
Zdenek Dohnal d4e17e
+  data.browsers ++;
Zdenek Dohnal d4e17e
+  ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data);
Zdenek Dohnal d4e17e
+#    endif /* HAVE_SSL */
Zdenek Dohnal d4e17e
+#  endif /* HAVE_DNSSD */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if (msec < 0)
Zdenek Dohnal d4e17e
+    remaining = INT_MAX;
Zdenek Dohnal d4e17e
+  else
Zdenek Dohnal d4e17e
+    remaining = msec;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  while (remaining > 0 && (!cancel || !*cancel))
Zdenek Dohnal d4e17e
+  {
Zdenek Dohnal d4e17e
+   /*
Zdenek Dohnal d4e17e
+    * Check for input...
Zdenek Dohnal d4e17e
+    */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    DEBUG_printf(("1cupsEnumDests2: remaining=%d", remaining));
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    cups_elapsed(&curtime);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  ifdef HAVE_DNSSD
Zdenek Dohnal d4e17e
+#    ifdef HAVE_POLL
Zdenek Dohnal d4e17e
+    pfd.fd     = main_fd;
Zdenek Dohnal d4e17e
+    pfd.events = POLLIN;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    nfds = poll(&pfd, 1, remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#    else
Zdenek Dohnal d4e17e
+    FD_ZERO(&input);
Zdenek Dohnal d4e17e
+    FD_SET(main_fd, &input);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    timeout.tv_sec  = 0;
Zdenek Dohnal d4e17e
+    timeout.tv_usec = 1000 * (remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    nfds = select(main_fd + 1, &input, NULL, NULL, &timeout);
Zdenek Dohnal d4e17e
+#    endif /* HAVE_POLL */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    if (nfds > 0)
Zdenek Dohnal d4e17e
+      DNSServiceProcessResult(data.main_ref);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  else /* HAVE_AVAHI */
Zdenek Dohnal d4e17e
+    data.got_data = 0;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    if ((error = avahi_simple_poll_iterate(data.simple_poll, _CUPS_DNSSD_MAXTIME)) > 0)
Zdenek Dohnal d4e17e
+    {
Zdenek Dohnal d4e17e
+     /*
Zdenek Dohnal d4e17e
+      * We've been told to exit the loop.  Perhaps the connection to
Zdenek Dohnal d4e17e
+      * Avahi failed.
Zdenek Dohnal d4e17e
+      */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+      break;
Zdenek Dohnal d4e17e
+    }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    DEBUG_printf(("1cupsEnumDests2: got_data=%d", data.got_data));
Zdenek Dohnal d4e17e
+#  endif /* HAVE_DNSSD */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    remaining -= cups_elapsed(&curtime);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    for (device = (_cups_dnssd_device_t *)cupsArrayFirst(data.devices),
Zdenek Dohnal d4e17e
+             count = 0, completed = 0;
Zdenek Dohnal d4e17e
+         device;
Zdenek Dohnal d4e17e
+         device = (_cups_dnssd_device_t *)cupsArrayNext(data.devices))
Zdenek Dohnal d4e17e
+    {
Zdenek Dohnal d4e17e
+      if (device->ref)
Zdenek Dohnal d4e17e
+        count ++;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+      if (device->state == _CUPS_DNSSD_ACTIVE)
Zdenek Dohnal d4e17e
+        completed ++;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+      if (!device->ref && device->state == _CUPS_DNSSD_NEW)
Zdenek Dohnal d4e17e
+      {
Zdenek Dohnal d4e17e
+	DEBUG_printf(("1cupsEnumDests2: Querying '%s'.", device->fullName));
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  ifdef HAVE_DNSSD
Zdenek Dohnal d4e17e
+        device->ref = data.main_ref;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+	if (DNSServiceQueryRecord(&(device->ref),
Zdenek Dohnal d4e17e
+				  kDNSServiceFlagsShareConnection,
Zdenek Dohnal d4e17e
+				  0, device->fullName,
Zdenek Dohnal d4e17e
+				  kDNSServiceType_TXT,
Zdenek Dohnal d4e17e
+				  kDNSServiceClass_IN,
Zdenek Dohnal d4e17e
+				  (DNSServiceQueryRecordReply)cups_dnssd_query_cb,
Zdenek Dohnal d4e17e
+				  &data) == kDNSServiceErr_NoError)
Zdenek Dohnal d4e17e
+	{
Zdenek Dohnal d4e17e
+	  count ++;
Zdenek Dohnal d4e17e
+	}
Zdenek Dohnal d4e17e
+	else
Zdenek Dohnal d4e17e
+	{
Zdenek Dohnal d4e17e
+	  device->ref   = 0;
Zdenek Dohnal d4e17e
+	  device->state = _CUPS_DNSSD_ERROR;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+	  DEBUG_puts("1cupsEnumDests2: Query failed.");
Zdenek Dohnal d4e17e
+	}
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  else /* HAVE_AVAHI */
Zdenek Dohnal d4e17e
+	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)
Zdenek Dohnal d4e17e
+        {
Zdenek Dohnal d4e17e
+          DEBUG_printf(("1cupsEnumDests2: Query ref=%p", device->ref));
Zdenek Dohnal d4e17e
+	  count ++;
Zdenek Dohnal d4e17e
+	}
Zdenek Dohnal d4e17e
+	else
Zdenek Dohnal d4e17e
+	{
Zdenek Dohnal d4e17e
+	  device->state = _CUPS_DNSSD_ERROR;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+	  DEBUG_printf(("1cupsEnumDests2: Query failed: %s", avahi_strerror(avahi_client_errno(data.client))));
Zdenek Dohnal d4e17e
+	}
Zdenek Dohnal d4e17e
+#  endif /* HAVE_DNSSD */
Zdenek Dohnal d4e17e
+      }
Zdenek Dohnal d4e17e
+      else if (device->ref && device->state == _CUPS_DNSSD_PENDING)
Zdenek Dohnal d4e17e
+      {
Zdenek Dohnal d4e17e
+        completed ++;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+        DEBUG_printf(("1cupsEnumDests2: Query for \"%s\" is complete.", device->fullName));
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+        if ((device->type & mask) == type)
Zdenek Dohnal d4e17e
+        {
Zdenek Dohnal d4e17e
+	  DEBUG_printf(("1cupsEnumDests2: Add callback for \"%s\".", device->dest.name));
Zdenek Dohnal d4e17e
+	  if (!(*cb)(user_data, CUPS_DEST_FLAGS_NONE, &device->dest))
Zdenek Dohnal d4e17e
+	  {
Zdenek Dohnal d4e17e
+	    remaining = -1;
Zdenek Dohnal d4e17e
+	    break;
Zdenek Dohnal d4e17e
+	  }
Zdenek Dohnal d4e17e
+        }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+        device->state = _CUPS_DNSSD_ACTIVE;
Zdenek Dohnal d4e17e
+      }
Zdenek Dohnal d4e17e
+    }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  ifdef HAVE_AVAHI
Zdenek Dohnal d4e17e
+    DEBUG_printf(("1cupsEnumDests2: remaining=%d, browsers=%d, completed=%d, count=%d, devices count=%d", remaining, data.browsers, completed, count, cupsArrayCount(data.devices)));
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    if (data.browsers == 0 && completed == cupsArrayCount(data.devices))
Zdenek Dohnal d4e17e
+      break;
Zdenek Dohnal d4e17e
+#  else
Zdenek Dohnal d4e17e
+    DEBUG_printf(("1cupsEnumDests2: remaining=%d, completed=%d, count=%d, devices count=%d", remaining, completed, count, cupsArrayCount(data.devices)));
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+    if (completed == cupsArrayCount(data.devices))
Zdenek Dohnal d4e17e
+      break;
Zdenek Dohnal d4e17e
+#  endif /* HAVE_AVAHI */
Zdenek Dohnal d4e17e
+  }
Zdenek Dohnal d4e17e
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+ /*
Zdenek Dohnal d4e17e
+  * Return...
Zdenek Dohnal d4e17e
+  */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  enum_finished:
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
Zdenek Dohnal d4e17e
+  cupsArrayDelete(data.devices);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  ifdef HAVE_DNSSD
Zdenek Dohnal d4e17e
+  if (ipp_ref)
Zdenek Dohnal d4e17e
+    DNSServiceRefDeallocate(ipp_ref);
Zdenek Dohnal d4e17e
+  if (local_ipp_ref)
Zdenek Dohnal d4e17e
+    DNSServiceRefDeallocate(local_ipp_ref);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#    ifdef HAVE_SSL
Zdenek Dohnal d4e17e
+  if (ipps_ref)
Zdenek Dohnal d4e17e
+    DNSServiceRefDeallocate(ipps_ref);
Zdenek Dohnal d4e17e
+  if (local_ipps_ref)
Zdenek Dohnal d4e17e
+    DNSServiceRefDeallocate(local_ipps_ref);
Zdenek Dohnal d4e17e
+#    endif /* HAVE_SSL */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if (data.main_ref)
Zdenek Dohnal d4e17e
+    DNSServiceRefDeallocate(data.main_ref);
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+#  else /* HAVE_AVAHI */
Zdenek Dohnal d4e17e
+  if (ipp_ref)
Zdenek Dohnal d4e17e
+    avahi_service_browser_free(ipp_ref);
Zdenek Dohnal d4e17e
+#    ifdef HAVE_SSL
Zdenek Dohnal d4e17e
+  if (ipps_ref)
Zdenek Dohnal d4e17e
+    avahi_service_browser_free(ipps_ref);
Zdenek Dohnal d4e17e
+#    endif /* HAVE_SSL */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if (data.client)
Zdenek Dohnal d4e17e
+    avahi_client_free(data.client);
Zdenek Dohnal d4e17e
+  if (data.simple_poll)
Zdenek Dohnal d4e17e
+    avahi_simple_poll_free(data.simple_poll);
Zdenek Dohnal d4e17e
+#  endif /* HAVE_DNSSD */
Zdenek Dohnal d4e17e
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  return (1);
Zdenek Dohnal d4e17e
+}
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
 #  ifdef __BLOCKS__
Zdenek Dohnal d4e17e
 /*
Zdenek Dohnal d4e17e
@@ -1413,6 +1830,24 @@ cupsEnumDestsBlock(
Zdenek Dohnal d4e17e
   return (cupsEnumDests(flags, timeout, cancel, type, mask,
Zdenek Dohnal d4e17e
                         (cups_dest_cb_t)cups_block_cb, (void *)block));
Zdenek Dohnal d4e17e
 }
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+/*
Zdenek Dohnal d4e17e
+ * 'cupsEnumDestsBlock2()' - same as cupsEnumDestsBlock(), only with non default http connection 
Zdenek Dohnal d4e17e
+ */
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+int					/* O - 1 on success, 0 on failure */
Zdenek Dohnal d4e17e
+cupsEnumDestsBlock2(
Zdenek Dohnal d4e17e
+    http_t            *http,		/* I - Connection to server@ */
Zdenek Dohnal d4e17e
+    unsigned          flags,		/* I - Enumeration flags */
Zdenek Dohnal d4e17e
+    int               timeout,		/* I - Timeout in milliseconds, 0 for indefinite */
Zdenek Dohnal d4e17e
+    int               *cancel,		/* I - Pointer to "cancel" variable */
Zdenek Dohnal d4e17e
+    cups_ptype_t      type,		/* I - Printer type bits */
Zdenek Dohnal d4e17e
+    cups_ptype_t      mask,		/* I - Mask for printer type bits */
Zdenek Dohnal d4e17e
+    cups_dest_block_t block)		/* I - Block */
Zdenek Dohnal d4e17e
+{
Zdenek Dohnal d4e17e
+  return (cupsEnumDests2(http, flags, timeout, cancel, type, mask,
Zdenek Dohnal d4e17e
+                        (cups_dest_cb_t)cups_block_cb, (void *)block));
Zdenek Dohnal d4e17e
+}
Zdenek Dohnal d4e17e
 #  endif /* __BLOCKS__ */
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
@@ -2057,7 +2492,13 @@ cupsGetDests2(http_t      *http,	/* I -
Zdenek Dohnal d4e17e
   data.num_dests = 0;
Zdenek Dohnal d4e17e
   data.dests     = NULL;
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
-  cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_get_cb, &data);
Zdenek Dohnal d4e17e
+  if (!http)
Zdenek Dohnal d4e17e
+    http = CUPS_HTTP_DEFAULT;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if (http == CUPS_HTTP_DEFAULT)
Zdenek Dohnal d4e17e
+    cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_get_cb, &data);
Zdenek Dohnal d4e17e
+  else
Zdenek Dohnal d4e17e
+    cupsEnumDests2(http, 0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_get_cb, &data);
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
  /*
Zdenek Dohnal d4e17e
   * Make a copy of the "real" queues for a later sanity check...
Zdenek Dohnal d4e17e
diff -up cups-2.2.4/cups/util.c.cupsenumdests2 cups-2.2.4/cups/util.c
Zdenek Dohnal d4e17e
--- cups-2.2.4/cups/util.c.cupsenumdests2	2017-06-30 17:44:38.000000000 +0200
Zdenek Dohnal d4e17e
+++ cups-2.2.4/cups/util.c	2017-10-04 15:36:08.453828842 +0200
Zdenek Dohnal d4e17e
@@ -197,7 +197,13 @@ cupsCreateJob(
Zdenek Dohnal d4e17e
   data.name = name;
Zdenek Dohnal d4e17e
   data.dest = NULL;
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
-  cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_create_cb, &data);
Zdenek Dohnal d4e17e
+  if (!http)
Zdenek Dohnal d4e17e
+    http = CUPS_HTTP_DEFAULT;
Zdenek Dohnal d4e17e
+
Zdenek Dohnal d4e17e
+  if (http == CUPS_HTTP_DEFAULT)
Zdenek Dohnal d4e17e
+    cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_create_cb, &data);
Zdenek Dohnal d4e17e
+  else
Zdenek Dohnal d4e17e
+    cupsEnumDests2(http, 0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_create_cb, &data);
Zdenek Dohnal d4e17e
 
Zdenek Dohnal d4e17e
   if (!data.dest)
Zdenek Dohnal d4e17e
   {