* commands such as IPP and Bonjour conformance tests. This tool is
* inspired by the UNIX "find" command, thus its name.
*
- * Copyright © 2020-2024 by OpenPrinting.
+ * Copyright © 2020-2025 by OpenPrinting.
* Copyright © 2020 by the IEEE-ISTO Printer Working Group
* Copyright © 2008-2018 by Apple Inc.
*
* information.
*/
-/*
- * Include necessary headers.
- */
-
#define _CUPS_NO_DEPRECATED
#include <cups/cups-private.h>
#ifdef _WIN32
static DNSServiceRef dnssd_ref; /* Master service reference */
#elif defined(HAVE_AVAHI)
static AvahiClient *avahi_client = NULL;/* Client information */
-static int avahi_got_data = 0; /* Got data from poll? */
static AvahiSimplePoll *avahi_poll = NULL;
/* Poll information */
#endif /* HAVE_MDNSRESPONDER */
static int bonjour_error = 0; /* Error browsing/resolving? */
static double bonjour_timeout = 1.0; /* Timeout in seconds */
static int ipp_version = 20; /* IPP version for LIST */
+static double last_update = 0.0; /* Last update time */
/*
static int exec_program(ippfind_srv_t *service, int num_args,
char **args);
static ippfind_srv_t *get_service(cups_array_t *services, const char *serviceName, const char *regtype, const char *replyDomain) _CUPS_NONNULL(1,2,3,4);
-static double get_time(void);
static int list_service(ippfind_srv_t *service);
static ippfind_expr_t *new_expr(ippfind_op_t op, int invert,
const char *value, const char *regex,
*/
if (bonjour_timeout > 1.0)
- endtime = get_time() + bonjour_timeout;
+ endtime = _cupsGetClock() + bonjour_timeout;
else
- endtime = get_time() + 300.0;
+ endtime = _cupsGetClock() + 300.0;
- while (get_time() < endtime)
+ while (_cupsGetClock() < endtime)
{
- int process = 0; /* Process services? */
-
#ifdef HAVE_MDNSRESPONDER
int fd = DNSServiceRefSockFD(dnssd_ref);
/* File descriptor for DNS-SD */
DNSServiceProcessResult(dnssd_ref);
}
- else
- {
- /*
- * Time to process services...
- */
-
- process = 1;
- }
#elif defined(HAVE_AVAHI)
- avahi_got_data = 0;
-
if (avahi_simple_poll_iterate(avahi_poll, 500) > 0)
{
/*
return (IPPFIND_EXIT_BONJOUR);
}
- if (!avahi_got_data)
- {
- /*
- * Time to process services...
- */
-
- process = 1;
- }
#endif /* HAVE_MDNSRESPONDER */
- if (process)
- {
- /*
- * Process any services that we have found...
- */
+ /*
+ * Process any services that we have found...
+ */
- int active = 0, /* Number of active resolves */
- processed = 0; /* Number of processed services */
+ int active = 0, /* Number of active resolves */
+ processed = 0; /* Number of processed services */
- for (service = (ippfind_srv_t *)cupsArrayFirst(services);
- service;
- service = (ippfind_srv_t *)cupsArrayNext(services))
- {
- if (service->is_processed)
- processed ++;
+ for (service = (ippfind_srv_t *)cupsArrayFirst(services);
+ service;
+ service = (ippfind_srv_t *)cupsArrayNext(services))
+ {
+ if (service->is_processed)
+ processed ++;
- if (!service->ref && !service->is_resolved)
- {
- /*
- * Found a service, now resolve it (but limit to 50 active resolves...)
- */
+ if (!service->ref && !service->is_resolved)
+ {
+ /*
+ * Found a service, now resolve it (but limit to 50 active resolves...)
+ */
- if (active < 50)
- {
+ if (active < 50)
+ {
#ifdef HAVE_MDNSRESPONDER
- service->ref = dnssd_ref;
- err = DNSServiceResolve(&(service->ref),
- kDNSServiceFlagsShareConnection, 0,
- service->name, service->regtype,
- service->domain, resolve_callback,
- service);
+ service->ref = dnssd_ref;
+ err = DNSServiceResolve(&(service->ref),
+ kDNSServiceFlagsShareConnection, 0,
+ service->name, service->regtype,
+ service->domain, resolve_callback,
+ service);
#elif defined(HAVE_AVAHI)
- service->ref = avahi_service_resolver_new(avahi_client,
- AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC,
- service->name,
- service->regtype,
- service->domain,
- AVAHI_PROTO_UNSPEC, 0,
- resolve_callback,
- service);
- if (service->ref)
- err = 0;
- else
- err = avahi_client_errno(avahi_client);
+ service->ref = avahi_service_resolver_new(avahi_client,
+ AVAHI_IF_UNSPEC,
+ AVAHI_PROTO_UNSPEC,
+ service->name,
+ service->regtype,
+ service->domain,
+ AVAHI_PROTO_UNSPEC, 0,
+ resolve_callback,
+ service);
+ if (service->ref)
+ err = 0;
+ else
+ err = avahi_client_errno(avahi_client);
#endif /* HAVE_MDNSRESPONDER */
- if (err)
- {
- _cupsLangPrintf(stderr,
- _("ippfind: Unable to browse or resolve: %s"),
- dnssd_error_string(err));
- return (IPPFIND_EXIT_BONJOUR);
- }
+ if (err)
+ {
+ _cupsLangPrintf(stderr,
+ _("ippfind: Unable to browse or resolve: %s"),
+ dnssd_error_string(err));
+ return (IPPFIND_EXIT_BONJOUR);
+ }
- active ++;
- }
- }
- else if (service->is_resolved && !service->is_processed)
- {
- /*
- * Resolved, not process this service against the expressions...
- */
+ active ++;
+ }
+ }
+ else if (service->is_resolved && !service->is_processed)
+ {
+ /*
+ * Resolved, not process this service against the expressions...
+ */
- if (service->ref)
- {
+ if (service->ref)
+ {
#ifdef HAVE_MDNSRESPONDER
- DNSServiceRefDeallocate(service->ref);
+ DNSServiceRefDeallocate(service->ref);
#else
- avahi_service_resolver_free(service->ref);
+ avahi_service_resolver_free(service->ref);
#endif /* HAVE_MDNSRESPONDER */
- service->ref = NULL;
- }
+ service->ref = NULL;
+ }
- if (eval_expr(service, expressions))
- status = IPPFIND_EXIT_TRUE;
+ if (eval_expr(service, expressions))
+ status = IPPFIND_EXIT_TRUE;
- service->is_processed = 1;
- }
- else if (service->ref)
- active ++;
+ service->is_processed = 1;
}
+ else if (service->ref)
+ active ++;
+ }
- /*
- * If we have processed all services we have discovered, then we are done.
- */
+ /*
+ * If we have processed all services we have discovered, then we are done.
+ */
- if (processed == cupsArrayCount(services) && bonjour_timeout <= 1.0)
- break;
- }
+ if (processed > 0 && (processed == cupsArrayCount(services) || (_cupsGetClock() - last_update) >= 2.5) && bonjour_timeout <= 1.0)
+ break;
+
+ /*
+ * Give the browsers/resolvers some time...
+ */
+
+ usleep(250000);
}
if (bonjour_error)
* Only process "add" data...
*/
+ last_update = _cupsGetClock();
+
(void)sdRef;
(void)interfaceIndex;
ippfind_srv_t *service; /* Service */
+ last_update = _cupsGetClock();
+
/*
* Only process "add" data...
*/
ippfind_srv_t *service; /* Service information */
+ last_update = _cupsGetClock();
+
(void)interface;
(void)protocol;
(void)context;
}
-/*
- * 'get_time()' - Get the current time-of-day in seconds.
- */
-
-static double
-get_time(void)
-{
-#ifdef _WIN32
- struct _timeb curtime; /* Current Windows time */
-
- _ftime(&curtime);
-
- return (curtime.time + 0.001 * curtime.millitm);
-
-#else
- struct timeval curtime; /* Current UNIX time */
-
- if (gettimeofday(&curtime, NULL))
- return (0.0);
- else
- return (curtime.tv_sec + 0.000001 * curtime.tv_usec);
-#endif /* _WIN32 */
-}
-
-
/*
* 'list_service()' - List the contents of a service.
*/
*
* Note: This function is needed because avahi_simple_poll_iterate is broken
* and always uses a timeout of 0 (!) milliseconds.
- * (Avahi Ticket #364)
+ * (Avahi Github issue #127)
*/
static int /* O - Number of file descriptors matching */
int timeout, /* I - Timeout in milliseconds (unused) */
void *context) /* I - User data (unused) */
{
- int val; /* Return value */
-
-
(void)timeout;
(void)context;
- val = poll(pollfds, num_pollfds, 500);
-
- if (val > 0)
- avahi_got_data = 1;
-
- return (val);
+ return (poll(pollfds, num_pollfds, 500));
}
#endif /* HAVE_AVAHI */
/* Service */
+ last_update = _cupsGetClock();
+
/*
* Only process "add" data...
*/
AvahiStringList *current; /* Current TXT key/value pair */
+ last_update = _cupsGetClock();
+
(void)address;
if (event != AVAHI_RESOLVER_FOUND)