void plumblook(Plumbmsg *m) { Expand e; char *addr; if(m->ndata >= BUFSIZE){ warning(nil, "insanely long file name (%d bytes) in plumb message (%.32s...)\n", m->ndata, m->data); return; } e.q0 = 0; e.q1 = 0; if(m->data[0] == '\0') return; e.u.ar = nil; e.bname = m->data; e.name = bytetorune(e.bname, &e.nname); e.jump = TRUE; e.a0 = 0; e.a1 = 0; addr = plumblookup(m->attr, "addr"); if(addr != nil){ e.u.ar = bytetorune(addr, &e.a1); e.agetc = plumbgetc; } drawtopwindow(); openfile(nil, &e); free(e.name); free(e.u.at); }
static int plumbquit(Plumbmsg *msg) { char *s; s = plumblookup(msg->attr, "action"); return s && strcmp(s, "quit")==0; }
static int showdata(Plumbmsg *msg) { char *s; s = plumblookup(msg->attr, "action"); return s && strcmp(s, "showdata")==0; }
char* value(Plumbattr *attr, char *key, char *def) { char *v; v = plumblookup(attr, key); if(v) return v; return def; }
int plumbformat(int i) { Plumbmsg *m; char *addr, *data, *act; int n; data = (char*)plumbbuf[i].data; m = plumbunpack(data, plumbbuf[i].n); if(m == nil) return 0; n = m->ndata; if(n == 0){ plumbfree(m); return 0; } act = plumblookup(m->attr, "action"); if(act!=nil && strcmp(act, "showfile")!=0){ /* can't handle other cases yet */ plumbfree(m); return 0; } addr = plumblookup(m->attr, "addr"); if(addr){ if(addr[0] == '\0') addr = nil; else addr = strdup(addr); /* copy to safe storage; we'll overwrite data */ } memmove(data, "B ", 2); /* we know there's enough room for this */ memmove(data+2, m->data, n); n += 2; if(data[n-1] != '\n') data[n++] = '\n'; if(addr != nil){ if(n+strlen(addr)+1+1 <= READBUFSIZE) n += sprint(data+n, "%s\n", addr); free(addr); } plumbbuf[i].n = n; plumbfree(m); return 1; }
void plumbshowthread(void *v) { Plumbmsg *m; USED(v); threadsetname("plumbshowthread"); while((m = recvp(cplumbshow)) != nil){ showmesg(m->data, plumblookup(m->attr, "digest")); plumbfree(m); } threadexits(nil); }
void plumbthread(void) { Plumbmsg *m; Plumbattr *a; char *type, *digest; threadsetname("plumbthread"); while((m = recvp(cplumb)) != nil){ a = m->attr; digest = plumblookup(a, "digest"); type = plumblookup(a, "mailtype"); if(type == nil) fprint(2, "Mail: plumb message with no mailtype attribute\n"); else if(strcmp(type, "new") == 0) newmesg(m->data, digest); else if(strcmp(type, "delete") == 0) delmesg(m->data, digest, 0, nil); else fprint(2, "Mail: unknown plumb attribute %s\n", type); plumbfree(m); } threadexits(nil); }
static void plumbwebthread(void*) { char *base; Plumbmsg *m; for(;;){ m = recvp(plumbchan); if(m == nil) threadexits(nil); base = plumblookup(m->attr, "baseurl"); if(base == nil) base = m->wdir; plumburl(m->data, base); plumbfree(m); } }
void plumbshow(Plumbmsg *m) { Window *w; Rune rb[256], *r; int nb, nr; Runestr rs; char *name, *p, namebuf[16]; drawtopwindow(); w = makenewwindow(nil); name = plumblookup(m->attr, "filename"); if(name == nil){ name = namebuf; nuntitled++; snprint(namebuf, sizeof namebuf, "Untitled-%d", nuntitled); } p = nil; if(name[0]!='/' && m->wdir!=nil && m->wdir[0]!='\0'){ nb = strlen(m->wdir) + 1 + strlen(name) + 1; p = emalloc(nb); snprint(p, nb, "%s/%s", m->wdir, name); name = p; } cvttorunes(name, strlen(name), rb, &nb, &nr, nil); free(p); rs = cleanrname(runestr(rb, nr)); winsetname(w, rs.r, rs.nr); r = runemalloc(m->ndata); cvttorunes(m->data, m->ndata, r, &nb, &nr, nil); textinsert(&w->body, 0, r, nr, TRUE); free(r); w->body.file->mod = FALSE; w->dirty = FALSE; winsettag(w); textscrdraw(&w->body); textsetselect(&w->tag, w->tag.file->b.nc, w->tag.file->b.nc); xfidlog(w, "new"); }
void threadmain(int argc, char *argv[]) { char buf[1024], *p; int fd, i, input; input = 0; m.src = "plumb"; m.dst = nil; m.wdir = getwd(buf, sizeof buf); m.type = "text"; m.attr = nil; ARGBEGIN{ case '9': chatty9pclient = 1; break; case 'a': p = ARGF(); if(p == nil) usage(); m.attr = plumbaddattr(m.attr, plumbunpackattr(p)); break; case 'd': m.dst = ARGF(); if(m.dst == nil) usage(); break; case 'i': input++; break; case 't': case 'k': /* for backwards compatibility */ m.type = ARGF(); if(m.type == nil) usage(); break; case 'p': plumbfile = ARGF(); if(plumbfile == nil) usage(); break; case 's': m.src = ARGF(); if(m.src == nil) usage(); break; case 'w': m.wdir = ARGF(); if(m.wdir == nil) usage(); break; }ARGEND if((input && argc>0) || (!input && argc<1)) usage(); if(plumbfile != nil) fd = open(plumbfile, OWRITE); else fd = plumbopen("send", OWRITE); if(fd < 0){ fprint(2, "plumb: can't open plumb file: %r\n"); threadexitsall("open"); } if(input){ gather(); if(plumblookup(m.attr, "action") == nil) m.attr = plumbaddattr(m.attr, plumbunpackattr("action=showdata")); if(plumbsend(fd, &m) < 0){ fprint(2, "plumb: can't send message: %r\n"); threadexitsall("error"); } threadexitsall(nil); } for(i=0; i<argc; i++){ if(input == 0){ m.data = argv[i]; m.ndata = -1; } if(plumbsend(fd, &m) < 0){ fprint(2, "plumb: can't send message: %r\n"); threadexitsall("error"); } } threadexitsall(nil); }
void mousethread(void *v) { Text *t, *argt; int but; uint q0, q1; Window *w; Plumbmsg *pm; Mouse m; char *act; enum { MResize, MMouse, MPlumb, MWarnings, NMALT }; static Alt alts[NMALT+1]; USED(v); threadsetname("mousethread"); alts[MResize].c = mousectl->resizec; alts[MResize].v = nil; alts[MResize].op = CHANRCV; alts[MMouse].c = mousectl->c; alts[MMouse].v = &mousectl->m; alts[MMouse].op = CHANRCV; alts[MPlumb].c = cplumb; alts[MPlumb].v = ± alts[MPlumb].op = CHANRCV; alts[MWarnings].c = cwarn; alts[MWarnings].v = nil; alts[MWarnings].op = CHANRCV; if(cplumb == nil) alts[MPlumb].op = CHANNOP; alts[NMALT].op = CHANEND; for(;;){ qlock(&row.lk); flushwarnings(); qunlock(&row.lk); flushimage(display, 1); switch(alt(alts)){ case MResize: if(getwindow(display, Refnone) < 0) error("attach to window"); draw(screen, screen->r, display->white, nil, ZP); iconinit(); scrlresize(); rowresize(&row, screen->clipr); break; case MPlumb: if(strcmp(pm->type, "text") == 0){ act = plumblookup(pm->attr, "action"); if(act==nil || strcmp(act, "showfile")==0) plumblook(pm); else if(strcmp(act, "showdata")==0) plumbshow(pm); } plumbfree(pm); break; case MWarnings: break; case MMouse: /* * Make a copy so decisions are consistent; mousectl changes * underfoot. Can't just receive into m because this introduces * another race; see /sys/src/libdraw/mouse.c. */ m = mousectl->m; qlock(&row.lk); t = rowwhich(&row, m.xy); if(t!=mousetext && mousetext!=nil && mousetext->w!=nil){ winlock(mousetext->w, 'M'); mousetext->eq0 = ~0; wincommit(mousetext->w, mousetext); winunlock(mousetext->w); } mousetext = t; if(t == nil) goto Continue; w = t->w; if(t==nil || m.buttons==0) goto Continue; but = 0; if(m.buttons == 1) but = 1; else if(m.buttons == 2) but = 2; else if(m.buttons == 4) but = 3; barttext = t; if(t->what==Body && ptinrect(m.xy, t->scrollr)){ if(but){ if(swapscrollbuttons){ if(but == 1) but = 3; else if(but == 3) but = 1; } winlock(w, 'M'); t->eq0 = ~0; textscroll(t, but); winunlock(w); } goto Continue; } /* scroll buttons, wheels, etc. */ if(w != nil && (m.buttons & (8|16))){ if(m.buttons & 8) but = Kscrolloneup; else but = Kscrollonedown; winlock(w, 'M'); t->eq0 = ~0; texttype(t, but); winunlock(w); goto Continue; } if(ptinrect(m.xy, t->scrollr)){ if(but){ if(t->what == Columntag) rowdragcol(&row, t->col, but); else if(t->what == Tag){ coldragwin(t->col, t->w, but); if(t->w) barttext = &t->w->body; } if(t->col) activecol = t->col; } goto Continue; } if(m.buttons){ if(w) winlock(w, 'M'); t->eq0 = ~0; if(w) wincommit(w, t); else textcommit(t, TRUE); if(m.buttons & 1){ textselect(t); if(w) winsettag(w); argtext = t; seltext = t; if(t->col) activecol = t->col; /* button 1 only */ if(t->w!=nil && t==&t->w->body) activewin = t->w; }else if(m.buttons & 2){ if(textselect2(t, &q0, &q1, &argt)) execute(t, q0, q1, FALSE, argt); }else if(m.buttons & 4){ if(textselect3(t, &q0, &q1)) look3(t, q0, q1, FALSE); } if(w) winunlock(w); goto Continue; } Continue: qunlock(&row.lk); break; } } }