33 * commands such as IPP and Bonjour conformance tests. This tool is
44 * inspired by the UNIX "find" command, thus its name.
55 *
6- * Copyright © 2020-2024 by OpenPrinting.
6+ * Copyright © 2020-2025 by OpenPrinting.
77 * Copyright © 2020 by the IEEE-ISTO Printer Working Group
88 * Copyright © 2008-2018 by Apple Inc.
99 *
1010 * Licensed under Apache License v2.0. See the file "LICENSE" for more
1111 * information.
1212 */
1313
14- /*
15- * Include necessary headers.
16- */
17-
1814#define _CUPS_NO_DEPRECATED
1915#include <cups/cups-private.h>
2016#ifdef _WIN32
@@ -129,7 +125,6 @@ typedef struct ippfind_srv_s /* Service information */
129125static DNSServiceRef dnssd_ref ; /* Master service reference */
130126#elif defined(HAVE_AVAHI )
131127static AvahiClient * avahi_client = NULL ;/* Client information */
132- static int avahi_got_data = 0 ; /* Got data from poll? */
133128static AvahiSimplePoll * avahi_poll = NULL ;
134129 /* Poll information */
135130#endif /* HAVE_MDNSRESPONDER */
@@ -139,6 +134,7 @@ static int address_family = AF_UNSPEC;
139134static int bonjour_error = 0 ; /* Error browsing/resolving? */
140135static double bonjour_timeout = 1.0 ; /* Timeout in seconds */
141136static int ipp_version = 20 ; /* IPP version for LIST */
137+ static double last_update = 0.0 ; /* Last update time */
142138
143139
144140/*
@@ -170,7 +166,6 @@ static int eval_expr(ippfind_srv_t *service,
170166static int exec_program (ippfind_srv_t * service , int num_args ,
171167 char * * args );
172168static ippfind_srv_t * get_service (cups_array_t * services , const char * serviceName , const char * regtype , const char * replyDomain ) _CUPS_NONNULL (1 ,2 ,3 ,4 );
173- static double get_time (void );
174169static int list_service (ippfind_srv_t * service );
175170static ippfind_expr_t * new_expr (ippfind_op_t op , int invert ,
176171 const char * value , const char * regex ,
@@ -1308,14 +1303,12 @@ main(int argc, /* I - Number of command-line args */
13081303 */
13091304
13101305 if (bonjour_timeout > 1.0 )
1311- endtime = get_time () + bonjour_timeout ;
1306+ endtime = _cupsGetClock () + bonjour_timeout ;
13121307 else
1313- endtime = get_time () + 300.0 ;
1308+ endtime = _cupsGetClock () + 300.0 ;
13141309
1315- while (get_time () < endtime )
1310+ while (_cupsGetClock () < endtime )
13161311 {
1317- int process = 0 ; /* Process services? */
1318-
13191312#ifdef HAVE_MDNSRESPONDER
13201313 int fd = DNSServiceRefSockFD (dnssd_ref );
13211314 /* File descriptor for DNS-SD */
@@ -1337,18 +1330,8 @@ main(int argc, /* I - Number of command-line args */
13371330
13381331 DNSServiceProcessResult (dnssd_ref );
13391332 }
1340- else
1341- {
1342- /*
1343- * Time to process services...
1344- */
1345-
1346- process = 1 ;
1347- }
13481333
13491334#elif defined(HAVE_AVAHI )
1350- avahi_got_data = 0 ;
1351-
13521335 if (avahi_simple_poll_iterate (avahi_poll , 500 ) > 0 )
13531336 {
13541337 /*
@@ -1359,108 +1342,103 @@ main(int argc, /* I - Number of command-line args */
13591342 return (IPPFIND_EXIT_BONJOUR );
13601343 }
13611344
1362- if (!avahi_got_data )
1363- {
1364- /*
1365- * Time to process services...
1366- */
1367-
1368- process = 1 ;
1369- }
13701345#endif /* HAVE_MDNSRESPONDER */
13711346
1372- if (process )
1373- {
1374- /*
1375- * Process any services that we have found...
1376- */
1347+ /*
1348+ * Process any services that we have found...
1349+ */
13771350
1378- int active = 0 , /* Number of active resolves */
1379- processed = 0 ; /* Number of processed services */
1351+ int active = 0 , /* Number of active resolves */
1352+ processed = 0 ; /* Number of processed services */
13801353
1381- for (service = (ippfind_srv_t * )cupsArrayFirst (services );
1382- service ;
1383- service = (ippfind_srv_t * )cupsArrayNext (services ))
1384- {
1385- if (service -> is_processed )
1386- processed ++ ;
1354+ for (service = (ippfind_srv_t * )cupsArrayFirst (services );
1355+ service ;
1356+ service = (ippfind_srv_t * )cupsArrayNext (services ))
1357+ {
1358+ if (service -> is_processed )
1359+ processed ++ ;
13871360
1388- if (!service -> ref && !service -> is_resolved )
1389- {
1390- /*
1391- * Found a service, now resolve it (but limit to 50 active resolves...)
1392- */
1361+ if (!service -> ref && !service -> is_resolved )
1362+ {
1363+ /*
1364+ * Found a service, now resolve it (but limit to 50 active resolves...)
1365+ */
13931366
1394- if (active < 50 )
1395- {
1367+ if (active < 50 )
1368+ {
13961369#ifdef HAVE_MDNSRESPONDER
1397- service -> ref = dnssd_ref ;
1398- err = DNSServiceResolve (& (service -> ref ),
1399- kDNSServiceFlagsShareConnection , 0 ,
1400- service -> name , service -> regtype ,
1401- service -> domain , resolve_callback ,
1402- service );
1370+ service -> ref = dnssd_ref ;
1371+ err = DNSServiceResolve (& (service -> ref ),
1372+ kDNSServiceFlagsShareConnection , 0 ,
1373+ service -> name , service -> regtype ,
1374+ service -> domain , resolve_callback ,
1375+ service );
14031376
14041377#elif defined(HAVE_AVAHI )
1405- service -> ref = avahi_service_resolver_new (avahi_client ,
1406- AVAHI_IF_UNSPEC ,
1407- AVAHI_PROTO_UNSPEC ,
1408- service -> name ,
1409- service -> regtype ,
1410- service -> domain ,
1411- AVAHI_PROTO_UNSPEC , 0 ,
1412- resolve_callback ,
1413- service );
1414- if (service -> ref )
1415- err = 0 ;
1416- else
1417- err = avahi_client_errno (avahi_client );
1378+ service -> ref = avahi_service_resolver_new (avahi_client ,
1379+ AVAHI_IF_UNSPEC ,
1380+ AVAHI_PROTO_UNSPEC ,
1381+ service -> name ,
1382+ service -> regtype ,
1383+ service -> domain ,
1384+ AVAHI_PROTO_UNSPEC , 0 ,
1385+ resolve_callback ,
1386+ service );
1387+ if (service -> ref )
1388+ err = 0 ;
1389+ else
1390+ err = avahi_client_errno (avahi_client );
14181391#endif /* HAVE_MDNSRESPONDER */
14191392
1420- if (err )
1421- {
1422- _cupsLangPrintf (stderr ,
1423- _ ("ippfind: Unable to browse or resolve: %s" ),
1424- dnssd_error_string (err ));
1425- return (IPPFIND_EXIT_BONJOUR );
1426- }
1393+ if (err )
1394+ {
1395+ _cupsLangPrintf (stderr ,
1396+ _ ("ippfind: Unable to browse or resolve: %s" ),
1397+ dnssd_error_string (err ));
1398+ return (IPPFIND_EXIT_BONJOUR );
1399+ }
14271400
1428- active ++ ;
1429- }
1430- }
1431- else if (service -> is_resolved && !service -> is_processed )
1432- {
1433- /*
1434- * Resolved, not process this service against the expressions...
1435- */
1401+ active ++ ;
1402+ }
1403+ }
1404+ else if (service -> is_resolved && !service -> is_processed )
1405+ {
1406+ /*
1407+ * Resolved, not process this service against the expressions...
1408+ */
14361409
1437- if (service -> ref )
1438- {
1410+ if (service -> ref )
1411+ {
14391412#ifdef HAVE_MDNSRESPONDER
1440- DNSServiceRefDeallocate (service -> ref );
1413+ DNSServiceRefDeallocate (service -> ref );
14411414#else
1442- avahi_service_resolver_free (service -> ref );
1415+ avahi_service_resolver_free (service -> ref );
14431416#endif /* HAVE_MDNSRESPONDER */
14441417
1445- service -> ref = NULL ;
1446- }
1418+ service -> ref = NULL ;
1419+ }
14471420
1448- if (eval_expr (service , expressions ))
1449- status = IPPFIND_EXIT_TRUE ;
1421+ if (eval_expr (service , expressions ))
1422+ status = IPPFIND_EXIT_TRUE ;
14501423
1451- service -> is_processed = 1 ;
1452- }
1453- else if (service -> ref )
1454- active ++ ;
1424+ service -> is_processed = 1 ;
14551425 }
1426+ else if (service -> ref )
1427+ active ++ ;
1428+ }
14561429
1457- /*
1458- * If we have processed all services we have discovered, then we are done.
1459- */
1430+ /*
1431+ * If we have processed all services we have discovered, then we are done.
1432+ */
14601433
1461- if (processed == cupsArrayCount (services ) && bonjour_timeout <= 1.0 )
1462- break ;
1463- }
1434+ if (processed > 0 && (processed == cupsArrayCount (services ) || (_cupsGetClock () - last_update ) >= 2.5 ) && bonjour_timeout <= 1.0 )
1435+ break ;
1436+
1437+ /*
1438+ * Give the browsers/resolvers some time...
1439+ */
1440+
1441+ usleep (250000 );
14641442 }
14651443
14661444 if (bonjour_error )
@@ -1490,6 +1468,8 @@ browse_callback(
14901468 * Only process "add" data...
14911469 */
14921470
1471+ last_update = _cupsGetClock ();
1472+
14931473 (void )sdRef ;
14941474 (void )interfaceIndex ;
14951475
@@ -1522,6 +1502,8 @@ browse_local_callback(
15221502 ippfind_srv_t * service ; /* Service */
15231503
15241504
1505+ last_update = _cupsGetClock ();
1506+
15251507 /*
15261508 * Only process "add" data...
15271509 */
@@ -1565,6 +1547,8 @@ browse_callback(
15651547 ippfind_srv_t * service ; /* Service information */
15661548
15671549
1550+ last_update = _cupsGetClock ();
1551+
15681552 (void )interface ;
15691553 (void )protocol ;
15701554 (void )context ;
@@ -2190,31 +2174,6 @@ get_service(cups_array_t *services, /* I - Service array */
21902174}
21912175
21922176
2193- /*
2194- * 'get_time()' - Get the current time-of-day in seconds.
2195- */
2196-
2197- static double
2198- get_time (void )
2199- {
2200- #ifdef _WIN32
2201- struct _timeb curtime ; /* Current Windows time */
2202-
2203- _ftime (& curtime );
2204-
2205- return (curtime .time + 0.001 * curtime .millitm );
2206-
2207- #else
2208- struct timeval curtime ; /* Current UNIX time */
2209-
2210- if (gettimeofday (& curtime , NULL ))
2211- return (0.0 );
2212- else
2213- return (curtime .tv_sec + 0.000001 * curtime .tv_usec );
2214- #endif /* _WIN32 */
2215- }
2216-
2217-
22182177/*
22192178 * 'list_service()' - List the contents of a service.
22202179 */
@@ -2517,7 +2476,7 @@ new_expr(ippfind_op_t op, /* I - Operation */
25172476 *
25182477 * Note: This function is needed because avahi_simple_poll_iterate is broken
25192478 * and always uses a timeout of 0 (!) milliseconds.
2520- * (Avahi Ticket #364 )
2479+ * (Avahi Github issue #127 )
25212480 */
25222481
25232482static int /* O - Number of file descriptors matching */
@@ -2527,18 +2486,10 @@ poll_callback(
25272486 int timeout , /* I - Timeout in milliseconds (unused) */
25282487 void * context ) /* I - User data (unused) */
25292488{
2530- int val ; /* Return value */
2531-
2532-
25332489 (void )timeout ;
25342490 (void )context ;
25352491
2536- val = poll (pollfds , num_pollfds , 500 );
2537-
2538- if (val > 0 )
2539- avahi_got_data = 1 ;
2540-
2541- return (val );
2492+ return (poll (pollfds , num_pollfds , 500 ));
25422493}
25432494#endif /* HAVE_AVAHI */
25442495
@@ -2569,6 +2520,8 @@ resolve_callback(
25692520 /* Service */
25702521
25712522
2523+ last_update = _cupsGetClock ();
2524+
25722525 /*
25732526 * Only process "add" data...
25742527 */
@@ -2650,6 +2603,8 @@ resolve_callback(
26502603 AvahiStringList * current ; /* Current TXT key/value pair */
26512604
26522605
2606+ last_update = _cupsGetClock ();
2607+
26532608 (void )address ;
26542609
26552610 if (event != AVAHI_RESOLVER_FOUND )
0 commit comments