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>
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 2277c5d7 2004-03-21 devnull #include <fs.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"
24 941c9f36 2003-10-11 devnull static char *exname;
26 64bcfff3 2003-11-25 devnull #define STACK 16384
29 84b1cb73 2003-09-30 devnull getscreen(int argc, char **argv)
34 be36ff68 2004-04-29 devnull /* not exactly right */
35 be36ff68 2004-04-29 devnull for(i=0; i<argc-1; i++){
36 be36ff68 2004-04-29 devnull if(strcmp(argv[i], "-W") == 0)
37 be36ff68 2004-04-29 devnull winsize = argv[i+1];
40 84b1cb73 2003-09-30 devnull if(initdraw(panic1, nil, "sam") < 0){
41 941c9f36 2003-10-11 devnull fprint(2, "samterm: initdraw: %r\n");
42 84b1cb73 2003-09-30 devnull threadexitsall("init");
44 84b1cb73 2003-09-30 devnull t = getenv("tabstop");
45 84b1cb73 2003-09-30 devnull if(t != nil)
46 84b1cb73 2003-09-30 devnull maxtab = strtoul(t, nil, 0);
47 84b1cb73 2003-09-30 devnull draw(screen, screen->clipr, display->white, nil, ZP);
51 84b1cb73 2003-09-30 devnull screensize(int *w, int *h)
53 84b1cb73 2003-09-30 devnull int fd, n;
54 84b1cb73 2003-09-30 devnull char buf[5*12+1];
56 84b1cb73 2003-09-30 devnull fd = open("/dev/screen", OREAD);
57 84b1cb73 2003-09-30 devnull if(fd < 0)
58 84b1cb73 2003-09-30 devnull return 0;
59 84b1cb73 2003-09-30 devnull n = read(fd, buf, sizeof(buf)-1);
60 84b1cb73 2003-09-30 devnull close(fd);
61 84b1cb73 2003-09-30 devnull if (n != sizeof(buf)-1)
62 84b1cb73 2003-09-30 devnull return 0;
63 84b1cb73 2003-09-30 devnull buf[n] = 0;
65 84b1cb73 2003-09-30 devnull *h = atoi(buf+4*12)-atoi(buf+2*12);
66 84b1cb73 2003-09-30 devnull if (*h < 0)
67 84b1cb73 2003-09-30 devnull return 0;
70 84b1cb73 2003-09-30 devnull *w = atoi(buf+3*12)-atoi(buf+1*12);
71 84b1cb73 2003-09-30 devnull if (*w < 0)
72 84b1cb73 2003-09-30 devnull return 0;
74 84b1cb73 2003-09-30 devnull return 1;
78 84b1cb73 2003-09-30 devnull snarfswap(char *fromsam, int nc, char **tosam)
82 941c9f36 2003-10-11 devnull s = getsnarf();
83 941c9f36 2003-10-11 devnull putsnarf(fromsam);
84 941c9f36 2003-10-11 devnull *tosam = s;
85 941c9f36 2003-10-11 devnull return s ? strlen(s) : 0;
89 84b1cb73 2003-09-30 devnull dumperrmsg(int count, int type, int count0, int c)
91 84b1cb73 2003-09-30 devnull fprint(2, "samterm: host mesg: count %d %ux %ux %ux %s...ignored\n",
92 84b1cb73 2003-09-30 devnull count, type, count0, c, rcvstring());
96 84b1cb73 2003-09-30 devnull removeextern(void)
98 84b1cb73 2003-09-30 devnull remove(exname);
101 84b1cb73 2003-09-30 devnull Readbuf hostbuf[2];
102 84b1cb73 2003-09-30 devnull Readbuf plumbbuf[2];
105 84b1cb73 2003-09-30 devnull extproc(void *argv)
107 84b1cb73 2003-09-30 devnull Channel *c;
108 941c9f36 2003-10-11 devnull int i, n, which, fd;
109 84b1cb73 2003-09-30 devnull void **arg;
111 84b1cb73 2003-09-30 devnull arg = argv;
112 84b1cb73 2003-09-30 devnull c = arg[0];
113 941c9f36 2003-10-11 devnull fd = (int)arg[1];
115 5a8e63b2 2004-02-29 devnull threadfdnoblock(fd);
117 84b1cb73 2003-09-30 devnull for(;;){
118 941c9f36 2003-10-11 devnull i = 1-i; /* toggle */
119 5a8e63b2 2004-02-29 devnull n = threadread(fd, plumbbuf[i].data, sizeof plumbbuf[i].data);
120 84b1cb73 2003-09-30 devnull if(n <= 0){
121 84b1cb73 2003-09-30 devnull fprint(2, "samterm: extern read error: %r\n");
122 941c9f36 2003-10-11 devnull threadexits("extern"); /* not a fatal error */
124 84b1cb73 2003-09-30 devnull plumbbuf[i].n = n;
125 84b1cb73 2003-09-30 devnull which = i;
126 84b1cb73 2003-09-30 devnull send(c, &which);
131 84b1cb73 2003-09-30 devnull extstart(void)
133 941c9f36 2003-10-11 devnull char *user, *disp;
134 941c9f36 2003-10-11 devnull int fd, flags;
135 84b1cb73 2003-09-30 devnull static void *arg[2];
137 941c9f36 2003-10-11 devnull user = getenv("USER");
138 941c9f36 2003-10-11 devnull if(user == nil)
140 941c9f36 2003-10-11 devnull disp = getenv("DISPLAY");
141 941c9f36 2003-10-11 devnull if(disp)
142 941c9f36 2003-10-11 devnull exname = smprint("/tmp/.sam.%s.%s", user, disp);
144 941c9f36 2003-10-11 devnull exname = smprint("/tmp/.sam.%s", user);
145 941c9f36 2003-10-11 devnull if(exname == nil){
146 941c9f36 2003-10-11 devnull fprint(2, "not posting for B: out of memory\n");
150 941c9f36 2003-10-11 devnull if(mkfifo(exname, 0600) < 0){
151 941c9f36 2003-10-11 devnull struct stat st;
152 941c9f36 2003-10-11 devnull if(errno != EEXIST || stat(exname, &st) < 0)
154 941c9f36 2003-10-11 devnull if(!S_ISFIFO(st.st_mode)){
155 941c9f36 2003-10-11 devnull removeextern();
156 941c9f36 2003-10-11 devnull if(mkfifo(exname, 0600) < 0)
161 941c9f36 2003-10-11 devnull fd = open(exname, OREAD|O_NONBLOCK);
162 941c9f36 2003-10-11 devnull if(fd == -1){
163 941c9f36 2003-10-11 devnull removeextern();
168 941c9f36 2003-10-11 devnull * Turn off no-delay and provide ourselves as a lingering
169 941c9f36 2003-10-11 devnull * writer so as not to get end of file on read.
171 941c9f36 2003-10-11 devnull flags = fcntl(fd, F_GETFL, 0);
172 941c9f36 2003-10-11 devnull if(flags<0 || fcntl(fd, F_SETFL, flags&~O_NONBLOCK)<0
173 941c9f36 2003-10-11 devnull ||open(exname, OWRITE) < 0){
174 941c9f36 2003-10-11 devnull close(fd);
175 941c9f36 2003-10-11 devnull removeextern();
179 84b1cb73 2003-09-30 devnull plumbc = chancreate(sizeof(int), 0);
180 84b1cb73 2003-09-30 devnull arg[0] = plumbc;
181 941c9f36 2003-10-11 devnull arg[1] = (void*)fd;
182 5a8e63b2 2004-02-29 devnull threadcreate(extproc, arg, STACK);
183 84b1cb73 2003-09-30 devnull atexit(removeextern);
187 af78a4cd 2004-03-02 devnull plumbformat(Plumbmsg *m, int i)
189 84b1cb73 2003-09-30 devnull char *addr, *data, *act;
192 84b1cb73 2003-09-30 devnull data = (char*)plumbbuf[i].data;
193 84b1cb73 2003-09-30 devnull n = m->ndata;
194 af78a4cd 2004-03-02 devnull if(n == 0 || 2+n+2 >= READBUFSIZE){
195 84b1cb73 2003-09-30 devnull plumbfree(m);
196 84b1cb73 2003-09-30 devnull return 0;
198 84b1cb73 2003-09-30 devnull act = plumblookup(m->attr, "action");
199 84b1cb73 2003-09-30 devnull if(act!=nil && strcmp(act, "showfile")!=0){
200 84b1cb73 2003-09-30 devnull /* can't handle other cases yet */
201 84b1cb73 2003-09-30 devnull plumbfree(m);
202 84b1cb73 2003-09-30 devnull return 0;
204 84b1cb73 2003-09-30 devnull addr = plumblookup(m->attr, "addr");
205 84b1cb73 2003-09-30 devnull if(addr){
206 84b1cb73 2003-09-30 devnull if(addr[0] == '\0')
207 84b1cb73 2003-09-30 devnull addr = nil;
209 84b1cb73 2003-09-30 devnull addr = strdup(addr); /* copy to safe storage; we'll overwrite data */
211 84b1cb73 2003-09-30 devnull memmove(data, "B ", 2); /* we know there's enough room for this */
212 84b1cb73 2003-09-30 devnull memmove(data+2, m->data, n);
214 84b1cb73 2003-09-30 devnull if(data[n-1] != '\n')
215 84b1cb73 2003-09-30 devnull data[n++] = '\n';
216 84b1cb73 2003-09-30 devnull if(addr != nil){
217 84b1cb73 2003-09-30 devnull if(n+strlen(addr)+1+1 <= READBUFSIZE)
218 84b1cb73 2003-09-30 devnull n += sprint(data+n, "%s\n", addr);
219 84b1cb73 2003-09-30 devnull free(addr);
221 84b1cb73 2003-09-30 devnull plumbbuf[i].n = n;
222 84b1cb73 2003-09-30 devnull plumbfree(m);
223 84b1cb73 2003-09-30 devnull return 1;
227 2277c5d7 2004-03-21 devnull plumbproc(void *arg)
229 2277c5d7 2004-03-21 devnull Fid *fid;
231 af78a4cd 2004-03-02 devnull Plumbmsg *m;
233 2277c5d7 2004-03-21 devnull fid = arg;
235 84b1cb73 2003-09-30 devnull for(;;){
236 2277c5d7 2004-03-21 devnull m = plumbrecvfid(fid);
237 af78a4cd 2004-03-02 devnull if(m == nil){
238 84b1cb73 2003-09-30 devnull fprint(2, "samterm: plumb read error: %r\n");
239 84b1cb73 2003-09-30 devnull threadexits("plumb"); /* not a fatal error */
241 af78a4cd 2004-03-02 devnull if(plumbformat(m, i)){
242 2277c5d7 2004-03-21 devnull send(plumbc, &i);
243 af78a4cd 2004-03-02 devnull i = 1-i; /* toggle */
249 84b1cb73 2003-09-30 devnull plumbstart(void)
251 2277c5d7 2004-03-21 devnull Fid *fid;
253 84b1cb73 2003-09-30 devnull plumbfd = plumbopen("send", OWRITE|OCEXEC); /* not open is ok */
254 2277c5d7 2004-03-21 devnull fid = plumbopenfid("edit", OREAD|OCEXEC);
255 2277c5d7 2004-03-21 devnull if(fid == nil)
256 84b1cb73 2003-09-30 devnull return -1;
257 84b1cb73 2003-09-30 devnull plumbc = chancreate(sizeof(int), 0);
258 84b1cb73 2003-09-30 devnull if(plumbc == nil){
259 2277c5d7 2004-03-21 devnull fsclose(fid);
260 84b1cb73 2003-09-30 devnull return -1;
262 2277c5d7 2004-03-21 devnull threadcreate(plumbproc, fid, STACK);
263 84b1cb73 2003-09-30 devnull return 1;
267 84b1cb73 2003-09-30 devnull hostproc(void *arg)
269 84b1cb73 2003-09-30 devnull Channel *c;
270 84b1cb73 2003-09-30 devnull int i, n, which;
272 84b1cb73 2003-09-30 devnull c = arg;
275 5a8e63b2 2004-02-29 devnull threadfdnoblock(hostfd[0]);
276 84b1cb73 2003-09-30 devnull for(;;){
277 84b1cb73 2003-09-30 devnull i = 1-i; /* toggle */
278 5a8e63b2 2004-02-29 devnull n = threadread(hostfd[0], hostbuf[i].data, sizeof hostbuf[i].data);
279 84b1cb73 2003-09-30 devnull if(n <= 0){
280 84b1cb73 2003-09-30 devnull fprint(2, "samterm: host read error: %r\n");
281 84b1cb73 2003-09-30 devnull threadexitsall("host");
283 84b1cb73 2003-09-30 devnull hostbuf[i].n = n;
284 84b1cb73 2003-09-30 devnull which = i;
285 84b1cb73 2003-09-30 devnull send(c, &which);
290 84b1cb73 2003-09-30 devnull hoststart(void)
292 84b1cb73 2003-09-30 devnull hostc = chancreate(sizeof(int), 0);
293 5a8e63b2 2004-02-29 devnull threadcreate(hostproc, hostc, STACK);