Hello community,

here is the log from the commit of package cups for openSUSE:Factory checked in 
at 2017-05-03 15:53:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cups (Old)
 and      /work/SRC/openSUSE:Factory/.cups.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cups"

Wed May  3 15:53:05 2017 rev:138 rq:491776 version:2.1.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/cups/cups.changes        2017-04-12 
17:09:03.808014252 +0200
+++ /work/SRC/openSUSE:Factory/.cups.new/cups.changes   2017-05-03 
15:53:07.250694792 +0200
@@ -1,0 +2,22 @@
+Thu Apr 20 16:26:52 UTC 2017 - alarr...@suse.com
+
+- Drop cups-1.7.5-cupsEnumDests-react-to-all-for-now.diff and add
+  0001-Update-cupsEnumDests-implementation-to-return-early-if-all.patch,
+  0002-Save-work-on-Avahi-code.patch and
+  0003-Avahi-fixes-for-cupsEnumDests.patch which is what upstream
+  finally commited to cups 2.2 sources in response to
+  https://github.com/apple/cups/pull/4989 in order to fix cupsEnumDests
+  to react to the ALL_FOR_NOW avahi event (and also include a similar
+  fix for the dnssd case). Related to bsc#955432.
+
+-------------------------------------------------------------------
+Mon Apr 10 17:37:16 UTC 2017 - alarr...@suse.com
+
+- Add cups-2.1.3-cupsEnumDests-react-to-all-for-now.diff .
+  Avahi sends an ALL_FOR_NOW event when it finishes sending
+  its cache contents. This patch makes cupsEnumDests finish
+  when the signal is received so it doesn't block the caller
+  doing nothing until the timeout finishes (related to bsc#955432,
+  submitted upstream at https://github.com/apple/cups/pull/4989)
+
+-------------------------------------------------------------------

New:
----
  0001-Update-cupsEnumDests-implementation-to-return-early-if-all.patch
  0002-Save-work-on-Avahi-code.patch
  0003-Avahi-fixes-for-cupsEnumDests.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cups.spec ++++++
--- /var/tmp/diff_new_pack.7RKfiL/_old  2017-05-03 15:53:08.526514677 +0200
+++ /var/tmp/diff_new_pack.7RKfiL/_new  2017-05-03 15:53:08.530514112 +0200
@@ -45,6 +45,12 @@
 Patch11:        cups-2.1.0-default-webcontent-path.patch
 # Patch12 cups-2.1.0-cups-systemd-socket.patch Use systemd socket activation 
properly:
 Patch12:        cups-2.1.0-cups-systemd-socket.patch
+# Patch13 
0001-Update-cupsEnumDests-implementation-to-return-early-if-all.patch 
bsc#955432 -- React properly to avahi's ALL_FOR_NOW signal to reduce unneeded 
delay
+Patch13:        
0001-Update-cupsEnumDests-implementation-to-return-early-if-all.patch
+# Patch14 0002-Save-work-on-Avahi-code.patch bsc#955432 -- React properly to 
avahi's ALL_FOR_NOW signal to reduce unneeded delay
+Patch14:        0002-Save-work-on-Avahi-code.patch
+# Patch15 0003-Avahi-fixes-for-cupsEnumDests.patch bsc#955432 -- React 
properly to avahi's ALL_FOR_NOW signal to reduce unneeded delay
+Patch15:        0003-Avahi-fixes-for-cupsEnumDests.patch
 # Patch100...Patch999 is for private patches from SUSE which are not intended 
for upstream:
 # Patch100 cups-pam.diff adds conf/pam.suse regarding support for PAM for SUSE:
 Patch100:       cups-pam.diff
@@ -133,9 +139,9 @@
 
 %package libs
 Summary:        Libraries for CUPS
-# Prerequire /sbin/ldconfig which is used in the traditional bash scriptlets 
for post/postun:
 License:        GPL-2.0 and LGPL-2.1
 Group:          Hardware/Printing
+# Prerequire /sbin/ldconfig which is used in the traditional bash scriptlets 
for post/postun:
 Requires(pre):  /sbin/ldconfig
 %if 0%{?suse_version} >= 1330
 Requires(pre): group(lp)
@@ -157,6 +163,8 @@
 
 %package client
 Summary:        CUPS Client Programs
+License:        GPL-2.0
+Group:          Hardware/Printing
 # Require the exact matching version-release of the cups-libs sub-package 
because
 # non-matching CUPS libraries may let CUPS software crash (e.g. segfault)
 # because all CUPS software is built from the one same CUPS source tar ball
@@ -166,8 +174,6 @@
 # on the same package repository where the cups package is because
 # all are built simulaneously from the same cups source package
 # and all required packages are provided on the same repository:
-License:        GPL-2.0
-Group:          Hardware/Printing
 Requires:       cups-libs = %{version}-%{release}
 # Conflicts with other print spoolers which provide same binaries like 
/usr/bin/lp and so on:
 Conflicts:      lprng
@@ -190,13 +196,13 @@
 
 %package devel
 Summary:        Development Environment for CUPS
+License:        GPL-2.0
+Group:          Development/Libraries/C and C++
 # Do not require the exact matching version-release of cups-libs
 # but only a cups-libs package with matching version because
 # for building third-party software which uses only the CUPS public API
 # there are no CUPS-internal dependencies via CUPS private API calls
 # (the latter would require the exact matching cups-libs version-release):
-License:        GPL-2.0
-Group:          Development/Libraries/C and C++
 Requires:       cups-libs = %{version}
 Requires:       glibc-devel
 
@@ -258,6 +264,12 @@
 %patch11 -b default-webcontent-path.prig
 # Patch12 cups-2.1.0-cups-systemd-socket.patch Use systemd socket activation 
properly:
 %patch12 -b cups-systemd-socket.orig
+# Patch13 
0001-Update-cupsEnumDests-implementation-to-return-early-if-all.patch React 
properly to avahi's ALL_FOR_NOW signal to reduce unneeded delay
+%patch13 -p1
+# Patch14 0002-Save-work-on-Avahi-code.patch React properly to avahi's 
ALL_FOR_NOW signal to reduce unneeded delay
+%patch14 -p1
+# Patch15 0003-Avahi-fixes-for-cupsEnumDests.patch React properly to avahi's 
ALL_FOR_NOW signal to reduce unneeded delay
+%patch15 -p1
 # Patch100...Patch999 is for private patches from SUSE which are not intended 
for upstream:
 # Patch100 cups-pam.diff adds conf/pam.suse regarding support for PAM for SUSE:
 %patch100

++++++ 0001-Update-cupsEnumDests-implementation-to-return-early-if-all.patch 
++++++
>From a2187a63425a3d6c05de1e1cbf8c26fd39a1aced Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michaelrsw...@gmail.com>
Date: Wed, 19 Apr 2017 15:29:42 -0400
Subject: [PATCH] Update cupsEnumDests implementation to return early if all
 printers have been discovered (Issue #4989)

Also update the code to generate the same queue names as cupsd does for IPP
Everywhere printers.
---
 CHANGES.txt     |   4 +-
 cups/dest.c     | 169 +++++++++++++++++++++++++++++++++++++++++++-------------
 cups/testdest.c |   4 +-
 3 files changed, 136 insertions(+), 41 deletions(-)

diff --git a/cups/dest.c b/cups/dest.c
index b06a9ee..54f2a7f 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -101,9 +101,10 @@ typedef struct _cups_dnssd_device_s        /* Enumerated 
device */
 #  else /* HAVE_AVAHI */
   AvahiRecordBrowser   *ref;           /* Browser for query */
 #  endif /* HAVE_DNSSD */
-  char                 *domain,        /* Domain name */
-                       *fullName,      /* Full name */
-                       *regtype;       /* Registration type */
+  char                 *fullName,      /* Full name */
+//                     *serviceName,   /* Service name */
+                       *regtype,       /* Registration type */
+                       *domain;        /* Domain name */
   cups_ptype_t         type;           /* Device registration type */
   cups_dest_t          dest;           /* Destination record */
 } _cups_dnssd_device_t;
@@ -202,6 +203,7 @@ static void         cups_dnssd_query_cb(AvahiRecordBrowser 
*browser,
                                            AvahiLookupResultFlags flags,
                                            void *context);
 #  endif /* HAVE_DNSSD */
+static void            cups_dnssd_queue_name(char *name, const char 
*serviceName, size_t namesize);
 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);
@@ -920,14 +922,13 @@ _cupsCreateDest(const char *name, /* I - Printer name */
 
 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 */
+  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,              /* Looping var */
                        num_dests;      /* Number of destinations */
@@ -939,6 +940,7 @@ cupsEnumDests(
                        *user_default;  /* User default printer */
 #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
   int                  count,          /* Number of queries started */
+                       completed,      /* Number of completed queries */
                        remaining;      /* Remainder of timeout */
   _cups_dnssd_data_t   data;           /* Data for callback */
   _cups_dnssd_device_t *device;        /* Current device */
@@ -1007,29 +1009,70 @@ cupsEnumDests(
       dest->is_default = 1;
   }
 
+#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 */
+
   for (i = num_dests, dest = dests;
        i > 0 && (!cancel || !*cancel);
        i --, dest ++)
+  {
+    const char *device_uri;            /* Device URI */
+
     if (!(*cb)(user_data, i > 1 ? CUPS_DEST_FLAGS_MORE : CUPS_DEST_FLAGS_NONE,
                dest))
       break;
 
+    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;
+         }
+        }
+      }
+    }
+  }
+
   cupsFreeDests(num_dests, dests);
 
   if (i > 0 || msec == 0)
+  {
+    cupsArrayDelete(data.devices);
     return (1);
+  }
 
 #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
  /*
   * Get Bonjour-shared printers...
   */
 
-  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);
-
 #  ifdef HAVE_DNSSD
   if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError)
     return (0);
@@ -1105,27 +1148,25 @@ cupsEnumDests(
     pfd.fd     = main_fd;
     pfd.events = POLLIN;
 
-    nfds = poll(&pfd, 1, remaining > 250 ? 250 : remaining);
+    nfds = poll(&pfd, 1, remaining > 500 ? 500 : remaining);
 
 #    else
     FD_ZERO(&input);
     FD_SET(main_fd, &input);
 
     timeout.tv_sec  = 0;
-    timeout.tv_usec = remaining > 250 ? 250000 : remaining * 1000;
+    timeout.tv_usec = remaining > 500 ? 500000 : remaining * 1000;
 
     nfds = select(main_fd + 1, &input, NULL, NULL, &timeout);
 #    endif /* HAVE_POLL */
 
     if (nfds > 0)
       DNSServiceProcessResult(data.main_ref);
-    else if (nfds == 0)
-      remaining -= 250;
 
 #  else /* HAVE_AVAHI */
     data.got_data = 0;
 
-    if ((error = avahi_simple_poll_iterate(data.simple_poll, 250)) > 0)
+    if ((error = avahi_simple_poll_iterate(data.simple_poll, 500)) > 0)
     {
      /*
       * We've been told to exit the loop.  Perhaps the connection to
@@ -1135,18 +1176,21 @@ cupsEnumDests(
       break;
     }
 
-    if (!data.got_data)
-      remaining -= 250;
 #  endif /* HAVE_DNSSD */
 
+    remaining -= 500;
+
     for (device = (_cups_dnssd_device_t *)cupsArrayFirst(data.devices),
-             count = 0;
+             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(("1cupsEnumDests: Querying '%s'.", device->fullName));
@@ -1196,8 +1240,11 @@ cupsEnumDests(
       }
       else if (device->ref && device->state == _CUPS_DNSSD_PENDING)
       {
+        completed ++;
+
         if ((device->type & mask) == type)
         {
+         DEBUG_printf(("1cupsEnumDests: Add callback for \"%s\".", 
device->dest.name));
          if (!(*cb)(user_data, CUPS_DEST_FLAGS_NONE, &device->dest))
          {
            remaining = -1;
@@ -1208,6 +1255,9 @@ cupsEnumDests(
         device->state = _CUPS_DNSSD_ACTIVE;
       }
     }
+
+    if (completed == cupsArrayCount(data.devices))
+      break;
   }
 
   cupsArrayDelete(data.devices);
@@ -2964,8 +3014,9 @@ cups_dnssd_get_device(
 {
   _cups_dnssd_device_t key,            /* Search key */
                        *device;        /* Device */
-  char                 fullName[kDNSServiceMaxDomainName];
+  char                 fullName[kDNSServiceMaxDomainName],
                                        /* Full name for query */
+                       name[128];      /* Queue name */
 
 
   DEBUG_printf(("5cups_dnssd_get_device(data=%p, serviceName=\"%s\", "
@@ -2974,7 +3025,9 @@ cups_dnssd_get_device(
   * See if this is an existing device...
   */
 
-  key.dest.name = (char *)serviceName;
+  cups_dnssd_queue_name(name, serviceName, sizeof(name));
+
+  key.dest.name = name;
 
   if ((device = cupsArrayFind(data->devices, &key)) != NULL)
   {
@@ -3035,10 +3088,12 @@ cups_dnssd_get_device(
                   replyDomain));
 
     device            = calloc(sizeof(_cups_dnssd_device_t), 1);
-    device->dest.name = _cupsStrAlloc(serviceName);
+    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);
   }
 
@@ -3047,11 +3102,9 @@ cups_dnssd_get_device(
   */
 
 #  ifdef HAVE_DNSSD
-  DNSServiceConstructFullName(fullName, device->dest.name, device->regtype,
-                             device->domain);
+  DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain);
 #  else /* HAVE_AVAHI */
-  avahi_service_name_join(fullName, kDNSServiceMaxDomainName, serviceName,
-                          regtype, replyDomain);
+  avahi_service_name_join(fullName, kDNSServiceMaxDomainName, serviceName, 
regtype, replyDomain);
 #  endif /* HAVE_DNSSD */
 
   _cupsStrFree(device->fullName);
@@ -3070,6 +3123,8 @@ cups_dnssd_get_device(
 
   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;
   }
@@ -3128,7 +3183,10 @@ cups_dnssd_local_cb(
   }
 
   if (device->state == _CUPS_DNSSD_ACTIVE)
+  {
+    DEBUG_printf(("6cups_dnssd_local_cb: Remove callback for \"%s\".", 
device->dest.name));
     (*data->cb)(data->user_data, CUPS_DEST_FLAGS_REMOVED, &device->dest);
+  }
 
   device->state = _CUPS_DNSSD_LOCAL;
 }
@@ -3214,7 +3272,8 @@ cups_dnssd_query_cb(
 #  endif /* HAVE_DNSSD */
   _cups_dnssd_data_t   *data = (_cups_dnssd_data_t *)context;
                                        /* Enumeration data */
-  char                 name[1024],     /* Service name */
+  char                 serviceName[256],/* Service name */
+                       name[128],      /* Queue name */
                        *ptr;           /* Pointer into string */
   _cups_dnssd_device_t dkey,           /* Search key */
                        *device;        /* Device */
@@ -3255,14 +3314,16 @@ cups_dnssd_query_cb(
   * Lookup the service in the devices array.
   */
 
-  dkey.dest.name = name;
-
-  cups_dnssd_unquote(name, fullName, sizeof(name));
+  cups_dnssd_unquote(serviceName, fullName, sizeof(serviceName));
 
-  if ((ptr = strstr(name, "._")) != NULL)
+  if ((ptr = strstr(serviceName, "._")) != NULL)
     *ptr = '\0';
 
-  if ((device = cupsArrayFind(data->devices, &dkey)) != NULL)
+  cups_dnssd_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...
@@ -3620,6 +3681,38 @@ cups_dnssd_unquote(char       *dst,      /* I - 
Destination buffer */
 #endif /* HAVE_DNSSD */
 
 
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+/*
+ * 'cups_dnssd_queue_name()' - Create a local queue name based on the service 
name.
+ */
+
+static void
+cups_dnssd_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';
+}
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
+
+
 /*
  * 'cups_find_dest()' - Find a destination using a binary search.
  */
++++++ 0002-Save-work-on-Avahi-code.patch ++++++
>From 657c5b5f91e6d5120c4ad7b118cf9098dd27f03d Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michael.r.sw...@gmail.com>
Date: Thu, 20 Apr 2017 09:11:45 -0400
Subject: [PATCH] Save work on Avahi code

---
 cups/dest.c | 64 +++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 19 deletions(-)

diff --git a/cups/dest.c b/cups/dest.c
index 54f2a7f..c1a0913 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -85,6 +85,7 @@ typedef struct _cups_dnssd_data_s     /* Enumeration data */
   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 */
@@ -102,7 +103,6 @@ typedef struct _cups_dnssd_device_s /* Enumerated device */
   AvahiRecordBrowser   *ref;           /* Browser for query */
 #  endif /* HAVE_DNSSD */
   char                 *fullName,      /* Full name */
-//                     *serviceName,   /* Service name */
                        *regtype,       /* Registration type */
                        *domain;        /* Domain name */
   cups_ptype_t         type;           /* Device registration type */
@@ -1021,12 +1021,15 @@ cupsEnumDests(
        i > 0 && (!cancel || !*cancel);
        i --, dest ++)
   {
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
     const char *device_uri;            /* Device URI */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
 
     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))
     {
      /*
@@ -1058,13 +1061,17 @@ cupsEnumDests(
         }
       }
     }
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
   }
 
   cupsFreeDests(num_dests, dests);
 
   if (i > 0 || msec == 0)
   {
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
     cupsArrayDelete(data.devices);
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
+
     return (1);
   }
 
@@ -1122,10 +1129,12 @@ cupsEnumDests(
     return (1);
   }
 
+  data.browsers ++;
   ipp_ref  = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC,
                                       AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL,
                                       0, cups_dnssd_browse_cb, &data);
 #    ifdef HAVE_SSL
+  data.browsers ++;
   ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC,
                                       AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL,
                                       0, cups_dnssd_browse_cb, &data);
@@ -1166,7 +1175,7 @@ cupsEnumDests(
 #  else /* HAVE_AVAHI */
     data.got_data = 0;
 
-    if ((error = avahi_simple_poll_iterate(data.simple_poll, 500)) > 0)
+    if ((error = avahi_simple_poll_iterate(data.simple_poll, 1000)) > 0)
     {
      /*
       * We've been told to exit the loop.  Perhaps the connection to
@@ -1176,6 +1185,7 @@ cupsEnumDests(
       break;
     }
 
+    DEBUG_printf(("1cupsEnumDests: got_data=%d", data.got_data));
 #  endif /* HAVE_DNSSD */
 
     remaining -= 500;
@@ -1227,14 +1237,14 @@ cupsEnumDests(
                                                    cups_dnssd_query_cb,
                                                    &data)) != NULL)
         {
+          DEBUG_printf(("1cupsEnumDests: browser ref=%p", device->ref));
          count ++;
        }
        else
        {
          device->state = _CUPS_DNSSD_ERROR;
 
-         DEBUG_printf(("1cupsEnumDests: Query failed: %s",
-                       avahi_strerror(avahi_client_errno(data.client))));
+         DEBUG_printf(("1cupsEnumDests: Query failed: %s", 
avahi_strerror(avahi_client_errno(data.client))));
        }
 #  endif /* HAVE_DNSSD */
       }
@@ -1256,8 +1266,17 @@ cupsEnumDests(
       }
     }
 
+#  ifdef HAVE_AVAHI
+    DEBUG_printf(("1cupsEnumDests: browsers=%d, completed=%d, count=%d, 
devices count=%d", data.browsers, completed, count, 
cupsArrayCount(data.devices)));
+
+    if (data.browsers == 0 && completed == cupsArrayCount(data.devices))
+      break;
+#  else
+    DEBUG_printf(("1cupsEnumDests: completed=%d, count=%d, devices count=%d", 
completed, count, cupsArrayCount(data.devices)));
+
     if (completed == cupsArrayCount(data.devices))
       break;
+#  endif /* HAVE_AVAHI */
   }
 
   cupsArrayDelete(data.devices);
@@ -2889,11 +2908,12 @@ cups_dnssd_browse_cb(
   (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))));
+       DEBUG_printf(("cups_dnssd_browse_cb: %s", 
avahi_strerror(avahi_client_errno(client))));
        avahi_simple_poll_quit(data->simple_poll);
        break;
 
@@ -2908,8 +2928,7 @@ cups_dnssd_browse_cb(
          * This comes from the local machine so ignore it.
          */
 
-         DEBUG_printf(("cups_dnssd_browse_cb: Ignoring local service \"%s\".",
-                       name));
+         DEBUG_printf(("cups_dnssd_browse_cb: Ignoring local service \"%s\".", 
name));
        }
        else
        {
@@ -2921,9 +2940,13 @@ cups_dnssd_browse_cb(
        }
        break;
 
-    case AVAHI_BROWSER_REMOVE:
-    case AVAHI_BROWSER_ALL_FOR_NOW:
-    case AVAHI_BROWSER_CACHE_EXHAUSTED:
+    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;
   }
 }
@@ -2945,6 +2968,8 @@ cups_dnssd_client_cb(
 
   (void)client;
 
+  DEBUG_printf(("cups_dnssd_client_cb(client=%p, state=%d, context=%p)", 
client, state, context));
+
  /*
   * If the connection drops, quit.
   */
@@ -3214,16 +3239,22 @@ cups_dnssd_poll_cb(
   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, 250);
+  val = poll(pollfds, num_pollfds, 500);
+
+  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);
 }
@@ -3290,11 +3321,7 @@ cups_dnssd_query_cb(
     return;
 
 #  else /* HAVE_AVAHI */
-  DEBUG_printf(("5cups_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));
+  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...
@@ -3303,8 +3330,7 @@ cups_dnssd_query_cb(
   if (event != AVAHI_BROWSER_NEW)
   {
     if (event == AVAHI_BROWSER_FAILURE)
-      DEBUG_printf(("cups_dnssd_query_cb: %s",
-                   avahi_strerror(avahi_client_errno(client))));
+      DEBUG_printf(("cups_dnssd_query_cb: %s", 
avahi_strerror(avahi_client_errno(client))));
 
     return;
   }
++++++ 0003-Avahi-fixes-for-cupsEnumDests.patch ++++++
>From 3fae3b337df0be1a766857be741173d8a9915da7 Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michael.r.sw...@gmail.com>
Date: Thu, 20 Apr 2017 10:12:40 -0400
Subject: [PATCH] Avahi fixes for cupsEnumDests (Issue #4989)

Also fix timeouts to track elapsed time so the timeout is more accurate.
---
 cups/dest.c | 70 ++++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 46 insertions(+), 24 deletions(-)

diff --git a/cups/dest.c b/cups/dest.c
index c1a0913..48758bf 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -60,6 +60,10 @@
 #  define kUseLastPrinter      CFSTR("UseLastPrinter")
 #endif /* __APPLE__ */
 
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+#  define _CUPS_DNSSD_MAXTIME  500     /* Milliseconds for maximum quantum of 
time */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
+
 
 /*
  * Types...
@@ -211,6 +215,7 @@ static int          cups_dnssd_resolve_cb(void *context);
 static void            cups_dnssd_unquote(char *dst, const char *src,
                                           size_t dstsize);
 #endif /* HAVE_DNSSD || HAVE_AVAHI */
+static int             cups_elapsed(struct timeval *t);
 static int             cups_find_dest(const char *name, const char *instance,
                                       int num_dests, cups_dest_t *dests, int 
prev,
                                       int *rdiff);
@@ -942,6 +947,7 @@ cupsEnumDests(
   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
@@ -1129,15 +1135,12 @@ cupsEnumDests(
     return (1);
   }
 
-  data.browsers ++;
-  ipp_ref  = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC,
-                                      AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL,
-                                      0, cups_dnssd_browse_cb, &data);
+  data.browsers = 1;
+  ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, 
AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, cups_dnssd_browse_cb, &data);
+
 #    ifdef HAVE_SSL
   data.browsers ++;
-  ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC,
-                                      AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL,
-                                      0, cups_dnssd_browse_cb, &data);
+  ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, 
AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data);
 #    endif /* HAVE_SSL */
 #  endif /* HAVE_DNSSD */
 
@@ -1152,19 +1155,23 @@ cupsEnumDests(
     * Check for input...
     */
 
+    DEBUG_printf(("1cupsEnumDests: remaining=%d", remaining));
+
+    cups_elapsed(&curtime);
+
 #  ifdef HAVE_DNSSD
 #    ifdef HAVE_POLL
     pfd.fd     = main_fd;
     pfd.events = POLLIN;
 
-    nfds = poll(&pfd, 1, remaining > 500 ? 500 : remaining);
+    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 = remaining > 500 ? 500000 : remaining * 1000;
+    timeout.tv_usec = 1000 * (remaining > _CUPS_DNSSD_MAXTIME ? 
_CUPS_DNSSD_MAXTIME : remaining);
 
     nfds = select(main_fd + 1, &input, NULL, NULL, &timeout);
 #    endif /* HAVE_POLL */
@@ -1175,7 +1182,7 @@ cupsEnumDests(
 #  else /* HAVE_AVAHI */
     data.got_data = 0;
 
-    if ((error = avahi_simple_poll_iterate(data.simple_poll, 1000)) > 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
@@ -1188,7 +1195,7 @@ cupsEnumDests(
     DEBUG_printf(("1cupsEnumDests: got_data=%d", data.got_data));
 #  endif /* HAVE_DNSSD */
 
-    remaining -= 500;
+    remaining -= cups_elapsed(&curtime);
 
     for (device = (_cups_dnssd_device_t *)cupsArrayFirst(data.devices),
              count = 0, completed = 0;
@@ -1227,17 +1234,9 @@ cupsEnumDests(
        }
 
 #  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)
+       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(("1cupsEnumDests: browser ref=%p", device->ref));
+          DEBUG_printf(("1cupsEnumDests: Query ref=%p", device->ref));
          count ++;
        }
        else
@@ -1252,6 +1251,8 @@ cupsEnumDests(
       {
         completed ++;
 
+        DEBUG_printf(("1cupsEnumDests: Query for \"%s\" is complete.", 
device->fullName));
+
         if ((device->type & mask) == type)
         {
          DEBUG_printf(("1cupsEnumDests: Add callback for \"%s\".", 
device->dest.name));
@@ -1267,12 +1268,12 @@ cupsEnumDests(
     }
 
 #  ifdef HAVE_AVAHI
-    DEBUG_printf(("1cupsEnumDests: browsers=%d, completed=%d, count=%d, 
devices count=%d", data.browsers, completed, count, 
cupsArrayCount(data.devices)));
+    DEBUG_printf(("1cupsEnumDests: 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(("1cupsEnumDests: completed=%d, count=%d, devices count=%d", 
completed, count, cupsArrayCount(data.devices)));
+    DEBUG_printf(("1cupsEnumDests: remaining=%d, completed=%d, count=%d, 
devices count=%d", remaining, completed, count, cupsArrayCount(data.devices)));
 
     if (completed == cupsArrayCount(data.devices))
       break;
@@ -3243,7 +3244,7 @@ cups_dnssd_poll_cb(
 
   (void)timeout;
 
-  val = poll(pollfds, num_pollfds, 500);
+  val = poll(pollfds, num_pollfds, _CUPS_DNSSD_MAXTIME);
 
   DEBUG_printf(("cups_dnssd_poll_cb: poll() returned %d", val));
 
@@ -3740,6 +3741,27 @@ cups_dnssd_queue_name(
 
 
 /*
+ * '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 = 1000 * (nt.tv_sec - t->tv_sec) + (nt.tv_usec - t->tv_usec) / 1000;
+
+  *t = nt;
+
+  return (msecs);
+}
+
+ 
+/*
  * 'cups_find_dest()' - Find a destination using a binary search.
  */
 





Reply via email to