code: purgatorio

ref: a8083462e62459b2ae8a243dc4ba88416eba03b1
dir: /appl/alphabet/fs/ls.b/

View raw version
implement Ls, Fsmodule;
include "sys.m";
	sys: Sys;
include "daytime.m";
	daytime: Daytime;
include "draw.m";
include "sh.m";
include "alphabet/reports.m";
	reports: Reports;
	Report: import reports;
include "alphabet/fs.m";
	fs: Fs;
	Option, Value, Entrychan: import fs;

Ls: module {};

types(): string
{
	return "ft-u-m";
}

badmod(p: string)
{
	sys->fprint(sys->fildes(2), "fs: ls: cannot load %s: %r\n", p);
	raise "fail:bad module";
}

init()
{
	sys = load Sys Sys->PATH;
	fs = load Fs Fs->PATH;
	reports = load Reports Reports->PATH;
	if(reports == nil)
		badmod(Reports->PATH);
	if(fs == nil)
		badmod(Fs->PATH);
	fs->init();
	daytime = load Daytime Daytime->PATH;
	if(daytime == nil)
		badmod(Daytime->PATH);
}

run(nil: ref Draw->Context, report: ref Report,
			opts: list of Option, args: list of ref Value): ref Value
{
	f := chan of ref Sys->FD;
	spawn lsproc(f, opts, (hd args).t().i, report.start("/fs/ls"));
	return ref Value.Vf(f);
}

lsproc(f: chan of ref Sys->FD, opts: list of Option, c: Entrychan, errorc: chan of string)
{
	f <-= nil;
	if((fd := <-f) == nil){
		c.sync <-= 0;
		reports->quit(errorc);
	}
	now := daytime->now();
	mflag := uflag := 0;
	c.sync <-= 1;
	for(; opts != nil; opts = tl opts){
		case (hd opts).opt {
		'm' =>
			mflag = 1;
		'u' =>
			uflag = 1;
		}
	}
	while(((dir, p, nil) := <-c.c).t0 != nil){
		t := dir.mtime;
		if(uflag)
			t = dir.atime;
		s := sys->sprint("%s %c %d %s %s %bud %s %s\n",
			modes(dir.mode), dir.dtype, dir.dev,
			dir.uid, dir.gid, dir.length,
			daytime->filet(now, dir.mtime), p);
		if(mflag)
			s = "[" + dir.muid + "] " + s;
		sys->fprint(fd, "%s", s);
	}
	reports->quit(errorc);
}

mtab := array[] of {
	"---",	"--x",	"-w-",	"-wx",
	"r--",	"r-x",	"rw-",	"rwx"
};

modes(mode: int): string
{
	s: string;

	if(mode & Sys->DMDIR)
		s = "d";
	else if(mode & Sys->DMAPPEND)
		s = "a";
	else if(mode & Sys->DMAUTH)
		s = "A";
	else
		s = "-";
	if(mode & Sys->DMEXCL)
		s += "l";
	else
		s += "-";
	s += mtab[(mode>>6)&7]+mtab[(mode>>3)&7]+mtab[mode&7];
	return s;
}