+ logreq(&data);
+}
+
+static int passdata(struct bufio *in, struct bufio *out, off_t *passed)
+{
+ ssize_t read;
+ off_t total;
+
+ total = 0;
+ while(!bioeof(in)) {
+ if((read = biordata(in)) > 0) {
+ if((read = biowritesome(out, in->rbuf.b + in->rh, read)) < 0)
+ return(-1);
+ in->rh += read;
+ total += read;
+ }
+ if(biorspace(in) && (biofillsome(in) < 0))
+ return(-1);
+ }
+ if(passed)
+ *passed = total;
+ return(0);
+}
+
+static void filterreq(struct muth *mt, va_list args)
+{
+ vavar(struct hthead *, req);
+ vavar(int, fd);
+ int pfds[2];
+ struct hthead *resp;
+ struct bufio *cl, *hd;
+ struct stdiofd *cli, *hdi;
+ struct logdata data;
+
+ hd = NULL;
+ resp = NULL;
+ data = defdata;
+ data.req = req;
+ gettimeofday(&data.start, NULL);
+ cl = mtbioopen(fd, 1, 600, "r+", &cli);
+ if(socketpair(PF_UNIX, SOCK_STREAM, 0, pfds))
+ goto out;
+ hd = mtbioopen(pfds[1], 1, 600, "r+", &hdi);
+ if(sendreq(ch, req, pfds[0])) {
+ close(pfds[0]);
+ goto out;
+ }
+ close(pfds[0]);
+
+ if(passdata(cl, hd, &data.bytesin))
+ goto out;
+ if(bioflush(hd))
+ goto out;
+ shutdown(pfds[1], SHUT_WR);
+ if((resp = parseresponseb(hd)) == NULL)
+ goto out;
+ cli->sendrights = hdi->rights;
+ hdi->rights = -1;
+ data.resp = resp;
+ writerespb(cl, resp);
+ bioprintf(cl, "\r\n");
+ if(passdata(hd, cl, &data.bytesout))
+ goto out;
+ gettimeofday(&data.end, NULL);
+
+out:
+ logreq(&data);
+
+ freehthead(req);
+ if(resp != NULL)
+ freehthead(resp);
+ bioclose(cl);
+ if(hd != NULL)
+ bioclose(hd);