コード例 #1
0
ファイル: avahi.c プロジェクト: clcarwin/x11vnc
void avahi_initialise(void) {
	int ret;
	static int first = 1;

	if (getenv("AVAHI_DEBUG")) {
		db = 1;
	}
	if (first) {
		int i;
		for (i=0; i<NREG; i++) {
			registered[i].name = NULL;
			registered[i].host = NULL;
		}
		first = 0;
	}

if (db) fprintf(stderr, "in  avahi_initialise\n");
	if (_poll) {
if (db) fprintf(stderr, "    avahi_initialise: poll not null\n");
		return;
	}

	if (! (_poll = avahi_threaded_poll_new()) ) {
		rfbLog("warning: unable to open Avahi poll.\n");
		return;
	}

	_client = avahi_client_new(avahi_threaded_poll_get(_poll),
	    0, NULL, NULL, &ret);
	if (! _client) {
		rfbLog("warning: unable to open Avahi client: %s\n",
		    avahi_strerror(ret));

		avahi_threaded_poll_free(_poll);
		_poll = NULL;
		return;
	}

	if (avahi_threaded_poll_start(_poll) < 0) {
		rfbLog("warning: unable to start Avahi poll.\n");
		avahi_client_free(_client);
		_client = NULL;
		avahi_threaded_poll_free(_poll);
		_poll = NULL;
		return;
	}
if (db) fprintf(stderr, "out avahi_initialise\n");
}
コード例 #2
0
ファイル: avahi.c プロジェクト: clcarwin/x11vnc
void avahi_cleanup(void) {
if (db) fprintf(stderr, "in  avahi_cleanup\n");
	if (!_client) {
if (db) fprintf(stderr, "    avahi_cleanup client null\n");
		return;
	}
if (db) fprintf(stderr, "    avahi_cleanup poll_lock\n");
	avahi_threaded_poll_lock(_poll);
if (db) fprintf(stderr, "    avahi_cleanup poll_stop\n");

	signal(SIGALRM, avahi_timeout);
	alarm(3);
	avahi_threaded_poll_stop(_poll);
	alarm(0);
	signal(SIGALRM, SIG_DFL);

if (db) fprintf(stderr, "    avahi_cleanup client_free\n");
	avahi_client_free(_client);
	_client = NULL;

if (db) fprintf(stderr, "    avahi_cleanup poll_free\n");
	avahi_threaded_poll_free(_poll);
	_poll = NULL;
if (db) fprintf(stderr, "out avahi_cleanup\n");
}
コード例 #3
0
ファイル: ZeroconfAvahi.cpp プロジェクト: Alxandr/spotyxbmc2
CZeroconfAvahi::~CZeroconfAvahi()
{
  CLog::Log(LOGDEBUG, "CZeroconfAvahi::~CZeroconfAvahi() Going down! cleaning up...");

  if (mp_poll)
  {
    //normally we would stop the avahi thread here and do our work, but
    //it looks like this does not work -> www.avahi.org/ticket/251
    //so instead of calling
    //avahi_threaded_poll_stop(mp_poll);
    //we set m_shutdown=true, post an event and wait for it to stop itself
    struct timeval tv = { 0, 0 }; //TODO: does tv survive the thread?
    AvahiTimeout* lp_timeout;
    {
      ScopedEventLoopBlock l_block(mp_poll);
      const AvahiPoll* cp_apoll = avahi_threaded_poll_get(mp_poll);
      m_shutdown = true;
      lp_timeout = cp_apoll->timeout_new(cp_apoll,
                                         &tv,
                                         shutdownCallback,
                                         this);
    }

    //now wait for the thread to stop
    assert(m_thread_id);
    pthread_join(m_thread_id, NULL);
    avahi_threaded_poll_get(mp_poll)->timeout_free(lp_timeout);
  }

  //free the client (frees all browsers, groups, ...)
  if (mp_client)
    avahi_client_free(mp_client);
  if (mp_poll)
    avahi_threaded_poll_free(mp_poll);
}
コード例 #4
0
Publisher::~Publisher() {
	stop();
	if (client)
		avahi_client_free(client);
	if (poller)
		avahi_threaded_poll_free( poller);
}
コード例 #5
0
void dns_service_publisher_cleanup( void )
{
	if( group )
	{
		avahi_entry_group_free( group );
		group = NULL;
	}

	if( client)
	{
		avahi_client_free( client );
		client = NULL;
	}

	if( threaded_poll )
	{
		avahi_threaded_poll_free( threaded_poll );
		threaded_poll = NULL;
	}

	if( sd_name_copy )
	{
		avahi_free( sd_name_copy );
		sd_name_copy = NULL;
	}

	if( sd_service_copy )
	{
		avahi_free( sd_service_copy );
		sd_service_copy = NULL;
	}
}
コード例 #6
0
ファイル: Rendezvous.cpp プロジェクト: 8c6794b6/supercollider
AvahiSession::AvahiSession()
	: mPoll(0),
	  mClient(0),
	  mGroup(0),
	  mEntries(0),
	  mServiceName(0)
{
	int err;

	mServiceName = avahi_strdup(kSCRendezvousServiceName);

	mPoll = avahi_threaded_poll_new();
	if (!mPoll) {
		scprintf("Zeroconf: failed to create poll API\n");
		return;
	}

	mClient = avahi_client_new(
		avahi_threaded_poll_get(mPoll),
		(AvahiClientFlags)0, client_cb, this, &err);
	if (!mClient) {
		scprintf("Zeroconf: failed to create client: %s\n", avahi_strerror(err));
		avahi_threaded_poll_free(mPoll);
		mPoll = 0;
		return;
	}

	avahi_threaded_poll_start(mPoll);
}
コード例 #7
0
ファイル: AvahiQuerier.cpp プロジェクト: jakjothi/swift
void AvahiQuerier::stop() {
    assert(threadedPoll);
    avahi_threaded_poll_stop(threadedPoll);
    assert(client);
    avahi_client_free(client);
    avahi_threaded_poll_free(threadedPoll);
}
コード例 #8
0
ファイル: avahi.c プロジェクト: chouquette/vlc
/*****************************************************************************
 * Open: initialize and create stuff
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    services_discovery_t *p_sd = ( services_discovery_t* )p_this;
    services_discovery_sys_t *p_sys;
    int err;

    p_sd->p_sys = p_sys = calloc( 1, sizeof( services_discovery_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    p_sd->description = _("Zeroconf network services");

    vlc_dictionary_init( &p_sys->services_name_to_input_item, 1 );

    p_sys->poll = avahi_threaded_poll_new();
    if( p_sys->poll == NULL )
    {
        msg_Err( p_sd, "failed to create Avahi threaded poll" );
        goto error;
    }

    p_sys->client = avahi_client_new( avahi_threaded_poll_get(p_sys->poll),
                                      0, client_callback, p_sd, &err );
    if( p_sys->client == NULL )
    {
        msg_Err( p_sd, "failed to create avahi client: %s",
                 avahi_strerror( err ) );
        goto error;
    }

    for( unsigned i = 0; i < NB_PROTOCOLS; i++ )
    {
        AvahiServiceBrowser *sb;
        sb = avahi_service_browser_new( p_sys->client, AVAHI_IF_UNSPEC,
                AVAHI_PROTO_UNSPEC,
                protocols[i].psz_service_name, NULL,
                0, browse_callback, p_sd );
        if( sb == NULL )
        {
            msg_Err( p_sd, "failed to create avahi service browser %s", avahi_strerror( avahi_client_errno(p_sys->client) ) );
            goto error;
        }
    }

    avahi_threaded_poll_start( p_sys->poll );

    return VLC_SUCCESS;

error:
    if( p_sys->client != NULL )
        avahi_client_free( p_sys->client );
    if( p_sys->poll != NULL )
        avahi_threaded_poll_free( p_sys->poll );

    vlc_dictionary_clear( &p_sys->services_name_to_input_item, NULL, NULL );
    free( p_sys );

    return VLC_EGENERIC;
}
コード例 #9
0
ファイル: bonjour.c プロジェクト: FLYKingdom/vlc
/*****************************************************************************
 * Open: initialize and create stuff
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    services_discovery_t *p_sd = ( services_discovery_t* )p_this;
    services_discovery_sys_t *p_sys;
    int err;

    p_sd->p_sys = p_sys = calloc( 1, sizeof( services_discovery_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    vlc_dictionary_init( &p_sys->services_name_to_input_item, 1 );

    p_sys->poll = avahi_threaded_poll_new();
    if( p_sys->poll == NULL )
    {
        msg_Err( p_sd, "failed to create Avahi threaded poll" );
        goto error;
    }

    p_sys->client = avahi_client_new( avahi_threaded_poll_get(p_sys->poll),
                                      0, client_callback, p_sd, &err );
    if( p_sys->client == NULL )
    {
        msg_Err( p_sd, "failed to create avahi client: %s",
                 avahi_strerror( err ) );
        goto error;
    }

    p_sys->sb = avahi_service_browser_new( p_sys->client, AVAHI_IF_UNSPEC,
                                           AVAHI_PROTO_UNSPEC,
                                           "_vlc-http._tcp", NULL,
                                           0, browse_callback, p_sd );
    if( p_sys->sb == NULL )
    {
        msg_Err( p_sd, "failed to create avahi service browser" );
        goto error;
    }

    return VLC_SUCCESS;

error:
    if( p_sys->sb != NULL )
        avahi_service_browser_free( p_sys->sb );
    if( p_sys->client != NULL )
        avahi_client_free( p_sys->client );
    if( p_sys->poll != NULL )
        avahi_threaded_poll_free( p_sys->poll );

    vlc_dictionary_clear( &p_sys->services_name_to_input_item, NULL, NULL );
    free( p_sys );

    return VLC_EGENERIC;
}
コード例 #10
0
ファイル: bonjour.c プロジェクト: FLYKingdom/vlc
/*****************************************************************************
 * Close: cleanup
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    services_discovery_t *p_sd = ( services_discovery_t* )p_this;
    services_discovery_sys_t *p_sys = p_sd->p_sys;

    avahi_service_browser_free( p_sys->sb );
    avahi_client_free( p_sys->client );
    avahi_threaded_poll_free( p_sys->poll );

    vlc_dictionary_clear( &p_sys->services_name_to_input_item, NULL, NULL );
    free( p_sys );
}
コード例 #11
0
ファイル: avahi.c プロジェクト: t-yuki/cups-connector
// startAvahiClient initializes a poll object, and a client.
const char *startAvahiClient(AvahiThreadedPoll **threaded_poll, AvahiClient **client) {
  *threaded_poll = avahi_threaded_poll_new();
  if (!*threaded_poll) {
    return avahi_strerror(avahi_client_errno(*client));
  }

  int error;
  *client = avahi_client_new(avahi_threaded_poll_get(*threaded_poll),
      AVAHI_CLIENT_NO_FAIL, handleClientStateChange, NULL, &error);
  if (!*client) {
    avahi_threaded_poll_free(*threaded_poll);
    return avahi_strerror(error);
  }

  error = avahi_threaded_poll_start(*threaded_poll);
  if (AVAHI_OK != error) {
    avahi_client_free(*client);
    avahi_threaded_poll_free(*threaded_poll);
    return avahi_strerror(error);
  }
  return NULL;
}
コード例 #12
0
ファイル: dirsvc.c プロジェクト: AndychenCL/cups
static void
dnssdStop(void)
{
  cupsd_printer_t	*p;		/* Current printer */


 /*
  * De-register the individual printers
  */

  for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
       p;
       p = (cupsd_printer_t *)cupsArrayNext(Printers))
    dnssdDeregisterPrinter(p, 1, 0);

 /*
  * Shutdown the rest of the service refs...
  */

  dnssdDeregisterInstance(&WebIFSrv, 0);

#  ifdef HAVE_DNSSD
  cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDMaster));

  DNSServiceRefDeallocate(DNSSDMaster);
  DNSSDMaster = NULL;

#  else /* HAVE_AVAHI */
  if (DNSSDMaster)
    avahi_threaded_poll_stop(DNSSDMaster);

  if (DNSSDClient)
  {
    avahi_client_free(DNSSDClient);
    DNSSDClient = NULL;
  }

  if (DNSSDMaster)
  {
    avahi_threaded_poll_free(DNSSDMaster);
    DNSSDMaster = NULL;
  }
#  endif /* HAVE_DNSSD */

  cupsArrayDelete(DNSSDPrinters);
  DNSSDPrinters = NULL;

  DNSSDPort = 0;
}
コード例 #13
0
ファイル: afp_avahi.c プロジェクト: Netatalk/Netatalk
/*
 * Tries to shutdown this loop impl.
 * Call this function from inside this thread.
 */
int av_zeroconf_unregister() {
    LOG(log_debug, logtype_afpd, "av_zeroconf_unregister");

    if (ctx) {
        if (ctx->threaded_poll)
            avahi_threaded_poll_stop(ctx->threaded_poll);
        if (ctx->client)
            avahi_client_free(ctx->client);
        if (ctx->threaded_poll)
            avahi_threaded_poll_free(ctx->threaded_poll);
        free(ctx);
        ctx = NULL;
    }
    return 0;
}
コード例 #14
0
ファイル: Rendezvous.cpp プロジェクト: 8c6794b6/supercollider
AvahiSession::~AvahiSession()
{
	if (mClient) {
		avahi_threaded_poll_stop(mPoll);
		avahi_client_free(mClient);
		avahi_threaded_poll_free(mPoll);
		AvahiEntry* entry = mEntries;
		while (entry) {
			AvahiEntry* next = entry->mNext;
			delete entry;
			entry = next;
		}
	}
	free(mServiceName);
}
コード例 #15
0
ファイル: avahi.c プロジェクト: leigh123linux/minidlna
/*
 * Tries to shutdown this loop impl.
 * Call this function from inside this thread.
 */
void tivo_bonjour_unregister(void)
{
	DPRINTF(E_DEBUG, L_SSDP, "tivo_bonjour_unregister\n");

	if (ctx.group)
	{
		avahi_entry_group_reset(ctx.group);
		avahi_entry_group_free(ctx.group);
	}
	if (ctx.threaded_poll)
		avahi_threaded_poll_stop(ctx.threaded_poll);
	if (ctx.client)
		avahi_client_free(ctx.client);
	if (ctx.threaded_poll)
		avahi_threaded_poll_free(ctx.threaded_poll);
}
コード例 #16
0
ファイル: mdns_avahi.c プロジェクト: kwasmich/shairport-sync
void avahi_dacp_dont_monitor(rtsp_conn_info *conn) {
  dacp_browser_struct *dbs = (dacp_browser_struct *)conn->mdns_private_pointer;
  if (dbs) {
    // stop and dispose of everything
    if ((dbs)->service_poll)
      avahi_threaded_poll_stop((dbs)->service_poll);
    if ((dbs)->service_browser)
      avahi_service_browser_free((dbs)->service_browser);
    if ((dbs)->service_client)
      avahi_client_free((dbs)->service_client);
    if ((dbs)->service_poll)
      avahi_threaded_poll_free((dbs)->service_poll);
    free((char *)(dbs));
    conn->mdns_private_pointer = NULL;
  } else {
    debug(1, "DHCP Monitor is not running.");
  }
}
コード例 #17
0
ファイル: dnssd.c プロジェクト: tillkamppeter/ippusbxd
void
dnssd_shutdown() {

  if (g_options.dnssd_data->DNSSDMaster) {
    avahi_threaded_poll_stop(g_options.dnssd_data->DNSSDMaster);
    dnssd_unregister();
  }

  if (g_options.dnssd_data->DNSSDClient) {
    avahi_client_free(g_options.dnssd_data->DNSSDClient);
    g_options.dnssd_data->DNSSDClient = NULL;
  }

  if (g_options.dnssd_data->DNSSDMaster) {
    avahi_threaded_poll_free(g_options.dnssd_data->DNSSDMaster);
    g_options.dnssd_data->DNSSDMaster = NULL;
  }

  free(g_options.dnssd_data);
  NOTE("DNS-SD shut down.");
}
コード例 #18
0
/* Unregister this server from DNS-SD/mDNS */
int dcc_zeroconf_unregister(void *u) {
    struct context *ctx = u;

    if (ctx->threaded_poll)
        avahi_threaded_poll_stop(ctx->threaded_poll);

    if (ctx->client)
        avahi_client_free(ctx->client);

    if (ctx->threaded_poll)
        avahi_threaded_poll_free(ctx->threaded_poll);

    if (ctx->name)
        avahi_free(ctx->name);

    if (ctx->service_type)
        free(ctx->service_type);

    free(ctx);

    return 0;
}
コード例 #19
0
ファイル: dirsvc.c プロジェクト: AndychenCL/cups
void
cupsdStartBrowsing(void)
{
  if (!Browsing || !BrowseLocalProtocols)
    return;

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
  if (BrowseLocalProtocols & BROWSE_DNSSD)
  {
#  ifdef HAVE_DNSSD
    DNSServiceErrorType error;		/* Error from service creation */

   /*
    * First create a "master" connection for all registrations...
    */

    if ((error = DNSServiceCreateConnection(&DNSSDMaster))
	    != kDNSServiceErr_NoError)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR,
		      "Unable to create master DNS-SD reference: %d", error);

      if (FatalErrors & CUPSD_FATAL_BROWSE)
	cupsdEndProcess(getpid(), 0);
    }
    else
    {
     /*
      * Add the master connection to the select list...
      */

      int fd = DNSServiceRefSockFD(DNSSDMaster);

      fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);

      cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
    }

   /*
    * Set the computer name and register the web interface...
    */

    DNSSDPort = 0;
    cupsdUpdateDNSSDName();

#  else /* HAVE_AVAHI */
    if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");

      if (FatalErrors & CUPSD_FATAL_BROWSE)
	cupsdEndProcess(getpid(), 0);
    }
    else
    {
      int error;			/* Error code, if any */

      DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);

      if (DNSSDClient == NULL)
      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Unable to communicate with avahi-daemon: %s",
                        dnssdErrorString(error));

        if (FatalErrors & CUPSD_FATAL_BROWSE)
	  cupsdEndProcess(getpid(), 0);

        avahi_threaded_poll_free(DNSSDMaster);
        DNSSDMaster = NULL;
      }
      else
	avahi_threaded_poll_start(DNSSDMaster);
    }
#  endif /* HAVE_DNSSD */
  }
#endif /* HAVE_DNSSD || HAVE_AVAHI */

 /*
  * Enable LPD and SMB printer sharing as needed through external programs...
  */

  if (BrowseLocalProtocols & BROWSE_LPD)
    update_lpd(1);

  if (BrowseLocalProtocols & BROWSE_SMB)
    update_smb(1);

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
 /*
  * Register the individual printers
  */

  dnssdRegisterAllPrinters(0);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
コード例 #20
0
ファイル: pool.cpp プロジェクト: stahta01/wxCode_components
wxAvahiThreadPool::~wxAvahiThreadPool(){
    if(m_pool!=NULL)
        avahi_threaded_poll_free(m_pool);
}
コード例 #21
0
ファイル: avahi.c プロジェクト: t-yuki/cups-connector
void stopAvahiClient(AvahiThreadedPoll *threaded_poll, AvahiClient *client) {
  avahi_threaded_poll_stop(threaded_poll);
  avahi_client_free(client);
  avahi_threaded_poll_free(threaded_poll);
}
コード例 #22
0
ファイル: mdns_avahi.c プロジェクト: kwasmich/shairport-sync
int avahi_dacp_monitor(rtsp_conn_info *conn) {

  dacp_browser_struct *dbs = (dacp_browser_struct *)malloc(sizeof(dacp_browser_struct));
  

  if (dbs == NULL)
    die("can not allocate a dacp_browser_struct.");
    
  conn->mdns_private_pointer = (void *)dbs;

  // create the threaded poll code
  int err;
  if (!(dbs->service_poll = avahi_threaded_poll_new())) {
    warn("couldn't create avahi threaded service_poll!");
    if (dbs) {
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }

  // create the service client
  if (!(dbs->service_client =
            avahi_client_new(avahi_threaded_poll_get(dbs->service_poll), AVAHI_CLIENT_NO_FAIL,
                             service_client_callback, (void *)conn, &err))) {
    warn("couldn't create avahi service client: %s!", avahi_strerror(err));
    if (dbs) { // should free the threaded poll code
      avahi_threaded_poll_free(dbs->service_poll);
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }

  /* Create the service browser */
  if (!(dbs->service_browser =
            avahi_service_browser_new(dbs->service_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
                                      "_dacp._tcp", NULL, 0, browse_callback, (void *)conn))) {
    warn("Failed to create service browser: %s\n",
         avahi_strerror(avahi_client_errno(dbs->service_client)));
    if (dbs) { // should free the threaded poll code and the service client
      avahi_client_free(dbs->service_client);
      avahi_threaded_poll_free(dbs->service_poll);
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }
  // start the polling thread
  if (avahi_threaded_poll_start(dbs->service_poll) < 0) {
    warn("couldn't start avahi service_poll thread");
    if (dbs) { // should free the threaded poll code and the service client and the service browser
      avahi_service_browser_free(dbs->service_browser);
      avahi_client_free(dbs->service_client);
      avahi_threaded_poll_free(dbs->service_poll);
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }
  return 0;
}
コード例 #23
0
ファイル: tivod.c プロジェクト: paul-chambers/tivod
int main( AVAHI_GCC_UNUSED int argc, char *argv[] )
{
    AvahiClient *client = NULL;
    AvahiServiceBrowser *serviceBrowser = NULL;
    char       *myName;
    int         error;
    int         result = 1;
    TiVoUnit   *tivo;

    myName = strrchr(argv[0], '/') + 1;
    if (myName == (NULL+1))
        myName = argv[0];

    openlog( myName, LOG_PID, LOG_DAEMON );
    loginfo("started");

    /* must be done before any threads start */
    curl_global_init( CURL_GLOBAL_ALL );

    /* Allocate main loop object */
    bonjourThread = avahi_threaded_poll_new();
    if ( !bonjourThread )
    {
        logerror( "Failed to create threaded poll object." );
    }
    else
    {
        /* Allocate a new client */
        client = avahi_client_new( avahi_threaded_poll_get( bonjourThread ), 0, client_callback, NULL, &error );

        /* Check wether creating the client object succeeded */
        if ( !client )
        {
            logerror( "Unable to create client: %s", avahi_strerror( error ) );
        }
        else
        {
            /* Create the service browser */
            serviceBrowser = avahi_service_browser_new( client,
                                                        AVAHI_IF_UNSPEC,
                                                        AVAHI_PROTO_UNSPEC,
                                                        "_tivo-device._tcp",
                                                        NULL, 0,
                                                        browseCallback, client );
            if ( !serviceBrowser )
            {
                logerror( "Unable to create service browser: %s", avahi_strerror( avahi_client_errno( client ) ) );
            }
            else
            {
                /* start the background network scan for TiVos */
                avahi_threaded_poll_start( bonjourThread );

                /* hack: wait for some results to arrive */
                sleep(5);
                /* what did we find? */
                result = dumpTiVos();

                avahi_threaded_poll_stop( bonjourThread );
                avahi_service_browser_free( serviceBrowser );
            }
            avahi_client_free( client );
        }
        avahi_threaded_poll_free( bonjourThread );
    }

    /* docs say no other threads may be running */
    curl_global_cleanup();

    loginfo( "stopped" );
    closelog();

    return result;
}