diff options
-rwxr-xr-x | home/.bin/dtch.c | 134 |
1 files changed, 59 insertions, 75 deletions
diff --git a/home/.bin/dtch.c b/home/.bin/dtch.c index dc3b5719..f5483e4a 100755 --- a/home/.bin/dtch.c +++ b/home/.bin/dtch.c @@ -6,20 +6,23 @@ ln -f $bin/dtch $bin/atch exit #endif -#include <err.h> -#include <errno.h> +#include <sys/wait.h> +#include <util.h> +#include <sys/stat.h> #include <fcntl.h> #include <poll.h> -#include <stdio.h> #include <stdlib.h> -#include <sys/ioctl.h> +#include <sysexits.h> +#include <unistd.h> +#include <sys/types.h> #include <sys/socket.h> -#include <sys/stat.h> +#include <pwd.h> +#include <err.h> #include <sys/un.h> -#include <sysexits.h> +#include <stdio.h> +#include <errno.h> +#include <sys/ioctl.h> #include <termios.h> -#include <unistd.h> -#include <util.h> static struct passwd *getUser(void) { uid_t uid = getuid(); @@ -28,28 +31,23 @@ static struct passwd *getUser(void) { return user; } -static void createDir(const char *home) { - int fd = open(home, 0); - if (fd < 0) err(EX_IOERR, "%s", home); - - int error = mkdirat(fd, ".dtch", S_IRWXU); - if (error && errno != EEXIST) err(EX_IOERR, "%s/.dtch", home); - - error = close(fd); - if (error) err(EX_IOERR, "%s", home); -} - static struct sockaddr_un sockAddr(const char *home, const char *name) { struct sockaddr_un addr = { .sun_family = AF_LOCAL }; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/.dtch/%s", home, name); return addr; } -static char z; -static struct iovec iov = { - .iov_base = &z, - .iov_len = sizeof(z), -}; +static ssize_t writeAll(int fd, const char *buf, size_t len) { + ssize_t writeLen; + while (0 < (writeLen = write(fd, buf, len))) { + buf += writeLen; + len -= writeLen; + } + return writeLen; +} + +char z; +struct iovec iov = { .iov_base = &z, .iov_len = 1 }; static ssize_t sendFd(int sock, int fd) { size_t len = CMSG_LEN(sizeof(int)); @@ -84,27 +82,12 @@ static int recvFd(int sock) { if (n < 0) return -1; struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - if (!cmsg) { - errno = ENOMSG; - return -1; - } - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { - errno = EBADMSG; - return -1; - } + if (!cmsg) { errno = ENOMSG; return -1; } + if (cmsg->cmsg_type != SCM_RIGHTS) { errno = EBADMSG; return -1; } return *(int *)CMSG_DATA(cmsg); } -static ssize_t writeAll(int fd, const char *buf, ssize_t len) { - ssize_t writeLen; - while (0 < (writeLen = write(fd, buf, len))) { - buf += writeLen; - len -= writeLen; - } - return writeLen; -} - static struct sockaddr_un addr; static void unlinkAddr(void) { @@ -114,10 +97,10 @@ static void unlinkAddr(void) { static int dtch(int argc, char *argv[]) { int error; - const struct passwd *user = getUser(); - const char *name = user->pw_name; - const char *cmd = user->pw_shell; + struct passwd *user = getUser(); + char *name = user->pw_name; + char *cmd = user->pw_shell; if (argc > 2) { name = argv[1]; cmd = argv[2]; @@ -127,12 +110,17 @@ static int dtch(int argc, char *argv[]) { argv++; } + int home = open(user->pw_dir, 0); + if (home < 0) err(EX_IOERR, "%s", user->pw_dir); + error = mkdirat(home, ".dtch", S_IRWXU); + if (error && errno != EEXIST) err(EX_IOERR, "%s/.dtch", user->pw_dir); + error = close(home); + if (error) err(EX_IOERR, "%s", user->pw_dir); + int server = socket(PF_LOCAL, SOCK_STREAM, 0); - if (server < 0) err(EX_IOERR, "socket"); + if (server < 0) err(EX_OSERR, "socket"); - createDir(user->pw_dir); addr = sockAddr(user->pw_dir, name); - error = bind(server, (struct sockaddr *)&addr, sizeof(addr)); if (error) err(EX_IOERR, "%s", addr.sun_path); atexit(unlinkAddr); @@ -151,12 +139,12 @@ static int dtch(int argc, char *argv[]) { err(EX_OSERR, "%s", cmd); } - error = listen(server, 1); - if (error) err(EX_IOERR, "listen"); + error = listen(server, 0); + if (error) err(EX_OSERR, "listen"); for (;;) { int client = accept(server, NULL, NULL); - if (client < 0) err(EX_IOERR, "accept"); + if (client < 0) err(EX_IOERR, "accept(%d)", server); ssize_t len = sendFd(client, master); if (len < 0) warn("sendmsg(%d)", client); @@ -182,23 +170,28 @@ static void restoreTerm(void) { static int atch(int argc, char *argv[]) { int error; - const struct passwd *user = getUser(); - - const char *name = user->pw_name; - if (argc > 1) name = argv[1]; + struct passwd *user = getUser(); + char *name = (argc > 1) ? argv[1] : user->pw_name; int client = socket(PF_LOCAL, SOCK_STREAM, 0); - if (client < 0) err(EX_IOERR, "socket"); + if (client < 0) err(EX_OSERR, "socket"); - addr = sockAddr(user->pw_dir, name); + struct sockaddr_un addr = sockAddr(user->pw_dir, name); error = connect(client, (struct sockaddr *)&addr, sizeof(addr)); if (error) err(EX_IOERR, "%s", addr.sun_path); int master = recvFd(client); if (master < 0) err(EX_IOERR, "recvmsg(%d)", client); + struct winsize window; + error = ioctl(STDERR_FILENO, TIOCGWINSZ, &window); + if (error) err(EX_IOERR, "ioctl(%d, TIOCGWINSZ)", STDERR_FILENO); + + error = ioctl(master, TIOCSWINSZ, &window); + if (error) err(EX_IOERR, "ioctl(%d, TIOCSWINSZ)", master); + error = tcgetattr(STDERR_FILENO, &saveTerm); - if (error) err(EX_USAGE, "tcgetattr(%d)", STDERR_FILENO); + if (error) err(EX_IOERR, "tcgetattr(%d)", STDERR_FILENO); atexit(restoreTerm); struct termios raw; @@ -206,41 +199,32 @@ static int atch(int argc, char *argv[]) { error = tcsetattr(STDERR_FILENO, TCSADRAIN, &raw); if (error) err(EX_IOERR, "tcsetattr(%d)", STDERR_FILENO); - struct winsize window; - error = ioctl(STDERR_FILENO, TIOCGWINSZ, &window); - if (error) warn("ioctl(%d, TIOCGWINSZ)", STDERR_FILENO); - error = ioctl(master, TIOCSWINSZ, &window); - if (error) warn("ioctl(%d, TIOCSWINSZ)", master); - - struct pollfd fds[2]; - fds[0].fd = STDIN_FILENO; - fds[0].events = POLLIN; - fds[1].fd = master; - fds[1].events = POLLIN; + struct pollfd fds[2] = { + { .fd = STDIN_FILENO, .events = POLLIN }, + { .fd = master, .events = POLLIN }, + }; char buf[4096]; + ssize_t len; while (0 < poll(fds, 2, -1)) { if (fds[0].revents) { - ssize_t len = read(STDIN_FILENO, buf, sizeof(buf)); + len = read(STDIN_FILENO, buf, sizeof(buf)); if (len < 0) err(EX_IOERR, "read(%d)", STDIN_FILENO); - if (len && buf[0] == CTRL('Q')) { - exit(EX_OK); - } + if (len && buf[0] == CTRL('Q')) exit(EX_OK); len = writeAll(master, buf, len); if (len < 0) err(EX_IOERR, "write(%d)", master); } if (fds[1].revents) { - ssize_t len = read(master, buf, sizeof(buf)); + len = read(master, buf, sizeof(buf)); if (len < 0) err(EX_IOERR, "read(%d)", master); len = writeAll(STDOUT_FILENO, buf, len); if (len < 0) err(EX_IOERR, "write(%d)", STDOUT_FILENO); } - } - err(EX_IOERR, "poll"); + err(EX_IOERR, "poll([%d,%d])", STDIN_FILENO, master); } int main(int argc, char *argv[]) { |