17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <fcall.h>
47dd7cddfSDavid du Colombier #include <thread.h>
59a747e4fSDavid du Colombier #include <9p.h>
67dd7cddfSDavid du Colombier #include "dat.h"
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier typedef struct Wpid Wpid;
97dd7cddfSDavid du Colombier struct Wpid
107dd7cddfSDavid du Colombier {
117dd7cddfSDavid du Colombier int pid;
127dd7cddfSDavid du Colombier Window *w;
137dd7cddfSDavid du Colombier Wpid *next;
147dd7cddfSDavid du Colombier };
157dd7cddfSDavid du Colombier
167dd7cddfSDavid du Colombier void pipectl(void*);
177dd7cddfSDavid du Colombier
187dd7cddfSDavid du Colombier int pipefd;
197dd7cddfSDavid du Colombier Wpid *wpid;
207dd7cddfSDavid du Colombier int snarffd;
219a747e4fSDavid du Colombier Channel *newpipechan;
227dd7cddfSDavid du Colombier
239a747e4fSDavid du Colombier int
newpipewin(int pid,char * p)247dd7cddfSDavid du Colombier newpipewin(int pid, char *p)
257dd7cddfSDavid du Colombier {
269a747e4fSDavid du Colombier int id;
277dd7cddfSDavid du Colombier Window *w;
287dd7cddfSDavid du Colombier Wpid *wp;
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier w = newwindow();
317dd7cddfSDavid du Colombier winname(w, p);
327dd7cddfSDavid du Colombier wintagwrite(w, "Send ", 5);
337dd7cddfSDavid du Colombier wp = emalloc(sizeof(Wpid));
347dd7cddfSDavid du Colombier wp->pid = pid;
357dd7cddfSDavid du Colombier wp->w = w;
369a747e4fSDavid du Colombier wp->next = wpid; /* BUG: this happens in fsread proc (we don't use wpid, so it's okay) */
377dd7cddfSDavid du Colombier wpid = wp;
389a747e4fSDavid du Colombier id = w->id;
399a747e4fSDavid du Colombier sendp(newpipechan, w);
409a747e4fSDavid du Colombier return id;
417dd7cddfSDavid du Colombier }
427dd7cddfSDavid du Colombier
437dd7cddfSDavid du Colombier int
pipecommand(Window * w,char * s)447dd7cddfSDavid du Colombier pipecommand(Window *w, char *s)
457dd7cddfSDavid du Colombier {
467dd7cddfSDavid du Colombier ulong q0, q1;
477dd7cddfSDavid du Colombier char tmp[32], *t;
487dd7cddfSDavid du Colombier int n, k;
497dd7cddfSDavid du Colombier
507dd7cddfSDavid du Colombier while(*s==' ' || *s=='\t' || *s=='\n')
517dd7cddfSDavid du Colombier s++;
527dd7cddfSDavid du Colombier if(strcmp(s, "Delete")==0){
537dd7cddfSDavid du Colombier windel(w, 1);
547dd7cddfSDavid du Colombier threadexits(nil);
557dd7cddfSDavid du Colombier return 1;
567dd7cddfSDavid du Colombier }
577dd7cddfSDavid du Colombier if(strcmp(s, "Del")==0){
587dd7cddfSDavid du Colombier if(windel(w, 0))
597dd7cddfSDavid du Colombier threadexits(nil);
607dd7cddfSDavid du Colombier return 1;
617dd7cddfSDavid du Colombier }
627dd7cddfSDavid du Colombier if(strcmp(s, "Send") == 0){
637dd7cddfSDavid du Colombier if(w->addr < 0)
647dd7cddfSDavid du Colombier w->addr = winopenfile(w, "addr");
657dd7cddfSDavid du Colombier ctlprint(w->ctl, "addr=dot\n");
667dd7cddfSDavid du Colombier seek(w->addr, 0UL, 0);
677dd7cddfSDavid du Colombier if(read(w->addr, tmp, 2*12) == 2*12){
687dd7cddfSDavid du Colombier q0 = atol(tmp+0*12);
697dd7cddfSDavid du Colombier q1 = atol(tmp+1*12);
707dd7cddfSDavid du Colombier if(q0 == q1){
717dd7cddfSDavid du Colombier t = nil;
727dd7cddfSDavid du Colombier k = 0;
737dd7cddfSDavid du Colombier if(snarffd > 0){
747dd7cddfSDavid du Colombier seek(0, snarffd, 0);
757dd7cddfSDavid du Colombier for(;;){
769a747e4fSDavid du Colombier t = realloc(t, k+8192+2);
777dd7cddfSDavid du Colombier if(t == nil)
78*afb30c3eSDavid du Colombier error("alloc failed: %r\n");
797dd7cddfSDavid du Colombier n = read(snarffd, t+k, 8192);
807dd7cddfSDavid du Colombier if(n <= 0)
817dd7cddfSDavid du Colombier break;
827dd7cddfSDavid du Colombier k += n;
837dd7cddfSDavid du Colombier }
847dd7cddfSDavid du Colombier t[k] = 0;
857dd7cddfSDavid du Colombier }
867dd7cddfSDavid du Colombier }else{
879a747e4fSDavid du Colombier t = emalloc((q1-q0)*UTFmax+2);
887dd7cddfSDavid du Colombier winread(w, q0, q1, t);
899a747e4fSDavid du Colombier k = strlen(t);
907dd7cddfSDavid du Colombier }
919a747e4fSDavid du Colombier if(t!=nil && t[0]!='\0'){
929a747e4fSDavid du Colombier if(t[k-1]!='\n' && t[k-1]!='\004'){
939a747e4fSDavid du Colombier t[k++] = '\n';
949a747e4fSDavid du Colombier t[k] = '\0';
959a747e4fSDavid du Colombier }
967dd7cddfSDavid du Colombier sendit(t);
979a747e4fSDavid du Colombier }
987dd7cddfSDavid du Colombier free(t);
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier return 1;
1017dd7cddfSDavid du Colombier }
1027dd7cddfSDavid du Colombier return 0;
1037dd7cddfSDavid du Colombier }
1047dd7cddfSDavid du Colombier
1057dd7cddfSDavid du Colombier void
pipectl(void * v)1067dd7cddfSDavid du Colombier pipectl(void *v)
1077dd7cddfSDavid du Colombier {
1087dd7cddfSDavid du Colombier Window *w;
1097dd7cddfSDavid du Colombier Event *e;
1107dd7cddfSDavid du Colombier
1117dd7cddfSDavid du Colombier w = v;
1127dd7cddfSDavid du Colombier proccreate(wineventproc, w, STACK);
1137dd7cddfSDavid du Colombier
1149a747e4fSDavid du Colombier windormant(w);
1157dd7cddfSDavid du Colombier winsetaddr(w, "0", 0);
1167dd7cddfSDavid du Colombier for(;;){
1177dd7cddfSDavid du Colombier e = recvp(w->cevent);
1187dd7cddfSDavid du Colombier switch(e->c1){
1197dd7cddfSDavid du Colombier default:
1207dd7cddfSDavid du Colombier Unknown:
1219a747e4fSDavid du Colombier fprint(2, "unknown message %c%c\n", e->c1, e->c2);
1227dd7cddfSDavid du Colombier break;
1237dd7cddfSDavid du Colombier
1247dd7cddfSDavid du Colombier case 'E': /* write to body; can't affect us */
1257dd7cddfSDavid du Colombier break;
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier case 'F': /* generated by our actions; ignore */
1287dd7cddfSDavid du Colombier break;
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier case 'K': /* ignore */
1317dd7cddfSDavid du Colombier break;
1327dd7cddfSDavid du Colombier
1337dd7cddfSDavid du Colombier case 'M':
1347dd7cddfSDavid du Colombier switch(e->c2){
1357dd7cddfSDavid du Colombier case 'x':
1367dd7cddfSDavid du Colombier case 'X':
1377dd7cddfSDavid du Colombier execevent(w, e, pipecommand);
1387dd7cddfSDavid du Colombier break;
1397dd7cddfSDavid du Colombier
1407dd7cddfSDavid du Colombier case 'l': /* reflect all searches back to acme */
1417dd7cddfSDavid du Colombier case 'L':
1427dd7cddfSDavid du Colombier if(e->flag & 2)
1437dd7cddfSDavid du Colombier recvp(w->cevent);
1447dd7cddfSDavid du Colombier winwriteevent(w, e);
1457dd7cddfSDavid du Colombier break;
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier case 'I': /* modify away; we don't care */
1487dd7cddfSDavid du Colombier case 'i':
1497dd7cddfSDavid du Colombier case 'D':
1507dd7cddfSDavid du Colombier case 'd':
1517dd7cddfSDavid du Colombier break;
1527dd7cddfSDavid du Colombier
1537dd7cddfSDavid du Colombier default:
1547dd7cddfSDavid du Colombier goto Unknown;
1557dd7cddfSDavid du Colombier }
1567dd7cddfSDavid du Colombier }
1577dd7cddfSDavid du Colombier }
1587dd7cddfSDavid du Colombier }
1597dd7cddfSDavid du Colombier
1607dd7cddfSDavid du Colombier void
newpipethread(void *)1619a747e4fSDavid du Colombier newpipethread(void*)
1627dd7cddfSDavid du Colombier {
1639a747e4fSDavid du Colombier Window *w;
1647dd7cddfSDavid du Colombier
1659a747e4fSDavid du Colombier while(w = recvp(newpipechan))
1669a747e4fSDavid du Colombier threadcreate(pipectl, w, STACK);
1677dd7cddfSDavid du Colombier }
1687dd7cddfSDavid du Colombier
1697dd7cddfSDavid du Colombier void
startpipe(void)1707dd7cddfSDavid du Colombier startpipe(void)
1717dd7cddfSDavid du Colombier {
1729a747e4fSDavid du Colombier newpipechan = chancreate(sizeof(Window*), 0);
1739a747e4fSDavid du Colombier threadcreate(newpipethread, nil, STACK);
1747dd7cddfSDavid du Colombier snarffd = open("/dev/snarf", OREAD|OCEXEC);
1757dd7cddfSDavid du Colombier }
176