diff options
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | Makefile | 38 | ||||
-rw-r--r-- | create.c | 49 | ||||
-rw-r--r-- | destroy.c | 40 | ||||
-rw-r--r-- | ingest.c | 54 | ||||
-rw-r--r-- | ssh-command.sh | 58 | ||||
-rw-r--r-- | view.c | 136 |
7 files changed, 18 insertions, 363 deletions
diff --git a/.gitignore b/.gitignore index cd963a4..f5ed2af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,5 @@ chroot.tar -create -destroy -ingest +config.mk ptee root -ssh-command tags -view diff --git a/Makefile b/Makefile index 7e8053e..ece7cca 100644 --- a/Makefile +++ b/Makefile @@ -1,36 +1,32 @@ -BINS = create destroy ingest ptee ssh-command view -USER = stream +CHROOT_USER = stream +CHROOT_GROUP = ${CHROOT_USER} CFLAGS += -Wall -Wextra -Wpedantic +LDFLAGS = -static LDLIBS = -lutil -all: tags $(BINS) +-include config.mk + +BINS = ptee + +all: tags ${BINS} tags: *.c ctags -w *.c -chroot.tar: $(BINS) +chroot.tar: ${BINS} mkdir -p root install -d -o root -g wheel \ + root \ root/bin \ root/home \ - root/lib \ - root/libexec \ - root/usr \ - root/usr/share \ root/usr/share/misc - install -d -o $(USER) -g $(USER) root/home/$(USER) - install -o root -g wheel -m 555 /libexec/ld-elf.so.1 root/libexec - install -o root -g wheel -m 444 \ - /lib/libc.so.7 \ - /lib/libedit.so.7 \ - /lib/libncursesw.so.8 \ - /lib/libutil.so.9 \ - root/lib - install -o root -g wheel -m 444 /usr/share/misc/termcap.db root/usr/share/misc - install -o root -g wheel -m 555 /bin/sh root/bin - install -o root -g wheel -m 555 $(BINS) root/bin - tar -c -f chroot.tar -C root bin home lib libexec usr + install -d -o ${CHROOT_USER} -g ${CHROOT_GROUP} root/home/${CHROOT_USER} + cp -af /usr/share/locale root/usr/share + cp -fp /usr/share/misc/termcap.db root/usr/share/misc + cp -fp /rescue/sh root/bin + install ${BINS} root/bin + tar -c -f chroot.tar -C root bin home usr clean: - rm -f tags $(BINS) chroot.tar + rm -fr ${BINS} tags chroot.tar root diff --git a/create.c b/create.c deleted file mode 100644 index 59eb3e0..0000000 --- a/create.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2018 Causal Agent June <june@causal.agency> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <err.h> -#include <fcntl.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <sysexits.h> -#include <unistd.h> - -int main(int argc, char *argv[]) { - if (argc < 2) errx(EX_USAGE, "missing public id"); - - uint32_t id[4]; - char public[sizeof("../public/") + 32]; - char private[sizeof("private/") + 2 * sizeof(id)]; - - arc4random_buf(id, sizeof(id)); - snprintf(public, sizeof(public), "public/%s", argv[1]); - snprintf( - private, sizeof(private), - "private/%08x%08x%08x%08x", - id[0], id[1], id[2], id[3] - ); - - int fd = open(public, O_CREAT | O_EXCL, 0644); - if (fd < 0) err(EX_CANTCREAT, "%s", public); - - snprintf(public, sizeof(public), "../public/%s", argv[1]); - int error = symlink(public, private); - if (error) err(EX_CANTCREAT, "%s", private); - - printf("%08x%08x%08x%08x\n", id[0], id[1], id[2], id[3]); - return EX_OK; -} diff --git a/destroy.c b/destroy.c deleted file mode 100644 index 6a82bbe..0000000 --- a/destroy.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2018 Causal Agent June <june@causal.agency> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <err.h> -#include <fcntl.h> -#include <sysexits.h> -#include <unistd.h> - -int main(int argc, char *argv[]) { - if (argc < 2) errx(EX_USAGE, "missing private id"); - - int fd = open("private", 0); - if (fd < 0) err(EX_NOINPUT, "private"); - - const char *private = argv[1]; - char public[sizeof("../public/") + 32] = {0}; - ssize_t n = readlinkat(fd, private, public, sizeof(public) - 1); - if (n < 0) err(EX_NOINPUT, "%s", private); - - int error = unlinkat(fd, public, 0); - if (error) err(EX_NOINPUT, "%s", public); - - error = unlinkat(fd, private, 0); - if (error) err(EX_NOINPUT, "%s", private); - - return EX_OK; -} diff --git a/ingest.c b/ingest.c deleted file mode 100644 index b729169..0000000 --- a/ingest.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2018 Causal Agent June <june@causal.agency> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <err.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sysexits.h> -#include <unistd.h> - -int main(int argc, char *argv[]) { - if (argc < 2) errx(EX_USAGE, "missing private id"); - - const char *path = argv[1]; - int local = open(path, O_WRONLY); - if (local < 0) err(EX_NOINPUT, "%s", path); - - int remote = STDIN_FILENO; - - struct winsize window; - ssize_t size = read(remote, &window, sizeof(window)); - if (size < 0) err(EX_IOERR, "read(%d)", remote); - if ((size_t)size < sizeof(window)) errx(EX_DATAERR, "short read(%d)", remote); - - for (;;) { - ftruncate(local, 0); - lseek(local, 0, SEEK_SET); - - ssize_t size = write(local, &window, sizeof(window)); - if (size < 0) err(EX_IOERR, "write(%d)", local); - - char buf[4096]; - for (size_t totalSize = 0; totalSize < 1024 * 1024; totalSize += size) { - size = read(remote, buf, sizeof(buf)); - if (size < 0) err(EX_IOERR, "read(%d)", remote); - if (!size) return EX_OK; - - size = write(local, buf, size); - if (size < 0) err(EX_IOERR, "write(%d)", local); - } - } -} diff --git a/ssh-command.sh b/ssh-command.sh deleted file mode 100644 index 81564b4..0000000 --- a/ssh-command.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh -set -e -u - -SSH_URL=stream@ascii.town -GIT_URL=git@ascii.town:stream.git - -welcome() { - echo - echo ' [~ The Stream at ASCII Town ~] ' - echo - cd public - for id in *; do - echo " ssh -t $SSH_URL $id" - done - echo - echo ' [~ A Stream of Your Own ~] ' - echo - echo " ssh -t $SSH_URL start" - echo -} - -start() { - local public private trash - read -p 'Public ID: ' -r public trash - public=${public##*/} - private=$(create $public) - echo "Private ID: $private" - echo - echo ' [~ Stop ~] ' - echo - echo " ssh -t $SSH_URL stop $private" - echo - echo ' [~ View ~] ' - echo - echo " ssh -t $SSH_URL $public" - echo - echo ' [~ Broadcast ~] ' - echo - echo " git clone $GIT_URL" - echo ' cd stream' - echo ' make ptee' - echo " ./ptee | ssh $SSH_URL ingest $private" - echo -} - -if [ -z "${SSH_ORIGINAL_COMMAND:-}" ]; then - welcome - exit -else - set $SSH_ORIGINAL_COMMAND - case $1 in - start) start ;; - stop) exec destroy ${2##*/} ;; - ingest) exec ingest private/${2##*/} ;; - view) exec view public/${2##*/} ;; - *) exec view public/${1##*/} ;; - esac -fi diff --git a/view.c b/view.c deleted file mode 100644 index b8f8793..0000000 --- a/view.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (C) 2018 Causal Agent June <june@causal.agency> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <sys/types.h> - -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdlib.h> -#include <sys/event.h> -#include <sys/ioctl.h> -#include <sysexits.h> -#include <termios.h> -#include <unistd.h> - -static void nop() { } - -static struct { - int remote; - int local; - int input; -} fd = { -1, STDOUT_FILENO, STDIN_FILENO }; - -static struct termios saveTerm; -static void restoreTerm(void) { - tcsetattr(fd.input, TCSADRAIN, &saveTerm); -} - -int main(int argc, char *argv[]) { - int error; - - if (argc < 2) errx(EX_USAGE, "missing public id"); - if (!isatty(fd.local)) errx(EX_USAGE, "no terminal (use ssh -t)"); - - const char *path = argv[1]; - fd.remote = open(path, O_RDONLY); - if (fd.remote < 0) err(EX_NOINPUT, "%s", path); - - error = tcgetattr(fd.input, &saveTerm); - if (error) err(EX_IOERR, "tcgetattr"); - atexit(restoreTerm); - - struct termios term = saveTerm; - term.c_lflag &= ~(ICANON | ECHO); - error = tcsetattr(fd.input, TCSADRAIN, &term); - if (error) err(EX_IOERR, "tcsetattr"); - - signal(SIGWINCH, nop); - - int kq = kqueue(); - if (kq < 0) err(EX_OSERR, "kqueue"); - - struct kevent events[2] = { - { .ident = fd.input, .filter = EVFILT_READ, .flags = EV_ADD }, - { .ident = fd.remote, .filter = EVFILT_READ, .flags = EV_ADD }, - }; - int nevents = kevent(kq, events, 2, NULL, 0, NULL); - if (nevents < 0) err(EX_OSERR, "kevent"); - - for (;;) { - off_t off = lseek(fd.remote, 0, SEEK_SET); - if (off < 0) err(EX_IOERR, "%s", path); - - struct winsize localWindow; - error = ioctl(fd.local, TIOCGWINSZ, &localWindow); - if (error) err(EX_IOERR, "TIOCGWINSZ"); - - // FIXME: Hack spin waiting for remote window. - struct winsize remoteWindow; - ssize_t size; - for (int i = 0; i < 100; ++i, usleep(100)) { - size = read(fd.remote, &remoteWindow, sizeof(remoteWindow)); - if (size < 0) err(EX_IOERR, "read(%d)", fd.remote); - if (size) break; - } - if ((size_t)size < sizeof(remoteWindow)) { - errx(EX_DATAERR, "no window size (stream not started)"); - } - - if ( - localWindow.ws_col < remoteWindow.ws_col - || localWindow.ws_row < remoteWindow.ws_row - ) { - warnx( - "resize window %hux%hu to at least %hux%hu", - localWindow.ws_col, localWindow.ws_row, - remoteWindow.ws_col, remoteWindow.ws_row - ); - sigset_t mask; - sigemptyset(&mask); - sigsuspend(&mask); - continue; - } - - char buf[4096]; - for (;;) { - struct kevent event; - int nevents = kevent(kq, NULL, 0, &event, 1, NULL); - if (nevents < 0) { - if (errno == EINTR) break; - err(EX_OSERR, "kevent"); - } - - if (event.ident == (uintptr_t)fd.input) { - ssize_t size = read(fd.input, buf, sizeof(buf)); - if (size < 0) err(EX_IOERR, "read(%d)", fd.input); - if (size == 1 && buf[0] == 'q') return EX_OK; - } - - if (event.ident == (uintptr_t)fd.remote) { - if (event.data < 0) break; - - ssize_t readSize = read(fd.remote, buf, sizeof(buf)); - if (readSize < 0) err(EX_IOERR, "read(%d)", fd.remote); - - ssize_t writeSize = write(fd.local, buf, readSize); - if (writeSize < 0) err(EX_IOERR, "write(%d)", fd.local); - if (writeSize < readSize) errx(EX_IOERR, "short write(%d)", fd.local); - } - } - } -} |