1/*** 2 This file is part of avahi. 3 4 avahi is free software; you can redistribute it and/or modify it 5 under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 2.1 of the 7 License, or (at your option) any later version. 8 9 avahi is distributed in the hope that it will be useful, but WITHOUT 10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 12 Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with avahi; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 17 USA. 18***/ 19 20#ifdef HAVE_CONFIG_H 21#include <config.h> 22#endif 23 24#include <string.h> 25#include <unistd.h> 26#include <errno.h> 27#include <stdlib.h> 28#include <locale.h> 29#include <getopt.h> 30 31#include <gtk/gtk.h> 32 33#include <avahi-client/client.h> 34#include <avahi-common/strlst.h> 35#include <avahi-common/malloc.h> 36#include <avahi-common/domain.h> 37#include <avahi-common/i18n.h> 38 39#include "avahi-ui.h" 40 41typedef enum { 42 COMMAND_HELP, 43 COMMAND_SSH, 44 COMMAND_VNC, 45 COMMAND_SHELL 46} Command; 47 48typedef struct Config { 49 char *domain; 50 Command command; 51} Config; 52 53static void help(FILE *f, const char *argv0) { 54 fprintf(f, 55 _("%s [options]\n\n" 56 " -h --help Show this help\n" 57 " -s --ssh Browse SSH servers\n" 58 " -v --vnc Browse VNC servers\n" 59 " -S --shell Browse both SSH and VNC\n" 60 " -d --domain=DOMAIN The domain to browse in\n"), 61 argv0); 62} 63 64static int parse_command_line(Config *c, int argc, char *argv[]) { 65 int o; 66 67 static const struct option long_options[] = { 68 { "help", no_argument, NULL, 'h' }, 69 { "ssh", no_argument, NULL, 's' }, 70 { "vnc", no_argument, NULL, 'v' }, 71 { "shell", no_argument, NULL, 'S' }, 72 { "domain", required_argument, NULL, 'd' }, 73 { NULL, 0, NULL, 0 } 74 }; 75 76 while ((o = getopt_long(argc, argv, "hVd:svS", long_options, NULL)) >= 0) { 77 78 switch(o) { 79 case 'h': 80 c->command = COMMAND_HELP; 81 break; 82 case 's': 83 c->command = COMMAND_SSH; 84 break; 85 case 'v': 86 c->command = COMMAND_VNC; 87 break; 88 case 'S': 89 c->command = COMMAND_SHELL; 90 break; 91 case 'd': 92 avahi_free(c->domain); 93 c->domain = avahi_strdup(optarg); 94 break; 95 default: 96 return -1; 97 } 98 } 99 100 if (optind < argc) { 101 fprintf(stderr, _("Too many arguments\n")); 102 return -1; 103 } 104 105 return 0; 106} 107 108int main(int argc, char*argv[]) { 109 GtkWidget *d; 110 Config config; 111 const char *argv0; 112 113 avahi_init_i18n(); 114 setlocale(LC_ALL, ""); 115 116 if ((argv0 = strrchr(argv[0], '/'))) 117 argv0++; 118 else 119 argv0 = argv[0]; 120 121 if (g_str_has_suffix(argv[0], "bshell")) 122 config.command = COMMAND_SHELL; 123 else if (g_str_has_suffix(argv[0], "bvnc")) 124 config.command = COMMAND_VNC; 125 else 126 config.command = COMMAND_SSH; 127 128 /* defaults to local */ 129 config.domain = NULL; 130 131 if (parse_command_line(&config, argc, argv) < 0) { 132 help(stderr, argv0); 133 return 1; 134 } 135 136 bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); 137 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); 138 textdomain (GETTEXT_PACKAGE); 139 140 gtk_init(&argc, &argv); 141 142 switch (config.command) { 143 case COMMAND_HELP: 144 help(stdout, argv0); 145 return 0; 146 break; 147 148 case COMMAND_SHELL: 149 d = aui_service_dialog_new(_("Choose Shell Server"), NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL); 150 aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(d), "_rfb._tcp", "_ssh._tcp", NULL); 151 aui_service_dialog_set_service_type_name(AUI_SERVICE_DIALOG(d), "_rfb._tcp", _("Desktop")); 152 aui_service_dialog_set_service_type_name(AUI_SERVICE_DIALOG(d), "_ssh._tcp", _("Terminal")); 153 break; 154 155 case COMMAND_VNC: 156 d = aui_service_dialog_new(_("Choose VNC server"), NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL); 157 aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(d), "_rfb._tcp", NULL); 158 break; 159 160 case COMMAND_SSH: 161 d = aui_service_dialog_new(_("Choose SSH server"), NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL); 162 aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(d), "_ssh._tcp", NULL); 163 break; 164 } 165 166 aui_service_dialog_set_domain (AUI_SERVICE_DIALOG(d), config.domain); 167 aui_service_dialog_set_resolve_service(AUI_SERVICE_DIALOG(d), TRUE); 168 aui_service_dialog_set_resolve_host_name(AUI_SERVICE_DIALOG(d), !avahi_nss_support()); 169 170 gtk_window_present(GTK_WINDOW(d)); 171 172 if (gtk_dialog_run(GTK_DIALOG(d)) == GTK_RESPONSE_ACCEPT) { 173 char a[AVAHI_ADDRESS_STR_MAX], *u = NULL, *n = NULL; 174 char *h = NULL, *t = NULL; 175 const AvahiStringList *txt; 176 177 t = g_strdup(aui_service_dialog_get_service_type(AUI_SERVICE_DIALOG(d))); 178 n = g_strdup(aui_service_dialog_get_service_name(AUI_SERVICE_DIALOG(d))); 179 180 if (avahi_nss_support()) 181 h = g_strdup(aui_service_dialog_get_host_name(AUI_SERVICE_DIALOG(d))); 182 else 183 h = g_strdup(avahi_address_snprint(a, sizeof(a), aui_service_dialog_get_address(AUI_SERVICE_DIALOG(d)))); 184 185 g_print(_("Connecting to '%s' ...\n"), n); 186 187 if (avahi_domain_equal(t, "_rfb._tcp")) { 188 char p[AVAHI_DOMAIN_NAME_MAX+16]; 189 snprintf(p, sizeof(p), "%s:%u", h, aui_service_dialog_get_port(AUI_SERVICE_DIALOG(d))-5900); 190 191 gtk_widget_destroy(d); 192 193 g_print("vncviewer %s\n", p); 194 execlp("xvncviewer", "xvncviewer", p, NULL); 195 execlp("vncviewer", "vncviewer", p, NULL); 196 197 } else { 198 char p[16]; 199 200 snprintf(p, sizeof(p), "%u", aui_service_dialog_get_port(AUI_SERVICE_DIALOG(d))); 201 202 for (txt = aui_service_dialog_get_txt_data(AUI_SERVICE_DIALOG(d)); txt; txt = txt->next) { 203 char *key, *value; 204 205 if (avahi_string_list_get_pair((AvahiStringList*) txt, &key, &value, NULL) < 0) 206 break; 207 208 if (strcmp(key, "u") == 0) 209 u = g_strdup(value); 210 211 avahi_free(key); 212 avahi_free(value); 213 } 214 215 gtk_widget_destroy(d); 216 217 if (u) { 218 g_print("ssh -p %s -l %s %s\n", p, u, h); 219 220 if (isatty(0) || !getenv("DISPLAY")) 221 execlp("ssh", "ssh", "-p", p, "-l", u, h, NULL); 222 else { 223 execlp("x-terminal-emulator", "x-terminal-emulator", "-T", n, "-e", "ssh", "-p", p, "-l", u, h, NULL); 224 execlp("gnome-terminal", "gnome-terminal", "-t", n, "-x", "ssh", "-p", p, "-l", u, h, NULL); 225 execlp("xterm", "xterm", "-T", n, "-e", "ssh", "-p", p, "-l", u, h, NULL); 226 } 227 } else { 228 g_print("ssh -p %s %s\n", p, h); 229 230 if (isatty(0) || !getenv("DISPLAY")) 231 execlp("ssh", "ssh", "-p", p, h, NULL); 232 else { 233 execlp("x-terminal-emulator", "x-terminal-emulator", "-T", n, "-e", "ssh", "-p", p, h, NULL); 234 execlp("gnome-terminal", "gnome-terminal", "-t", n, "-x", "ssh", "-p", p, h, NULL); 235 execlp("xterm", "xterm", "-T", n, "-e", "ssh", "-p", p, h, NULL); 236 } 237 } 238 } 239 240 g_warning(_("execlp() failed: %s\n"), strerror(errno)); 241 242 g_free(h); 243 g_free(u); 244 g_free(t); 245 g_free(n); 246 247 } else { 248 gtk_widget_destroy(d); 249 250 g_print(_("Canceled.\n")); 251 } 252 253 g_free(config.domain); 254 255 return 1; 256} 257