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