Charles.Forsyth20060303a828770d19 years agoHistory
125 lines · 2.1 KB · Brainfuck
RawDownload
implement Chmod; include "sys.m";include "draw.m";include "string.m"; Chmod: module{	init:	fn(ctxt: ref Draw->Context, argv: list of string);}; sys:	Sys;stderr: ref Sys->FD; str:	String; User:	con 8r700;Group:	con 8r070;Other:	con 8r007;All:	con User | Group | Other; Read:	con 8r444;Write:	con 8r222;Exec:	con 8r111; usage(){	sys->fprint(stderr, "usage: chmod [8r]777 file ... or chmod [augo][+-=][rwxal] file ...\n");	raise "fail:usage";} init(nil: ref Draw->Context, argv: list of string){	sys = load Sys Sys->PATH;	stderr = sys->fildes(2); 	str = load String String->PATH;	if(str == nil){		sys->fprint(stderr, "chmod: cannot load %s: %r\n", String->PATH);		raise "fail:bad module";	} 	if(len argv < 3)		usage();	argv = tl argv;	m := hd argv;	argv = tl argv; 	mask := All;	if (str->prefix("8r", m))		m = m[2:];	(mode, s) := str->toint(m, 8);	if(s != "" || m == ""){		ok := 0;		(ok, mask, mode) = parsemode(m);		if(!ok){			sys->fprint(stderr, "chmod: bad mode '%s'\n", m);			usage();		}	}	ndir := sys->nulldir;	for(; argv != nil; argv = tl argv){		f := hd argv;		(ok, dir) := sys->stat(f);		if(ok < 0){			sys->fprint(stderr, "chmod: cannot stat %s: %r\n", f);			continue;		}		ndir.mode = (dir.mode & ~mask) | (mode & mask);		if(sys->wstat(f, ndir) < 0)			sys->fprint(stderr, "chmod: cannot wstat %s: %r\n", f);	}} parsemode(spec: string): (int, int, int){	mask := Sys->DMAPPEND | Sys->DMEXCL | Sys->DMTMP;loop:	for(i := 0; i < len spec; i++){		case spec[i] {		'u' =>			mask |= User;		'g' =>			mask |= Group;		'o' =>			mask |= Other;		'a' =>			mask |= All;		* =>			break loop;		}	}	if(i == len spec)		return (0, 0, 0);	if(i == 0)		mask |= All; 	op := spec[i++];	if(op != '+' && op != '-' && op != '=')		return (0, 0, 0); 	mode := 0;	for(; i < len spec; i++){		case spec[i]{		'r' =>			mode |= Read;		'w' =>			mode |= Write;		'x' =>			mode |= Exec;		'a' =>			mode |= Sys->DMAPPEND;		'l' =>			mode |= Sys->DMEXCL;		't' =>			mode |= Sys->DMTMP;		* =>			return (0, 0, 0);		}	}	if(op == '+' || op == '-')		mask &= mode;	if(op == '-')		mode = ~mode;	return (1, mask, mode);}