#include #include #include #include #include #include #include #include #include "ox.h" static int plumbeditfd = -1; static int plumbexecfd = -1; static Channel* plumbeditc; static Channel* plumbexecc; int addr2ln(Edit* e, char* addr) { char* fn; char* cmd; char buf[60]; char* s; Xcmd* x; if (!addr[0] || !e->gtext || !e->gtext->repl) return 0; fn = smprint("%s/data", e->gtext->repl->path); cmd = smprint("grep -n '%s'", addr); x = allocxcmd(nil, "/", cmd, nil); x->infd[0] = open(fn, OREAD); pipe(x->outfd); x->pidc = chancreate(sizeof(ulong), 0); procrfork(xcmdproc, x, 16*1024, RFFDG|RFNOTEG); x->pid = recvul(x->pidc); chanfree(x->pidc); free(cmd); free(fn); close(x->infd[0]); close(x->outfd[1]); memset(buf, 0, sizeof(buf)); read(x->outfd[0], buf, sizeof(buf)); close(x->outfd[0]); s = strchr(buf ,':'); if (s) *s = 0; freexcmd(x); if (buf[0] && isdigit(buf[0])) return atoi(buf); else return 0; } static void plumbfile(Plumbmsg* m) { char* a; Edit* e; char* k; char* path; path = cleanpath(m->data, m->wdir); e = editfile(path, 0); free(path); if (e == nil) return; openpanelctl(e->gcol); panelctl(e->gcol, "show\nnomin\n"); closepanelctl(e->gcol); a = plumblookup(m->attr, "addr"); if (a){ if (a[0] == '/') k = smprint(":%d", addr2ln(e, a+1)); else if (a[0]) k = smprint(":%s", a); else k = nil; if (k) look(e, k, nil); free(k); } } static void plumbdata(Plumbmsg* m) { char* fn; Edit* e; char* t; fn = plumblookup(m->attr, "filename"); if (fn == nil){ fn = estrdup("Plumb"); } fn = cleanpath(fn, m->wdir); t = smprint("[%s]", fn); e = musthavemsgs(t); free(fn); free(t); free(e->text); e->text = emalloc(m->ndata + 1); e->text[m->ndata] = 0; memmove(e->text, m->data, m->ndata); updatetext(e); } static void plumbeditthread(void*) { Plumbmsg* m; char* a; for(;;){ m = recvp(plumbeditc); if (strcmp(m->type, "text")){ plumbfree(m); continue; } a = plumblookup(m->attr, "action"); if (a == nil || !strcmp(a, "showfile")) plumbfile(m); else plumbdata(m); plumbfree(m); } } static void plumbexecthread(void*) { Plumbmsg* m; int i; Edit* e; char* path; for(;;){ m = recvp(plumbexecc); if (strcmp(m->type, "text")){ plumbfree(m); continue; } if (!strncmp(m->data, "exec ", 5)) if (strchr(":|<>", m->data[5])){ path = readfstr("/dev/sel"); e = nil; if (path){ for (i = 0; i < nedits; i++) if (edits[i] && strstr(path, edits[i]->gcolname)){ e = edits[i]; break; } if (e) run(e, m->data+5, 1, path); else externrunevent(path, "exec", m->data+5); free(path); } } else { xcmd(nil, m->wdir, m->data+5, nil, nil, nil); } plumbfree(m); } } void plumbinit(void) { plumbeditc = createportproc("edit"); if (plumbeditc == nil) fprint(2,"%s: can't create edit port: %r\n", argv0); else threadcreate(plumbeditthread, 0, 8*1024); plumbexecc = createportproc("exec"); if (plumbexecc == nil) fprint(2,"%s: can't create exec port: %r\n", argv0); else threadcreate(plumbexecthread, 0, 8*1024); }