Blame


1 be22ae2d 2004-03-26 devnull #include <u.h>
2 941c9f36 2003-10-11 devnull #include <sys/types.h>
3 941c9f36 2003-10-11 devnull #include <sys/stat.h>
4 941c9f36 2003-10-11 devnull #include <errno.h>
5 941c9f36 2003-10-11 devnull
6 84b1cb73 2003-09-30 devnull #include <u.h>
7 84b1cb73 2003-09-30 devnull #include <libc.h>
8 84b1cb73 2003-09-30 devnull #include <draw.h>
9 84b1cb73 2003-09-30 devnull #include <thread.h>
10 84b1cb73 2003-09-30 devnull #include <mouse.h>
11 84b1cb73 2003-09-30 devnull #include <cursor.h>
12 84b1cb73 2003-09-30 devnull #include <keyboard.h>
13 84b1cb73 2003-09-30 devnull #include <frame.h>
14 2277c5d7 2004-03-21 devnull #define Tversion Tversion9p
15 2277c5d7 2004-03-21 devnull #define Twrite Twrite9p
16 2277c5d7 2004-03-21 devnull #include <fcall.h>
17 2277c5d7 2004-03-21 devnull #undef Tversion
18 2277c5d7 2004-03-21 devnull #undef Twrite
19 d4045724 2005-01-04 devnull #include <9pclient.h>
20 af78a4cd 2004-03-02 devnull #include <plumb.h>
21 84b1cb73 2003-09-30 devnull #include "flayer.h"
22 84b1cb73 2003-09-30 devnull #include "samterm.h"
23 84b1cb73 2003-09-30 devnull
24 941c9f36 2003-10-11 devnull static char *exname;
25 84b1cb73 2003-09-30 devnull
26 64bcfff3 2003-11-25 devnull #define STACK 16384
27 912fba95 2003-11-24 devnull
28 84b1cb73 2003-09-30 devnull void
29 17ab31aa 2005-01-27 devnull usage(void)
30 17ab31aa 2005-01-27 devnull {
31 17ab31aa 2005-01-27 devnull fprint(2, "usage: samterm -a -W winsize\n");
32 17ab31aa 2005-01-27 devnull threadexitsall("usage");
33 17ab31aa 2005-01-27 devnull }
34 17ab31aa 2005-01-27 devnull
35 17ab31aa 2005-01-27 devnull void
36 84b1cb73 2003-09-30 devnull getscreen(int argc, char **argv)
37 84b1cb73 2003-09-30 devnull {
38 84b1cb73 2003-09-30 devnull char *t;
39 84b1cb73 2003-09-30 devnull
40 17ab31aa 2005-01-27 devnull ARGBEGIN{
41 17ab31aa 2005-01-27 devnull case 'a':
42 17ab31aa 2005-01-27 devnull autoindent = 1;
43 17ab31aa 2005-01-27 devnull break;
44 17ab31aa 2005-01-27 devnull case 'W':
45 17ab31aa 2005-01-27 devnull winsize = EARGF(usage());
46 17ab31aa 2005-01-27 devnull break;
47 17ab31aa 2005-01-27 devnull default:
48 17ab31aa 2005-01-27 devnull usage();
49 17ab31aa 2005-01-27 devnull }ARGEND
50 be36ff68 2004-04-29 devnull
51 84b1cb73 2003-09-30 devnull if(initdraw(panic1, nil, "sam") < 0){
52 941c9f36 2003-10-11 devnull fprint(2, "samterm: initdraw: %r\n");
53 84b1cb73 2003-09-30 devnull threadexitsall("init");
54 84b1cb73 2003-09-30 devnull }
55 84b1cb73 2003-09-30 devnull t = getenv("tabstop");
56 75ea8515 2018-03-27 0intro if(t != nil){
57 84b1cb73 2003-09-30 devnull maxtab = strtoul(t, nil, 0);
58 75ea8515 2018-03-27 0intro free(t);
59 75ea8515 2018-03-27 0intro }
60 84b1cb73 2003-09-30 devnull draw(screen, screen->clipr, display->white, nil, ZP);
61 84b1cb73 2003-09-30 devnull }
62 84b1cb73 2003-09-30 devnull
63 84b1cb73 2003-09-30 devnull int
64 84b1cb73 2003-09-30 devnull screensize(int *w, int *h)
65 84b1cb73 2003-09-30 devnull {
66 84b1cb73 2003-09-30 devnull int fd, n;
67 84b1cb73 2003-09-30 devnull char buf[5*12+1];
68 84b1cb73 2003-09-30 devnull
69 84b1cb73 2003-09-30 devnull fd = open("/dev/screen", OREAD);
70 84b1cb73 2003-09-30 devnull if(fd < 0)
71 84b1cb73 2003-09-30 devnull return 0;
72 84b1cb73 2003-09-30 devnull n = read(fd, buf, sizeof(buf)-1);
73 84b1cb73 2003-09-30 devnull close(fd);
74 84b1cb73 2003-09-30 devnull if (n != sizeof(buf)-1)
75 84b1cb73 2003-09-30 devnull return 0;
76 84b1cb73 2003-09-30 devnull buf[n] = 0;
77 84b1cb73 2003-09-30 devnull if (h) {
78 84b1cb73 2003-09-30 devnull *h = atoi(buf+4*12)-atoi(buf+2*12);
79 84b1cb73 2003-09-30 devnull if (*h < 0)
80 84b1cb73 2003-09-30 devnull return 0;
81 84b1cb73 2003-09-30 devnull }
82 84b1cb73 2003-09-30 devnull if (w) {
83 84b1cb73 2003-09-30 devnull *w = atoi(buf+3*12)-atoi(buf+1*12);
84 84b1cb73 2003-09-30 devnull if (*w < 0)
85 84b1cb73 2003-09-30 devnull return 0;
86 84b1cb73 2003-09-30 devnull }
87 84b1cb73 2003-09-30 devnull return 1;
88 84b1cb73 2003-09-30 devnull }
89 84b1cb73 2003-09-30 devnull
90 84b1cb73 2003-09-30 devnull int
91 84b1cb73 2003-09-30 devnull snarfswap(char *fromsam, int nc, char **tosam)
92 84b1cb73 2003-09-30 devnull {
93 941c9f36 2003-10-11 devnull char *s;
94 84b1cb73 2003-09-30 devnull
95 941c9f36 2003-10-11 devnull s = getsnarf();
96 941c9f36 2003-10-11 devnull putsnarf(fromsam);
97 941c9f36 2003-10-11 devnull *tosam = s;
98 941c9f36 2003-10-11 devnull return s ? strlen(s) : 0;
99 84b1cb73 2003-09-30 devnull }
100 84b1cb73 2003-09-30 devnull
101 84b1cb73 2003-09-30 devnull void
102 84b1cb73 2003-09-30 devnull dumperrmsg(int count, int type, int count0, int c)
103 84b1cb73 2003-09-30 devnull {
104 84b1cb73 2003-09-30 devnull fprint(2, "samterm: host mesg: count %d %ux %ux %ux %s...ignored\n",
105 84b1cb73 2003-09-30 devnull count, type, count0, c, rcvstring());
106 84b1cb73 2003-09-30 devnull }
107 84b1cb73 2003-09-30 devnull
108 84b1cb73 2003-09-30 devnull void
109 84b1cb73 2003-09-30 devnull removeextern(void)
110 84b1cb73 2003-09-30 devnull {
111 84b1cb73 2003-09-30 devnull remove(exname);
112 84b1cb73 2003-09-30 devnull }
113 84b1cb73 2003-09-30 devnull
114 84b1cb73 2003-09-30 devnull Readbuf hostbuf[2];
115 84b1cb73 2003-09-30 devnull Readbuf plumbbuf[2];
116 84b1cb73 2003-09-30 devnull
117 84b1cb73 2003-09-30 devnull void
118 84b1cb73 2003-09-30 devnull extproc(void *argv)
119 84b1cb73 2003-09-30 devnull {
120 84b1cb73 2003-09-30 devnull Channel *c;
121 941c9f36 2003-10-11 devnull int i, n, which, fd;
122 84b1cb73 2003-09-30 devnull void **arg;
123 84b1cb73 2003-09-30 devnull
124 84b1cb73 2003-09-30 devnull arg = argv;
125 84b1cb73 2003-09-30 devnull c = arg[0];
126 cbf43783 2006-04-20 devnull fd = (int)(uintptr)arg[1];
127 84b1cb73 2003-09-30 devnull
128 84b1cb73 2003-09-30 devnull i = 0;
129 84b1cb73 2003-09-30 devnull for(;;){
130 941c9f36 2003-10-11 devnull i = 1-i; /* toggle */
131 93f2ae0d 2004-12-27 devnull n = read(fd, plumbbuf[i].data, sizeof plumbbuf[i].data);
132 93f2ae0d 2004-12-27 devnull if(0) fprint(2, "ext %d\n", n);
133 84b1cb73 2003-09-30 devnull if(n <= 0){
134 84b1cb73 2003-09-30 devnull fprint(2, "samterm: extern read error: %r\n");
135 941c9f36 2003-10-11 devnull threadexits("extern"); /* not a fatal error */
136 84b1cb73 2003-09-30 devnull }
137 84b1cb73 2003-09-30 devnull plumbbuf[i].n = n;
138 84b1cb73 2003-09-30 devnull which = i;
139 84b1cb73 2003-09-30 devnull send(c, &which);
140 84b1cb73 2003-09-30 devnull }
141 84b1cb73 2003-09-30 devnull }
142 84b1cb73 2003-09-30 devnull
143 84b1cb73 2003-09-30 devnull void
144 84b1cb73 2003-09-30 devnull extstart(void)
145 84b1cb73 2003-09-30 devnull {
146 941c9f36 2003-10-11 devnull char *user, *disp;
147 941c9f36 2003-10-11 devnull int fd, flags;
148 84b1cb73 2003-09-30 devnull static void *arg[2];
149 84b1cb73 2003-09-30 devnull
150 941c9f36 2003-10-11 devnull user = getenv("USER");
151 941c9f36 2003-10-11 devnull if(user == nil)
152 84b1cb73 2003-09-30 devnull return;
153 941c9f36 2003-10-11 devnull disp = getenv("DISPLAY");
154 75ea8515 2018-03-27 0intro if(disp){
155 941c9f36 2003-10-11 devnull exname = smprint("/tmp/.sam.%s.%s", user, disp);
156 75ea8515 2018-03-27 0intro free(disp);
157 75ea8515 2018-03-27 0intro }
158 941c9f36 2003-10-11 devnull else
159 941c9f36 2003-10-11 devnull exname = smprint("/tmp/.sam.%s", user);
160 75ea8515 2018-03-27 0intro free(user);
161 941c9f36 2003-10-11 devnull if(exname == nil){
162 941c9f36 2003-10-11 devnull fprint(2, "not posting for B: out of memory\n");
163 84b1cb73 2003-09-30 devnull return;
164 84b1cb73 2003-09-30 devnull }
165 941c9f36 2003-10-11 devnull
166 941c9f36 2003-10-11 devnull if(mkfifo(exname, 0600) < 0){
167 941c9f36 2003-10-11 devnull struct stat st;
168 941c9f36 2003-10-11 devnull if(errno != EEXIST || stat(exname, &st) < 0)
169 941c9f36 2003-10-11 devnull return;
170 941c9f36 2003-10-11 devnull if(!S_ISFIFO(st.st_mode)){
171 941c9f36 2003-10-11 devnull removeextern();
172 941c9f36 2003-10-11 devnull if(mkfifo(exname, 0600) < 0)
173 941c9f36 2003-10-11 devnull return;
174 941c9f36 2003-10-11 devnull }
175 941c9f36 2003-10-11 devnull }
176 941c9f36 2003-10-11 devnull
177 a19ff5b2 2005-01-07 devnull fd = open(exname, OREAD|ONONBLOCK);
178 941c9f36 2003-10-11 devnull if(fd == -1){
179 941c9f36 2003-10-11 devnull removeextern();
180 941c9f36 2003-10-11 devnull return;
181 941c9f36 2003-10-11 devnull }
182 941c9f36 2003-10-11 devnull
183 84b1cb73 2003-09-30 devnull /*
184 941c9f36 2003-10-11 devnull * Turn off no-delay and provide ourselves as a lingering
185 941c9f36 2003-10-11 devnull * writer so as not to get end of file on read.
186 84b1cb73 2003-09-30 devnull */
187 941c9f36 2003-10-11 devnull flags = fcntl(fd, F_GETFL, 0);
188 941c9f36 2003-10-11 devnull if(flags<0 || fcntl(fd, F_SETFL, flags&~O_NONBLOCK)<0
189 941c9f36 2003-10-11 devnull ||open(exname, OWRITE) < 0){
190 941c9f36 2003-10-11 devnull close(fd);
191 941c9f36 2003-10-11 devnull removeextern();
192 941c9f36 2003-10-11 devnull return;
193 941c9f36 2003-10-11 devnull }
194 941c9f36 2003-10-11 devnull
195 84b1cb73 2003-09-30 devnull plumbc = chancreate(sizeof(int), 0);
196 93f2ae0d 2004-12-27 devnull chansetname(plumbc, "plumbc");
197 84b1cb73 2003-09-30 devnull arg[0] = plumbc;
198 cbf43783 2006-04-20 devnull arg[1] = (void*)(uintptr)fd;
199 93f2ae0d 2004-12-27 devnull proccreate(extproc, arg, STACK);
200 84b1cb73 2003-09-30 devnull atexit(removeextern);
201 84b1cb73 2003-09-30 devnull }
202 84b1cb73 2003-09-30 devnull
203 84b1cb73 2003-09-30 devnull int
204 af78a4cd 2004-03-02 devnull plumbformat(Plumbmsg *m, int i)
205 84b1cb73 2003-09-30 devnull {
206 84b1cb73 2003-09-30 devnull char *addr, *data, *act;
207 84b1cb73 2003-09-30 devnull int n;
208 84b1cb73 2003-09-30 devnull
209 84b1cb73 2003-09-30 devnull data = (char*)plumbbuf[i].data;
210 84b1cb73 2003-09-30 devnull n = m->ndata;
211 af78a4cd 2004-03-02 devnull if(n == 0 || 2+n+2 >= READBUFSIZE){
212 84b1cb73 2003-09-30 devnull plumbfree(m);
213 84b1cb73 2003-09-30 devnull return 0;
214 84b1cb73 2003-09-30 devnull }
215 84b1cb73 2003-09-30 devnull act = plumblookup(m->attr, "action");
216 84b1cb73 2003-09-30 devnull if(act!=nil && strcmp(act, "showfile")!=0){
217 84b1cb73 2003-09-30 devnull /* can't handle other cases yet */
218 84b1cb73 2003-09-30 devnull plumbfree(m);
219 84b1cb73 2003-09-30 devnull return 0;
220 84b1cb73 2003-09-30 devnull }
221 84b1cb73 2003-09-30 devnull addr = plumblookup(m->attr, "addr");
222 84b1cb73 2003-09-30 devnull if(addr){
223 84b1cb73 2003-09-30 devnull if(addr[0] == '\0')
224 84b1cb73 2003-09-30 devnull addr = nil;
225 84b1cb73 2003-09-30 devnull else
226 84b1cb73 2003-09-30 devnull addr = strdup(addr); /* copy to safe storage; we'll overwrite data */
227 84b1cb73 2003-09-30 devnull }
228 84b1cb73 2003-09-30 devnull memmove(data, "B ", 2); /* we know there's enough room for this */
229 84b1cb73 2003-09-30 devnull memmove(data+2, m->data, n);
230 84b1cb73 2003-09-30 devnull n += 2;
231 84b1cb73 2003-09-30 devnull if(data[n-1] != '\n')
232 84b1cb73 2003-09-30 devnull data[n++] = '\n';
233 84b1cb73 2003-09-30 devnull if(addr != nil){
234 84b1cb73 2003-09-30 devnull if(n+strlen(addr)+1+1 <= READBUFSIZE)
235 84b1cb73 2003-09-30 devnull n += sprint(data+n, "%s\n", addr);
236 84b1cb73 2003-09-30 devnull free(addr);
237 84b1cb73 2003-09-30 devnull }
238 84b1cb73 2003-09-30 devnull plumbbuf[i].n = n;
239 84b1cb73 2003-09-30 devnull plumbfree(m);
240 84b1cb73 2003-09-30 devnull return 1;
241 84b1cb73 2003-09-30 devnull }
242 84b1cb73 2003-09-30 devnull
243 84b1cb73 2003-09-30 devnull void
244 2277c5d7 2004-03-21 devnull plumbproc(void *arg)
245 84b1cb73 2003-09-30 devnull {
246 d4045724 2005-01-04 devnull CFid *fid;
247 2277c5d7 2004-03-21 devnull int i;
248 af78a4cd 2004-03-02 devnull Plumbmsg *m;
249 84b1cb73 2003-09-30 devnull
250 2277c5d7 2004-03-21 devnull fid = arg;
251 2277c5d7 2004-03-21 devnull i = 0;
252 84b1cb73 2003-09-30 devnull for(;;){
253 2277c5d7 2004-03-21 devnull m = plumbrecvfid(fid);
254 af78a4cd 2004-03-02 devnull if(m == nil){
255 84b1cb73 2003-09-30 devnull fprint(2, "samterm: plumb read error: %r\n");
256 84b1cb73 2003-09-30 devnull threadexits("plumb"); /* not a fatal error */
257 84b1cb73 2003-09-30 devnull }
258 af78a4cd 2004-03-02 devnull if(plumbformat(m, i)){
259 2277c5d7 2004-03-21 devnull send(plumbc, &i);
260 af78a4cd 2004-03-02 devnull i = 1-i; /* toggle */
261 84b1cb73 2003-09-30 devnull }
262 84b1cb73 2003-09-30 devnull }
263 84b1cb73 2003-09-30 devnull }
264 84b1cb73 2003-09-30 devnull
265 84b1cb73 2003-09-30 devnull int
266 84b1cb73 2003-09-30 devnull plumbstart(void)
267 84b1cb73 2003-09-30 devnull {
268 d4045724 2005-01-04 devnull CFid *fid;
269 84b1cb73 2003-09-30 devnull
270 84b1cb73 2003-09-30 devnull plumbfd = plumbopen("send", OWRITE|OCEXEC); /* not open is ok */
271 2277c5d7 2004-03-21 devnull fid = plumbopenfid("edit", OREAD|OCEXEC);
272 2277c5d7 2004-03-21 devnull if(fid == nil)
273 84b1cb73 2003-09-30 devnull return -1;
274 84b1cb73 2003-09-30 devnull plumbc = chancreate(sizeof(int), 0);
275 93f2ae0d 2004-12-27 devnull chansetname(plumbc, "plumbc");
276 84b1cb73 2003-09-30 devnull if(plumbc == nil){
277 2277c5d7 2004-03-21 devnull fsclose(fid);
278 84b1cb73 2003-09-30 devnull return -1;
279 84b1cb73 2003-09-30 devnull }
280 2277c5d7 2004-03-21 devnull threadcreate(plumbproc, fid, STACK);
281 84b1cb73 2003-09-30 devnull return 1;
282 84b1cb73 2003-09-30 devnull }
283 84b1cb73 2003-09-30 devnull
284 84b1cb73 2003-09-30 devnull void
285 84b1cb73 2003-09-30 devnull hostproc(void *arg)
286 84b1cb73 2003-09-30 devnull {
287 84b1cb73 2003-09-30 devnull Channel *c;
288 84b1cb73 2003-09-30 devnull int i, n, which;
289 84b1cb73 2003-09-30 devnull
290 84b1cb73 2003-09-30 devnull c = arg;
291 84b1cb73 2003-09-30 devnull
292 84b1cb73 2003-09-30 devnull i = 0;
293 84b1cb73 2003-09-30 devnull for(;;){
294 84b1cb73 2003-09-30 devnull i = 1-i; /* toggle */
295 93f2ae0d 2004-12-27 devnull n = read(hostfd[0], hostbuf[i].data, sizeof hostbuf[i].data);
296 93f2ae0d 2004-12-27 devnull if(0) fprint(2, "hostproc %d\n", n);
297 84b1cb73 2003-09-30 devnull if(n <= 0){
298 f0264abf 2005-01-20 devnull if(n == 0){
299 f0264abf 2005-01-20 devnull if(exiting)
300 f0264abf 2005-01-20 devnull threadexits(nil);
301 f0264abf 2005-01-20 devnull werrstr("unexpected eof");
302 f0264abf 2005-01-20 devnull }
303 84b1cb73 2003-09-30 devnull fprint(2, "samterm: host read error: %r\n");
304 84b1cb73 2003-09-30 devnull threadexitsall("host");
305 84b1cb73 2003-09-30 devnull }
306 84b1cb73 2003-09-30 devnull hostbuf[i].n = n;
307 84b1cb73 2003-09-30 devnull which = i;
308 93f2ae0d 2004-12-27 devnull if(0) fprint(2, "hostproc send %d\n", which);
309 84b1cb73 2003-09-30 devnull send(c, &which);
310 84b1cb73 2003-09-30 devnull }
311 84b1cb73 2003-09-30 devnull }
312 84b1cb73 2003-09-30 devnull
313 84b1cb73 2003-09-30 devnull void
314 84b1cb73 2003-09-30 devnull hoststart(void)
315 84b1cb73 2003-09-30 devnull {
316 84b1cb73 2003-09-30 devnull hostc = chancreate(sizeof(int), 0);
317 93f2ae0d 2004-12-27 devnull chansetname(hostc, "hostc");
318 93f2ae0d 2004-12-27 devnull proccreate(hostproc, hostc, STACK);
319 84b1cb73 2003-09-30 devnull }