Matus "fantomas" Uhlar wrote:
> I think that means xmove isn't able to use local sockets for X connection,
> which is what I want.

It is what I want too, and here is some code that implements
it.

So, here's what it does:

When xargs connects to a server it will check if the name
of the server is the same as the the local host.  It it is,
it will try to connect to /tmp/X11-unix/Xn before it tries
to connect via tcp.

This could be made better (feel free to do so!).  It breaks
the convention that :0 means "some (maybe local)" type of
connection and host:0 means tcp connection, since host:0 may
now create a local connection.  It only tries the /tmp...unix
path; I believe there are some other ways to make a local
connection to an X server.

It also adds a new option -interface.  By default xmove
listens to all interfaces, and I only want to run it locally
on my machine.  But with `-interface host' it only listens
for connections to host (which will be localhost in my case).

patch is against 2.0beta2-6


-- 
Tommy Pettersson <[EMAIL PROTECTED]>
diff -rN -u old/man/man1/xmove.1 new/man/man1/xmove.1
--- old/man/man1/xmove.1        Thu Mar 31 19:17:44 2005
+++ new/man/man1/xmove.1        Thu Mar 31 16:06:47 2005
@@ -11,6 +11,10 @@
 .B -port 
 .I listen_port
 ]
+] [
+.B -interface 
+.I listen_interface
+]
 
 .SH DESCRIPTION
 .I xmove
@@ -25,7 +29,7 @@
 .PP
 .I xmove
 will assume logical default values for both the
-default listening port and the default server. Take as an
+default listening port, default interface and the default server. Take as an
 example a typical machine named \fIchestnut\fP, with a standard X11 server
 named \fIchestnut:0\fP.
 .PP
@@ -41,6 +45,11 @@
 \fIchestnut:0\fP if you wish them to be run through 
 .I xmove.
 .PP
+The default is to listen on all interfaces of the machine,
+so local clients can use both localhost:1 and chestnut:1.
+.I xmove
+can be restricted to only listen on one specific interface.
+.PP
 .SH TYPICAL USAGE
 Assuming that the environment variable \fBDISPLAY\fP contains
 the name of your default server, no options need to be set. 
@@ -95,6 +104,18 @@
 .I xmove
 was executed, and n is the specified port.
 The port must be a number from 1 to 9.
+.TP
+.I -interface
+Clients can only connect to
+.I xmove
+through the specified interface.
+Users must specify a \fBDISPLAY\fP of \fIname:n\fP,
+where \fIname\fP is a name of that perticular interface on the machine on which
+.I xmove
+was executed.
+Without this option,
+.I xmove
+will accept connections to all interfaces on the machine.
 
 .SH "MULTI-HEADED DISPLAYS"
 .I xmove
diff -rN -u old/xmove/main.c new/xmove/main.c
--- old/xmove/main.c    Thu Mar 31 19:17:44 2005
+++ new/xmove/main.c    Thu Mar 31 15:14:26 2005
@@ -26,6 +26,7 @@
 
 #include <sys/types.h>         /* needed by sys/socket.h and netinet/in.h */
 #include <sys/uio.h>           /* for struct iovec, used by socket.h */
+#include <sys/un.h>
 #include <sys/socket.h>        /* for AF_INET, SOCK_STREAM, ... */
 #include <sys/ioctl.h>         /* for FIONCLEX, FIONBIO, ... */
 #if defined(SYSV) || defined(SVR4)
@@ -130,6 +131,7 @@
 static int  ServerPort = 0;
 Global int  ServerScreen = 0;
 static int  ListenForClientsPort = 1;
+static char *ListenForClientsInterface = NULL;
 static char ServerHostName[255];
 static char DefaultHost[256];
 
@@ -313,6 +315,15 @@
                                ListenForClientsPort = 0;
                        debug(1,(stderr, 
"ListenForClientsPort=%d\n",ListenForClientsPort));
                }
+               else if (Streq(argv[i], "-interface"))
+               {
+                       if (++i < argc)
+                               ListenForClientsInterface = argv[i];
+                       else
+                               Usage();
+                       debug(1,(stderr, "ListenForClientsInterface=%s\n",
+                                         ListenForClientsInterface));
+               }
                else if (Streq(argv[i], "-debug"))
                {
                        /*
@@ -355,8 +366,13 @@
                        Usage();
        }
 
-       LocalHostName = (char *)malloc(255);
-       (void) gethostname(LocalHostName, 255);
+       if (ListenForClientsInterface)
+               LocalHostName = ListenForClientsInterface;
+       else
+       {
+               LocalHostName = (char *)malloc(255);
+               (void) gethostname(LocalHostName, 255);
+       }
 
        if (string == NULL)
                string = getenv("DISPLAY");
@@ -427,7 +443,13 @@
           host machine.  The host machine may have several different network
           addresses.  INADDR_ANY should work with all of them at once. */
 
-       sin.sin_addr.s_addr = INADDR_ANY;
+       /* But the user can have specified a single one of them with the
+          -interface option. */
+
+       if (ListenForClientsInterface)
+               sin.sin_addr.s_addr = HostIPAddr;
+       else
+               sin.sin_addr.s_addr = INADDR_ANY;
 
        sin.sin_port = htons (iport);
 
@@ -652,6 +674,7 @@
        fprintf(stderr, "Usage: xmove\n");
        fprintf(stderr, "              [-server <server_name:port>]\n");
        fprintf(stderr, "              [-port <listen_port>]\n");
+       fprintf(stderr, "              [-interface <listen_interface>]\n");
        fprintf(stderr, "              [-verbose <output_level>]\n");
        exit(1);
 }
@@ -1138,31 +1161,53 @@
 ConnectToServer(char *hostName, short portNum, unsigned long *ip_addr)
 {
     int ON = 1;
-    int ServerFD;
+    int ServerFD = -1;
+    struct sockaddr *sap;
+    socklen_t saz;
+    struct sockaddr_un  sun;
     struct sockaddr_in  sin;
     struct hostent *hp;
     
     enterprocedure("ConnectToServer");
 
-    hp = gethostbyname(hostName);
-    if (hp == NULL)
+    /* try local unix socket first if server is local */
+    if (Streq(hostName, LocalHostName))
     {
-       perror("gethostbyname failed");
-       return -1;
+       bzero((char *)&sun, sizeof(sun));
+       sun.sun_family = AF_UNIX;
+       sprintf(sun.sun_path, "/tmp/.X11-unix/X%d", portNum);
+       sap = (struct sockaddr *)&sun;
+       saz = SUN_LEN(&sun);
+       ServerFD = socket(AF_UNIX, SOCK_STREAM, 0);
     }
+    if (ServerFD < 0)
+    {
+       hp = gethostbyname(hostName);
+       if (hp == NULL)
+       {
+           perror("gethostbyname failed");
+           return -1;
+       }
 
-    if (ip_addr)
-        *ip_addr = *(unsigned long *)(hp->h_addr);
+       if (ip_addr)
+            *ip_addr = *(unsigned long *)(hp->h_addr);
     
-    if (*(unsigned long *)(hp->h_addr) == HostIPAddr &&
-       portNum == ListenForClientsPort)
-    {
-        return -1;
-    }
+       if (*(unsigned long *)(hp->h_addr) == HostIPAddr &&
+           portNum == ListenForClientsPort)
+       {
+            return -1;
+       }
     
-    /* establish a socket to the name server for this host */
-    bzero((char *)&sin, sizeof(sin));
-    ServerFD = socket(AF_INET, SOCK_STREAM, 0);
+       /* establish a socket to the name server for this host */
+       bzero((char *)&sin, sizeof(sin));
+       sin.sin_family = AF_INET;
+       bcopy((char *)hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
+       sin.sin_port = htons (portNum + XBasePort);
+       sap = (struct sockaddr *)&sin;
+       saz = sizeof(sin);
+       ServerFD = socket(AF_INET, SOCK_STREAM, 0);
+    }
+
     if (ServerFD < 0)
     {
        perror("socket() to Server failed");
@@ -1180,14 +1225,10 @@
 
     debug(4,(stderr, "try to connect on %s\n", hostName));
 
-    sin.sin_family = AF_INET;
-    bcopy((char *)hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
-    sin.sin_port = htons (portNum + XBasePort);
-
     /* ******************************************************** */
     /* try to connect to Server */
     
-    if (connect(ServerFD, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+    if (connect(ServerFD, sap, saz) < 0)
     {
        debug(4,(stderr, "connect returns errno of %d\n", errno));
        close (ServerFD);

Reply via email to