plan9.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <thread.h>
  5. #include <mouse.h>
  6. #include <keyboard.h>
  7. #include <frame.h>
  8. #include <plumb.h>
  9. #include "flayer.h"
  10. #include "samterm.h"
  11. static char exname[64];
  12. void
  13. getscreen(int argc, char **argv)
  14. {
  15. char *t;
  16. USED(argc);
  17. USED(argv);
  18. if(initdraw(panic1, nil, "sam") < 0){
  19. fprint(2, "samterm: initimage: %r\n");
  20. threadexitsall("init");
  21. }
  22. t = getenv("tabstop");
  23. if(t != nil)
  24. maxtab = strtoul(t, nil, 0);
  25. draw(screen, screen->clipr, display->white, nil, ZP);
  26. }
  27. int
  28. screensize(int *w, int *h)
  29. {
  30. int fd, n;
  31. char buf[5*12+1];
  32. fd = open("/dev/screen", OREAD);
  33. if(fd < 0)
  34. return 0;
  35. n = read(fd, buf, sizeof(buf)-1);
  36. close(fd);
  37. if (n != sizeof(buf)-1)
  38. return 0;
  39. buf[n] = 0;
  40. if (h) {
  41. *h = atoi(buf+4*12)-atoi(buf+2*12);
  42. if (*h < 0)
  43. return 0;
  44. }
  45. if (w) {
  46. *w = atoi(buf+3*12)-atoi(buf+1*12);
  47. if (*w < 0)
  48. return 0;
  49. }
  50. return 1;
  51. }
  52. int
  53. snarfswap(char *fromsam, int nc, char **tosam)
  54. {
  55. char *s1;
  56. int f, n, ss;
  57. f = open("/dev/snarf", 0);
  58. if(f < 0)
  59. return -1;
  60. ss = SNARFSIZE;
  61. if(hversion < 2)
  62. ss = 4096;
  63. *tosam = s1 = alloc(ss);
  64. n = read(f, s1, ss-1);
  65. close(f);
  66. if(n < 0)
  67. n = 0;
  68. if (n == 0) {
  69. *tosam = 0;
  70. free(s1);
  71. } else
  72. s1[n] = 0;
  73. f = create("/dev/snarf", 1, 0666);
  74. if(f >= 0){
  75. write(f, fromsam, nc);
  76. close(f);
  77. }
  78. return n;
  79. }
  80. void
  81. dumperrmsg(int count, int type, int count0, int c)
  82. {
  83. fprint(2, "samterm: host mesg: count %d %ux %ux %ux %s...ignored\n",
  84. count, type, count0, c, rcvstring());
  85. }
  86. void
  87. removeextern(void)
  88. {
  89. remove(exname);
  90. }
  91. Readbuf hostbuf[2];
  92. Readbuf plumbbuf[2];
  93. void
  94. extproc(void *argv)
  95. {
  96. Channel *c;
  97. int i, n, which, *fdp;
  98. void **arg;
  99. arg = argv;
  100. c = arg[0];
  101. fdp = arg[1];
  102. i = 0;
  103. for(;;){
  104. i = 1-i; /* toggle */
  105. n = read(*fdp, plumbbuf[i].data, sizeof plumbbuf[i].data);
  106. if(n <= 0){
  107. fprint(2, "samterm: extern read error: %r\n");
  108. threadexits("extern"); /* not a fatal error */
  109. }
  110. plumbbuf[i].n = n;
  111. which = i;
  112. send(c, &which);
  113. }
  114. }
  115. void
  116. extstart(void)
  117. {
  118. char buf[32];
  119. int fd;
  120. static int p[2];
  121. static void *arg[2];
  122. if(pipe(p) < 0)
  123. return;
  124. sprint(exname, "/srv/sam.%s", getuser());
  125. fd = create(exname, 1, 0600);
  126. if(fd < 0){ /* assume existing guy is more important */
  127. Err:
  128. close(p[0]);
  129. close(p[1]);
  130. return;
  131. }
  132. sprint(buf, "%d", p[0]);
  133. if(write(fd, buf, strlen(buf)) <= 0)
  134. goto Err;
  135. close(fd);
  136. /*
  137. * leave p[0] open so if the file is removed the event
  138. * library won't get an error
  139. */
  140. plumbc = chancreate(sizeof(int), 0);
  141. arg[0] = plumbc;
  142. arg[1] = &p[1];
  143. proccreate(extproc, arg, 1024);
  144. atexit(removeextern);
  145. }
  146. int
  147. plumbformat(int i)
  148. {
  149. Plumbmsg *m;
  150. char *addr, *data, *act;
  151. int n;
  152. data = (char*)plumbbuf[i].data;
  153. m = plumbunpack(data, plumbbuf[i].n);
  154. if(m == nil)
  155. return 0;
  156. n = m->ndata;
  157. if(n == 0){
  158. plumbfree(m);
  159. return 0;
  160. }
  161. act = plumblookup(m->attr, "action");
  162. if(act!=nil && strcmp(act, "showfile")!=0){
  163. /* can't handle other cases yet */
  164. plumbfree(m);
  165. return 0;
  166. }
  167. addr = plumblookup(m->attr, "addr");
  168. if(addr){
  169. if(addr[0] == '\0')
  170. addr = nil;
  171. else
  172. addr = strdup(addr); /* copy to safe storage; we'll overwrite data */
  173. }
  174. memmove(data, "B ", 2); /* we know there's enough room for this */
  175. memmove(data+2, m->data, n);
  176. n += 2;
  177. if(data[n-1] != '\n')
  178. data[n++] = '\n';
  179. if(addr != nil){
  180. if(n+strlen(addr)+1+1 <= READBUFSIZE)
  181. n += sprint(data+n, "%s\n", addr);
  182. free(addr);
  183. }
  184. plumbbuf[i].n = n;
  185. plumbfree(m);
  186. return 1;
  187. }
  188. void
  189. plumbproc(void *argv)
  190. {
  191. Channel *c;
  192. int i, n, which, *fdp;
  193. void **arg;
  194. arg = argv;
  195. c = arg[0];
  196. fdp = arg[1];
  197. i = 0;
  198. for(;;){
  199. i = 1-i; /* toggle */
  200. n = read(*fdp, plumbbuf[i].data, READBUFSIZE);
  201. if(n <= 0){
  202. fprint(2, "samterm: plumb read error: %r\n");
  203. threadexits("plumb"); /* not a fatal error */
  204. }
  205. plumbbuf[i].n = n;
  206. if(plumbformat(i)){
  207. which = i;
  208. send(c, &which);
  209. }
  210. }
  211. }
  212. int
  213. plumbstart(void)
  214. {
  215. static int fd;
  216. static void *arg[2];
  217. plumbfd = plumbopen("send", OWRITE|OCEXEC); /* not open is ok */
  218. fd = plumbopen("edit", OREAD|OCEXEC);
  219. if(fd < 0)
  220. return -1;
  221. plumbc = chancreate(sizeof(int), 0);
  222. if(plumbc == nil){
  223. close(fd);
  224. return -1;
  225. }
  226. arg[0] =plumbc;
  227. arg[1] = &fd;
  228. proccreate(plumbproc, arg, 4096);
  229. return 1;
  230. }
  231. void
  232. hostproc(void *arg)
  233. {
  234. Channel *c;
  235. int i, n, which;
  236. c = arg;
  237. i = 0;
  238. for(;;){
  239. i = 1-i; /* toggle */
  240. n = read(0, hostbuf[i].data, sizeof hostbuf[i].data);
  241. if(n <= 0){
  242. if(n==0){
  243. if(exiting)
  244. threadexits(nil);
  245. werrstr("unexpected eof");
  246. }
  247. fprint(2, "samterm: host read error: %r\n");
  248. threadexitsall("host");
  249. }
  250. hostbuf[i].n = n;
  251. which = i;
  252. send(c, &which);
  253. }
  254. }
  255. void
  256. hoststart(void)
  257. {
  258. hostc = chancreate(sizeof(int), 0);
  259. proccreate(hostproc, hostc, 1024);
  260. }