diff options
author | John Ankarström <john@ankarstrom.se> | 2021-07-14 19:54:17 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2021-07-14 19:54:17 +0200 |
commit | 550f057dcf1713c5e1d4b55d2108ed69ca9c28d7 (patch) | |
tree | 7497b4b090956c33354492ae829abd9cdb4c4f13 /rtty.c | |
parent | 380dbf038fe4bb257b52067ec2a5a1e30a3f10a5 (diff) | |
download | rtty-550f057dcf1713c5e1d4b55d2108ed69ca9c28d7.tar.gz |
Implement rtty in rio.c, rename to rtty.c
Diffstat (limited to 'rtty.c')
-rw-r--r-- | rtty.c | 123 |
1 files changed, 123 insertions, 0 deletions
@@ -0,0 +1,123 @@ +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/select.h> +#include <sys/stat.h> +#include <unistd.h> + +#define MAXBUF 2048 + +int +main(int argc, char *argv[]) +{ + char bufin[MAXBUF], bufout[MAXBUF], *bi, *bo, in[30], **nargv, out[30]; + fd_set rfds0, rfds1; + int fdin, fdout, i, n; + struct timeval tv; + + /* Create named pipes. */ + sprintf(in, "/var/tmp/rtty.in.%d", getpid()); + sprintf(out, "/var/tmp/rtty.out.%d", getpid()); + if(mkfifo(in, 0644) == -1 || mkfifo(out, 0664) == -1) + if(errno != EEXIST) + err(1, "mkfifo"); + + if(fork() == 0){ + /* Redirect standard in, out. */ + if(!(fdin = open(in, O_RDONLY))) + err(1, "open"); + if(!(fdout = open(out, O_WRONLY))) + err(1, "open"); + dup2(fdin, 0); + dup2(fdout, 1); + + /* Create new argument vector. */ + if(!(nargv = malloc(sizeof(char *)*(argc+1)))) + err(1, "malloc"); + nargv[0] = "ssh"; + nargv[1] = "-tt"; + for(i = 1; i < argc; i++) + nargv[i+1] = argv[i]; + nargv[argc+1] = NULL; + + /* Exec into ssh. */ + execvp("ssh", nargv); + err(1, "execvp"); + } + + if(!(fdin = open(in, O_WRONLY))) + err(1, "open"); + if(!(fdout = open(out, O_RDONLY))) + err(1, "open"); + + dprintf(fdin, "export TERM=tty43 PAGER=cat EDITOR=ed\n"); + + FD_ZERO(&rfds0); + FD_ZERO(&rfds1); + + tv.tv_sec = 0; + tv.tv_usec = 1; + + for(;;){ + /* + * User input is read from standard in and copied the + * input pipe. It is saved in bufin for later use. + */ + FD_SET(0, &rfds0); + if(select(0+1, &rfds0, NULL, NULL, &tv) > 0){ + n = read(0, bufin, MAXBUF); + bufin[n] = 0; + dprintf(fdin, "%s", bufin); + fflush(stdout); + } + + /* + * System output is read from the output pipe and copied + * to standard out for the user to see. + */ + FD_SET(fdout, &rfds1); + if(select(fdout+1, &rfds1, NULL, NULL, &tv) > 0){ + n = read(fdout, bufout, MAXBUF); + if(!n) continue; + bufout[n] = 0; + + /* + * Bufin and bufout are copied to the temporary + * pointers bi and bo. Bo is incremented in order + * to skip any potential repetition of the command + * given by the user on standard in. (It is assumed + * that the typed command fits in bufin, i.e. is + * not larger than MAXBUF.) + */ + bi = bufin; + bo = bufout; + for(;;){ + if(*bo == '\n'){ + bo++; + break; + } + if(*bo == 13){ + bo++; + continue; + } + if(*bi != *bo){ + bo = bufout; + break; + } + bi++; bo++; + } + + /* + * Bo is printed and bufin is cleared, so as not + * to perform the skip again, incorrectly. + */ + printf("%s", bo); + fflush(stdout); + bufin[0] = 0; + } + } + +} |