Exemple #1
0
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;
}
Exemple #2
0
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;
}