diff options
Diffstat (limited to 'view.c')
-rw-r--r-- | view.c | 136 |
1 files changed, 0 insertions, 136 deletions
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); - } - } - } -} |