few minor bugfixes
[ovirt-viewer.git] / main.c
diff --git a/main.c b/main.c
index 356d379..23af6fa 100644 (file)
--- a/main.c
+++ b/main.c
@@ -36,6 +36,8 @@
 #include <netinet/in.h>
 #endif
 
+#include <arpa/inet.h>
+
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
@@ -55,6 +57,8 @@
 
 gboolean debug = 0;
 
+gboolean verbose = 0;
+
 /* Usually /etc/pki/tls/certs/ca-bundle.crt unless overridden during
  * configure or on the command line.
  */
@@ -68,6 +72,10 @@ gboolean check_cert = FALSE; // do we want this enabled by default ?
 */
 static GSList *vmlist = NULL;
 
+/*  internal.h shared constructs */
+const char* hostname;
+struct vm* vm_in_focus;
+
 /* Private functions. */
 static void start_ui (void);
 static GtkWidget *menu_item_new (int which_menu);
@@ -198,6 +206,8 @@ static const GOptionEntry options[] = {
     "check the SSL certificate of the server", NULL },
   { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug,
     "turn on debugging messages", NULL },
+  { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+    "turn on verbose messages", NULL },
   { "version", 'V', 0, G_OPTION_ARG_NONE, &print_version,
     "display version and exit", NULL },
   { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
@@ -225,6 +235,10 @@ main (int argc, char *argv[])
    * processed in the main thread - see:
    * http://mail.gnome.org/archives/gtk-app-devel-list/2007-March/msg00232.html
    *
+   * A tunnel thread is also started to locally listen for vnc packets
+   * and make them proxyable, adding the vm name, before forwarding onto
+   * the server
+   *
    * Note that under Win32 you must confine all Gtk/Gdk interactions
    * to a single thread - see:
    * http://developer.gimp.org/api/2.0/gdk/gdk-Threads.html
@@ -267,6 +281,7 @@ main (int argc, char *argv[])
   gtk_main ();
 
   stop_wui_thread ();
+  stop_tunnel();
 
   exit (0);
 }
@@ -510,6 +525,7 @@ help_about (GtkWidget *menu)
   const char *authors[] = {
     "Richard W.M. Jones <rjones@redhat.com>",
     "Daniel P. Berrange <berrange@redhat.com>",
+    "Mohammed Morsi <mmorsi@redhat.com>",
     NULL
   };
 
@@ -557,7 +573,6 @@ connect_to_wui_on_enter (GtkWidget *widget, gpointer data)
 static void
 connect_to_wui (GtkWidget *widget, gpointer data)
 {
-  const char *hostname;
   char *uri;
   int len;
 
@@ -570,6 +585,7 @@ connect_to_wui (GtkWidget *widget, gpointer data)
   snprintf (uri, len, HTTPS "://%s/ovirt", hostname);
 
   wui_thread_send_connect (uri);
+  start_tunnel();
 }
 
 static void
@@ -606,7 +622,6 @@ connect_to_vm (GtkWidget *widget, gpointer _vm)
   int i, uuidlen, len, fd;
   GtkWidget *child;
   const char *label;
-  const char* hostname;
   char *label2;
   char new_title[97]; // 47 chars for title + 50 for vm name
 
@@ -637,9 +652,12 @@ connect_to_vm (GtkWidget *widget, gpointer _vm)
     return;
   }
 
+  // FIXME on notebook tab switch, change vm_in_focus
+  vm_in_focus = vm;
+
   /* This VM isn't in the notebook already, so create a new console. */
-  hostname = gtk_entry_get_text (GTK_ENTRY (ca_hostname));
-  fd = viewer_open_vnc_socket(hostname, vm->forward_vnc_port);
+  DEBUG ("connecting to local tunnel on port %i", tunnel_port);
+  fd = viewer_open_vnc_socket("127.0.0.1", tunnel_port);
   if (fd == -1) return;                /* We've already given an error. */
 
   child = vnc_display_new ();
@@ -887,37 +905,35 @@ viewer_credential (GtkWidget *vnc, GValueArray *credList)
                 gtk_widget_destroy(GTK_WIDGET(dialog));
 }
 
-#if defined(HAVE_SOCKET) && defined(HAVE_CONNECT) && defined(HAVE_HTONS) && defined(HAVE_GETHOSTBYNAME)
+#if defined(HAVE_SOCKET) && defined(HAVE_CONNECT) && defined(HAVE_HTONS)
 
 static int 
 viewer_open_vnc_socket(const char* vnchost, int vncport)
 {
-  int socketfd;
-  struct hostent *serv;
-  struct sockaddr_in serv_addr;
+  int result, socketfd;
+  char port[10];
+  struct addrinfo* vnc_addr;
 
-  socketfd = socket(PF_INET, SOCK_STREAM, 0);
-  if(socketfd < 0){
-      return -1;
-  }
+  sprintf(port, "%d", vncport);
 
-  serv = gethostbyname(vnchost);
-  if(serv == NULL){
+  result = getaddrinfo(vnchost, port, NULL, &vnc_addr);
+  if(result != 0 || vnc_addr == NULL)
       return -1;
-  }
 
-  serv_addr.sin_family = PF_INET;
-  serv_addr.sin_port = htons(vncport);
-  serv_addr.sin_addr.s_addr = ((struct in_addr *)(serv->h_addr))->s_addr; 
+  // just use first found, ignoring rest
+  socketfd = socket(vnc_addr->ai_family,
+                    vnc_addr->ai_socktype,
+                    vnc_addr->ai_protocol);
 
-  if (connect(socketfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0){
-      return -1;
-  }
+  if(connect(socketfd, vnc_addr->ai_addr, vnc_addr->ai_addrlen) <0)
+      socketfd = -1;
+
+  freeaddrinfo(vnc_addr);
 
   return socketfd;
 }
 
-#endif /* defined(HAVE_SOCKET) && defined(HAVE_CONNECT) && defined(HAVE_HTONS) && defined(HAVE_GETHOSTBYNAME) */
+#endif /* defined(HAVE_SOCKET) && defined(HAVE_CONNECT) && defined(HAVE_HTONS) */
 
 /* Remove all menu items from the Connect menu. */
 static void