blind-from-named.c (2249B)
1 /* See LICENSE file for copyright and license details. */ 2 #include "common.h" 3 4 USAGE("[-t decisecs] [-a] ([-f fd] path [command ...] | path)") 5 6 static int 7 erecv_fd(int sock) 8 { 9 int fd; 10 char buf[1]; 11 struct iovec iov; 12 struct msghdr msg; 13 struct cmsghdr *cmsg; 14 char cms[CMSG_SPACE(sizeof(fd))]; 15 16 iov.iov_base = buf; 17 iov.iov_len = 1; 18 19 memset(&msg, 0, sizeof(msg)); 20 msg.msg_name = 0; 21 msg.msg_namelen = 0; 22 msg.msg_iov = &iov; 23 msg.msg_iovlen = 1; 24 25 msg.msg_control = (caddr_t)cms; 26 msg.msg_controllen = sizeof(cms); 27 28 switch (recvmsg(sock, &msg, 0)) { 29 case -1: 30 eprintf("recvmsg:"); 31 case 0: 32 eprintf("recvmsg: connection closed by peer"); 33 default: 34 break; 35 } 36 37 cmsg = CMSG_FIRSTHDR(&msg); 38 memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); 39 return fd; 40 } 41 42 int 43 main(int argc, char *argv[]) 44 { 45 char buf[BUFSIZ]; 46 struct sockaddr_un addr; 47 int abstract = 0; 48 int filedes = -1; 49 int tries = 11; 50 int sockfd, fd; 51 size_t n; 52 53 ARGBEGIN { 54 case 'a': 55 abstract = 1; 56 break; 57 case 'f': 58 filedes = etoi_flag('f', UARGF(), 0, INT_MAX); 59 break; 60 case 't': 61 tries = etoi_flag('t', UARGF(), 0, INT_MAX - 1) + 1; 62 break; 63 default: 64 usage(); 65 } ARGEND; 66 if (argc < 1 || (filedes >= 0 && argc == 1)) 67 usage(); 68 if (filedes < 0) 69 filedes = STDIN_FILENO; 70 71 memset(&addr, 0, sizeof(addr)); 72 addr.sun_family = AF_UNIX; 73 if (strlen(argv[0]) + (size_t)(1 + abstract) > sizeof(addr.sun_path)) { 74 errno = ENAMETOOLONG; 75 eprintf("%s:", argv[0]); 76 } 77 strcpy(addr.sun_path + abstract, argv[0]); 78 argv++, argc--; 79 80 sockfd = socket(PF_UNIX, SOCK_SEQPACKET, 0); 81 if (sockfd < 0) 82 eprintf("socket PF_UNIX SOCK_SEQPACKET:"); 83 84 retry: 85 if ((connect(sockfd, (const struct sockaddr *)&addr, (size_t)sizeof(addr))) < 0) { 86 if (--tries) { 87 usleep((useconds_t)100000L); 88 goto retry; 89 } else { 90 eprintf("bind %s%s%s:", 91 abstract ? "<abstract:" : "", 92 addr.sun_path + abstract, 93 abstract ? ">" : ""); 94 } 95 } 96 97 fd = erecv_fd(sockfd); 98 close(sockfd); 99 100 if (argc) { 101 if (fd != filedes) { 102 if (dup2(fd, filedes) < 0) 103 eprintf("dup2 %i %i:", fd, filedes); 104 close(fd); 105 } 106 execvp(argv[0], argv); 107 eprintf("execvp %s:", argv[0]); 108 } 109 110 while ((n = eread(fd, buf, sizeof(buf), "<received file>"))) 111 ewriteall(STDOUT_FILENO, buf, n, "<stdout>"); 112 return 0; 113 }