#include "stdinc.h"
#include <bio.h>
#include "dat.h"
#include "fns.h"
#include "9.h"

struct Fsys {
	QLock	lock;

	char*	name;		/* copy here & Fs to ease error reporting */
	char*	dev;
	char*	venti;

	Fs*	fs;
	VtConn* session;
	int	ref;

	int	noauth;
	int	noperm;
	int	wstatallow;

	Fsys*	next;
};

int mempcnt;			/* from fossil.c */

int	fsGetBlockSize(Fs *fs);

static struct {
	RWLock	lock;
	Fsys*	head;
	Fsys*	tail;

	char*	curfsys;
} sbox;

static char *_argv0;
#define argv0 _argv0

static char FsysAll[] = "all";

static char EFsysBusy[] = "fsys: '%s' busy";
static char EFsysExists[] = "fsys: '%s' already exists";
static char EFsysNoCurrent[] = "fsys: no current fsys";
static char EFsysNotFound[] = "fsys: '%s' not found";
static char EFsysNotOpen[] = "fsys: '%s' not open";

static char *
ventihost(char *host)
{
	if(host != nil)
		return vtstrdup(host);
	host = getenv("venti");
	if(host == nil)
		host = vtstrdup("$venti");
	return host;
}

static void
prventihost(char *host)
{
	char *vh;

	vh = ventihost(host);
	fprint(2, "%s: dialing venti at %s\n",
		argv0, netmkaddr(vh, 0, "venti"));
	free(vh);
}

static VtConn *
myDial(char *host)
{
	prventihost(host);
	return vtdial(host);
}

static int
myRedial(VtConn *z, char *host)
{
	prventihost(host);
	return vtredial(z, host);
}

static Fsys*
_fsysGet(char* name)
{
	Fsys *fsys;

	if(name == nil || name[0] == '\0')
		name = "main";

	rlock(&sbox.lock);
	for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
		if(strcmp(name, fsys->name) == 0){
			fsys->ref++;
			break;
		}
	}
	runlock(&sbox.lock);
	if(fsys == nil)
		werrstr(EFsysNotFound, name);
	return fsys;
}

static int
cmdPrintConfig(int argc, char* argv[])
{
	Fsys *fsys;
	char *usage = "usage: printconfig";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND

	if(argc)
		return cliError(usage);

	rlock(&sbox.lock);
	for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
		consPrint("\tfsys %s config %s\n", fsys->name, fsys->dev);
		if(fsys->venti && fsys->venti[0])
			consPrint("\tfsys %s venti %q\n", fsys->name,
				fsys->venti);
	}
	runlock(&sbox.lock);
	return 1;
}

Fsys*
fsysGet(char* name)
{
	Fsys *fsys;

	if((fsys = _fsysGet(name)) == nil)
		return nil;

	qlock(&fsys->lock);
	if(fsys->fs == nil){
		werrstr(EFsysNotOpen, fsys->name);
		qunlock(&fsys->lock);
		fsysPut(fsys);
		return nil;
	}
	qunlock(&fsys->lock);

	return fsys;
}

char*
fsysGetName(Fsys* fsys)
{
	return fsys->name;
}

Fsys*
fsysIncRef(Fsys* fsys)
{
	wlock(&sbox.lock);
	fsys->ref++;
	wunlock(&sbox.lock);

	return fsys;
}

void
fsysPut(Fsys* fsys)
{
	wlock(&sbox.lock);
	assert(fsys->ref > 0);
	fsys->ref--;
	wunlock(&sbox.lock);
}

Fs*
fsysGetFs(Fsys* fsys)
{
	assert(fsys != nil && fsys->fs != nil);

	return fsys->fs;
}

void
fsysFsRlock(Fsys* fsys)
{
	rlock(&fsys->fs->elk);
}

void
fsysFsRUnlock(Fsys* fsys)
{
	runlock(&fsys->fs->elk);
}

int
fsysNoAuthCheck(Fsys* fsys)
{
	return fsys->noauth;
}

int
fsysNoPermCheck(Fsys* fsys)
{
	return fsys->noperm;
}

int
fsysWstatAllow(Fsys* fsys)
{
	return fsys->wstatallow;
}

static char modechars[] = "YUGalLdHSATs";
static ulong modebits[] = {
	ModeSticky,
	ModeSetUid,
	ModeSetGid,
	ModeAppend,
	ModeExclusive,
	ModeLink,
	ModeDir,
	ModeHidden,
	ModeSystem,
	ModeArchive,
	ModeTemporary,
	ModeSnapshot,
	0
};

char*
fsysModeString(ulong mode, char *buf)
{
	int i;
	char *p;

	p = buf;
	for(i=0; modebits[i]; i++)
		if(mode & modebits[i])
			*p++ = modechars[i];
	sprint(p, "%luo", mode&0777);
	return buf;
}

int
fsysParseMode(char* s, ulong* mode)
{
	ulong x, y;
	char *p;

	x = 0;
	for(; *s < '0' || *s > '9'; s++){
		if(*s == 0)
			return 0;
		p = strchr(modechars, *s);
		if(p == nil)
			return 0;
		x |= modebits[p-modechars];
	}
	y = strtoul(s, &p, 8);
	if(*p != '\0' || y > 0777)
		return 0;
	*mode = x|y;
	return 1;
}

File*
fsysGetRoot(Fsys* fsys, char* name)
{
	File *root, *sub;

	assert(fsys != nil && fsys->fs != nil);

	root = fsGetRoot(fsys->fs);
	if(name == nil || strcmp(name, "") == 0)
		return root;

	sub = fileWalk(root, name);
	fileDecRef(root);

	return sub;
}

static Fsys*
fsysAlloc(char* name, char* dev)
{
	Fsys *fsys;

	wlock(&sbox.lock);
	for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
		if(strcmp(fsys->name, name) != 0)
			continue;
		werrstr(EFsysExists, name);
		wunlock(&sbox.lock);
		return nil;
	}

	fsys = vtmallocz(sizeof(Fsys));
	fsys->name = vtstrdup(name);
	fsys->dev = vtstrdup(dev);

	fsys->ref = 1;

	if(sbox.tail != nil)
		sbox.tail->next = fsys;
	else
		sbox.head = fsys;
	sbox.tail = fsys;
	wunlock(&sbox.lock);

	return fsys;
}

static int
fsysClose(Fsys* fsys, int argc, char* argv[])
{
	char *usage = "usage: [fsys name] close";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc)
		return cliError(usage);

	return cliError("close isn't working yet; halt %s and then kill fossil",
		fsys->name);

	/*
	 * Oooh. This could be hard. What if fsys->ref != 1?
	 * Also, fsClose() either does the job or panics, can we
	 * gracefully detect it's still busy?
	 *
	 * More thought and care needed here.
	fsClose(fsys->fs);
	fsys->fs = nil;
	vtfreeconn(fsys->session);
	fsys->session = nil;

	if(sbox.curfsys != nil && strcmp(fsys->name, sbox.curfsys) == 0){
		sbox.curfsys = nil;
		consPrompt(nil);
	}

	return 1;
	 */
}

static int
fsysVac(Fsys* fsys, int argc, char* argv[])
{
	uchar score[VtScoreSize];
	char *usage = "usage: [fsys name] vac path";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc != 1)
		return cliError(usage);

	if(!fsVac(fsys->fs, argv[0], score))
		return 0;

	consPrint("vac:%V\n", score);
	return 1;
}

static int
fsysSnap(Fsys* fsys, int argc, char* argv[])
{
	int doarchive;
	char *usage = "usage: [fsys name] snap [-a] [-s /active] [-d /archive/yyyy/mmmm]";
	char *src, *dst;

	src = nil;
	dst = nil;
	doarchive = 0;
	ARGBEGIN{
	default:
		return cliError(usage);
	case 'a':
		doarchive = 1;
		break;
	case 'd':
		if((dst = ARGF()) == nil)
			return cliError(usage);
		break;
	case 's':
		if((src = ARGF()) == nil)
			return cliError(usage);
		break;
	}ARGEND
	if(argc)
		return cliError(usage);

	if(!fsSnapshot(fsys->fs, src, dst, doarchive))
		return 0;

	return 1;
}

static int
fsysSnapClean(Fsys *fsys, int argc, char* argv[])
{
	u32int arch, snap, life;
	char *usage = "usage: [fsys name] snapclean [maxminutes]\n";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND

	if(argc > 1)
		return cliError(usage);
	if(argc == 1)
		life = atoi(argv[0]);
	else
		snapGetTimes(fsys->fs->snap, &arch, &snap, &life);

	fsSnapshotCleanup(fsys->fs, life);
	return 1;
}

static int
fsysSnapTime(Fsys* fsys, int argc, char* argv[])
{
	char buf[128], *x;
	int hh, mm, changed;
	u32int arch, snap, life;
	char *usage = "usage: [fsys name] snaptime [-a hhmm] [-s snapminutes] [-t maxminutes]";

	changed = 0;
	snapGetTimes(fsys->fs->snap, &arch, &snap, &life);
	ARGBEGIN{
	case 'a':
		changed = 1;
		x = ARGF();
		if(x == nil)
			return cliError(usage);
		if(strcmp(x, "none") == 0){
			arch = ~(u32int)0;
			break;
		}
		if(strlen(x) != 4 || strspn(x, "0123456789") != 4)
			return cliError(usage);
		hh = (x[0]-'0')*10 + x[1]-'0';
		mm = (x[2]-'0')*10 + x[3]-'0';
		if(hh >= 24 || mm >= 60)
			return cliError(usage);
		arch = hh*60+mm;
		break;
	case 's':
		changed = 1;
		x = ARGF();
		if(x == nil)
			return cliError(usage);
		if(strcmp(x, "none") == 0){
			snap = ~(u32int)0;
			break;
		}
		snap = atoi(x);
		break;
	case 't':
		changed = 1;
		x = ARGF();
		if(x == nil)
			return cliError(usage);
		if(strcmp(x, "none") == 0){
			life = ~(u32int)0;
			break;
		}
		life = atoi(x);
		break;
	default:
		return cliError(usage);
	}ARGEND
	if(argc > 0)
		return cliError(usage);

	if(changed){
		snapSetTimes(fsys->fs->snap, arch, snap, life);
		return 1;
	}
	snapGetTimes(fsys->fs->snap, &arch, &snap, &life);
	if(arch != ~(u32int)0)
		sprint(buf, "-a %02d%02d", arch/60, arch%60);
	else
		sprint(buf, "-a none");
	if(snap != ~(u32int)0)
		sprint(buf+strlen(buf), " -s %d", snap);
	else
		sprint(buf+strlen(buf), " -s none");
	if(life != ~(u32int)0)
		sprint(buf+strlen(buf), " -t %ud", life);
	else
		sprint(buf+strlen(buf), " -t none");
	consPrint("\tsnaptime %s\n", buf);
	return 1;
}

static int
fsysSync(Fsys* fsys, int argc, char* argv[])
{
	char *usage = "usage: [fsys name] sync";
	int n;
	
	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc > 0)
		return cliError(usage);

	n = cacheDirty(fsys->fs->cache);
	fsSync(fsys->fs);
	consPrint("\t%s sync: wrote %d blocks\n", fsys->name, n);
	return 1;
}

static int
fsysHalt(Fsys *fsys, int argc, char* argv[])
{
	char *usage = "usage: [fsys name] halt";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc > 0)
		return cliError(usage);

	fsHalt(fsys->fs);
	return 1;
}

static int
fsysUnhalt(Fsys *fsys, int argc, char* argv[])
{
	char *usage = "usage: [fsys name] unhalt";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc > 0)
		return cliError(usage);

	if(!fsys->fs->halted)
		return cliError("file system %s not halted", fsys->name);

	fsUnhalt(fsys->fs);
	return 1;
}

static int
fsysRemove(Fsys* fsys, int argc, char* argv[])
{
	File *file;
	char *usage = "usage: [fsys name] remove path ...";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc == 0)
		return cliError(usage);

	rlock(&fsys->fs->elk);
	while(argc > 0){
		if((file = fileOpen(fsys->fs, argv[0])) == nil)
			consPrint("%s: %r\n", argv[0]);
		else{
			if(!fileRemove(file, uidadm))
				consPrint("%s: %r\n", argv[0]);
			fileDecRef(file);
		}
		argc--;
		argv++;
	}
	runlock(&fsys->fs->elk);

	return 1;
}

static int
fsysClri(Fsys* fsys, int argc, char* argv[])
{
	char *usage = "usage: [fsys name] clri path ...";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc == 0)
		return cliError(usage);

	rlock(&fsys->fs->elk);
	while(argc > 0){
		if(!fileClriPath(fsys->fs, argv[0], uidadm))
			consPrint("clri %s: %r\n", argv[0]);
		argc--;
		argv++;
	}
	runlock(&fsys->fs->elk);

	return 1;
}

/*
 * Inspect and edit the labels for blocks on disk.
 */
static int
fsysLabel(Fsys* fsys, int argc, char* argv[])
{
	Fs *fs;
	Label l;
	int n, r;
	u32int addr;
	Block *b, *bb;
	char *usage = "usage: [fsys name] label addr [type state epoch epochClose tag]";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc != 1 && argc != 6)
		return cliError(usage);

	r = 0;
	rlock(&fsys->fs->elk);

	fs = fsys->fs;
	addr = strtoul(argv[0], 0, 0);
	b = cacheLocal(fs->cache, PartData, addr, OReadOnly);
	if(b == nil)
		goto Out0;

	l = b->l;
	consPrint("%slabel %#ux %ud %ud %ud %ud %#x\n",
		argc==6 ? "old: " : "", addr, l.type, l.state,
		l.epoch, l.epochClose, l.tag);

	if(argc == 6){
		if(strcmp(argv[1], "-") != 0)
			l.type = atoi(argv[1]);
		if(strcmp(argv[2], "-") != 0)
			l.state = atoi(argv[2]);
		if(strcmp(argv[3], "-") != 0)
			l.epoch = strtoul(argv[3], 0, 0);
		if(strcmp(argv[4], "-") != 0)
			l.epochClose = strtoul(argv[4], 0, 0);
		if(strcmp(argv[5], "-") != 0)
			l.tag = strtoul(argv[5], 0, 0);

		consPrint("new: label %#ux %ud %ud %ud %ud %#x\n",
			addr, l.type, l.state, l.epoch, l.epochClose, l.tag);
		bb = _blockSetLabel(b, &l);
		if(bb == nil)
			goto Out1;
		n = 0;
		for(;;){
			if(blockWrite(bb, Waitlock)){
				while(bb->iostate != BioClean){
					assert(bb->iostate == BioWriting);
					rsleep(&bb->ioready);
				}
				break;
			}
			consPrint("blockWrite: %r\n");
			if(n++ >= 5){
				consPrint("giving up\n");
				break;
			}
			sleep(5*1000);
		}
		blockPut(bb);
	}
	r = 1;
Out1:
	blockPut(b);
Out0:
	runlock(&fs->elk);

	return r;
}

/*
 * Inspect and edit the blocks on disk.
 */
static int
fsysBlock(Fsys* fsys, int argc, char* argv[])
{
	Fs *fs;
	char *s;
	Block *b;
	uchar *buf;
	u32int addr;
	int c, count, i, offset;
	char *usage = "usage: [fsys name] block addr offset [count [data]]";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc < 2 || argc > 4)
		return cliError(usage);

	fs = fsys->fs;
	addr = strtoul(argv[0], 0, 0);
	offset = strtoul(argv[1], 0, 0);
	if(offset < 0 || offset >= fs->blockSize){
		werrstr("bad offset");
		return 0;
	}
	if(argc > 2)
		count = strtoul(argv[2], 0, 0);
	else
		count = 100000000;
	if(offset+count > fs->blockSize)
		count = fs->blockSize - count;

	rlock(&fs->elk);

	b = cacheLocal(fs->cache, PartData, addr, argc==4 ? OReadWrite : OReadOnly);
	if(b == nil){
		werrstr("cacheLocal %#ux: %r", addr);
		runlock(&fs->elk);
		return 0;
	}

	consPrint("\t%sblock %#ux %ud %ud %.*H\n",
		argc==4 ? "old: " : "", addr, offset, count, count, b->data+offset);

	if(argc == 4){
		s = argv[3];
		if(strlen(s) != 2*count){
			werrstr("bad data count");
			goto Out;
		}
		buf = vtmallocz(count);
		for(i = 0; i < count*2; i++){
			if(s[i] >= '0' && s[i] <= '9')
				c = s[i] - '0';
			else if(s[i] >= 'a' && s[i] <= 'f')
				c = s[i] - 'a' + 10;
			else if(s[i] >= 'A' && s[i] <= 'F')
				c = s[i] - 'A' + 10;
			else{
				werrstr("bad hex");
				vtfree(buf);
				goto Out;
			}
			if((i & 1) == 0)
				c <<= 4;
			buf[i>>1] |= c;
		}
		memmove(b->data+offset, buf, count);
		consPrint("\tnew: block %#ux %ud %ud %.*H\n",
			addr, offset, count, count, b->data+offset);
		blockDirty(b);
	}

Out:
	blockPut(b);
	runlock(&fs->elk);

	return 1;
}

/*
 * Free a disk block.
 */
static int
fsysBfree(Fsys* fsys, int argc, char* argv[])
{
	Fs *fs;
	Label l;
	char *p;
	Block *b;
	u32int addr;
	char *usage = "usage: [fsys name] bfree addr ...";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc == 0)
		return cliError(usage);

	fs = fsys->fs;
	rlock(&fs->elk);
	while(argc > 0){
		addr = strtoul(argv[0], &p, 0);
		if(*p != '\0'){
			consPrint("bad address - '%ud'\n", addr);
			/* syntax error; let's stop */
			runlock(&fs->elk);
			return 0;
		}
		b = cacheLocal(fs->cache, PartData, addr, OReadOnly);
		if(b == nil){
			consPrint("loading %#ux: %r\n", addr);
			continue;
		}
		l = b->l;
		if(l.state == BsFree)
			consPrint("%#ux is already free\n", addr);
		else{
			consPrint("label %#ux %ud %ud %ud %ud %#x\n",
				addr, l.type, l.state, l.epoch, l.epochClose, l.tag);
			l.state = BsFree;
			l.type = BtMax;
			l.tag = 0;
			l.epoch = 0;
			l.epochClose = 0;
			if(!blockSetLabel(b, &l, 0))
				consPrint("freeing %#ux: %r\n", addr);
		}
		blockPut(b);
		argc--;
		argv++;
	}
	runlock(&fs->elk);

	return 1;
}

static int
fsysDf(Fsys *fsys, int argc, char* argv[])
{
	char *usage = "usage: [fsys name] df";
	u32int used, tot, bsize;
	Fs *fs;

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc != 0)
		return cliError(usage);

	fs = fsys->fs;
	cacheCountUsed(fs->cache, fs->elo, &used, &tot, &bsize);
	consPrint("\t%s: %,llud used + %,llud free = %,llud (%.1f%% used)\n",
		fsys->name, used*(vlong)bsize, (tot-used)*(vlong)bsize,
		tot*(vlong)bsize, used*100.0/tot);
	return 1;
}

/*
 * Zero an entry or a pointer.
 */
static int
fsysClrep(Fsys* fsys, int argc, char* argv[], int ch)
{
	Fs *fs;
	Entry e;
	Block *b;
	u32int addr;
	int i, max, offset, sz;
	uchar zero[VtEntrySize];
	char *usage = "usage: [fsys name] clr%c addr offset ...";

	ARGBEGIN{
	default:
		return cliError(usage, ch);
	}ARGEND
	if(argc < 2)
		return cliError(usage, ch);

	fs = fsys->fs;
	rlock(&fsys->fs->elk);

	addr = strtoul(argv[0], 0, 0);
	b = cacheLocal(fs->cache, PartData, addr, argc==4 ? OReadWrite : OReadOnly);
	if(b == nil){
		werrstr("cacheLocal %#ux: %r", addr);
	Err:
		runlock(&fsys->fs->elk);
		return 0;
	}

	switch(ch){
	default:
		werrstr("clrep");
		goto Err;
	case 'e':
		if(b->l.type != BtDir){
			werrstr("wrong block type");
			goto Err;
		}
		sz = VtEntrySize;
		memset(&e, 0, sizeof e);
		entryPack(&e, zero, 0);
		break;
	case 'p':
		if(b->l.type == BtDir || b->l.type == BtData){
			werrstr("wrong block type");
			goto Err;
		}
		sz = VtScoreSize;
		memmove(zero, vtzeroscore, VtScoreSize);
		break;
	}
	max = fs->blockSize/sz;

	for(i = 1; i < argc; i++){
		offset = atoi(argv[i]);
		if(offset >= max){
			consPrint("\toffset %d too large (>= %d)\n", i, max);
			continue;
		}
		consPrint("\tblock %#ux %d %d %.*H\n", addr, offset*sz, sz, sz, b->data+offset*sz);
		memmove(b->data+offset*sz, zero, sz);
	}
	blockDirty(b);
	blockPut(b);
	runlock(&fsys->fs->elk);

	return 1;
}

static int
fsysClre(Fsys* fsys, int argc, char* argv[])
{
	return fsysClrep(fsys, argc, argv, 'e');
}

static int
fsysClrp(Fsys* fsys, int argc, char* argv[])
{
	return fsysClrep(fsys, argc, argv, 'p');
}

static int
fsysEsearch1(File* f, char* s, u32int elo)
{
	int n, r;
	DirEntry de;
	DirEntryEnum *dee;
	File *ff;
	Entry e, ee;
	char *t;

	dee = deeOpen(f);
	if(dee == nil)
		return 0;

	n = 0;
	for(;;){
		r = deeRead(dee, &de);
		if(r < 0){
			consPrint("\tdeeRead %s/%s: %r\n", s, de.elem);
			break;
		}
		if(r == 0)
			break;
		if(de.mode & ModeSnapshot){
			if((ff = fileWalk(f, de.elem)) == nil)
				consPrint("\tcannot walk %s/%s: %r\n", s, de.elem);
			else{
				if(!fileGetSources(ff, &e, &ee))
					consPrint("\tcannot get sources for %s/%s: %r\n", s, de.elem);
				else if(e.snap != 0 && e.snap < elo){
					consPrint("\t%ud\tclri %s/%s\n", e.snap, s, de.elem);
					n++;
				}
				fileDecRef(ff);
			}
		}
		else if(de.mode & ModeDir){
			if((ff = fileWalk(f, de.elem)) == nil)
				consPrint("\tcannot walk %s/%s: %r\n", s, de.elem);
			else{
				t = smprint("%s/%s", s, de.elem);
				n += fsysEsearch1(ff, t, elo);
				vtfree(t);
				fileDecRef(ff);
			}
		}
		deCleanup(&de);
		if(r < 0)
			break;
	}
	deeClose(dee);

	return n;
}

static int
fsysEsearch(Fs* fs, char* path, u32int elo)
{
	int n;
	File *f;
	DirEntry de;

	f = fileOpen(fs, path);
	if(f == nil)
		return 0;
	if(!fileGetDir(f, &de)){
		consPrint("\tfileGetDir %s failed: %r\n", path);
		fileDecRef(f);
		return 0;
	}
	if((de.mode & ModeDir) == 0){
		fileDecRef(f);
		deCleanup(&de);
		return 0;
	}
	deCleanup(&de);
	n = fsysEsearch1(f, path, elo);
	fileDecRef(f);
	return n;
}

static int
fsysEpoch(Fsys* fsys, int argc, char* argv[])
{
	Fs *fs;
	int force, n, remove;
	u32int low, old;
	char *usage = "usage: [fsys name] epoch [[-ry] low]";

	force = 0;
	remove = 0;
	ARGBEGIN{
	case 'y':
		force = 1;
		break;
	case 'r':
		remove = 1;
		break;
	default:
		return cliError(usage);
	}ARGEND
	if(argc > 1)
		return cliError(usage);
	if(argc > 0)
		low = strtoul(argv[0], 0, 0);
	else
		low = ~(u32int)0;

	if(low == 0)
		return cliError("low epoch cannot be zero");

	fs = fsys->fs;

	rlock(&fs->elk);
	consPrint("\tlow %ud hi %ud\n", fs->elo, fs->ehi);
	if(low == ~(u32int)0){
		runlock(&fs->elk);
		return 1;
	}
	n = fsysEsearch(fsys->fs, "/archive", low);
	n += fsysEsearch(fsys->fs, "/snapshot", low);
	consPrint("\t%d snapshot%s found with epoch < %ud\n", n, n==1 ? "" : "s", low);
	runlock(&fs->elk);

	/*
	 * There's a small race here -- a new snapshot with epoch < low might
	 * get introduced now that we unlocked fs->elk.  Low has to
	 * be <= fs->ehi.  Of course, in order for this to happen low has
	 * to be equal to the current fs->ehi _and_ a snapshot has to
	 * run right now.  This is a small enough window that I don't care.
	 */
	if(n != 0 && !force){
		consPrint("\tnot setting low epoch\n");
		return 1;
	}
	old = fs->elo;
	if(!fsEpochLow(fs, low))
		consPrint("\tfsEpochLow: %r\n");
	else{
		consPrint("\told: epoch%s %ud\n", force ? " -y" : "", old);
		consPrint("\tnew: epoch%s %ud\n", force ? " -y" : "", fs->elo);
		if(fs->elo < low)
			consPrint("\twarning: new low epoch < old low epoch\n");
		if(force && remove)
			fsSnapshotRemove(fs);
	}

	return 1;
}

static int
fsysCreate(Fsys* fsys, int argc, char* argv[])
{
	int r;
	ulong mode;
	char *elem, *p, *path;
	char *usage = "usage: [fsys name] create path uid gid perm";
	DirEntry de;
	File *file, *parent;

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc != 4)
		return cliError(usage);

	if(!fsysParseMode(argv[3], &mode))
		return cliError(usage);
	if(mode&ModeSnapshot)
		return cliError("create - cannot create with snapshot bit set");

	if(strcmp(argv[1], uidnoworld) == 0)
		return cliError("permission denied");

	rlock(&fsys->fs->elk);
	path = vtstrdup(argv[0]);
	if((p = strrchr(path, '/')) != nil){
		*p++ = '\0';
		elem = p;
		p = path;
		if(*p == '\0')
			p = "/";
	}
	else{
		p = "/";
		elem = path;
	}

	r = 0;
	if((parent = fileOpen(fsys->fs, p)) == nil)
		goto out;

	file = fileCreate(parent, elem, mode, argv[1]);
	fileDecRef(parent);
	if(file == nil){
		werrstr("create %s/%s: %r", p, elem);
		goto out;
	}

	if(!fileGetDir(file, &de)){
		werrstr("stat failed after create: %r");
		goto out1;
	}

	if(strcmp(de.gid, argv[2]) != 0){
		vtfree(de.gid);
		de.gid = vtstrdup(argv[2]);
		if(!fileSetDir(file, &de, argv[1])){
			werrstr("wstat failed after create: %r");
			goto out2;
		}
	}
	r = 1;

out2:
	deCleanup(&de);
out1:
	fileDecRef(file);
out:
	vtfree(path);
	runlock(&fsys->fs->elk);

	return r;
}

static void
fsysPrintStat(char *prefix, char *file, DirEntry *de)
{
	char buf[64];

	if(prefix == nil)
		prefix = "";
	consPrint("%sstat %q %q %q %q %s %llud\n", prefix,
		file, de->elem, de->uid, de->gid, fsysModeString(de->mode, buf), de->size);
}

static int
fsysStat(Fsys* fsys, int argc, char* argv[])
{
	int i;
	File *f;
	DirEntry de;
	char *usage = "usage: [fsys name] stat files...";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND

	if(argc == 0)
		return cliError(usage);

	rlock(&fsys->fs->elk);
	for(i=0; i<argc; i++){
		if((f = fileOpen(fsys->fs, argv[i])) == nil){
			consPrint("%s: %r\n", argv[i]);
			continue;
		}
		if(!fileGetDir(f, &de)){
			consPrint("%s: %r\n", argv[i]);
			fileDecRef(f);
			continue;
		}
		fsysPrintStat("\t", argv[i], &de);
		deCleanup(&de);
		fileDecRef(f);
	}
	runlock(&fsys->fs->elk);
	return 1;
}

static int
fsysWstat(Fsys *fsys, int argc, char* argv[])
{
	File *f;
	char *p;
	DirEntry de;
	char *usage = "usage: [fsys name] wstat file elem uid gid mode length\n"
		"\tuse - for any field to mean don't change";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND

	if(argc != 6)
		return cliError(usage);

	rlock(&fsys->fs->elk);
	if((f = fileOpen(fsys->fs, argv[0])) == nil){
		werrstr("console wstat - walk - %r");
		runlock(&fsys->fs->elk);
		return 0;
	}
	if(!fileGetDir(f, &de)){
		werrstr("console wstat - stat - %r");
		fileDecRef(f);
		runlock(&fsys->fs->elk);
		return 0;
	}
	fsysPrintStat("\told: w", argv[0], &de);

	if(strcmp(argv[1], "-") != 0){
		if(!validFileName(argv[1])){
			werrstr("console wstat - bad elem");
			goto error;
		}
		vtfree(de.elem);
		de.elem = vtstrdup(argv[1]);
	}
	if(strcmp(argv[2], "-") != 0){
		if(!validUserName(argv[2])){
			werrstr("console wstat - bad uid");
			goto error;
		}
		vtfree(de.uid);
		de.uid = vtstrdup(argv[2]);
	}
	if(strcmp(argv[3], "-") != 0){
		if(!validUserName(argv[3])){
			werrstr("console wstat - bad gid");
			goto error;
		}
		vtfree(de.gid);
		de.gid = vtstrdup(argv[3]);
	}
	if(strcmp(argv[4], "-") != 0){
		if(!fsysParseMode(argv[4], &de.mode)){
			werrstr("console wstat - bad mode");
			goto error;
		}
	}
	if(strcmp(argv[5], "-") != 0){
		de.size = strtoull(argv[5], &p, 0);
		if(argv[5][0] == '\0' || *p != '\0' || (vlong)de.size < 0){
			werrstr("console wstat - bad length");
			goto error;
		}
	}

	if(!fileSetDir(f, &de, uidadm)){
		werrstr("console wstat - %r");
		goto error;
	}
	deCleanup(&de);

	if(!fileGetDir(f, &de)){
		werrstr("console wstat - stat2 - %r");
		goto error;
	}
	fsysPrintStat("\tnew: w", argv[0], &de);
	deCleanup(&de);
	fileDecRef(f);
	runlock(&fsys->fs->elk);

	return 1;

error:
	deCleanup(&de);	/* okay to do this twice */
	fileDecRef(f);
	runlock(&fsys->fs->elk);
	return 0;
}

static void
fsckClri(Fsck *fsck, char *name, MetaBlock *mb, int i, Block *b)
{
	USED(name);

	if((fsck->flags&DoClri) == 0)
		return;

	mbDelete(mb, i);
	mbPack(mb);
	blockDirty(b);	
}

static void
fsckClose(Fsck *fsck, Block *b, u32int epoch)
{
	Label l;

	if((fsck->flags&DoClose) == 0)
		return;
	l = b->l;
	if(l.state == BsFree || (l.state&BsClosed)){
		consPrint("%#ux is already closed\n", b->addr);
		return;
	}
	if(epoch){	
		l.state |= BsClosed;
		l.epochClose = epoch;
	}else
		l.state = BsFree;
		
	if(!blockSetLabel(b, &l, 0))
		consPrint("%#ux setlabel: %r\n", b->addr);
}

static void
fsckClre(Fsck *fsck, Block *b, int offset)
{
	Entry e;

	if((fsck->flags&DoClre) == 0)
		return;
	if(offset<0 || offset*VtEntrySize >= fsck->bsize){
		consPrint("bad clre\n");
		return;
	}
	memset(&e, 0, sizeof e);
	entryPack(&e, b->data, offset);
	blockDirty(b);
}

static void
fsckClrp(Fsck *fsck, Block *b, int offset)
{
	if((fsck->flags&DoClrp) == 0)
		return;
	if(offset<0 || offset*VtScoreSize >= fsck->bsize){
		consPrint("bad clre\n");
		return;
	}
	memmove(b->data+offset*VtScoreSize, vtzeroscore, VtScoreSize);
	blockDirty(b);
}

static int
fsysCheck(Fsys *fsys, int argc, char *argv[])
{
	int i, halting;
	char *usage = "usage: [fsys name] check [-v] [options]";
	Fsck fsck;
	Block *b;
	Super super;

	memset(&fsck, 0, sizeof fsck);
	fsck.fs = fsys->fs;
	fsck.clri = fsckClri;
	fsck.clre = fsckClre;
	fsck.clrp = fsckClrp;
	fsck.close = fsckClose;
	fsck.print = consPrint;

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND

	for(i=0; i<argc; i++){
		if(strcmp(argv[i], "pblock") == 0)
			fsck.printblocks = 1;
		else if(strcmp(argv[i], "pdir") == 0)
			fsck.printdirs = 1;
		else if(strcmp(argv[i], "pfile") == 0)
			fsck.printfiles = 1;
		else if(strcmp(argv[i], "bclose") == 0)
			fsck.flags |= DoClose;
		else if(strcmp(argv[i], "clri") == 0)
			fsck.flags |= DoClri;
		else if(strcmp(argv[i], "clre") == 0)
			fsck.flags |= DoClre;
		else if(strcmp(argv[i], "clrp") == 0)
			fsck.flags |= DoClrp;
		else if(strcmp(argv[i], "fix") == 0)
			fsck.flags |= DoClose|DoClri|DoClre|DoClrp;
		else if(strcmp(argv[i], "venti") == 0)
			fsck.useventi = 1;
		else if(strcmp(argv[i], "snapshot") == 0)
			fsck.walksnapshots = 1;
		else{
			consPrint("unknown option '%s'\n", argv[i]);
			return cliError(usage);
		}
	}

	halting = fsys->fs->halted==0;
	if(halting)
		fsHalt(fsys->fs);
	if(fsys->fs->arch){
		b = superGet(fsys->fs->cache, &super);
		if(b == nil){
			consPrint("could not load super block\n");
			goto Out;
		}
		blockPut(b);
		if(super.current != NilBlock){
			consPrint("cannot check fs while archiver is running; "
				"wait for it to finish\n");
			goto Out;
		}
	}
	fsCheck(&fsck);
	consPrint("fsck: %d clri, %d clre, %d clrp, %d bclose\n",
		fsck.nclri, fsck.nclre, fsck.nclrp, fsck.nclose);
Out:
	if(halting)
		fsUnhalt(fsys->fs);
	return 1;
}

static int
fsysVenti(char* name, int argc, char* argv[])
{
	int r;
	char *host;
	char *usage = "usage: [fsys name] venti [address]";
	Fsys *fsys;

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND

	if(argc == 0)
		host = nil;
	else if(argc == 1)
		host = argv[0];
	else
		return cliError(usage);

	if((fsys = _fsysGet(name)) == nil)
		return 0;

	qlock(&fsys->lock);
	if(host == nil)
		host = fsys->venti;
	else{
		vtfree(fsys->venti);
		if(host[0])
			fsys->venti = vtstrdup(host);
		else{
			host = nil;
			fsys->venti = nil;
		}
	}

	/* already open: do a redial */
	if(fsys->fs != nil){
		if(fsys->session == nil){
			werrstr("file system was opened with -V");
			r = 0;
			goto out;
		}
		r = 1;
		if(myRedial(fsys->session, host) < 0
		|| vtconnect(fsys->session) < 0)
			r = 0;
		goto out;
	}

	/* not yet open: try to dial */
	if(fsys->session)
		vtfreeconn(fsys->session);
	r = 1;
	if((fsys->session = myDial(host)) == nil
	|| vtconnect(fsys->session) < 0)
		r = 0;
out:
	qunlock(&fsys->lock);
	fsysPut(fsys);
	return r;
}

static ulong
freemem(void)
{
	int nf, pgsize = 0;
	uvlong size, userpgs = 0, userused = 0;
	char *ln, *sl;
	char *fields[2];
	Biobuf *bp;

	size = 64*1024*1024;
	bp = Bopen("#c/swap", OREAD);
	if (bp != nil) {
		while ((ln = Brdline(bp, '\n')) != nil) {
			ln[Blinelen(bp)-1] = '\0';
			nf = tokenize(ln, fields, nelem(fields));
			if (nf != 2)
				continue;
			if (strcmp(fields[1], "pagesize") == 0)
				pgsize = atoi(fields[0]);
			else if (strcmp(fields[1], "user") == 0) {
				sl = strchr(fields[0], '/');
				if (sl == nil)
					continue;
				userpgs = atoll(sl+1);
				userused = atoll(fields[0]);
			}
		}
		Bterm(bp);
		if (pgsize > 0 && userpgs > 0)
			size = (userpgs - userused) * pgsize;
	}
	/* cap it to keep the size within 32 bits */
	if (size >= 3840UL * 1024 * 1024)
		size = 3840UL * 1024 * 1024;
	return size;
}

static int
fsysOpen(char* name, int argc, char* argv[])
{
	char *p, *host;
	Fsys *fsys;
	int noauth, noventi, noperm, rflag, wstatallow, noatimeupd;
	long ncache;
	char *usage = "usage: fsys name open [-APVWr] [-c ncache]";

	ncache = 1000;
	noauth = noperm = wstatallow = noventi = noatimeupd = 0;
	rflag = OReadWrite;

	ARGBEGIN{
	default:
		return cliError(usage);
	case 'A':
		noauth = 1;
		break;
	case 'P':
		noperm = 1;
		break;
	case 'V':
		noventi = 1;
		break;
	case 'W':
		wstatallow = 1;
		break;
	case 'a':
		noatimeupd = 1;
		break;
	case 'c':
		p = ARGF();
		if(p == nil)
			return cliError(usage);
		ncache = strtol(argv[0], &p, 0);
		if(ncache <= 0 || p == argv[0] || *p != '\0')
			return cliError(usage);
		break;
	case 'r':
		rflag = OReadOnly;
		break;
	}ARGEND
	if(argc)
		return cliError(usage);

	if((fsys = _fsysGet(name)) == nil)
		return 0;

	/* automatic memory sizing? */
	if(mempcnt > 0) {
		/* TODO: 8K is a hack; use the actual block size */
		ncache = (((vlong)freemem() * mempcnt) / 100) / (8*1024);
		if (ncache < 100)
			ncache = 100;
	}

	qlock(&fsys->lock);
	if(fsys->fs != nil){
		werrstr(EFsysBusy, fsys->name);
		qunlock(&fsys->lock);
		fsysPut(fsys);
		return 0;
	}

	if(noventi){
		if(fsys->session){
			vtfreeconn(fsys->session);
			fsys->session = nil;
		}
	}
	else if(fsys->session == nil){
		if(fsys->venti && fsys->venti[0])
			host = fsys->venti;
		else
			host = nil;

		if((fsys->session = myDial(host)) == nil
		|| vtconnect(fsys->session) < 0 && !noventi)
			fprint(2, "warning: connecting to venti: %r\n");
	}
	if((fsys->fs = fsOpen(fsys->dev, fsys->session, ncache, rflag)) == nil){
		werrstr("fsOpen: %r");
		qunlock(&fsys->lock);
		fsysPut(fsys);
		return 0;
	}
	fsys->fs->name = fsys->name;	/* for better error messages */
	fsys->noauth = noauth;
	fsys->noperm = noperm;
	fsys->wstatallow = wstatallow;
	fsys->fs->noatimeupd = noatimeupd;
	qunlock(&fsys->lock);
	fsysPut(fsys);

	if(strcmp(name, "main") == 0)
		usersFileRead(nil);

	return 1;
}

static int
fsysUnconfig(char* name, int argc, char* argv[])
{
	Fsys *fsys, **fp;
	char *usage = "usage: fsys name unconfig";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc)
		return cliError(usage);

	wlock(&sbox.lock);
	fp = &sbox.head;
	for(fsys = *fp; fsys != nil; fsys = fsys->next){
		if(strcmp(fsys->name, name) == 0)
			break;
		fp = &fsys->next;
	}
	if(fsys == nil){
		werrstr(EFsysNotFound, name);
		wunlock(&sbox.lock);
		return 0;
	}
	if(fsys->ref != 0 || fsys->fs != nil){
		werrstr(EFsysBusy, fsys->name);
		wunlock(&sbox.lock);
		return 0;
	}
	*fp = fsys->next;
	wunlock(&sbox.lock);

	if(fsys->session != nil)
		vtfreeconn(fsys->session);
	if(fsys->venti != nil)
		vtfree(fsys->venti);
	if(fsys->dev != nil)
		vtfree(fsys->dev);
	if(fsys->name != nil)
		vtfree(fsys->name);
	vtfree(fsys);

	return 1;
}

static int
fsysConfig(char* name, int argc, char* argv[])
{
	Fsys *fsys;
	char *part;
	char *usage = "usage: fsys name config [dev]";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND
	if(argc > 1)
		return cliError(usage);

	if(argc == 0)
		part = foptname;
	else
		part = argv[0];

	if((fsys = _fsysGet(part)) != nil){
		qlock(&fsys->lock);
		if(fsys->fs != nil){
			werrstr(EFsysBusy, fsys->name);
			qunlock(&fsys->lock);
			fsysPut(fsys);
			return 0;
		}
		vtfree(fsys->dev);
		fsys->dev = vtstrdup(part);
		qunlock(&fsys->lock);
	}
	else if((fsys = fsysAlloc(name, part)) == nil)
		return 0;

	fsysPut(fsys);
	return 1;
}

static struct {
	char*	cmd;
	int	(*f)(Fsys*, int, char**);
	int	(*f1)(char*, int, char**);
} fsyscmd[] = {
	{ "close",	fsysClose, },
	{ "config",	nil, fsysConfig, },
	{ "open",	nil, fsysOpen, },
	{ "unconfig",	nil, fsysUnconfig, },
	{ "venti",	nil, fsysVenti, },

	{ "bfree",	fsysBfree, },
	{ "block",	fsysBlock, },
	{ "check",	fsysCheck, },
	{ "clre",	fsysClre, },
	{ "clri",	fsysClri, },
	{ "clrp",	fsysClrp, },
	{ "create",	fsysCreate, },
	{ "df",		fsysDf, },
	{ "epoch",	fsysEpoch, },
	{ "halt",	fsysHalt, },
	{ "label",	fsysLabel, },
	{ "remove",	fsysRemove, },
	{ "snap",	fsysSnap, },
	{ "snaptime",	fsysSnapTime, },
	{ "snapclean",	fsysSnapClean, },
	{ "stat",	fsysStat, },
	{ "sync",	fsysSync, },
	{ "unhalt",	fsysUnhalt, },
	{ "wstat",	fsysWstat, },
	{ "vac",	fsysVac, },

	{ nil,		nil, },
};

static int
fsysXXX1(Fsys *fsys, int i, int argc, char* argv[])
{
	int r;

	qlock(&fsys->lock);
	if(fsys->fs == nil){
		qunlock(&fsys->lock);
		werrstr(EFsysNotOpen, fsys->name);
		return 0;
	}

	if(fsys->fs->halted
	&& fsyscmd[i].f != fsysUnhalt && fsyscmd[i].f != fsysCheck){
		werrstr("file system %s is halted", fsys->name);
		qunlock(&fsys->lock);
		return 0;
	}

	r = (*fsyscmd[i].f)(fsys, argc, argv);
	qunlock(&fsys->lock);
	return r;
}

static int
fsysXXX(char* name, int argc, char* argv[])
{
	int i, r;
	Fsys *fsys;

	for(i = 0; fsyscmd[i].cmd != nil; i++){
		if(strcmp(fsyscmd[i].cmd, argv[0]) == 0)
			break;
	}

	if(fsyscmd[i].cmd == nil){
		werrstr("unknown command - '%s'", argv[0]);
		return 0;
	}

	/* some commands want the name... */
	if(fsyscmd[i].f1 != nil){
		if(strcmp(name, FsysAll) == 0){
			werrstr("cannot use fsys %#q with %#q command", FsysAll, argv[0]);
			return 0;
		}
		return (*fsyscmd[i].f1)(name, argc, argv);
	}

	/* ... but most commands want the Fsys */
	if(strcmp(name, FsysAll) == 0){
		r = 1;
		rlock(&sbox.lock);
		for(fsys = sbox.head; fsys != nil; fsys = fsys->next){
			fsys->ref++;
			r = fsysXXX1(fsys, i, argc, argv) && r;
			fsys->ref--;
		}
		runlock(&sbox.lock);
	}else{
		if((fsys = _fsysGet(name)) == nil)
			return 0;
		r = fsysXXX1(fsys, i, argc, argv);
		fsysPut(fsys);
	}
	return r;
}

static int
cmdFsysXXX(int argc, char* argv[])
{
	char *name;

	if((name = sbox.curfsys) == nil){
		werrstr(EFsysNoCurrent, argv[0]);
		return 0;
	}

	return fsysXXX(name, argc, argv);
}

static int
cmdFsys(int argc, char* argv[])
{
	Fsys *fsys;
	char *usage = "usage: fsys [name ...]";

	ARGBEGIN{
	default:
		return cliError(usage);
	}ARGEND

	if(argc == 0){
		rlock(&sbox.lock);
		currfsysname = sbox.head->name;
		for(fsys = sbox.head; fsys != nil; fsys = fsys->next)
			consPrint("\t%s\n", fsys->name);
		runlock(&sbox.lock);
		return 1;
	}
	if(argc == 1){
		fsys = nil;
		if(strcmp(argv[0], FsysAll) != 0 && (fsys = fsysGet(argv[0])) == nil)
			return 0;
		sbox.curfsys = vtstrdup(argv[0]);
		consPrompt(sbox.curfsys);
		if(fsys)
			fsysPut(fsys);
		return 1;
	}

	return fsysXXX(argv[0], argc-1, argv+1);
}

int
fsysInit(void)
{
	int i;

	fmtinstall('H', encodefmt);
	fmtinstall('V', scoreFmt);
	fmtinstall('L', labelFmt);

	cliAddCmd("fsys", cmdFsys);
	for(i = 0; fsyscmd[i].cmd != nil; i++){
		if(fsyscmd[i].f != nil)
			cliAddCmd(fsyscmd[i].cmd, cmdFsysXXX);
	}
	/* the venti cmd is special: the fs can be either open or closed */
	cliAddCmd("venti", cmdFsysXXX);
	cliAddCmd("printconfig", cmdPrintConfig);

	return 1;
}
