PageRenderTime 39ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/src/clx/socket.c

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