[gtk-vnc] Add support for connecting to GSocketAddress instances



commit 078e3cffaab939151aa6afc2df08f7444f6db9ec
Author: Daniel P. Berrange <berrange redhat com>
Date:   Mon Jul 9 11:49:20 2012 +0100

    Add support for connecting to GSocketAddress instances
    
    To improve UNIX domain socket support, add the ability to open
    a GSocketAddress instance. Pass the 'hostname' with the addr
    for the purposes of SASL/TLS hostname verification. Also add
    another method for opening a FD which accepts a hostname, again
    for SASL/TLS hostname verification when using a tunnelled
    socket

 configure.ac               |    8 +++++
 examples/Makefile.am       |    6 ++-
 examples/gvncviewer.c      |   46 ++++++++++++++++++++++--------
 src/libgtk-vnc_sym.version |    2 +
 src/libgvnc_sym.version    |    2 +
 src/vncconnection.c        |   67 ++++++++++++++++++++++++++++++++++++++++++-
 src/vncconnection.h        |    3 ++
 src/vncdisplay.c           |   39 +++++++++++++++++++++++++
 src/vncdisplay.h           |    2 +
 9 files changed, 159 insertions(+), 16 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4d1283c..78bbb5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,6 +179,14 @@ PKG_CHECK_MODULES(GIO, gio-2.0 >= $GIO_REQUIRED)
 AC_SUBST(GIO_CFLAGS)
 AC_SUBST(GIO_LIBS)
 
+PKG_CHECK_MODULES(GIOUNIX, gio-unix-2.0 >= $GIO_REQUIRED, [have_giounix=yes], [have_giounix=no])
+AC_SUBST(GIOUNIX_CFLAGS)
+AC_SUBST(GIOUNIX_LIBS)
+if test $have_giounix = "yes" ; then
+  AC_DEFINE_UNQUOTED([HAVE_GIOUNIX],[1], [Whether GIO UNIX is available])
+fi
+
+
 PKG_CHECK_MODULES(GDK_PIXBUF, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED)
 AC_SUBST(GDK_PIXBUF_CFLAGS)
 AC_SUBST(GDK_PIXBUF_LIBS)
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 62d8445..ee98cb0 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -8,13 +8,15 @@ endif
 gvncviewer_SOURCES = gvncviewer.c
 gvncviewer_LDADD = ../src/libgtk-vnc-$(GTK_VNC_API_VERSION).la \
                    ../src/libgvnc-1.0.la \
-		   $(GTK_CFLAGS) \
+		   $(GIOUNIX_LIBS) \
 		   $(GTK_LIBS) \
 		   $(VIEW_LIBS)
 if HAVE_PULSEAUDIO
 gvncviewer_LDADD += ../src/libgvncpulse-1.0.la
 endif
-gvncviewer_CFLAGS = $(GTK_CFLAGS) $(WARNING_CFLAGS) \
+gvncviewer_CFLAGS = $(GTK_CFLAGS) \
+		    $(GIOUNIX_CFLAGS) \
+		    $(WARNING_CFLAGS) \
 		    $(VIEW_CFLAGS) -I$(top_srcdir)/src/
 
 EXTRA_DIST = gvncviewer.py gvncviewer.js
diff --git a/examples/gvncviewer.c b/examples/gvncviewer.c
index 6d47d71..598d926 100644
--- a/examples/gvncviewer.c
+++ b/examples/gvncviewer.c
@@ -30,6 +30,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <glib.h>
+#if HAVE_GIOUNIX
+#include <gio/gunixsocketaddress.h>
+#endif
 
 #if WITH_LIBVIEW
 #include <libview/autoDrawer.h>
@@ -565,8 +568,6 @@ int main(int argc, char **argv)
     gchar *name;
     GOptionContext *context;
     GError *error = NULL;
-    char port[1024], hostname[1024];
-    char *display;
     GtkWidget *window;
     GtkWidget *layout;
     GtkWidget *menubar;
@@ -687,18 +688,39 @@ int main(int argc, char **argv)
     gtk_container_add(GTK_CONTAINER(window), layout);
     gtk_widget_realize(vnc);
 
-    snprintf(hostname, sizeof(hostname), "%s", args[0]);
-    display = strchr(hostname, ':');
+#if HAVE_GIOUNIX
+    if (strchr(args[0], '/')) {
+        GSocketAddress *addr = g_unix_socket_address_new_with_type
+            (args[0], strlen(args[0]),
+             G_UNIX_SOCKET_ADDRESS_PATH);
 
-    if (display) {
-        *display = 0;
-        snprintf(port, sizeof(port), "%d", 5900 + atoi(display + 1));
-    } else
-        snprintf(port, sizeof(port), "%d", 5900);
+        vnc_display_open_addr(VNC_DISPLAY(vnc), addr, NULL);
 
-    if (!*hostname)
-        snprintf(hostname, sizeof(hostname), "%s", "127.0.0.1");
-    vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
+        g_object_unref(addr);
+    } else {
+#endif
+        gchar *tmp;
+        gchar *hostname;
+        gchar *port;
+
+        if (g_str_equal(args[0], ""))
+            hostname = g_strdup("127.0.0.1");
+        else
+            hostname = g_strdup(args[0]);
+
+        tmp = strchr(hostname, ':');
+        if (tmp) {
+            *tmp = '\0';
+            port = g_strdup_printf("%d", 5900 + atoi(tmp + 1));
+        } else {
+            port = g_strdup("5900");
+        }
+        vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
+        g_free(hostname);
+        g_free(port);
+#if HAVE_GIOUNIX
+    }
+#endif
     vnc_display_set_keyboard_grab(VNC_DISPLAY(vnc), TRUE);
     vnc_display_set_pointer_grab(VNC_DISPLAY(vnc), TRUE);
 
diff --git a/src/libgtk-vnc_sym.version b/src/libgtk-vnc_sym.version
index cdc69ab..d785eba 100644
--- a/src/libgtk-vnc_sym.version
+++ b/src/libgtk-vnc_sym.version
@@ -5,7 +5,9 @@
     vnc_display_key_event_get_type;
 
     vnc_display_new;
+    vnc_display_open_addr;
     vnc_display_open_fd;
+    vnc_display_open_fd_with_hostname;
     vnc_display_open_host;
     vnc_display_is_open;
     vnc_display_close;
diff --git a/src/libgvnc_sym.version b/src/libgvnc_sym.version
index 64a09dc..9adec25 100644
--- a/src/libgvnc_sym.version
+++ b/src/libgvnc_sym.version
@@ -51,7 +51,9 @@
 
 	vnc_connection_get_type;
 	vnc_connection_new;
+	vnc_connection_open_addr;
 	vnc_connection_open_fd;
+	vnc_connection_open_fd_with_hostname;
 	vnc_connection_open_host;
 	vnc_connection_is_open;
 	vnc_connection_shutdown;
diff --git a/src/vncconnection.c b/src/vncconnection.c
index f371f74..7bc481a 100644
--- a/src/vncconnection.c
+++ b/src/vncconnection.c
@@ -146,6 +146,7 @@ struct _VncConnectionPrivate
     struct coroutine coroutine;
     guint open_id;
     GSocket *sock;
+    GSocketAddress *addr;
     int fd;
     char *host;
     char *port;
@@ -4738,6 +4739,10 @@ static void vnc_connection_close(VncConnection *conn)
         g_object_unref(priv->sock);
         priv->sock = NULL;
     }
+    if (priv->addr) {
+        g_object_unref(priv->addr);
+        priv->addr = NULL;
+    }
     if (priv->fd != -1)
         priv->fd = -1;
 
@@ -4849,6 +4854,8 @@ gboolean vnc_connection_is_open(VncConnection *conn)
         return TRUE;
     if (priv->host)
         return TRUE;
+    if (priv->addr)
+        return TRUE;
     return FALSE;
 }
 
@@ -5015,6 +5022,24 @@ static GSocket *vnc_connection_connect_socket(GSocketAddress *sockaddr,
     return sock;
 }
 
+static gboolean vnc_connection_open_addr_internal(VncConnection *conn)
+{
+    VncConnectionPrivate *priv = conn->priv;
+    GError *conn_error = NULL;
+    GSocket *sock = NULL;
+
+    VNC_DEBUG("Connecting with addr %p", priv->addr);
+
+    sock = vnc_connection_connect_socket(priv->addr, &conn_error);
+    g_clear_error(&conn_error);
+    if (sock) {
+        priv->sock = sock;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
 static gboolean vnc_connection_open_host_internal(VncConnection *conn)
 {
     VncConnectionPrivate *priv = conn->priv;
@@ -5081,6 +5106,9 @@ static void *vnc_connection_coroutine(void *opaque)
     if (priv->fd != -1) {
         if (!vnc_connection_open_fd_internal(conn))
             goto cleanup;
+    } else if (priv->addr != NULL) {
+        if (!vnc_connection_open_addr_internal(conn))
+            goto cleanup;
     } else {
         if (!vnc_connection_open_host_internal(conn))
             goto cleanup;
@@ -5131,6 +5159,12 @@ static gboolean do_vnc_connection_open(gpointer data)
 
 gboolean vnc_connection_open_fd(VncConnection *conn, int fd)
 {
+    return vnc_connection_open_fd_with_hostname(conn, fd, NULL);
+}
+
+
+gboolean vnc_connection_open_fd_with_hostname(VncConnection *conn, int fd, const char *hostname)
+{
     VncConnectionPrivate *priv = conn->priv;
 
     VNC_DEBUG("Open fd=%d", fd);
@@ -5139,8 +5173,9 @@ gboolean vnc_connection_open_fd(VncConnection *conn, int fd)
         return FALSE;
 
     priv->fd = fd;
-    priv->host = NULL;
-    priv->port = NULL;
+    priv->addr = NULL;
+    priv->host = g_strdup(hostname ? hostname : "localhost");
+    priv->port = g_strdup("");
 
     g_object_ref(G_OBJECT(conn)); /* Unref'd when co-routine exits */
     priv->open_id = g_idle_add(do_vnc_connection_open, conn);
@@ -5148,6 +5183,7 @@ gboolean vnc_connection_open_fd(VncConnection *conn, int fd)
     return TRUE;
 }
 
+
 gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const char *port)
 {
     VncConnectionPrivate *priv = conn->priv;
@@ -5158,6 +5194,7 @@ gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const c
         return FALSE;
 
     priv->fd = -1;
+    priv->addr = NULL;
     priv->host = g_strdup(host);
     priv->port = g_strdup(port);
 
@@ -5167,6 +5204,32 @@ gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const c
     return TRUE;
 }
 
+gboolean vnc_connection_open_addr(VncConnection *conn, GSocketAddress *addr, const char *hostname)
+{
+    VncConnectionPrivate *priv = conn->priv;
+
+    VNC_DEBUG("Open addr=%p", addr);
+
+    if (vnc_connection_is_open(conn))
+        return FALSE;
+
+    priv->fd = -1;
+    priv->addr = g_object_ref(addr);
+
+    priv->host = g_strdup(hostname ? hostname : "localhost");
+    if (G_IS_INET_SOCKET_ADDRESS(addr)) {
+        guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(addr));
+        priv->port = g_strdup_printf("%d", (int)port);
+    } else {
+        priv->port = g_strdup("");
+    }
+
+    g_object_ref(G_OBJECT(conn)); /* Unref'd when co-routine exits */
+    priv->open_id = g_idle_add(do_vnc_connection_open, conn);
+
+    return TRUE;
+}
+
 
 gboolean vnc_connection_set_auth_type(VncConnection *conn, unsigned int type)
 {
diff --git a/src/vncconnection.h b/src/vncconnection.h
index 764b857..cbfefd7 100644
--- a/src/vncconnection.h
+++ b/src/vncconnection.h
@@ -23,6 +23,7 @@
 #define VNC_CONNECTION_H
 
 #include <glib.h>
+#include <gio/gio.h>
 
 #include <vncframebuffer.h>
 #include <vnccursor.h>
@@ -153,7 +154,9 @@ GType vnc_connection_get_type(void) G_GNUC_CONST;
 VncConnection *vnc_connection_new(void);
 
 gboolean vnc_connection_open_fd(VncConnection *conn, int fd);
+gboolean vnc_connection_open_fd_with_hostname(VncConnection *conn, int fd, const char *hostname);
 gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const char *port);
+gboolean vnc_connection_open_addr(VncConnection *conn, GSocketAddress *addr, const char *hostname);
 gboolean vnc_connection_is_open(VncConnection *conn);
 void vnc_connection_shutdown(VncConnection *conn);
 
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index c6354b5..5c0e994 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -1525,6 +1525,45 @@ gboolean vnc_display_open_fd(VncDisplay *obj, int fd)
     return TRUE;
 }
 
+
+gboolean vnc_display_open_fd_with_hostname(VncDisplay *obj, int fd, const char *hostname)
+{
+    VncDisplayPrivate *priv = obj->priv;
+
+    if (vnc_connection_is_open(priv->conn))
+        return FALSE;
+
+    if (!vnc_connection_set_shared(priv->conn, priv->shared_flag))
+        return FALSE;
+
+    if (!vnc_connection_open_fd_with_hostname(priv->conn, fd, hostname))
+        return FALSE;
+
+    g_object_ref(G_OBJECT(obj));
+
+    return TRUE;
+}
+
+
+gboolean vnc_display_open_addr(VncDisplay *obj, GSocketAddress *addr, const char *hostname)
+{
+    VncDisplayPrivate *priv = obj->priv;
+
+    if (vnc_connection_is_open(priv->conn))
+        return FALSE;
+
+    if (!vnc_connection_set_shared(priv->conn, priv->shared_flag))
+        return FALSE;
+
+    if (!vnc_connection_open_addr(priv->conn, addr, hostname))
+        return FALSE;
+
+    g_object_ref(G_OBJECT(obj));
+
+    return TRUE;
+}
+
+
 gboolean vnc_display_open_host(VncDisplay *obj, const char *host, const char *port)
 {
     VncDisplayPrivate *priv = obj->priv;
diff --git a/src/vncdisplay.h b/src/vncdisplay.h
index b2c9a22..b53eee3 100644
--- a/src/vncdisplay.h
+++ b/src/vncdisplay.h
@@ -87,6 +87,8 @@ GType vnc_display_get_type(void);
 GtkWidget *vnc_display_new(void);
 
 gboolean vnc_display_open_fd(VncDisplay *obj, int fd);
+gboolean vnc_display_open_fd_with_hostname(VncDisplay *obj, int fd, const char *hostname);
+gboolean vnc_display_open_addr(VncDisplay *obj, GSocketAddress *addr, const char *hostname);
 gboolean vnc_display_open_host(VncDisplay *obj, const char *host, const char *port);
 gboolean vnc_display_is_open(VncDisplay *obj);
 void vnc_display_close(VncDisplay *obj);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]