9 typedef struct IOProc IOProc;
10 typedef struct PFilter PFilter;
11 typedef struct PFid PFid;
28 Qid rootqid = {.type QTDIR};
49 last = smprint("/mnt/plumb/%s", n);
53 static void theioproc(void *);
65 p = emalloc9p(sizeof(IOProc));
66 p->ch = chancreate(sizeof(Req*), 0);
67 p->id = proccreate(theioproc, p, 4096);
86 pf = emalloc9p(sizeof(PFid));
89 r->ofcall.qid = rootqid;
90 r->fid->qid = rootqid;
95 ptrapclone(Fid *old, Fid *new)
99 pf = emalloc9p(sizeof(PFid));
100 memcpy(pf, old->aux, sizeof(PFid));
106 ptrapdestroyfid(Fid *f)
111 if(pf == nil) return;
120 ptrapwalk1(Fid *fid, char *name, Qid *qid)
124 static char err[ERRMAX];
128 return "phase error";
129 d = dirstat(fname(name));
131 rerrstr(err, ERRMAX);
134 pf->name = strdup(name);
148 pf->fd = open(fname(pf->name), r->ifcall.mode);
157 for(f = filters; f != nil; f = f->next)
158 if(strcmp(f->name, pf->name) == 0)
165 filterread(Req *r, PFid *pf)
173 rc = r->ifcall.count;
174 if(pf->msgp + rc >= pf->msgn)
175 rc = pf->msgn - pf->msgp;
176 r->ofcall.count = rc;
177 memmove(r->ofcall.data, pf->msg + pf->msgp, rc);
179 if(pf->msgp >= pf->msgn){
185 buf = emalloc9p(4096);
186 rc = read(pf->fd, buf, 4096);
189 while(pm = plumbunpackpartial(buf, len, &more), pm == nil){
190 if(more == 0) goto err;
191 buf = erealloc9p(buf, len + more);
192 rc = readn(pf->fd, buf + len, more);
197 if(regexec(pf->filter->filt, pm->data, nil, 0) ^ pf->filter->invert){
198 pf->msg = plumbpack(pm, &pf->msgn);
209 theioproc(void *iopp)
219 buf = smprint("/proc/%d/ctl", getpid());
220 fd = open(buf, OWRITE);
226 write(fd, "nointerrupt", 11);
230 switch(r->ifcall.type){
233 rc = pread(pf->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
238 r->ofcall.count = rc;
242 if(filterread(r, pf) < 0)
248 rc = pwrite(pf->fd, r->ifcall.data, r->ifcall.count, r->ifcall.offset);
252 r->ofcall.count = rc;
287 d = dirfstat(pf->fd);
289 d = dirstat(fname(pf->name));
294 memmove(&r->d, d, sizeof(Dir));
295 r->d.name = strdup(d->name);
296 r->d.uid = strdup(d->uid);
297 r->d.muid = strdup(d->muid);
298 r->d.gid = strdup(d->gid);
311 rc = dirfwstat(pf->fd, &r->d);
313 rc = dirwstat(fname(pf->name), &r->d);
323 if(r->oldreq->aux != nil)
324 threadint(((IOProc*)r->oldreq->aux)->id);
329 .attach = ptrapattach,
331 .destroyfid = ptrapdestroyfid,
344 fprint(2, "usage: %s port regex [ port regex ... ]\n", argv0);
349 threadmain(int argc, char **argv)
359 if(argc % 2) usage();
360 for(i = 0; i < argc; i += 2){
361 f = emalloc9p(sizeof(PFilter));
362 f->name = strdup(argv[i]);
368 f->filt = regcomp(p);
374 threadpostmountsrv(&ptrapsrv, nil, "/mnt/plumb", MREPL | MCREATE);