Accepting request 489647 from home:alarrosa:branches:Printing

- 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.

OBS-URL: https://build.opensuse.org/request/show/489647
OBS-URL: https://build.opensuse.org/package/show/Printing/cups?expand=0&rev=326
This commit is contained in:
Johannes Meixner 2017-04-21 08:44:45 +00:00 committed by Git OBS Bridge
parent 31b8620fa3
commit 6f9127aa90
6 changed files with 801 additions and 56 deletions

View File

@ -0,0 +1,366 @@
From a2187a63425a3d6c05de1e1cbf8c26fd39a1aced Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michaelrsweet@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.
*/

View File

@ -0,0 +1,226 @@
From 657c5b5f91e6d5120c4ad7b118cf9098dd27f03d Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michael.r.sweet@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;
}

View File

@ -0,0 +1,186 @@
From 3fae3b337df0be1a766857be741173d8a9915da7 Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michael.r.sweet@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.
*/

View File

@ -1,53 +0,0 @@
Index: cups-2.1.3/cups/dest.c
===================================================================
--- cups-2.1.3.orig/cups/dest.c
+++ cups-2.1.3/cups/dest.c
@@ -84,6 +84,7 @@ typedef struct _cups_dnssd_data_s /* Enu
AvahiSimplePoll *simple_poll; /* Polling interface */
AvahiClient *client; /* Client information */
int got_data; /* Did we get data? */
+ int remaining_browsers; /* Remaining avahi browsers running */
# endif /* HAVE_DNSSD */
cups_dest_cb_t cb; /* Callback */
void *user_data; /* User data pointer */
@@ -920,6 +921,7 @@ cupsEnumDests(
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);
+ data.remaining_browsers = 1;
# ifdef HAVE_DNSSD
if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError)
@@ -977,6 +979,7 @@ cupsEnumDests(
ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC,
AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL,
0, cups_dnssd_browse_cb, &data);
+ data.remaining_browsers++;
# endif /* HAVE_SSL */
# endif /* HAVE_DNSSD */
@@ -985,7 +988,7 @@ cupsEnumDests(
else
remaining = msec;
- while (remaining > 0 && (!cancel || !*cancel))
+ while (data.remaining_browsers > 0 && remaining > 0 && (!cancel || !*cancel))
{
/*
* Check for input...
@@ -2762,10 +2765,13 @@ cups_dnssd_browse_cb(
}
break;
- case AVAHI_BROWSER_REMOVE:
case AVAHI_BROWSER_ALL_FOR_NOW:
+ data->remaining_browsers--;
+ break;
+
+ case AVAHI_BROWSER_REMOVE:
case AVAHI_BROWSER_CACHE_EXHAUSTED:
- break;
+ break;
}
}

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Thu Apr 20 16:26:52 UTC 2017 - alarrosa@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 - alarrosa@suse.com

View File

@ -45,8 +45,12 @@ Patch10: cups-2.1.0-choose-uri-template.patch
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 cups-2.1.3-cupsEnumDests-react-to-all-for-now.diff bsc#955432 -- React properly to avahi's ALL_FOR_NOW signal to reduce unneeded delay
Patch13: cups-2.1.3-cupsEnumDests-react-to-all-for-now.diff
# 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
@ -260,8 +264,12 @@ browsing". This is now handled by cups-browsed service.
%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 cups-2.1.3-cupsEnumDests-react-to-all-for-now.diff React properly to avahi's ALL_FOR_NOW signal to reduce unneeded delay
# 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