home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / CLX / socket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-07  |  4.3 KB  |  154 lines

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