Accepting request 491776 from Printing

Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/491776
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/cups?expand=0&rev=138
This commit is contained in:
Dominique Leuenberger 2017-05-03 13:53:05 +00:00 committed by Git OBS Bridge
commit ec7989d947
5 changed files with 817 additions and 5 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,3 +1,25 @@
-------------------------------------------------------------------
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
- 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)
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Mar 29 13:41:15 UTC 2017 - kukuk@suse.com Wed Mar 29 13:41:15 UTC 2017 - kukuk@suse.com

View File

@ -45,6 +45,12 @@ Patch10: cups-2.1.0-choose-uri-template.patch
Patch11: cups-2.1.0-default-webcontent-path.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 Use systemd socket activation properly:
Patch12: cups-2.1.0-cups-systemd-socket.patch 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...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 adds conf/pam.suse regarding support for PAM for SUSE:
Patch100: cups-pam.diff Patch100: cups-pam.diff
@ -133,9 +139,9 @@ browsing". This is now handled by cups-browsed service.
%package libs %package libs
Summary: Libraries for CUPS 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 License: GPL-2.0 and LGPL-2.1
Group: Hardware/Printing Group: Hardware/Printing
# Prerequire /sbin/ldconfig which is used in the traditional bash scriptlets for post/postun:
Requires(pre): /sbin/ldconfig Requires(pre): /sbin/ldconfig
%if 0%{?suse_version} >= 1330 %if 0%{?suse_version} >= 1330
Requires(pre): group(lp) Requires(pre): group(lp)
@ -157,6 +163,8 @@ browsing". This is now handled by cups-browsed service.
%package client %package client
Summary: CUPS Client Programs Summary: CUPS Client Programs
License: GPL-2.0
Group: Hardware/Printing
# Require the exact matching version-release of the cups-libs sub-package because # 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) # 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 # because all CUPS software is built from the one same CUPS source tar ball
@ -166,8 +174,6 @@ Summary: CUPS Client Programs
# on the same package repository where the cups package is because # on the same package repository where the cups package is because
# all are built simulaneously from the same cups source package # all are built simulaneously from the same cups source package
# and all required packages are provided on the same repository: # and all required packages are provided on the same repository:
License: GPL-2.0
Group: Hardware/Printing
Requires: cups-libs = %{version}-%{release} Requires: cups-libs = %{version}-%{release}
# Conflicts with other print spoolers which provide same binaries like /usr/bin/lp and so on: # Conflicts with other print spoolers which provide same binaries like /usr/bin/lp and so on:
Conflicts: lprng Conflicts: lprng
@ -190,13 +196,13 @@ browsing". This is now handled by cups-browsed service.
%package devel %package devel
Summary: Development Environment for CUPS 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 # Do not require the exact matching version-release of cups-libs
# but only a cups-libs package with matching version because # but only a cups-libs package with matching version because
# for building third-party software which uses only the CUPS public API # for building third-party software which uses only the CUPS public API
# there are no CUPS-internal dependencies via CUPS private API calls # there are no CUPS-internal dependencies via CUPS private API calls
# (the latter would require the exact matching cups-libs version-release): # (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: cups-libs = %{version}
Requires: glibc-devel Requires: glibc-devel
@ -258,6 +264,12 @@ browsing". This is now handled by cups-browsed service.
%patch11 -b default-webcontent-path.prig %patch11 -b default-webcontent-path.prig
# Patch12 cups-2.1.0-cups-systemd-socket.patch Use systemd socket activation properly: # Patch12 cups-2.1.0-cups-systemd-socket.patch Use systemd socket activation properly:
%patch12 -b cups-systemd-socket.orig %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...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 adds conf/pam.suse regarding support for PAM for SUSE:
%patch100 %patch100