From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: *** X-Spam-Status: No, score=3.3 required=5.0 tests=BULK_RE_SUSP_NTLD,DKIM_INVALID, DKIM_SIGNED,FROM_SUSPICIOUS_NTLD,PDS_OTHER_BAD_TLD,RCVD_IN_DNSWL_NONE autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 18939 invoked from network); 5 Dec 2020 19:08:53 -0000 Received: from ewsd.inri.net (107.191.116.128) by inbox.vuxu.org with ESMTPUTF8; 5 Dec 2020 19:08:53 -0000 Received: from out0.migadu.com ([94.23.1.103]) by ewsd; Sat Dec 5 14:06:54 -0500 2020 Message-ID: <7BFBE5377160E95529838E329D9AEB60@hog> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=a-b.xyz; s=key1; t=1607195251; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to; bh=riF3nJlTnXy2MwjNwxhK9/j/Ki8dTIxKhb1SVJ5RHmE=; b=cIyUJ/lZOkww1dilQLECoTYBcxfDGohT6I/2VuM7TsAB+w9phH8vbC6Z2eBKYmFQDw7yaR 5y8He8reAWoR/e63hibgKhz686nbJrOGvqib5rbQEUnh0o4oYB+k5aAjiZ74B6tRSb2YHl b6SdeMRgCEbeRRsBEAs/mbSPUj9TP6ferLEPoZUacIf3IM698GhdWEGa/rbzxJVd+5zu08 yqNYZBvpkw5BjsAXU4vWjncLLACC5ty9Ji0phM10PN61w99tzXIrSE3Z4uKLfZurePUxGj 4Aelft1Fufb4GSYWlx7FOs3KPck/w2ahHNZI8s5TaJH7dApcSN4GQHlPvtsxyA== To: 9front@9front.org X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: kvik@a-b.xyz In-Reply-To: <0236D9AD4D5FBA15B144E815E3EBCC47@eigenstate.org> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_OUT X-Migadu-Auth-User: kvik@a-b.xyz Date: Sat, 05 Dec 2020 19:07:31 GMT List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: ISO-certified NoSQL-based property-based rails storage Subject: Re: [9front] [PATCH] ptrap: implement attribute filters Reply-To: 9front@9front.org Precedence: bulk Quoth ori@eigenstate.org: > Looking over the code, only thought is that this bit may read > better as a nested loop, like: That's quite true. Readability++ version follows. diff -r 52827b94aac8 sys/man/4/ptrap --- a/sys/man/4/ptrap Wed Dec 02 00:57:21 2020 +0100 +++ b/sys/man/4/ptrap Sat Dec 05 19:40:38 2020 +0100 @@ -7,10 +7,7 @@ .B ptrap .I port [\fB!\fR]\fIregexp\fR -[ -.I port -[\fB!\fR]\fIregexp\fR ... -] +[ +\fIattr\fR [\fB!\fR]\fIregexp\fR ... ] ... .SH DESCRIPTION .I Ptrap is a program that mounts itself over a @@ -20,20 +17,20 @@ and filters incoming messages according to the rules provided on the command line. .PP .I Ptrap -accepts an arbitrary number of argument pairs; each pair consists of a port name -.I port -and a regular expression -.I regexp -(see -.IR regexp (6)). -Each incoming message that does not match -.I regexp -is discarded. -The -.I regexp -can be optionally prefixed by -.B ! -to indicate logical inversion (i.e. messages matching the regexp are discarded). +accepts an arbitrary number of filters; +each filter applies to a port, and may match over both the data and attributes of plumb messages. +.PP +A filter is formatted as a port name, a data filter, and a list of attribute filters. +.PP +The data filter is a +.IR regex (6) +that matches the plumbed data. +The attribute filter consists of the attribute name prefixed with a '+', followed by a +.IR regex (6) +that matches the contents of the attribute. +Any regex may be prefixed with a '!' in order to negate a match, +causing all matches for that regex to be discarded. +All parts of a filter must match in order for a plumb message to be forwarded. .SH EXAMPLES Start a .IR sam (1) @@ -52,6 +49,15 @@ ptrap edit '!^/sys/src/9/' sam .EE +.PP +Start an +.IR acme (1) +instance instance dedicated to reading plumbed manual pages: +.IP +.EX +ptrap edit '.*' +action '^showdata' +filename '^/man/' +acme -c1 +.EE .SH SOURCE .B /sys/src/cmd/ptrap.c .SH SEE ALSO diff -r 52827b94aac8 sys/src/cmd/ptrap.c --- a/sys/src/cmd/ptrap.c Wed Dec 02 00:57:21 2020 +0100 +++ b/sys/src/cmd/ptrap.c Sat Dec 05 19:40:38 2020 +0100 @@ -8,6 +8,7 @@ typedef struct IOProc IOProc; typedef struct PFilter PFilter; +typedef struct FAttr FAttr; typedef struct PFid PFid; struct IOProc { @@ -27,11 +28,19 @@ }; Qid rootqid = {.type QTDIR}; +struct FAttr { + char *name; + Reprog *filt; + int invert; + FAttr *next; +}; + struct PFilter { char *name; Reprog *filt; + int invert; + FAttr *attr; PFilter *next; - int invert; }; PFilter *filters; @@ -162,12 +171,32 @@ } static int +filter(PFilter *f, Plumbmsg *pm) +{ + FAttr *a; + char *value; + + if(!(regexec(f->filt, pm->data, nil, 0) ^ f->invert)) + return 0; + for(a = f->attr; a; a = a->next){ + value = plumblookup(pm->attr, a->name); + if(value == nil) + return 0; + if(!(regexec(a->filt, value, nil, 0) ^ f->attr->invert)) + return 0; + } + return 1; +} + +static int filterread(Req *r, PFid *pf) { int rc, len, more; char *buf; Plumbmsg *pm; + PFilter *f; + f = pf->filter; for(;;){ if(pf->msg != nil){ rc = r->ifcall.count; @@ -194,7 +223,7 @@ len += rc; } free(buf); - if(regexec(pf->filter->filt, pm->data, nil, 0) ^ pf->filter->invert){ + if(filter(f, pm)){ pf->msg = plumbpack(pm, &pf->msgn); pf->msgp = 0; } @@ -341,7 +370,7 @@ void usage(void) { - fprint(2, "usage: %s port regex [ port regex ... ]\n", argv0); + fprint(2, "usage: %s port regex [ +attr regex ... ] ...\n", argv0); exits("usage"); } @@ -349,6 +378,7 @@ threadmain(int argc, char **argv) { PFilter *f; + FAttr *fa; char *p; int i; @@ -357,19 +387,33 @@ }ARGEND; if(argc == 0 || argc % 2) usage(); - for(i = 0; i < argc; i += 2){ + for(i = 0; i+1 < argc;){ + p = argv[i]; f = emalloc9p(sizeof(PFilter)); - f->name = strdup(argv[i]); + f->name = estrdup9p(p); p = argv[i+1]; - if(*p == '!'){ + if(p[0] == '!'){ p++; f->invert = 1; } - f->filt = regcomp(p); - if(f->filt == nil) - sysfatal("%r"); + if((f->filt = regcomp(p)) == nil) + sysfatal("regcomp: %r"); f->next = filters; filters = f; + for(i += 2; p = argv[i], i+1 < argc && p[0] == '+'; i += 2){ + p++; + fa = emalloc9p(sizeof(FAttr)); + fa->name = estrdup9p(p); + p = argv[i+1]; + if(p[0] == '!'){ + p++; + fa->invert = 1; + } + if((fa->filt = regcomp(p)) == nil) + sysfatal("regcomp: %r"); + fa->next = f->attr; + f->attr = fa; + } } threadpostmountsrv(&ptrapsrv, nil, "/mnt/plumb", MREPL | MCREATE);