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; }
static void g_vfs_dns_sd_resolver_class_init (GVfsDnsSdResolverClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); resolver_supports_mdns = (avahi_nss_support () > 0); gobject_class->get_property = g_vfs_dns_sd_resolver_get_property; gobject_class->set_property = g_vfs_dns_sd_resolver_set_property; gobject_class->finalize = g_vfs_dns_sd_resolver_finalize; gobject_class->constructed = g_vfs_dns_sd_resolver_constructed; /** * GVfsDnsSdResolver::changed: * @resolver: The resolver emitting the signal. * * Emitted when resolved data changes. */ signals[CHANGED] = g_signal_new ("changed", G_VFS_TYPE_DNS_SD_RESOLVER, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GVfsDnsSdResolverClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * GVfsDnsSdResolver:encoded-triple: * * The encoded DNS-SD triple for the resolver. */ g_object_class_install_property (gobject_class, PROP_ENCODED_TRIPLE, g_param_spec_string ("encoded-triple", "Encoded triple", "Encoded triple", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:required-txt-keys: * * A comma separated list of keys that must appear in the TXT * records in order to consider the service being resolved. */ g_object_class_install_property (gobject_class, PROP_REQUIRED_TXT_KEYS, g_param_spec_string ("required-txt-keys", "Required TXT keys", "Required TXT keys", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:service-name: * * The name of the service for the resolver. */ g_object_class_install_property (gobject_class, PROP_SERVICE_NAME, g_param_spec_string ("service-name", "Service Name", "Service Name", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:service-type: * * The type of the service for the resolver. */ g_object_class_install_property (gobject_class, PROP_SERVICE_TYPE, g_param_spec_string ("service-type", "Service Type", "Service Type", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:domain: * * The domain for the resolver. */ g_object_class_install_property (gobject_class, PROP_DOMAIN, g_param_spec_string ("domain", "Domain", "Domain", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:timeout-msec: * * Timeout in milliseconds to use when resolving. */ g_object_class_install_property (gobject_class, PROP_TIMEOUT_MSEC, g_param_spec_uint ("timeout-msec", "Timeout in milliseconds", "Timeout in milliseconds", 0, G_MAXUINT, 5000, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:is-resolved: * * Whether the service is resolved. */ g_object_class_install_property (gobject_class, PROP_IS_RESOLVED, g_param_spec_boolean ("is-resolved", "Is resolved", "Is resolved", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:address: * * The resolved address. */ g_object_class_install_property (gobject_class, PROP_DOMAIN, g_param_spec_string ("address", "Address", "Address", NULL, G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:port: * * The resolved port. */ g_object_class_install_property (gobject_class, PROP_PORT, g_param_spec_uint ("port", "Port", "Port", 0, 65536, 0, G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); /** * GVfsDnsSdResolver:txt-records: * * The resolved TXT records. */ g_object_class_install_property (gobject_class, PROP_TXT_RECORDS, g_param_spec_boxed ("txt-records", "TXT Records", "TXT Records", G_TYPE_STRV, G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); }
int main(int argc, char*argv[]) { GtkWidget *d; gtk_init(&argc, &argv); if (g_str_has_suffix(argv[0], "bvnc")) { d = aui_service_dialog_new("Choose VNC server", NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL); aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(d), "_rfb._tcp", NULL); } else { d = aui_service_dialog_new("Choose SSH server", NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL); aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(d), "_ssh._tcp", NULL); } aui_service_dialog_set_resolve_service(AUI_SERVICE_DIALOG(d), TRUE); aui_service_dialog_set_resolve_host_name(AUI_SERVICE_DIALOG(d), !avahi_nss_support()); gtk_window_present(GTK_WINDOW(d)); if (gtk_dialog_run(GTK_DIALOG(d)) == GTK_RESPONSE_ACCEPT) { char a[AVAHI_ADDRESS_STR_MAX], *u = NULL, *n = NULL; char *h = NULL, *t = NULL; const AvahiStringList *txt; t = g_strdup(aui_service_dialog_get_service_type(AUI_SERVICE_DIALOG(d))); n = g_strdup(aui_service_dialog_get_service_name(AUI_SERVICE_DIALOG(d))); if (avahi_nss_support()) h = g_strdup(aui_service_dialog_get_host_name(AUI_SERVICE_DIALOG(d))); else h = g_strdup(avahi_address_snprint(a, sizeof(a), aui_service_dialog_get_address(AUI_SERVICE_DIALOG(d)))); g_print("Connecting to '%s' ...\n", n); if (avahi_domain_equal(t, "_rfb._tcp")) { char p[AVAHI_DOMAIN_NAME_MAX+16]; snprintf(p, sizeof(p), "%s:%u", h, aui_service_dialog_get_port(AUI_SERVICE_DIALOG(d))-5900); gtk_widget_destroy(d); g_print("xvncviewer %s\n", p); execlp("xvncviewer", "xvncviewer", p, NULL); } else { char p[16]; snprintf(p, sizeof(p), "%u", aui_service_dialog_get_port(AUI_SERVICE_DIALOG(d))); for (txt = aui_service_dialog_get_txt_data(AUI_SERVICE_DIALOG(d)); txt; txt = txt->next) { char *key, *value; if (avahi_string_list_get_pair((AvahiStringList*) txt, &key, &value, NULL) < 0) break; if (strcmp(key, "u") == 0) u = g_strdup(value); avahi_free(key); avahi_free(value); } gtk_widget_destroy(d); if (u) { g_print("ssh -p %s -l %s %s\n", p, u, h); if (isatty(0) || !getenv("DISPLAY")) execlp("ssh", "ssh", "-p", p, "-l", u, h, NULL); else { execlp("x-terminal-emulator", "x-terminal-emulator", "-T", n, "-e", "ssh", "-p", p, "-l", u, h, NULL); execlp("gnome-terminal", "gnome-terminal", "-t", n, "-x", "ssh", "-p", p, "-l", u, h, NULL); execlp("xterm", "xterm", "-T", n, "-e", "ssh", "-p", p, "-l", u, h, NULL); } } else { g_print("ssh -p %s %s\n", p, h); if (isatty(0) || !getenv("DISPLAY")) execlp("ssh", "ssh", "-p", p, h, NULL); else { execlp("x-terminal-emulator", "x-terminal-emulator", "-T", n, "-e", "ssh", "-p", p, h, NULL); execlp("gnome-terminal", "gnome-terminal", "-t", n, "-x", "ssh", "-p", p, h, NULL); execlp("xterm", "xterm", "-T", n, "-e", "ssh", "-p", p, h, NULL); } } } g_warning("execlp() failed: %s\n", strerror(errno)); g_free(h); g_free(u); g_free(t); g_free(n); } else { gtk_widget_destroy(d); g_print("Canceled.\n"); } return 1; }
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { printf("NSS Support available: %s\n", avahi_nss_support() ? "yes" : "no"); return 0; }