1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
#define INIT "export TERM=tty43 EDITOR=ed PAGER='pr -ptl23'\n"
#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, INIT);
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;
}
}
}
|