int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) { AvahiServer *server; AvahiServerConfig config; int error; AvahiSimplePoll *simple_poll; simple_poll = avahi_simple_poll_new(); avahi_server_config_init(&config); config.publish_hinfo = 0; config.publish_addresses = 0; config.publish_workstation = 0; config.publish_domain = 0; config.use_ipv6 = 0; config.enable_reflector = 1; server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error); avahi_server_config_free(&config); for (;;) if (avahi_simple_poll_iterate(simple_poll, -1) != 0) break; avahi_server_free(server); avahi_simple_poll_free(simple_poll); return 0; }
int avahi_simple_poll_loop(AvahiSimplePoll *s) { int r; assert(s); for (;;) if ((r = avahi_simple_poll_iterate(s, -1)) != 0) if (r >= 0 || errno != EINTR) return r; }
static void * avahi_thread(void *aux) { const AvahiPoll *ap = avahi_simple_poll_get(avahi_asp); name = avahi_strdup("Tvheadend"); avahi_client_new(ap, AVAHI_CLIENT_NO_FAIL, client_callback, NULL, NULL); while(avahi_simple_poll_iterate(avahi_asp, -1) == 0); return NULL; }
bool BrowseAvahi::browse(const std::string& serviceName, int proto, AvahiResult& result, int timeout) { int error; /* Allocate main loop object */ if (!(simple_poll = avahi_simple_poll_new())) { logE << "Failed to create simple poll object.\n"; goto fail; } /* Allocate a new client */ client_ = avahi_client_new(avahi_simple_poll_get(simple_poll), (AvahiClientFlags)0, client_callback, this, &error); /* Check wether creating the client object succeeded */ if (!client_) { logE << "Failed to create client: " << avahi_strerror(error) << "\n"; goto fail; } /* Create the service browser */ if (!(sb_ = avahi_service_browser_new(client_, AVAHI_IF_UNSPEC, proto, serviceName.c_str(), NULL, (AvahiLookupFlags)0, browse_callback, this))) { logE << "Failed to create service browser: " << avahi_strerror(avahi_client_errno(client_)) << "\n"; goto fail; } result_.valid_ = false; while (timeout > 0) { avahi_simple_poll_iterate(simple_poll, 100); timeout -= 100; if (result_.valid_) { result = result_; return true; } } fail: return false; }
bool BrowseAvahi::browse(const std::string& serviceName, mDNSResult& result, int timeout) { try { /* Allocate main loop object */ if (!(simple_poll = avahi_simple_poll_new())) throw SnapException("BrowseAvahi - Failed to create simple poll object"); /* Allocate a new client */ int error; if (!(client_ = avahi_client_new(avahi_simple_poll_get(simple_poll), (AvahiClientFlags)0, client_callback, this, &error))) throw SnapException("BrowseAvahi - Failed to create client: " + std::string(avahi_strerror(error))); /* Create the service browser */ if (!(sb_ = avahi_service_browser_new(client_, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, serviceName.c_str(), NULL, (AvahiLookupFlags)0, browse_callback, this))) throw SnapException("BrowseAvahi - Failed to create service browser: " + std::string(avahi_strerror(avahi_client_errno(client_)))); result_.valid_ = false; while (timeout > 0) { avahi_simple_poll_iterate(simple_poll, 100); timeout -= 100; if (result_.valid_) { result = result_; cleanUp(); return true; } } cleanUp(); return false; } catch (...) { cleanUp(); throw; } }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { const char *name; /* Backend name */ cups_array_t *devices; /* Device array */ cups_device_t *device; /* Current device */ char uriName[1024]; /* Unquoted fullName for URI */ #ifdef HAVE_DNSSD int fd; /* Main file descriptor */ fd_set input; /* Input set for select() */ struct timeval timeout; /* Timeout for select() */ DNSServiceRef main_ref, /* Main service reference */ fax_ipp_ref, /* IPP fax service reference */ ipp_ref, /* IPP service reference */ ipp_tls_ref, /* IPP w/TLS service reference */ ipps_ref, /* IPP service reference */ local_fax_ipp_ref, /* Local IPP fax service reference */ local_ipp_ref, /* Local IPP service reference */ local_ipp_tls_ref, /* Local IPP w/TLS service reference */ local_ipps_ref, /* Local IPP service reference */ local_printer_ref, /* Local LPD service reference */ pdl_datastream_ref, /* AppSocket service reference */ printer_ref, /* LPD service reference */ riousbprint_ref; /* Remote IO service reference */ #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI AvahiClient *client; /* Client information */ int error; /* Error code, if any */ #endif /* HAVE_AVAHI */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ /* * Don't buffer stderr, and catch SIGTERM... */ setbuf(stderr, NULL); #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ sigset(SIGTERM, sigterm_handler); #elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); action.sa_handler = sigterm_handler; sigaction(SIGTERM, &action, NULL); #else signal(SIGTERM, sigterm_handler); #endif /* HAVE_SIGSET */ /* * Check command-line... */ if (argc >= 6) exec_backend(argv); else if (argc != 1) { _cupsLangPrintf(stderr, _("Usage: %s job-id user title copies options [file]"), argv[0]); return (1); } /* * Only do discovery when run as "dnssd"... */ if ((name = strrchr(argv[0], '/')) != NULL) name ++; else name = argv[0]; if (strcmp(name, "dnssd")) return (0); /* * Create an array to track devices... */ devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); /* * Browse for different kinds of printers... */ #ifdef HAVE_DNSSD if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) { perror("ERROR: Unable to create service connection"); return (1); } fd = DNSServiceRefSockFD(main_ref); fax_ipp_ref = main_ref; DNSServiceBrowse(&fax_ipp_ref, kDNSServiceFlagsShareConnection, 0, "_fax-ipp._tcp", NULL, browse_callback, devices); ipp_ref = main_ref; DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, browse_callback, devices); ipp_tls_ref = main_ref; DNSServiceBrowse(&ipp_tls_ref, kDNSServiceFlagsShareConnection, 0, "_ipp-tls._tcp", NULL, browse_callback, devices); ipps_ref = main_ref; DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, "_ipps._tcp", NULL, browse_callback, devices); local_fax_ipp_ref = main_ref; DNSServiceBrowse(&local_fax_ipp_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_fax-ipp._tcp", NULL, browse_local_callback, devices); local_ipp_ref = main_ref; DNSServiceBrowse(&local_ipp_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipp._tcp", NULL, browse_local_callback, devices); local_ipp_tls_ref = main_ref; DNSServiceBrowse(&local_ipp_tls_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipp-tls._tcp", NULL, browse_local_callback, devices); local_ipps_ref = main_ref; DNSServiceBrowse(&local_ipps_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipps._tcp", NULL, browse_local_callback, devices); local_printer_ref = main_ref; DNSServiceBrowse(&local_printer_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_printer._tcp", NULL, browse_local_callback, devices); pdl_datastream_ref = main_ref; DNSServiceBrowse(&pdl_datastream_ref, kDNSServiceFlagsShareConnection, 0, "_pdl-datastream._tcp", NULL, browse_callback, devices); printer_ref = main_ref; DNSServiceBrowse(&printer_ref, kDNSServiceFlagsShareConnection, 0, "_printer._tcp", NULL, browse_callback, devices); riousbprint_ref = main_ref; DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0, "_riousbprint._tcp", NULL, browse_callback, devices); #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI if ((simple_poll = avahi_simple_poll_new()) == NULL) { fputs("DEBUG: Unable to create Avahi simple poll object.\n", stderr); return (0); } avahi_simple_poll_set_func(simple_poll, poll_callback, NULL); client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, simple_poll, &error); if (!client) { fputs("DEBUG: Unable to create Avahi client.\n", stderr); return (0); } browsers = 6; avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_fax-ipp._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp-tls._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_pdl-datastream._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_printer._tcp", NULL, 0, browse_callback, devices); #endif /* HAVE_AVAHI */ /* * Loop until we are killed... */ while (!job_canceled) { int announce = 0; /* Announce printers? */ #ifdef HAVE_DNSSD FD_ZERO(&input); FD_SET(fd, &input); timeout.tv_sec = 0; timeout.tv_usec = 500000; if (select(fd + 1, &input, NULL, NULL, &timeout) < 0) continue; if (FD_ISSET(fd, &input)) { /* * Process results of our browsing... */ DNSServiceProcessResult(main_ref); } else announce = 1; #elif defined(HAVE_AVAHI) got_data = 0; if ((error = avahi_simple_poll_iterate(simple_poll, 500)) > 0) { /* * We've been told to exit the loop. Perhaps the connection to * Avahi failed. */ break; } if (!got_data) announce = 1; #endif /* HAVE_DNSSD */ /* fprintf(stderr, "DEBUG: announce=%d\n", announce);*/ if (announce) { /* * Announce any devices we've found... */ #ifdef HAVE_DNSSD DNSServiceErrorType status; /* DNS query status */ #endif /* HAVE_DNSSD */ cups_device_t *best; /* Best matching device */ char device_uri[1024]; /* Device URI */ int count; /* Number of queries */ int sent; /* Number of sent */ for (device = (cups_device_t *)cupsArrayFirst(devices), best = NULL, count = 0, sent = 0; device; device = (cups_device_t *)cupsArrayNext(devices)) { if (device->sent) sent ++; if (device->ref) count ++; if (!device->ref && !device->sent) { /* * Found the device, now get the TXT record(s) for it... */ if (count < 50) { fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName); #ifdef HAVE_DNSSD device->ref = main_ref; status = DNSServiceQueryRecord(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->fullName, kDNSServiceType_TXT, kDNSServiceClass_IN, query_callback, device); if (status != kDNSServiceErr_NoError) fprintf(stderr, "ERROR: Unable to query \"%s\" for TXT records: %d\n", device->fullName, status); /* Users never see this */ else count ++; #else if ((device->ref = avahi_record_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, query_callback, device)) == NULL) fprintf(stderr, "ERROR: Unable to query \"%s\" for TXT records: %s\n", device->fullName, avahi_strerror(avahi_client_errno(client))); /* Users never see this */ else count ++; #endif /* HAVE_AVAHI */ } } else if (!device->sent) { #ifdef HAVE_DNSSD /* * Got the TXT records, now report the device... */ DNSServiceRefDeallocate(device->ref); #else avahi_record_browser_free(device->ref); #endif /* HAVE_DNSSD */ device->ref = NULL; if (!best) best = device; else if (_cups_strcasecmp(best->name, device->name) || _cups_strcasecmp(best->domain, device->domain)) { unquote(uriName, best->fullName, sizeof(uriName)); if (best->uuid) httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s", best->uuid); else httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups" : "/"); cupsBackendReport("network", device_uri, best->make_and_model, best->name, best->device_id, NULL); best->sent = 1; best = device; sent ++; } else if (best->priority > device->priority || (best->priority == device->priority && best->type < device->type)) { best->sent = 1; best = device; sent ++; } else { device->sent = 1; sent ++; } } } if (best) { unquote(uriName, best->fullName, sizeof(uriName)); if (best->uuid) httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s", best->uuid); else httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups" : "/"); cupsBackendReport("network", device_uri, best->make_and_model, best->name, best->device_id, NULL); best->sent = 1; sent ++; } fprintf(stderr, "DEBUG: sent=%d, count=%d\n", sent, count); #ifdef HAVE_AVAHI if (sent == cupsArrayCount(devices) && browsers == 0) #else if (sent == cupsArrayCount(devices)) #endif /* HAVE_AVAHI */ break; } } return (CUPS_BACKEND_OK); }
static int run_server(DaemonConfig *c) { int r = -1; int error; const AvahiPoll *poll_api = NULL; AvahiWatch *sig_watch = NULL; int retval_is_sent = 0; #ifdef HAVE_INOTIFY AvahiWatch *inotify_watch = NULL; #endif #ifdef HAVE_KQUEUE int i; AvahiWatch *kqueue_watch = NULL; #endif assert(c); ignore_signal(SIGPIPE); if (!(nss_support = avahi_nss_support())) avahi_log_warn("WARNING: No NSS support for mDNS detected, consider installing nss-mdns!"); if (!(simple_poll_api = avahi_simple_poll_new())) { avahi_log_error("Failed to create main loop object."); goto finish; } poll_api = avahi_simple_poll_get(simple_poll_api); if (daemon_signal_init(SIGINT, SIGHUP, SIGTERM, SIGUSR1, 0) < 0) { avahi_log_error("Could not register signal handlers (%s).", strerror(errno)); goto finish; } if (!(sig_watch = poll_api->watch_new(poll_api, daemon_signal_fd(), AVAHI_WATCH_IN, signal_callback, simple_poll_api))) { avahi_log_error( "Failed to create signal watcher"); goto finish; } if (simple_protocol_setup(poll_api) < 0) goto finish; #ifdef HAVE_DBUS if (c->enable_dbus) { if (dbus_protocol_setup(poll_api, config.disable_user_service_publishing, config.n_clients_max, config.n_objects_per_client_max, config.n_entries_per_entry_group_max, !c->fail_on_missing_dbus #ifdef ENABLE_CHROOT && !config.use_chroot #endif ) < 0) { avahi_log_warn("WARNING: Failed to contact D-Bus daemon."); if (c->fail_on_missing_dbus) goto finish; } } #endif #ifdef ENABLE_CHROOT if (config.drop_root && config.use_chroot) { if (chroot(AVAHI_CONFIG_DIR) < 0) { avahi_log_error("Failed to chroot(): %s", strerror(errno)); goto finish; } avahi_log_info("Successfully called chroot()."); chdir("/"); if (avahi_caps_drop_all() < 0) { avahi_log_error("Failed to drop capabilities."); goto finish; } avahi_log_info("Successfully dropped remaining capabilities."); } #endif #ifdef HAVE_INOTIFY if ((inotify_fd = inotify_init()) < 0) avahi_log_warn( "Failed to initialize inotify: %s", strerror(errno)); else { add_inotify_watches(); if (!(inotify_watch = poll_api->watch_new(poll_api, inotify_fd, AVAHI_WATCH_IN, inotify_callback, NULL))) { avahi_log_error( "Failed to create inotify watcher"); goto finish; } } #endif #ifdef HAVE_KQUEUE if ((kq = kqueue()) < 0) avahi_log_warn( "Failed to initialize kqueue: %s", strerror(errno)); else { add_kqueue_watches(); if (!(kqueue_watch = poll_api->watch_new(poll_api, kq, AVAHI_WATCH_IN, kqueue_callback, NULL))) { avahi_log_error( "Failed to create kqueue watcher"); goto finish; } } #endif load_resolv_conf(); #ifdef ENABLE_CHROOT static_service_load(config.use_chroot); static_hosts_load(config.use_chroot); #else static_service_load(0); static_hosts_load(0); #endif if (!(avahi_server = avahi_server_new(poll_api, &c->server_config, server_callback, c, &error))) { avahi_log_error("Failed to create server: %s", avahi_strerror(error)); goto finish; } update_wide_area_servers(); update_browse_domains(); if (c->daemonize) { daemon_retval_send(0); retval_is_sent = 1; } for (;;) { if ((r = avahi_simple_poll_iterate(simple_poll_api, -1)) < 0) { /* We handle signals through an FD, so let's continue */ if (errno == EINTR) continue; avahi_log_error("poll(): %s", strerror(errno)); goto finish; } else if (r > 0) /* Quit */ break; } r = 0; finish: static_service_remove_from_server(); static_service_free_all(); static_hosts_remove_from_server(); static_hosts_free_all(); remove_dns_server_entry_groups(); simple_protocol_shutdown(); #ifdef HAVE_DBUS if (c->enable_dbus) dbus_protocol_shutdown(); #endif if (avahi_server) { avahi_server_free(avahi_server); avahi_server = NULL; } daemon_signal_done(); if (sig_watch) poll_api->watch_free(sig_watch); #ifdef HAVE_INOTIFY if (inotify_watch) poll_api->watch_free(inotify_watch); if (inotify_fd >= 0) close(inotify_fd); #endif #ifdef HAVE_KQUEUE if (kqueue_watch) poll_api->watch_free(kqueue_watch); if (kq >= 0) close(kq); for (i = 0; i < num_kfds; i++) { if (kfds[i] >= 0) close(kfds[i]); } #endif if (simple_poll_api) { avahi_simple_poll_free(simple_poll_api); simple_poll_api = NULL; } if (!retval_is_sent && c->daemonize) daemon_retval_send(1); return r; }
void PublishAvahi::worker() { while (active_ && (avahi_simple_poll_iterate(simple_poll, 100) == 0)); }
int wxAvahiSimplePool::Iterate(int sleep_time){ return avahi_simple_poll_iterate(m_pool, sleep_time); }
/* The main function of the background daemon */ static int daemon_proc(const char *host_file, const char *lock_file, int n_slots) { int ret = 1; int lock_fd = -1; struct daemon_data d; time_t clip_time; int error; char machine[64], version[64], stype[128]; rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0); /* Prepare daemon data structure */ d.fd = -1; d.hosts = NULL; d.n_slots = n_slots; d.simple_poll = NULL; d.browser = NULL; d.client = NULL; clip_time = time(NULL); rs_log_info("Zeroconf daemon running.\n"); /* Open daemon lock file and lock it */ if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) { rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno)); goto finish; } if (generic_lock(lock_fd, 1, 1, 0) < 0) { /* lock failed, there's probably already another daemon running */ goto finish; } /* Open host file */ if ((d.fd = open(host_file, O_RDWR|O_CREAT, 0666)) < 0) { rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno)); goto finish; } /* Clear host file */ write_hosts(&d); if (!(d.simple_poll = avahi_simple_poll_new())) { rs_log_crit("Failed to create simple poll object.\n"); goto finish; } if (!(d.client = avahi_client_new( avahi_simple_poll_get(d.simple_poll), 0, client_callback, &d, &error))) { rs_log_crit("Failed to create Avahi client object: %s\n", avahi_strerror(error)); goto finish; } if (dcc_get_gcc_version(version, sizeof(version)) && dcc_get_gcc_machine(machine, sizeof(machine))) { dcc_make_dnssd_subtype(stype, sizeof(stype), version, machine); } else { rs_log_warning("Warning, failed to get CC version and machine type.\n"); strncpy(stype, DCC_DNS_SERVICE_TYPE, sizeof(stype)); stype[sizeof(stype)-1] = 0; } rs_log_info("Browsing for '%s'.\n", stype); if (!(d.browser = avahi_service_browser_new( d.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, stype, NULL, 0, browse_reply, &d))) { rs_log_crit("Failed to create service browser object: %s\n", avahi_strerror(avahi_client_errno(d.client))); goto finish; } /* Check whether the host file has been used recently */ while (fd_last_used(d.fd, clip_time) <= MAX_IDLE_TIME) { /* Iterate the main loop for 5s */ if (avahi_simple_poll_iterate(d.simple_poll, 5000) != 0) { rs_log_crit("Event loop exited abnormaly.\n"); goto finish; } } /* Wer are idle */ rs_log_info("Zeroconf daemon unused.\n"); ret = 0; finish: /* Cleanup */ if (lock_fd >= 0) { generic_lock(lock_fd, 1, 0, 0); close(lock_fd); } if (d.fd >= 0) close(d.fd); while (d.hosts) { struct host *h = d.hosts; d.hosts = d.hosts->next; free_host(h); } if (d.client) avahi_client_free(d.client); if (d.simple_poll) avahi_simple_poll_free(d.simple_poll); rs_log_info("zeroconf daemon ended.\n"); return ret; }
static void init_local (void) { int i; MateVFSResult res; if (!started_local) { AvahiSimplePoll *simple_poll; const AvahiPoll *poll; AvahiClient *client = NULL; AvahiServiceBrowser **sb; struct timeval tv; int error; started_local = TRUE; for (i = 0; i < G_N_ELEMENTS (dns_sd_types); i++) { MateVFSDNSSDBrowseHandle *handle; res = mate_vfs_dns_sd_browse (&handle, "local", dns_sd_types[i].type, local_browse_callback, NULL, NULL); if (res == MATE_VFS_OK) { dns_sd_types[i].handle = handle; } } simple_poll = avahi_simple_poll_new (); if (simple_poll == NULL) { g_warning ("Failed to create simple poll object"); return; } poll = avahi_simple_poll_get (simple_poll); client = avahi_client_new (poll, 0, avahi_client_callback, simple_poll, &error); /* Check wether creating the client object succeeded */ if (client == NULL) { g_warning ("Failed to create client: %s\n", avahi_strerror (error)); avahi_simple_poll_free (simple_poll); return; } sb = g_new0 (AvahiServiceBrowser *, G_N_ELEMENTS (dns_sd_types)); for (i = 0; i < G_N_ELEMENTS (dns_sd_types); i++) { sb[i] = avahi_service_browser_new (client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, dns_sd_types[i].type, "local", AVAHI_LOOKUP_USE_MULTICAST, local_browse_callback_sync, simple_poll); } avahi_elapse_time (&tv, LOCAL_SYNC_BROWSE_DELAY_MSEC, 0); poll->timeout_new (poll, &tv, stop_poll_timeout, (void *)simple_poll); /* Run the main loop util reply or timeout */ for (;;) if (avahi_simple_poll_iterate (simple_poll, -1) != 0) break; for (i = 0; i < G_N_ELEMENTS (dns_sd_types); i++) { if (sb[i] != NULL) { avahi_service_browser_free (sb[i]); } } avahi_client_free (client); avahi_simple_poll_free (simple_poll); }