188 lines · 3.5 KB · Brainfuck
RawDownload
##       Software from the book "Inferno Programming with Limbo"#       published by John Wiley & Sons, January 2003.##       p. Stanley-Marbell <pip@gemusehaken.org>#implement FilterFS; include "sys.m";include "draw.m";include "styx.m";include "filter.m";include "cachelib.m"; sys : Sys;styx : Styx;filter : Filter;cachelib : CacheLib; Smsg : import styx;Cache : import cachelib;Filtermsg : import filter; CACHESIZE : con 64;fidcache : ref Cache; FilterFS : module{	init : fn(nil : ref Draw->Context, nil : list of string);}; init(nil : ref Draw->Context, nil : list of string){	sync := chan of int;	filterpath := "printfilter.dis";          sys = load Sys Sys->PATH;	styx = load Styx Styx->PATH;	cachelib = load CacheLib CacheLib->PATH;	filter = load Filter filterpath; 	fidcache = Cache.allocate(CACHESIZE);         sys->bind("#|", "/chan", sys->MBEFORE);	export_pipe := array [2] of ref Sys->FD;	mount_pipe := array [2] of ref Sys->FD; 	sys->pipe(export_pipe);	sys->pipe(mount_pipe); 	filter->init(export_pipe, mount_pipe);         spawn xfre2m(export_pipe, mount_pipe, sync);        spawn xfrm2e(export_pipe, mount_pipe, sync); 	<- sync;	<- sync; 	if (sys->export(export_pipe[0], sys->EXPASYNC))	{		sys->print("Error - Could not export : %r\n");                exit;	} 	if (sys->mount(mount_pipe[1], "/n/filterfs", sys->MREPL, nil) == -1)	{		sys->print("FilterFS : mount failed");	}} xfre2m (export_pipe, mount_pipe : array of ref Sys->FD, sync : chan of int){	sync <-= 1; 	buf := array [sys->ATOMICIO] of byte;	while (1)	{		n := sys->read(export_pipe[1], buf, len buf); 		msg := data2fmsg(buf[:n]);		filter->rewrite(msg); 		if (msg != nil)		{			sys->write(mount_pipe[0], fmsg2data(msg), n);		}	}} xfrm2e (export_pipe, mount_pipe : array of ref Sys->FD, sync : chan of int){	sync <-= 1; 	buf := array [sys->ATOMICIO] of byte;	while (1)	{		n := sys->read(mount_pipe[0], buf, len buf); 		msg := data2fmsg(buf[:n]);		filter->rewrite(msg); 		if (msg != nil)		{			sys->write(export_pipe[1], fmsg2data(msg), n);		}	}} fmsg2data(fmsg : ref Filtermsg) : array of byte{	nentries := len fmsg.dirlist;	for (i := 0; i < (Styx->DIRLEN*nentries); i += Styx->DIRLEN)	{		fmsg.styxmsg.data[i:] = styx->convD2M(hd fmsg.dirlist);		fmsg.dirlist = tl fmsg.dirlist;	} 	return fmsg.styxmsg.convS2M();} data2fmsg(buf : array of byte) : ref Filtermsg{	msg := ref Filtermsg; 	(n, styxmsg) := styx->convM2S(buf);	if (n < 0)	{		return nil;	} 	if ((styxmsg.mtype == Styx->Rattach)||		(styxmsg.mtype == Styx->Rwalk)||		(styxmsg.mtype == Styx->Ropen)||		(styxmsg.mtype == Styx->Rcreate))	{		if (styxmsg.qid.path & Sys->CHDIR)		{			fidcache.addtocache(styxmsg.fid);		}	} 	if ((styxmsg.mtype == Styx->Tclone) &&		fidcache.isincache(styxmsg.fid))	{		fidcache.addtocache(styxmsg.newfid);	} 	if ((styxmsg.mtype == Styx->Tclunk) ||		((styxmsg.mtype == Styx->Rwalk) && 			!(styxmsg.qid.path & Sys->CHDIR)))	{		fidcache.delfromcache(styxmsg.fid);	} 	msg.styxmsg = styxmsg; 	if (styxmsg.mtype == Styx->Rread)	{		if (fidcache.isincache(msg.styxmsg.fid))		{			msg.isdirread = 1;			msg.dirlist = data2dirlist(styxmsg.data);		}	} 	return msg;} data2dirlist(buf : array of byte) : list of ref Sys->Dir{	dirlist : list of ref Sys->Dir; 	if (len buf % Styx->DIRLEN)	{		sys->print("Weird read from directory, data length [%d]\n",				len buf);		return nil;	} 	for (i := 0; i < len buf; i += Styx->DIRLEN)	{		direntry := styx->convM2D(buf[i:i+116]);		dirlist = direntry :: dirlist;	} 	return dirlist;}