diff options
| author | Mattias Andrée <maandree@kth.se> | 2017-05-25 15:30:17 +0200 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2017-05-25 17:47:23 +0200 |
| commit | 7b147cb0c1eaa728f244cc8390ccfcc3f4aee03a (patch) | |
| tree | 80e23538c1d8b364ec9c8c7e58e895b9a471dfef /src | |
| parent | Fix errors and warnings and make the code cleaner (diff) | |
| download | blind-7b147cb0c1eaa728f244cc8390ccfcc3f4aee03a.tar.gz blind-7b147cb0c1eaa728f244cc8390ccfcc3f4aee03a.tar.bz2 blind-7b147cb0c1eaa728f244cc8390ccfcc3f4aee03a.tar.xz | |
Add blind-from-named and blind-to-named
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rw-r--r-- | src/blind-from-named.c | 149 | ||||
| -rw-r--r-- | src/blind-to-named.c | 84 | ||||
| -rw-r--r-- | src/common.h | 22 |
3 files changed, 255 insertions, 0 deletions
diff --git a/src/blind-from-named.c b/src/blind-from-named.c new file mode 100644 index 0000000..1ca4c7f --- /dev/null +++ b/src/blind-from-named.c @@ -0,0 +1,149 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-t decisecs] [-a] ([-f fd] path [command ...] | path)") + +static int +erecv_fd(int sock) +{ + int fd; + char buf[1]; + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsg; + char cms[CMSG_SPACE(sizeof(fd))]; + + iov.iov_base = buf; + iov.iov_len = 1; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = 0; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + msg.msg_control = (caddr_t)cms; + msg.msg_controllen = sizeof(cms); + + switch (recvmsg(sock, &msg, 0)) { + case -1: + eprintf("recvmsg:"); + case 0: + eprintf("recvmsg: connection closed by peer"); + default: + break; + } + + cmsg = CMSG_FIRSTHDR(&msg); + memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); + return fd; +} + +#if !defined(HAVE_SENDFILE) +# if !defined(PIPE_BUF) +# define PIPE_BUF BUFSIZ +# endif +static ssize_t +sendfile(int outfd, int infd, off_t *offset, size_t count) +{ + char buf[PIPE_BUF]; + ssize_t r, w, p, ret = 0; + + (void) offset; + (void) count; + + for (;;) { + r = read(infd, buf, sizeof(buf)); + if (r < 0) + eprintf("read <received file>:"); + if (!r) + break; + ret += r; + for (p = 0; p < r; p += w) { + w = write(outfd, buf + p, r - p); + if (w < 0) + eprintf("write <stdout>:"); + } + } + + return ret; +} +#endif + +int +main(int argc, char *argv[]) +{ + struct sockaddr_un addr; + int abstract = 0; + int filedes = -1; + int tries = 10; + int sockfd, fd; + + ARGBEGIN { + case 'a': + abstract = 1; + break; + case 'f': + filedes = etoi_flag('f', UARGF(), 0, INT_MAX); + break; + case 't': + tries = etoi_flag('t', UARGF(), 1, INT_MAX); + break; + default: + usage(); + } ARGEND; + if (argc < 1 || (filedes >= 0 && argc > 1)) + usage(); + if (argc > 0 && filedes < 0) + filedes = 0; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + if (strlen(argv[0]) + 1 + abstract > sizeof(addr.sun_path)) { + errno = ENAMETOOLONG; + eprintf("%s:", argv[0]); + } + strcpy(addr.sun_path + abstract, argv[0]); + argv++, argc--; + + sockfd = socket(PF_UNIX, SOCK_SEQPACKET, 0); + if (sockfd < 0) + eprintf("socket PF_UNIX SOCK_SEQPACKET:"); + +retry: + if ((connect(sockfd, (const struct sockaddr *)&addr, (size_t)sizeof(addr))) < 0) { + if (--tries) { + usleep((useconds_t)100000L); + goto retry; + } else { + eprintf("bind %s%s%s:", + abstract ? "<abstract:" : "", + addr.sun_path + abstract, + abstract ? ">" : ""); + } + } + + fd = erecv_fd(sockfd); + close(sockfd); + + if (argc) { + if (fd != filedes) { + if (dup2(fd, filedes) < 0) + eprintf("dup2 %i %i:", fd, filedes); + close(fd); + } + execvp(argv[0], argv); + eprintf("execvp %s:", argv[0]); + } + + for (;;) { + switch (sendfile(STDOUT_FILENO, fd, NULL, SIZE_MAX)) { + case 0: + return 0; + case -1: + eprintf("sendfile <stdout> <received file>:"); + default: + break; + } + } +} diff --git a/src/blind-to-named.c b/src/blind-to-named.c new file mode 100644 index 0000000..a42f771 --- /dev/null +++ b/src/blind-to-named.c @@ -0,0 +1,84 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-a] path") + +static void +esend_fd(int sock, int fd) +{ + char buf[1]; + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsg; + char cms[CMSG_SPACE(sizeof(fd))]; + + buf[0] = 0; + iov.iov_base = buf; + iov.iov_len = 1; + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = (caddr_t)cms; + msg.msg_controllen = CMSG_LEN(sizeof(fd)); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd)); + + if (sendmsg(sock, &msg, 0) != iov.iov_len) + eprintf("sendmsg:"); +} + +int +main(int argc, char *argv[]) +{ + struct sockaddr_un addr; + int abstract = 0; + int serverfd, connfd; + + ARGBEGIN { + case 'a': + abstract = 1; + break; + default: + usage(); + } ARGEND; + if (argc != 1) + usage(); + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + if (strlen(argv[0]) + 1 + abstract > sizeof(addr.sun_path)) { + errno = ENAMETOOLONG; + eprintf("%s:", argv[0]); + } + strcpy(addr.sun_path + abstract, argv[0]); + + serverfd = socket(PF_UNIX, SOCK_SEQPACKET, 0); + if (serverfd < 0) + eprintf("socket PF_UNIX SOCK_SEQPACKET:"); + + if (bind(serverfd, (const struct sockaddr *)&addr, (size_t)sizeof(addr)) < 0) + eprintf("bind %s%s%s:", + abstract ? "<abstract:" : "", + addr.sun_path + abstract, + abstract ? ">" : ""); + + if (listen(serverfd, 1) < 0) + eprintf("listen:"); + + connfd = accept(serverfd, NULL, NULL); + if (connfd < 0) + eprintf("accept:"); + + if (*addr.sun_path) + unlink(addr.sun_path); + close(serverfd); + + esend_fd(connfd, STDIN_FILENO); + close(connfd); + return 0; +} diff --git a/src/common.h b/src/common.h index 3a746f8..3e3f966 100644 --- a/src/common.h +++ b/src/common.h @@ -20,7 +20,13 @@ # include <sys/epoll.h> #endif #include <sys/mman.h> +#if defined(HAVE_SENDFILE) +# include <sys/sendfile.h> +#endif #include <sys/stat.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <sys/un.h> #include <sys/wait.h> #include <alloca.h> #include <ctype.h> @@ -35,3 +41,19 @@ #include <string.h> #include <strings.h> #include <unistd.h> + +#ifndef CMSG_ALIGN +# ifdef __sun__ +# define CMSG_ALIGN _CMSG_DATA_ALIGN +# else +# define CMSG_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1)) +# endif +#endif + +#ifndef CMSG_SPACE +# define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len)) +#endif + +#ifndef CMSG_LEN +# define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) +#endif |
