Charles.Forsyth20060303a828770d19 years agoHistory
157 lines · 3.1 KB · Brainfuck
RawDownload
# ns - display the construction of the current namespace (loosely based on plan 9's ns)implement Ns; include "sys.m";	sys: Sys; include "draw.m"; include "arg.m"; Ns: module{	init: fn(nil: ref Draw->Context, argv: list of string);}; SHELLMETA: con "' \t\\$#"; usage(){	sys->fprint(sys->fildes(2), "usage: ns [-r] [pid]\n");	raise "fail:usage";} init(nil: ref Draw->Context, args: list of string){	sys = load Sys Sys->PATH; 	arg := load Arg Arg->PATH;	if(arg == nil){		sys->fprint(sys->fildes(2), "ns: can't load %s: %r\n", Arg->PATH);		raise "fail:load";	}	arg->init(args);	pid := sys->pctl(0, nil);	raw := 0;	while((o := arg->opt()) != 0)		case o {		'r' =>			raw = 1;		* =>			usage();		}	args = arg->argv();	arg = nil; 	if(len args > 1)		usage();	if(len args > 0)		pid = int hd args; 	nsname := sys->sprint("/prog/%d/ns", pid);	nsfd := sys->open(nsname, Sys->OREAD);	if(nsfd == nil) {		sys->fprint(sys->fildes(2), "ns: can't open %s: %r\n", nsname);		raise "fail:open";	} 	buf := array[2048] of byte;	while((l := sys->read(nsfd, buf, len buf)) > 0){		(nstr, lstr) := sys->tokenize(string buf[0:l], " \n");		if(nstr < 2)			continue;		cmd := hd lstr;		lstr = tl lstr;		if(cmd == "cd" && lstr != nil){			sys->print("%s %s\n", cmd, quoted(hd lstr));			continue;		} 		sflag := "";		if((hd lstr)[0] == '-') {			sflag = hd lstr + " ";			lstr = tl lstr;		}		if(len lstr < 2)			continue; 		src := hd lstr;		lstr = tl lstr;		if(len src >= 3 && (src[0:2] == "#/" || src[0:2] == "#U")) # remove unnecesary #/'s and #U's			src = src[2:]; 		# remove "#." from beginning of destination path		dest := hd lstr;		if(dest == "#M") {			dest = dest[2:];			if(dest == "")				dest = "/";		} 		if(cmd == "mount" && !raw)			src = netaddr(src);	# optionally rewrite network files to network address 		# quote arguments if "#" found		sys->print("%s %s%s %s\n", cmd, sflag, quoted(src), quoted(dest));	} 	if(l < 0)		sys->fprint(sys->fildes(2), "ns: error reading %s: %r\n", nsname);} netaddr(f: string): string{	if(len f < 1 || f[0] != '/')		return f;	(nf, flds) := sys->tokenize(f, "/");	# expect /net[.alt]/proto/2/data	if(nf < 4)		return f;	netdir := hd flds;	if(netdir != "net" && netdir != "net.alt")		return f;	proto := hd tl flds;	d := hd tl tl flds;	if(hd tl tl tl flds != "data")		return f;	fd := sys->open(sys->sprint("/%s/%s/%s/remote", hd flds, proto, d), Sys->OREAD);	if(fd == nil)		return f;	buf := array[256] of byte;	n := sys->read(fd, buf, len buf);	if(n <= 0)		return f;	if(buf[n-1] == byte '\n')		n--;	if(netdir != "net")		proto = "/"+netdir+"/"+proto;	return sys->sprint("%s!%s", proto, string buf[0:n]);} any(c: int, t: string): int{	for(j := 0; j < len t; j++)		if(c == t[j])			return 1;	return 0;} contains(s: string, t: string): int{	for(i := 0; i<len s; i++)		if(any(s[i], t))			return 1;	return 0;} quoted(s: string): string{	if(!contains(s, SHELLMETA))		return s;	r := "'";	for(i := 0; i < len s; i++){		if(s[i] == '\'')			r[len r] = '\'';		r[len r] = s[i];	}	r[len r] = '\'';	return r;}