#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <ctype.h>
void
rot13(char *p, int n)
{
char *ep;
for(ep=p+n; p<ep; p++)
if(isalpha(*p))
if(tolower(*p) <= 'm')
*p += 13;
else
*p -= 13;
}
int isdir[65536];
void
filter(int rd, int wr)
{
char buf[MAXMSG+MAXFDATA], wbuf[MAXMSG+MAXFDATA];
Fcall f;
long n;
while(n=sizeof buf, getS(rd, buf, &f, &n) == nil){
if(f.type == Ropen)
isdir[f.fid] = f.qid.path&CHDIR;
if((f.type == Twrite || f.type == Rread) && !isdir[f.fid])
rot13(f.data, f.count);
n = convS2M(&f, wbuf);
write(wr, wbuf, n);
}
postnote(PNGROUP, getpid(), "spanish inquisition"); /* nobody expects this */
}
void
main(int argc, char **argv)
{
int sfd, p[2];
rfork(RFNOTEG);
if(argc != 1+2){
fprint(2, "usage: rot13fs service-in mountpoint\n");
exits("usage");
}
if((sfd = open(argv[1], ORDWR)) < 0)
sysfatal("cannot open %s: %r\n", argv[1]);
if(pipe(p) < 0)
sysfatal("pipe fails: %r\n");
switch(rfork(RFNAMEG|RFPROC|RFFDG|RFMEM)){
case -1:
sysfatal("rfork fails: %r\n");
case 0:
close(p[0]);
switch(fork()){
case -1:
sysfatal("rfork fails: %r\n");
case 0:
filter(sfd, p[1]);
break;
default:
filter(p[1], sfd);
break;
}
_exits(0);
default:
close(p[1]);
if(amount(p[0], argv[2], MREPL, "") < 0)
sysfatal("mount fails: %r\n");
exits(0);
}
}
|