home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / lisp / clx_tar.z / clx_tar / clx / socket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  4.3 KB  |  157 lines

  1. #include <sys/param.h>
  2. /* Copyright    Massachusetts Institute of Technology    1988    */
  3. /*
  4.  * THIS IS AN OS DEPENDENT FILE! It should work on 4.2BSD derived
  5.  * systems.  VMS and System V should plan to have their own version.
  6.  *
  7.  * This code was cribbed from lib/X/XConnDis.c.
  8.  * Compile using   
  9.  *                    % cc -c socket.c -DUNIXCONN
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <X11/Xos.h>
  14. #include <X11/Xproto.h>
  15. #include <errno.h>
  16. #include <netinet/in.h>
  17. #include <sys/ioctl.h>
  18. #include <netdb.h> 
  19. #include <sys/socket.h>
  20. #ifndef hpux
  21. #include <netinet/tcp.h>
  22. #endif
  23.  
  24. extern int errno;        /* Certain (broken) OS's don't have this */
  25.                 /* decl in errno.h */
  26.  
  27. #ifdef UNIXCONN
  28. #include <sys/un.h>
  29. #ifndef X_UNIX_PATH
  30. #ifdef hpux
  31. #define X_UNIX_PATH "/usr/spool/sockets/X11/"
  32. #define OLD_UNIX_PATH "/tmp/.X11-unix/X"
  33. #else /* hpux */
  34. #define X_UNIX_PATH "/tmp/.X11-unix/X"
  35. #endif /* hpux */
  36. #endif /* X_UNIX_PATH */
  37. #endif /* UNIXCONN */
  38.  
  39. #ifndef hpux
  40. #ifndef bcopy
  41. void bcopy();
  42. #endif /* bcopy */
  43. #endif /* hpux */
  44.  
  45. /* 
  46.  * Attempts to connect to server, given host and display. Returns file 
  47.  * descriptor (network socket) or 0 if connection fails.
  48.  */
  49.  
  50. int connect_to_server (host, display)
  51.      char *host;
  52.      int display;
  53. {
  54.   struct sockaddr_in inaddr;    /* INET socket address. */
  55.   struct sockaddr *addr;        /* address to connect to */
  56.   struct hostent *host_ptr;
  57.   int addrlen;            /* length of address */
  58. #ifdef UNIXCONN
  59.   struct sockaddr_un unaddr;    /* UNIX socket address. */
  60. #endif
  61.   extern char *getenv();
  62.   extern struct hostent *gethostbyname();
  63.   int fd;                /* Network socket */
  64.   {
  65. #ifdef UNIXCONN
  66.     if ((host[0] == '\0') || (strcmp("unix", host) == 0)) {
  67.     /* Connect locally using Unix domain. */
  68.     unaddr.sun_family = AF_UNIX;
  69.     (void) strcpy(unaddr.sun_path, X_UNIX_PATH);
  70.     (void) sprintf(&unaddr.sun_path[strlen(unaddr.sun_path)], "%d", display);
  71.     addr = (struct sockaddr *) &unaddr;
  72.     addrlen = strlen(unaddr.sun_path) + 2;
  73.     /*
  74.      * Open the network connection.
  75.      */
  76.     if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0) {
  77. #ifdef hpux /* this is disgusting */  /* cribbed from X11R4 xlib source */
  78.           if (errno == ENOENT) {  /* No such file or directory */
  79.           (void) sprintf(unaddr.sun_path, "%s%d", OLD_UNIX_PATH, display);
  80.               addrlen = strlen(unaddr.sun_path) + 2;
  81.               if ((fd = socket ((int) addr->sa_family, SOCK_STREAM, 0)) < 0)
  82.                 return(-1);     /* errno set by most recent system call. */
  83.         } else 
  84. #endif /* hpux */
  85.         return(-1);        /* errno set by system call. */
  86.         }
  87.     } else 
  88. #endif /* UNIXCONN */
  89.     {
  90.       /* Get the statistics on the specified host. */
  91.       if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1) 
  92.     {
  93.       if ((host_ptr = gethostbyname(host)) == NULL) 
  94.         {
  95.           /* No such host! */
  96.           errno = EINVAL;
  97.           return(-1);
  98.         }
  99.       /* Check the address type for an internet host. */
  100.       if (host_ptr->h_addrtype != AF_INET) 
  101.         {
  102.           /* Not an Internet host! */
  103.           errno = EPROTOTYPE;
  104.           return(-1);
  105.         }
  106.       /* Set up the socket data. */
  107.       inaddr.sin_family = host_ptr->h_addrtype;
  108. #ifdef hpux
  109.       (void) memcpy((char *)&inaddr.sin_addr, 
  110.             (char *)host_ptr->h_addr, 
  111.             sizeof(inaddr.sin_addr));
  112. #else /* hpux */
  113.       (void) bcopy((char *)host_ptr->h_addr, 
  114.                (char *)&inaddr.sin_addr, 
  115.                sizeof(inaddr.sin_addr));
  116. #endif /* hpux */
  117.     } 
  118.       else 
  119.     {
  120.       inaddr.sin_family = AF_INET;
  121.     }
  122.       addr = (struct sockaddr *) &inaddr;
  123.       addrlen = sizeof (struct sockaddr_in);
  124.       inaddr.sin_port = display + X_TCP_PORT;
  125.       inaddr.sin_port = htons(inaddr.sin_port);
  126.       /*
  127.        * Open the network connection.
  128.        */
  129.       if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0){
  130.     return(-1);        /* errno set by system call. */}
  131.       /* make sure to turn off TCP coalescence */
  132. #ifdef TCP_NODELAY
  133.       {
  134.     int mi = 1;
  135.     setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof (int));
  136.       }
  137. #endif
  138.     }
  139.  
  140.     /*
  141.      * Changed 9/89 to retry connection if system call was interrupted.  This
  142.      * is necessary for multiprocessing implementations that use timers,
  143.      * since the timer results in a SIGALRM.    -- jdi
  144.      */
  145.     while (connect(fd, addr, addrlen) == -1) {
  146.     if (errno != EINTR) {
  147.           (void) close (fd);
  148.           return(-1);         /* errno set by system call. */
  149.     }
  150.       }
  151.   }
  152.   /*
  153.    * Return the id if the connection succeeded.
  154.    */
  155.   return(fd);
  156. }
  157.