author | viric@llimona |
Thu, 27 Sep 2007 00:25:54 +0200 | |
changeset 58 | 2cf8c513d18f |
parent 53 | 07500c5c53cb |
child 66 | b2469563a1dc |
permissions | -rw-r--r-- |
53 | 1 |
/* |
2 |
Terminal Mixer - multi-point multi-user access to terminal applications |
|
3 |
Copyright (C) 2007 LluĂs Batlle i Rossell |
|
4 |
||
5 |
Please find the license in the provided COPYING file. |
|
6 |
*/ |
|
21 | 7 |
#include <stdlib.h> |
24 | 8 |
#include <unistd.h> |
21 | 9 |
#include <assert.h> |
26
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
10 |
#include <errno.h> |
21 | 11 |
#include <sys/select.h> |
12 |
||
13 |
#include "main.h" |
|
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
14 |
#include "filter.h" |
21 | 15 |
#include "handlers.h" |
16 |
||
17 |
/* it uses app_stdin, app_stdout, app_stderr. |
|
18 |
* They have value -1 if not opened. */ |
|
19 |
||
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
20 |
static struct FilterRules *fr; |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
21 |
|
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
22 |
void write_newline_cb(struct FilterRules *myfr, |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
23 |
const struct FFilter *ff, char *obuf, int *olen, |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
24 |
const char *ibuf, int pos) |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
25 |
{ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
26 |
obuf[(*olen)++] = '\n'; |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
27 |
} |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
28 |
|
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
29 |
void app_control_start() |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
30 |
{ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
31 |
struct FFilter *ff; |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
32 |
fr = new_filter_rules(); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
33 |
|
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
34 |
/* We don't pay attention to any telnet command */ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
35 |
ff = new_ftelnet(); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
36 |
add_ffilter(fr, ff); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
37 |
|
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
38 |
/* The client will send \r\0 on enter */ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
39 |
ff = new_fstring_len("\r\0", 2); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
40 |
ff->callback = write_newline_cb; |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
41 |
add_ffilter(fr, ff); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
42 |
|
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
43 |
/* We should trim the no operation characters '\0'. |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
44 |
* We rely on the filter application order. First \r\0 above, |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
45 |
* then \0. */ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
46 |
ff = new_fstring_len("\0", 1); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
47 |
add_ffilter(fr, ff); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
48 |
} |
21 | 49 |
|
50 |
void app_control_shutdown() |
|
51 |
{ |
|
52 |
} |
|
53 |
||
54 |
void app_control_prepare_read_fdset(fd_set *read_set, int *maxfd) |
|
55 |
{ |
|
56 |
assert(app_stdout != -1 || app_stderr != -1); |
|
57 |
||
58 |
if (app_stdout != -1) |
|
59 |
{ |
|
60 |
FD_SET(app_stdout, read_set); |
|
61 |
*maxfd = max(*maxfd, app_stdout); |
|
62 |
} |
|
63 |
||
25 | 64 |
if (app_stderr != -1 && app_stdout != app_stderr) |
21 | 65 |
{ |
66 |
FD_SET(app_stderr, read_set); |
|
67 |
*maxfd = max(*maxfd, app_stderr); |
|
68 |
} |
|
69 |
} |
|
70 |
||
71 |
/* Return -1, finished stdout/stderr. Else, return 0. */ |
|
72 |
int app_control_process_read_fdset(fd_set *read_set) |
|
73 |
{ |
|
74 |
if (app_stdout != -1 && FD_ISSET(app_stdout, read_set)) |
|
75 |
{ |
|
76 |
int res; |
|
77 |
res = read(app_stdout, stream_buffer, stream_buffer_size); |
|
26
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
78 |
if (res == -1 && errno == EIO) |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
79 |
{ |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
80 |
/* I've noticed that when the app dies, read() returns EIO */ |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
81 |
app_stdout = -1; |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
82 |
app_stdin = -1; |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
83 |
return -1; |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
84 |
} |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
85 |
if (res == -1 ) |
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
86 |
error("Error reading from app."); |
21 | 87 |
if (res == 0) |
88 |
{ |
|
89 |
close(app_stdout); |
|
41 | 90 |
if (!command_line.s_param.nohup) |
91 |
close(1); |
|
26
96920c3707b3
Unix sockets version works! Well, signals don't. :)
viric@llimona
parents:
25
diff
changeset
|
92 |
if (app_stdout == app_stderr || app_stderr == -1) |
21 | 93 |
return -1; |
49
1cead94cfd99
Fixing a few bugs. The program runs well in Linux and Mac OS X.
viric@llimona
parents:
44
diff
changeset
|
94 |
app_stdout = -1; |
21 | 95 |
} else |
96 |
{ |
|
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
97 |
hex_dump("from app", stream_buffer, res); |
41 | 98 |
if (!command_line.s_param.nohup) |
99 |
write(1, stream_buffer, res); |
|
33 | 100 |
if (command_line.s_param.serve_unix) |
101 |
s_unix_send_to_connected(stream_buffer, res); |
|
102 |
if (command_line.s_param.serve_tcp) |
|
103 |
s_tcp_send_to_connected(stream_buffer, res); |
|
49
1cead94cfd99
Fixing a few bugs. The program runs well in Linux and Mac OS X.
viric@llimona
parents:
44
diff
changeset
|
104 |
#ifdef linux |
44 | 105 |
if (command_line.s_param.serve_eth) |
106 |
s_eth_send_to_connected(stream_buffer, res); |
|
49
1cead94cfd99
Fixing a few bugs. The program runs well in Linux and Mac OS X.
viric@llimona
parents:
44
diff
changeset
|
107 |
#endif /* linux */ |
21 | 108 |
} |
109 |
} |
|
25 | 110 |
if (app_stderr != -1 && app_stdout != app_stderr && |
111 |
FD_ISSET(app_stderr, read_set)) |
|
21 | 112 |
{ |
113 |
int res; |
|
114 |
res = read(app_stderr, stream_buffer, stream_buffer_size); |
|
115 |
if (res == 0) |
|
116 |
{ |
|
117 |
close(app_stderr); |
|
118 |
close(2); /* MOVE */ |
|
119 |
app_stderr = -1; |
|
120 |
if (app_stdout == -1) |
|
121 |
return -1; |
|
122 |
} else |
|
123 |
{ |
|
41 | 124 |
if (!command_line.s_param.nohup) |
125 |
write(2, stream_buffer, res); |
|
33 | 126 |
|
127 |
if (command_line.s_param.serve_unix) |
|
128 |
s_unix_send_to_connected(stream_buffer, res); |
|
129 |
if (command_line.s_param.serve_tcp) |
|
130 |
s_tcp_send_to_connected(stream_buffer, res); |
|
49
1cead94cfd99
Fixing a few bugs. The program runs well in Linux and Mac OS X.
viric@llimona
parents:
44
diff
changeset
|
131 |
#ifdef linux |
44 | 132 |
if (command_line.s_param.serve_eth) |
133 |
s_eth_send_to_connected(stream_buffer, res); |
|
49
1cead94cfd99
Fixing a few bugs. The program runs well in Linux and Mac OS X.
viric@llimona
parents:
44
diff
changeset
|
134 |
#endif /* linux */ |
21 | 135 |
} |
136 |
} |
|
137 |
return 0; |
|
138 |
} |
|
139 |
||
32
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
140 |
void app_control_local_send_to_stdin(const char *buffer, size_t size) |
21 | 141 |
{ |
142 |
if (size == 0) |
|
143 |
close(app_stdin); |
|
144 |
else |
|
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
145 |
{ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
146 |
hex_dump("from local to app", buffer, size); |
21 | 147 |
write(app_stdin, buffer, size); |
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
148 |
} |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
149 |
} |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
150 |
|
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
151 |
static void write_data_to_app_stdin(const char *buffer, size_t size) |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
152 |
{ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
153 |
if (size > 0) |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
154 |
{ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
155 |
hex_dump("to app", buffer, size); |
41 | 156 |
if( !command_line.s_param.nohup && |
157 |
command_line.s_param.echo_in_local_terminal) |
|
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
158 |
write(1, buffer, size); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
159 |
write(app_stdin, buffer, size); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
160 |
} |
21 | 161 |
} |
32
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
162 |
|
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
163 |
void app_control_remote_send_to_stdin(const char *buffer, size_t size) |
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
164 |
{ |
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
165 |
hex_dump("from client prefilter", buffer, size); |
32
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
166 |
if (command_line.s_param.client_can_write) |
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
167 |
{ |
36
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
168 |
int osize; |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
169 |
if (size > 0) |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
170 |
{ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
171 |
filter_stream(fr, ostream_buffer, &osize, |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
172 |
buffer, size); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
173 |
if (osize > 0) |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
174 |
write_data_to_app_stdin(ostream_buffer, osize); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
175 |
} else if (size == 0) |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
176 |
{ |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
177 |
filter_flush(fr, ostream_buffer, &osize); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
178 |
if (osize > 0) |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
179 |
write_data_to_app_stdin(ostream_buffer, osize); |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
180 |
} |
da427c23d755
Added dumps, telnet_filter, applied filters in tm, improved telnet experience.
viric@llimona
parents:
33
diff
changeset
|
181 |
|
32
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
182 |
if (size == 0 && command_line.s_param.client_may_close_app_stdin) |
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
183 |
close(app_stdin); |
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
184 |
} |
df110f784648
Added read-only clients, added stdin-close option to clients.
lbatlle@npdl268.bpo.hp.com
parents:
26
diff
changeset
|
185 |
} |