/*** This file is part of avahi. avahi is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. avahi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with avahi; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "avahi-ui.h" typedef enum { COMMAND_HELP, COMMAND_SSH, COMMAND_VNC, COMMAND_SHELL } Command; typedef struct Config { char *domain; Command command; } Config; static void help(FILE *f, const char *argv0) { fprintf(f, _("%s [options]\n\n" " -h --help Show this help\n" " -s --ssh Browse SSH servers\n" " -v --vnc Browse VNC servers\n" " -S --shell Browse both SSH and VNC\n" " -d --domain=DOMAIN The domain to browse in\n"), argv0); } static int parse_command_line(Config *c, int argc, char *argv[]) { int o; static const struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "ssh", no_argument, NULL, 's' }, { "vnc", no_argument, NULL, 'v' }, { "shell", no_argument, NULL, 'S' }, { "domain", required_argument, NULL, 'd' }, { NULL, 0, NULL, 0 } }; while ((o = getopt_long(argc, argv, "hVd:svS", long_options, NULL)) >= 0) { switch(o) { case 'h': c->command = COMMAND_HELP; break; case 's': c->command = COMMAND_SSH; break; case 'v': c->command = COMMAND_VNC; break; case 'S': c->command = COMMAND_SHELL; break; case 'd': avahi_free(c->domain); c->domain = avahi_strdup(optarg); break; default: return -1; } } if (optind < argc) { fprintf(stderr, _("Too many arguments\n")); return -1; } return 0; } int main(int argc, char*argv[]) { GtkWidget *d; Config config; const char *argv0; avahi_init_i18n(); setlocale(LC_ALL, ""); if ((argv0 = strrchr(argv[0], '/'))) argv0++; else argv0 = argv[0]; if (g_str_has_suffix(argv[0], "bshell")) config.command = COMMAND_SHELL; else if (g_str_has_suffix(argv[0], "bvnc")) config.command = COMMAND_VNC; else config.command = COMMAND_SSH; /* defaults to local */ config.domain = NULL; if (parse_command_line(&config, argc, argv) < 0) { help(stderr, argv0); return 1; } bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); gtk_init(&argc, &argv); switch (config.command) { case COMMAND_HELP: help(stdout, argv0); return 0; break; case COMMAND_SHELL: d = aui_service_dialog_new(_("Choose Shell 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", "_ssh._tcp", NULL); aui_service_dialog_set_service_type_name(AUI_SERVICE_DIALOG(d), "_rfb._tcp", _("Desktop")); aui_service_dialog_set_service_type_name(AUI_SERVICE_DIALOG(d), "_ssh._tcp", _("Terminal")); break; case COMMAND_VNC: 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); break; case COMMAND_SSH: 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); break; } aui_service_dialog_set_domain (AUI_SERVICE_DIALOG(d), config.domain); 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("vncviewer %s\n", p); execlp("xvncviewer", "xvncviewer", p, NULL); execlp("vncviewer", "vncviewer", 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")); } g_free(config.domain); return 1; }