blind-to-named.c (1722B)
1 /* See LICENSE file for copyright and license details. */ 2 #include "common.h" 3 4 USAGE("[-a] path") 5 6 static void 7 esend_fd(int sock, int fd) 8 { 9 char buf[1]; 10 struct iovec iov; 11 struct msghdr msg; 12 struct cmsghdr *cmsg; 13 char cms[CMSG_SPACE(sizeof(fd))]; 14 15 buf[0] = 0; 16 iov.iov_base = buf; 17 iov.iov_len = 1; 18 19 memset(&msg, 0, sizeof(msg)); 20 msg.msg_iov = &iov; 21 msg.msg_iovlen = 1; 22 msg.msg_control = (caddr_t)cms; 23 msg.msg_controllen = CMSG_LEN(sizeof(fd)); 24 25 cmsg = CMSG_FIRSTHDR(&msg); 26 cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); 27 cmsg->cmsg_level = SOL_SOCKET; 28 cmsg->cmsg_type = SCM_RIGHTS; 29 memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd)); 30 31 if (sendmsg(sock, &msg, 0) != (ssize_t)iov.iov_len) 32 eprintf("sendmsg:"); 33 } 34 35 int 36 main(int argc, char *argv[]) 37 { 38 struct sockaddr_un addr; 39 int abstract = 0; 40 int serverfd, connfd; 41 42 ARGBEGIN { 43 case 'a': 44 abstract = 1; 45 break; 46 default: 47 usage(); 48 } ARGEND; 49 if (argc != 1) 50 usage(); 51 52 memset(&addr, 0, sizeof(addr)); 53 addr.sun_family = AF_UNIX; 54 if (strlen(argv[0]) + (size_t)(1 + abstract) > sizeof(addr.sun_path)) { 55 errno = ENAMETOOLONG; 56 eprintf("%s:", argv[0]); 57 } 58 strcpy(addr.sun_path + abstract, argv[0]); 59 60 serverfd = socket(PF_UNIX, SOCK_SEQPACKET, 0); 61 if (serverfd < 0) 62 eprintf("socket PF_UNIX SOCK_SEQPACKET:"); 63 64 if (bind(serverfd, (const struct sockaddr *)&addr, (size_t)sizeof(addr)) < 0) 65 eprintf("bind %s%s%s:", 66 abstract ? "<abstract:" : "", 67 addr.sun_path + abstract, 68 abstract ? ">" : ""); 69 70 if (listen(serverfd, 1) < 0) 71 eprintf("listen:"); 72 73 connfd = accept(serverfd, NULL, NULL); 74 if (connfd < 0) 75 eprintf("accept:"); 76 77 if (*addr.sun_path) 78 unlink(addr.sun_path); 79 close(serverfd); 80 81 esend_fd(connfd, STDIN_FILENO); 82 close(connfd); 83 return 0; 84 }