void avahi_dbus_service_type_browser_free(ServiceTypeBrowserInfo *i) {
    assert(i);

    if (i->service_type_browser)
        avahi_s_service_type_browser_free(i->service_type_browser);
    dbus_connection_unregister_object_path(server->bus, i->path);
    avahi_free(i->path);
    AVAHI_LLIST_REMOVE(ServiceTypeBrowserInfo, service_type_browsers, i->client->service_type_browsers, i);

    i->client->n_objects--;
    assert(i->client->n_objects >= 0);

    avahi_free(i);
}
static void start_server(AvahiTimeout *t, void *userdata) {
  int error;
  
  assert(t);
  
  if (stb) {
    DEBUG("Service type browser already exists");
    avahi_s_service_type_browser_free(stb);
    stb = NULL;
  }
  
  if (server) {
    DEBUG("Server already exists");
    avahi_server_free(server);
    server = NULL;
  }
  
  /* Allocate a new server */
  server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, server_callback, NULL, &error);
  
  /* Check whether creating the server object succeeded */
  if (!server) {
    ERROR("Failed to create server: %s", avahi_strerror(error));
    avahi_simple_poll_quit(simple_poll);
    return;
  }
  
  /* every UPDATE_INTERVAL seconds, shut down and re-create server. This
   * has the benefit of causing CSM to send queries to other nodes, prompting
   * them to re-multicast their services. This is done because mDNS seems to
   * be very unreliable on mesh, and often nodes don't get service announcements
   * or can't resolve them. */
  struct timeval tv = {0};
  avahi_elapse_time(&tv, 1000*UPDATE_INTERVAL, 0);
  avahi_simple_poll_get(simple_poll)->timeout_update(t, &tv);
}
int main(int argc, char*argv[]) {
    int ret = 1;

    argp_program_version = "1.0";
    static char doc[] = "Commotion Service Manager";
    static struct argp_option options[] = {
      {"bind", 'b', "URI", 0, "commotiond management socket"},
      {"nodaemon", 'n', 0, 0, "Do not fork into the background" },
      {"out", 'o', "FILE", 0, "Output file to write services to when USR1 signal is received" },
      {"pid", 'p', "FILE", 0, "Specify PID file"},
#ifdef USE_UCI
      {"uci", 'u', 0, 0, "Store service cache in UCI" },
#endif
      { 0 }
    };
    
    /* Set defaults */
    arguments.co_sock = DEFAULT_CO_SOCK;
#ifdef USE_UCI
    arguments.uci = 0;
#endif
    arguments.nodaemon = 0;
    arguments.output_file = DEFAULT_FILENAME;
    arguments.pid_file = PIDFILE;
    
    static struct argp argp = { options, parse_opt, NULL, doc };
    
    argp_parse (&argp, argc, argv, 0, 0, &arguments);
    //fprintf(stdout,"uci: %d, out: %s\n",arguments.uci,arguments.output_file);
    
    if (!arguments.nodaemon)
      daemon_start(arguments.pid_file);
    
    CHECK(co_init(),"Failed to initialize Commotion client");
    
    struct sigaction sa = {0};
    sa.sa_handler = print_services;
    CHECK(sigaction(SIGUSR1,&sa,NULL) == 0, "Failed to set signal handler");
    sa.sa_handler = shutdown;
    CHECK(sigaction(SIGINT,&sa,NULL) == 0, "Failed to set signal handler");
    CHECK(sigaction(SIGTERM,&sa,NULL) == 0, "Failed to set signal handler");

    /* Initialize the psuedo-RNG */
    srand(time(NULL));

    /* Allocate main loop object */
    CHECK((simple_poll = avahi_simple_poll_new()),"Failed to create simple poll object.");

    /* Do not publish any local records */
    avahi_server_config_init(&config);
    config.publish_hinfo = 0;
    config.publish_addresses = 0;
    config.publish_workstation = 0;
    config.publish_domain = 0;

    /* Set a unicast DNS server for wide area DNS-SD */
    avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &config.wide_area_servers[0]);
    config.n_wide_area_servers = 1;
    config.enable_wide_area = 1;

    // Start timer to create server
    struct timeval tv = {0};
    avahi_elapse_time(&tv, 0, 0);
    avahi_simple_poll_get(simple_poll)->timeout_new(avahi_simple_poll_get(simple_poll), &tv, start_server, NULL); // create expiration event for service
    
    /* Run the main loop */
    avahi_simple_poll_loop(simple_poll);
    
    ret = 0;

error:

    /* Free the configuration data */
    avahi_server_config_free(&config);

    co_shutdown();

    /* Cleanup things */
    if (stb)
        avahi_s_service_type_browser_free(stb);

    if (server)
        avahi_server_free(server);
    
    if (simple_poll)
        avahi_simple_poll_free(simple_poll);

    return ret;
}