#include #include #include #include #include #include #include #include #include #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; } } }