connect.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* posix */
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <fcntl.h>
  7. #include <string.h>
  8. #include <errno.h>
  9. /* bsd extensions */
  10. #include <sys/uio.h>
  11. #include <sys/socket.h>
  12. #include <netinet/in.h>
  13. #include <sys/un.h>
  14. #include "priv.h"
  15. int
  16. connect(int fd, void *a, int alen)
  17. {
  18. Rock *r;
  19. int n, cfd, nfd;
  20. char msg[128];
  21. char file[128];
  22. struct sockaddr_in *lip, *rip;
  23. struct sockaddr_un *runix;
  24. static int vers;
  25. r = _sock_findrock(fd, 0);
  26. if(r == 0){
  27. errno = ENOTSOCK;
  28. return -1;
  29. }
  30. if(alen > sizeof(r->raddr)){
  31. errno = ENAMETOOLONG;
  32. return -1;
  33. }
  34. memmove(&r->raddr, a, alen);
  35. switch(r->domain){
  36. case PF_INET:
  37. /* set up a tcp or udp connection */
  38. cfd = open(r->ctl, O_RDWR);
  39. if(cfd < 0){
  40. _syserrno();
  41. return -1;
  42. }
  43. rip = a;
  44. lip = (struct sockaddr_in*)&r->addr;
  45. if(lip->sin_port)
  46. sprintf(msg, "connect %s!%d%s %d",
  47. inet_ntoa(rip->sin_addr), ntohs(rip->sin_port),
  48. r->reserved ? "!r" : "",
  49. ntohs(lip->sin_port));
  50. else
  51. sprintf(msg, "connect %s!%d%s", inet_ntoa(rip->sin_addr),
  52. ntohs(rip->sin_port),
  53. r->reserved ? "!r" : "");
  54. n = write(cfd, msg, strlen(msg));
  55. if(n < 0){
  56. _syserrno();
  57. close(cfd);
  58. return -1;
  59. }
  60. close(cfd);
  61. return 0;
  62. case PF_UNIX:
  63. /* null terminate the address */
  64. if(alen == sizeof(r->raddr))
  65. alen--;
  66. *(((char*)&r->raddr)+alen) = 0;
  67. if(r->other < 0){
  68. errno = EGREG;
  69. return -1;
  70. }
  71. /* put far end of our pipe in /srv */
  72. sprintf(msg, "UD.%d.%d", getpid(), vers++);
  73. if(_sock_srv(msg, r->other) < 0){
  74. r->other = -1;
  75. return -1;
  76. }
  77. r->other = -1;
  78. /* tell server the /srv file to open */
  79. runix = (struct sockaddr_un*)&r->raddr;
  80. _sock_srvname(file, runix->sun_path);
  81. nfd = open(file, O_RDWR);
  82. if(nfd < 0){
  83. _syserrno();
  84. unlink(msg);
  85. return -1;
  86. }
  87. if(write(nfd, msg, strlen(msg)) < 0){
  88. _syserrno();
  89. close(nfd);
  90. unlink(msg);
  91. return -1;
  92. }
  93. close(nfd);
  94. /* wait for server to open it and then remove it */
  95. read(fd, file, sizeof(file));
  96. _sock_srvname(file, msg);
  97. unlink(file);
  98. return 0;
  99. default:
  100. errno = EAFNOSUPPORT;
  101. return -1;
  102. }
  103. }