Description: allow Unix domain sockets in gvncviewer
 gvncviewer is useful when connecting to unix domain sockets.
Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>

--- gtk-vnc-0.5.0.orig/examples/gvncviewer.c
+++ gtk-vnc-0.5.0/examples/gvncviewer.c
@@ -30,6 +30,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
 #if WITH_LIBVIEW
 #include <libview/autoDrawer.h>
@@ -586,6 +591,8 @@ int main(int argc, char **argv)
     GtkWidget *scaling;
     GtkWidget *showgrabkeydlg;
     const char *help_msg = "Run 'gvncviewer --help' to see a full list of available command line options";
+    struct stat sockstat;
+    int sock;
 
     name = g_strdup_printf("- Simple VNC Client on Gtk-VNC %s",
                            vnc_util_get_version_string());
@@ -688,17 +695,36 @@ int main(int argc, char **argv)
     gtk_widget_realize(vnc);
 
     snprintf(hostname, sizeof(hostname), "%s", args[0]);
-    display = strchr(hostname, ':');
-
-    if (display) {
-        *display = 0;
-        snprintf(port, sizeof(port), "%d", 5900 + atoi(display + 1));
-    } else
-        snprintf(port, sizeof(port), "%d", 5900);
-
-    if (!*hostname)
-        snprintf(hostname, sizeof(hostname), "%s", "127.0.0.1");
-    vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
+    if ((0 == stat(hostname, &sockstat)) &&
+        S_ISSOCK(sockstat.st_mode)) {
+        size_t sockaddrsize = offsetof(struct sockaddr_un, sun_path) + strlen(hostname) + 1;
+        struct sockaddr_un* addr = malloc(sockaddrsize);
+        
+        /* the argument refers to a unix domain socket */
+        sock = socket(AF_UNIX, SOCK_STREAM, 0);
+        addr->sun_family = AF_UNIX;
+        strcpy(addr->sun_path, hostname);
+        if (0 == connect(sock, (const struct sockaddr *)addr, sockaddrsize)) {
+            vnc_display_open_fd(VNC_DISPLAY(vnc), sock);
+        } else {
+            fprintf(stderr, "Failed to open unix domain socket %s\n", hostname);
+            return 1;
+        }
+        free(addr);
+    } else {
+        /* treat it as a regular hostname */
+        display = strchr(hostname, ':');
+
+        if (display) {
+            *display = 0;
+            snprintf(port, sizeof(port), "%d", 5900 + atoi(display + 1));
+        } else
+            snprintf(port, sizeof(port), "%d", 5900);
+
+        if (!*hostname)
+            snprintf(hostname, sizeof(hostname), "%s", "127.0.0.1");
+        vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
+    }
     vnc_display_set_keyboard_grab(VNC_DISPLAY(vnc), TRUE);
     vnc_display_set_pointer_grab(VNC_DISPLAY(vnc), TRUE);
 
