9 typedef struct IOProc IOProc;
10 typedef struct PFilter PFilter;
11 typedef struct FAttr FAttr;
12 typedef struct PFid PFid;
29 Qid rootqid = {.type QTDIR};
58 last = smprint("/mnt/plumb/%s", n);
62 static void theioproc(void *);
74 p = emalloc9p(sizeof(IOProc));
75 p->ch = chancreate(sizeof(Req*), 0);
76 p->id = proccreate(theioproc, p, 4096);
95 pf = emalloc9p(sizeof(PFid));
98 r->ofcall.qid = rootqid;
99 r->fid->qid = rootqid;
104 ptrapclone(Fid *old, Fid *new)
108 pf = emalloc9p(sizeof(PFid));
109 memcpy(pf, old->aux, sizeof(PFid));
115 ptrapdestroyfid(Fid *f)
120 if(pf == nil) return;
129 ptrapwalk1(Fid *fid, char *name, Qid *qid)
133 static char err[ERRMAX];
137 return "phase error";
138 d = dirstat(fname(name));
140 rerrstr(err, ERRMAX);
143 pf->name = strdup(name);
157 pf->fd = open(fname(pf->name), r->ifcall.mode);
166 for(f = filters; f != nil; f = f->next)
167 if(strcmp(f->name, pf->name) == 0)
174 filter(PFilter *f, Plumbmsg *pm)
179 if(!(regexec(f->filt, pm->data, nil, 0) ^ f->invert))
181 for(a = f->attr; a; a = a->next){
182 value = plumblookup(pm->attr, a->name);
185 if(!(regexec(a->filt, value, nil, 0) ^ f->attr->invert))
192 filterread(Req *r, PFid *pf)
202 rc = r->ifcall.count;
203 if(pf->msgp + rc >= pf->msgn)
204 rc = pf->msgn - pf->msgp;
205 r->ofcall.count = rc;
206 memmove(r->ofcall.data, pf->msg + pf->msgp, rc);
208 if(pf->msgp >= pf->msgn){
214 buf = emalloc9p(4096);
215 rc = read(pf->fd, buf, 4096);
218 while(pm = plumbunpackpartial(buf, len, &more), pm == nil){
219 if(more == 0) goto err;
220 buf = erealloc9p(buf, len + more);
221 rc = readn(pf->fd, buf + len, more);
227 pf->msg = plumbpack(pm, &pf->msgn);
238 theioproc(void *iopp)
248 buf = smprint("/proc/%d/ctl", getpid());
249 fd = open(buf, OWRITE);
255 write(fd, "nointerrupt", 11);
259 switch(r->ifcall.type){
262 rc = pread(pf->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
267 r->ofcall.count = rc;
271 if(filterread(r, pf) < 0)
277 rc = pwrite(pf->fd, r->ifcall.data, r->ifcall.count, r->ifcall.offset);
281 r->ofcall.count = rc;
316 d = dirfstat(pf->fd);
318 d = dirstat(fname(pf->name));
323 memmove(&r->d, d, sizeof(Dir));
324 r->d.name = strdup(d->name);
325 r->d.uid = strdup(d->uid);
326 r->d.muid = strdup(d->muid);
327 r->d.gid = strdup(d->gid);
340 rc = dirfwstat(pf->fd, &r->d);
342 rc = dirwstat(fname(pf->name), &r->d);
352 if(r->oldreq->aux != nil)
353 threadint(((IOProc*)r->oldreq->aux)->id);
358 .attach = ptrapattach,
360 .destroyfid = ptrapdestroyfid,
373 fprint(2, "usage: %s port regex [ +attr regex ... ] ...\n", argv0);
378 threadmain(int argc, char **argv)
389 if(argc == 0 || argc % 2) usage();
390 for(i = 0; i+1 < argc;){
392 f = emalloc9p(sizeof(PFilter));
393 f->name = estrdup9p(p);
399 if((f->filt = regcomp(p)) == nil)
400 sysfatal("regcomp: %r");
403 for(i += 2; p = argv[i], i+1 < argc && p[0] == '+'; i += 2){
405 fa = emalloc9p(sizeof(FAttr));
406 fa->name = estrdup9p(p);
412 if((fa->filt = regcomp(p)) == nil)
413 sysfatal("regcomp: %r");
418 threadpostmountsrv(&ptrapsrv, nil, "/mnt/plumb", MREPL | MCREATE);