On 01/05/2012 02:32 PM, Ola Lundqvist wrote:
> If someone is willing to apply the path on a Debian package, test it
> out and report whether it works well or not I'm willing to apply it
> and upload it.

I can confirm that the two patches from:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=502876#78

apply cleanly against vnc4 4.1.1+X4.3.0-37 and the package compiles.

Installing the modified package and running the xvnc4viewer binary works
fine, connecting to both unix-domain sockets and TCP sockets.

I've attached the debdiff from the package i made.

Sorry i don't have the personal bandwidth to help out more with this
package.

Regards,

        --dkg
diff -u vnc4-4.1.1+X4.3.0/unix/vncviewer/vncviewer.man 
vnc4-4.1.1+X4.3.0/unix/vncviewer/vncviewer.man
--- vnc4-4.1.1+X4.3.0/unix/vncviewer/vncviewer.man
+++ vnc4-4.1.1+X4.3.0/unix/vncviewer/vncviewer.man
@@ -8,6 +8,10 @@
 .br
 .B vncviewer
 .RI [ options ] 
+.RI [ unix_domain_socket ]
+.br
+.B vncviewer
+.RI [ options ] 
 .B \-listen
 .RI [ port ]
 .SH DESCRIPTION
@@ -27,6 +31,10 @@
 omitted.  So for example ":1" means display number 1 on the same machine, and
 "snoopy" means "snoopy:0" i.e. display 0 on machine "snoopy".
 
+A server specification containing a '/' is recognised as a path to an unix
+domain socket.  The viewer will then connect to a server listening on that
+socket, for example a QEMU virtual machine.
+
 If the VNC server is successfully contacted, you will be prompted for a
 password to authenticate you.  If the password is correct, a window will appear
 showing the desktop of the VNC server.
diff -u vnc4-4.1.1+X4.3.0/unix/vncviewer/CConn.cxx 
vnc4-4.1.1+X4.3.0/unix/vncviewer/CConn.cxx
--- vnc4-4.1.1+X4.3.0/unix/vncviewer/CConn.cxx
+++ vnc4-4.1.1+X4.3.0/unix/vncviewer/CConn.cxx
@@ -19,9 +19,16 @@
 // CConn.cxx
 //
 
+#include <iostream>
+#include <ostream>
+#include <string>
+#include <vector>
+
 #include <termios.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 #include "CConn.h"
 #include <rfb/CMsgWriter.h>
 #include <rfb/encodings.h>
@@ -85,35 +92,49 @@
     vlog.info("Accepted connection from %s", name);
     if (name) free(name);
   } else {
-    if (vncServerName) {
-      getHostAndPort(vncServerName, &serverHost, &serverPort);
-    } else {
+    std::string serverName;
+    if (vncServerName)
+      serverName = vncServerName;
+    else {
       int popup = popupXDialog;
       if (!popup) {
         /* Get server */
-        fprintf(stderr, "Server: ");
-        vncServerName = new char[128];
-       if(fgets(vncServerName, 128, stdin)) {
-         size_t len = strlen(vncServerName);
-         /* remove \n at the end */
-          if(vncServerName[len-1] == '\n')
-            vncServerName[len-1] = '\0';
-        } else {
-          /* fgets failed, probably eof -- assume empty string as input */
-          vncServerName[0] = '\0';
-        }
-       getHostAndPort(vncServerName, &serverHost, &serverPort);
+        std::cerr << "Server: " << std::flush;
+        if(!getline(std::cin, serverName))
+          serverName.clear();
       } else {
         ServerDialog dlg(dpy, &options, &about);
         if (!dlg.show() || dlg.entry.getText()[0] == 0) {
           exit(1);
         }
-        getHostAndPort(dlg.entry.getText(), &serverHost, &serverPort);
+        serverName = dlg.entry.getText();
       }
     }
 
-    sock = new network::TcpSocket(serverHost, serverPort, ipVersion);
-    vlog.info("connected to host %s port %d", serverHost, serverPort);
+    /* assume it's a unix domain socket if it contains a '/' */
+    if(serverName.find('/') != std::string::npos) {
+      int unix_sock = socket(PF_LOCAL, SOCK_STREAM, 0);
+      size_t sock_addr_size = offsetof(sockaddr_un, sun_path)
+        + serverName.size() + 1;
+      // buffer for the sockaddr structure that gets deallocated automatically
+      std::vector<char> name_buf(sock_addr_size);
+      sockaddr_un *name = (sockaddr_un *)&name_buf.front();
+      name->sun_family = AF_LOCAL;
+      strcpy(name->sun_path, serverName.c_str());
+      int result = connect(unix_sock, (const sockaddr *)name, sock_addr_size);
+      if(result == -1) {
+        /* connecting socket failed */
+        vlog.error("Can't connect to unix domain socket %s", vncServerName);
+        exit(1);
+      }
+
+      sock = new network::TcpSocket(unix_sock);
+      vlog.info("connected to unix domain socket %s", serverName.c_str());
+     } else {
+      getHostAndPort(serverName.c_str(), &serverHost, &serverPort);
+      sock = new network::TcpSocket(serverHost, serverPort, ipVersion);
+      vlog.info("connected to host %s port %d", serverHost, serverPort);
+    }
   }
 
   sameMachine = sock->sameMachine();
diff -u vnc4-4.1.1+X4.3.0/debian/changelog vnc4-4.1.1+X4.3.0/debian/changelog
--- vnc4-4.1.1+X4.3.0/debian/changelog
+++ vnc4-4.1.1+X4.3.0/debian/changelog
@@ -1,3 +1,10 @@
+vnc4 (4.1.1+X4.3.0-37.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * enabled connection to unix-domain sockets (Closes: #502876)
+
+ -- Daniel Kahn Gillmor <d...@fifthhorseman.net>  Thu, 05 Jan 2012 20:05:46 
-0500
+
 vnc4 (4.1.1+X4.3.0-37) unstable; urgency=low
 
   * Applied patch from Ben Armstrong <sy...@debian.org> that makes dpi

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to