diff options
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; + } + } + +} |