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;
}
예제 #2
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;
}
예제 #3
0
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;
  

}
예제 #4
0
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;
}
예제 #5
0
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;
	}
}
예제 #6
0
파일: dnssd.c 프로젝트: zdohnal/cups
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);
}
예제 #7
0
파일: main.c 프로젝트: Dessperado/avahi
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;
}
예제 #8
0
void PublishAvahi::worker()
{
	while (active_ && (avahi_simple_poll_iterate(simple_poll, 100) == 0));
}
예제 #9
0
int wxAvahiSimplePool::Iterate(int sleep_time){
    return avahi_simple_poll_iterate(m_pool, sleep_time);
}
예제 #10
0
/* 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);

					  
	}