/*
 * TO DO:
 *	- gc of file systems (not going to do just yet?)
 *	- statistics file
 *	- configure on amsterdam
 */

#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ip.h>
#include <thread.h>
#include <libsec.h>
#include <sunrpc.h>
#include <nfs3.h>
#include <diskfs.h>
#include <venti.h>
#include "nfs3srv.h"

#define trace if(!tracecalls){}else print

typedef struct Ipokay Ipokay;
typedef struct Config Config;
typedef struct Ctree Ctree;
typedef struct Cnode Cnode;

struct Ipokay
{
	int okay;
	uchar ip[IPaddrlen];
	uchar mask[IPaddrlen];
};

struct Config
{
	Ipokay *ok;
	uint nok;
	ulong mtime;
	Ctree *ctree;
};

char 		*addr;
int			blocksize;
int			cachesize;
Config		config;
char			*configfile;
int			encryptedhandles = 1;
Channel		*nfschan;
Channel		*mountchan;
Channel		*timerchan;
Nfs3Handle	root;
SunSrv		*srv;
int			tracecalls;
VtCache		*vcache;
VtConn		*z;

void			cryptinit(void);
void			timerthread(void*);
void			timerproc(void*);

extern	void			handleunparse(Fsys*, Nfs3Handle*, Nfs3Handle*, int);
extern	Nfs3Status	handleparse(Nfs3Handle*, Fsys**, Nfs3Handle*, int);

Nfs3Status	logread(Cnode*, u32int, u64int, uchar**, u32int*, u1int*);
Nfs3Status	refreshdiskread(Cnode*, u32int, u64int, uchar**, u32int*, u1int*);
Nfs3Status	refreshconfigread(Cnode*, u32int, u64int, uchar**, u32int*, u1int*);

int readconfigfile(Config *cp);
void setrootfid(void);
int ipokay(uchar *ip, ushort port);

void
usage(void)
{
	fprint(2, "usage: vnfs [-LLRVr] [-a addr] [-b blocksize] [-c cachesize] configfile\n");
	threadexitsall("usage");
}

void
threadmain(int argc, char **argv)
{
	fmtinstall('B', sunrpcfmt);
	fmtinstall('C', suncallfmt);
	fmtinstall('F', vtfcallfmt);
	fmtinstall('H', encodefmt);
	fmtinstall('I', eipfmt);
	fmtinstall('V', vtscorefmt);
	sunfmtinstall(&nfs3prog);
	sunfmtinstall(&nfsmount3prog);

	addr = "udp!*!2049";
	blocksize = 8192;
	cachesize = 400;
	srv = sunsrv();
	srv->ipokay = ipokay;
	cryptinit();

	ARGBEGIN{
	default:
		usage();
	case 'E':
		encryptedhandles = 0;
		break;
	case 'L':
		if(srv->localonly == 0)
			srv->localonly = 1;
		else
			srv->localparanoia = 1;
		break;
	case 'R':
		srv->chatty++;
		break;
	case 'T':
		tracecalls = 1;
		break;
	case 'V':
		chattyventi = 1;
		break;
	case 'a':
		addr = EARGF(usage());
		break;
	case 'b':
		blocksize = atoi(EARGF(usage()));
		break;
	case 'c':
		cachesize = atoi(EARGF(usage()));
		break;
	case 'r':
		srv->alwaysreject++;
		break;
	}ARGEND

	if(argc != 1)
		usage();

	if((z = vtdial(nil)) == nil)
		sysfatal("vtdial: %r");
	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");
	if((vcache = vtcachealloc(z, blocksize, cachesize, OREAD)) == nil)
		sysfatal("vtcache: %r");

	configfile = argv[0];
	if(readconfigfile(&config) < 0)
		sysfatal("readConfig: %r");
	setrootfid();

	nfschan = chancreate(sizeof(SunMsg*), 0);
	mountchan = chancreate(sizeof(SunMsg*), 0);
	timerchan = chancreate(sizeof(void*), 0);
	
	if(sunsrvudp(srv, addr) < 0)
		sysfatal("starting server: %r");

	sunsrvthreadcreate(srv, nfs3proc, nfschan);
	sunsrvthreadcreate(srv, mount3proc, mountchan);
	sunsrvthreadcreate(srv, timerthread, nil);
	proccreate(timerproc, nil, 32768);
	
	sunsrvprog(srv, &nfs3prog, nfschan);
	sunsrvprog(srv, &nfsmount3prog, mountchan);

	threadexits(nil);
}

/*
 * Handles.
 * 
 * We store all the state about which file a client is accessing in
 * the handle, so that we don't have to maintain any per-client state
 * ourselves.  In order to avoid leaking handles or letting clients 
 * create arbitrary handles, we sign and encrypt each handle with
 * AES using a key selected randomly when the server starts.
 * Thus, handles cannot be used across sessions.  
 *
 * The decrypted handles begin with the following header:
 *
 *	rand[12]		random bytes used to make encryption non-deterministic
 *	len[4]		length of handle that follows
 *	sessid[8]		random session id chosen at start time
 *
 * If we're pressed for space in the rest of the handle, we could
 * probably reduce the amount of randomness.
 *
 * Security woes aside, the fact that we have to shove everything
 * into the handles is quite annoying.  We have to encode, in 40 bytes:
 *
 *	- position in the synthesized config tree
 *	- enough of the path to do glob matching
 *	- position in an archived file system image
 *
 * and the handles need to be stable across changes in the config file
 * (though not across server restarts since encryption screws
 * that up nicely).
 * 
 * We encode each of the first two as a 10-byte hash that is 
 * the first half of a SHA1 hash.  
 */

enum
{
	RandSize = 16,
	SessidSize = 8,
	HeaderSize = RandSize+SessidSize,
	MaxHandleSize = Nfs3MaxHandleSize - HeaderSize,
};

AESstate		aesstate;
uchar		sessid[SessidSize];

static void
hencrypt(Nfs3Handle *h)
{
	uchar *p;
	AESstate aes;

	/*
	 * root handle has special encryption - a single 0 byte - so that it
	 * never goes stale.
	 */
	if(h->len == root.len && memcmp(h->h, root.h, root.len) == 0){
		h->h[0] = 0;
		h->len = 1;
		return;
	}

	if(!encryptedhandles)
		return;

	if(h->len > MaxHandleSize){
		/* oops */
		fprint(2, "handle too long: %.*lH\n", h->len, h->h);
		memset(h->h, 'X', Nfs3MaxHandleSize);
		h->len = Nfs3MaxHandleSize;
		return;
	}

	p = h->h;
	memmove(p+HeaderSize, p, h->len);
	*(u32int*)p = fastrand();
	*(u32int*)(p+4) = fastrand();
	*(u32int*)(p+8) = fastrand();
	*(u32int*)(p+12) = h->len;
	memmove(p+16, sessid, SessidSize);
	h->len += HeaderSize;

	if(encryptedhandles){
		while(h->len < MaxHandleSize)
			h->h[h->len++] = fastrand();
		aes = aesstate;
		aesCBCencrypt(h->h, MaxHandleSize, &aes);
	}
}

static Nfs3Status
hdecrypt(Nfs3Handle *h)
{
	AESstate aes;
	
	if(h->len == 1 && h->h[0] == 0){	/* single 0 byte is root */
		*h = root;
		return Nfs3Ok;
	}

	if(!encryptedhandles)
		return Nfs3Ok;

	if(h->len <= HeaderSize)
		return Nfs3ErrBadHandle;
	if(encryptedhandles){
		if(h->len != MaxHandleSize)
			return Nfs3ErrBadHandle;
		aes = aesstate;
		aesCBCdecrypt(h->h, h->len, &aes);
	}
	if(memcmp(h->h+RandSize, sessid, sizeof sessid) != 0)
		return Nfs3ErrStale;	/* give benefit of doubt */
	h->len = *(u32int*)(h->h+12); /* XXX byte order */
	memmove(h->h, h->h+HeaderSize, h->len);
	return Nfs3Ok;
}

void
cryptinit(void)
{
	uchar key[32], ivec[AESbsize];
	int i;
	
	*(u32int*)sessid = truerand();
	for(i=0; i<nelem(key); i+=4)
		*(u32int*)&key[i] = truerand();
	for(i=0; i<nelem(ivec); i++)
		ivec[i] = fastrand();
	setupAESstate(&aesstate, key, sizeof key, ivec);
}

/*
 * Config file.
 *
 * The main purpose of the configuration file is to define a tree
 * in which the archived file system images are mounted.
 * The tree is stored as Entry structures, defined below.
 *
 * The configuration file also allows one to define shell-like
 * glob expressions matching paths that are not to be displayed.
 * The matched files or directories are shown in directory listings
 * (could suppress these if we cared) but they cannot be opened,
 * read, or written, and getattr returns zeroed data.
 */
enum
{
	/* sizes used in handles; see nfs server below */
	CnodeHandleSize = 8,
	FsysHandleOffset = CnodeHandleSize,
};

/*
 * Config file tree.
 */
struct Ctree
{
	Cnode *root;
	Cnode *hash[1024];
};

struct Cnode
{
	char *name;	/* path element */
	Cnode *parent;	/* in tree */
	Cnode *nextsib;	/* in tree */
	Cnode *kidlist;	/* in tree */
	Cnode *nexthash;	/* in hash list */
	
	Nfs3Status (*read)(Cnode*, u32int, u64int, uchar**, u32int*, u1int*);	/* synthesized read fn */

	uchar handle[VtScoreSize];	/* sha1(path to here) */
	ulong mtime;	/* mtime for this directory entry */
	
	/* fsys overlay on this node */
	Fsys *fsys;	/* cache of memory structure */
	Nfs3Handle fsyshandle;
	int isblackhole;	/* walking down keeps you here */

	/*
	 * mount point info.
	 * if a mount point is inside another file system,
	 * the fsys and fsyshandle above have the old fs info,
	 * the mfsys and mfsyshandle below have the new one.
	 * getattrs must use the old info for consistency.
	 */
	int ismtpt;	/* whether there is an fsys mounted here */
	uchar fsysscore[VtScoreSize];	/* score of fsys image on venti */
	char *fsysimage;	/* raw disk image */
	Fsys *mfsys;	/* mounted file system (nil until walked) */
	Nfs3Handle mfsyshandle;	/* handle to root of mounted fsys */
	
	int mark;	/* gc */
};

static uint
dumbhash(uchar *s)
{
	return (s[0]<<2)|(s[1]>>6);	/* first 10 bits */
}

static Cnode*
mkcnode(Ctree *t, Cnode *parent, char *elem, uint elen, char *path, uint plen)
{
	uint h;
	Cnode *n;
	
	n = emalloc(sizeof *n + elen+1);
	n->name = (char*)(n+1);
	memmove(n->name, elem, elen);
	n->name[elen] = 0;
	n->parent = parent;
	if(parent){
		n->nextsib = parent->kidlist;
		parent->kidlist = n;
	}
	n->kidlist = nil;
	sha1((uchar*)path, plen, n->handle, nil);
	h = dumbhash(n->handle);
	n->nexthash = t->hash[h];
	t->hash[h] = n;
	
	return n;
}

void
markctree(Ctree *t)
{
	int i;
	Cnode *n;

	for(i=0; i<nelem(t->hash); i++)
		for(n=t->hash[i]; n; n=n->nexthash)
			if(n->name[0] != '+')
				n->mark = 1;
}

int
refreshdisk(void)
{
	int i;
	Cnode *n;
	Ctree *t;
	
	t = config.ctree;
	for(i=0; i<nelem(t->hash); i++)
		for(n=t->hash[i]; n; n=n->nexthash){
			if(n->mfsys)
				disksync(n->mfsys->disk);
			if(n->fsys)
				disksync(n->fsys->disk);
		}
	return 0;
}

void
sweepctree(Ctree *t)
{
	int i;
	Cnode *n;

	/* just zero all the garbage and leave it linked into the tree */
	for(i=0; i<nelem(t->hash); i++){
		for(n=t->hash[i]; n; n=n->nexthash){
			if(!n->mark)
				continue;
			n->fsys = nil;
			free(n->fsysimage);
			n->fsysimage = nil;
			memset(n->fsysscore, 0, sizeof n->fsysscore);
			n->mfsys = nil;
			n->ismtpt = 0;
			memset(&n->fsyshandle, 0, sizeof n->fsyshandle);
			memset(&n->mfsyshandle, 0, sizeof n->mfsyshandle);
		}
	}
}

static Cnode*
cnodewalk(Cnode *n, char *name, uint len, int markokay)
{
	Cnode *nn;
	
	for(nn=n->kidlist; nn; nn=nn->nextsib)
		if(strncmp(nn->name, name, len) == 0 && nn->name[len] == 0)
		if(!nn->mark || markokay)
			return nn;
	return nil;
}

Cnode*
ctreewalkpath(Ctree *t, char *name, ulong createmtime)
{
	Cnode *n, *nn;
	char *p, *nextp;
	
	n = t->root;
	p = name;
	for(; *p; p=nextp){
		n->mark = 0;
		assert(*p == '/');
		p++;
		nextp = strchr(p, '/');
		if(nextp == nil)
			nextp = p+strlen(p);
		if((nn = cnodewalk(n, p, nextp-p, 1)) == nil){
			if(createmtime == 0)
				return nil;
			nn = mkcnode(t, n, p, nextp-p, name, nextp-name);
			nn->mtime = createmtime;
		}
		if(nn->mark)
			nn->mark = 0;
		n = nn;
	}
	n->mark = 0;
	return n;
}

Ctree*
mkctree(void)
{
	Ctree *t;
	
	t = emalloc(sizeof *t);
	t->root = mkcnode(t, nil, "", 0, "", 0);
	
	ctreewalkpath(t, "/+log", time(0))->read = logread;
	ctreewalkpath(t, "/+refreshdisk", time(0))->read = refreshdiskread;
	ctreewalkpath(t, "/+refreshconfig", time(0))->read = refreshconfigread;

	return t;
}

Cnode*
ctreemountfsys(Ctree *t, char *path, ulong time, uchar *score, char *file)
{
	Cnode *n;
	
	if(time == 0)
		time = 1;
	n = ctreewalkpath(t, path, time);
	if(score){
		if(n->ismtpt && (n->fsysimage || memcmp(n->fsysscore, score, VtScoreSize) != 0)){
			free(n->fsysimage);
			n->fsysimage = nil;
			n->fsys = nil;	/* leak (might be other refs) */
		}
		memmove(n->fsysscore, score, VtScoreSize);
	}else{
		if(n->ismtpt && (n->fsysimage==nil || strcmp(n->fsysimage, file) != 0)){
			free(n->fsysimage);
			n->fsysimage = nil;
			n->fsys = nil;	/* leak (might be other refs) */
		}
		n->fsysimage = emalloc(strlen(file)+1);
		strcpy(n->fsysimage, file);
	}
	n->ismtpt = 1;
	return n;
}

Cnode*
cnodebyhandle(Ctree *t, uchar *p)
{
	int h;
	Cnode *n;
	
	h = dumbhash(p);
	for(n=t->hash[h]; n; n=n->nexthash)
		if(memcmp(n->handle, p, CnodeHandleSize) == 0)
			return n;
	return nil;
}

static int
parseipandmask(char *s, uchar *ip, uchar *mask)
{
	char *p, *q;
	
	p = strchr(s, '/');
	if(p)
		*p++ = 0;
	if(parseip(ip, s) == ~0UL)
		return -1;
	if(p == nil)
		memset(mask, 0xFF, IPaddrlen);
	else{
		if(isdigit(*p) && strtol(p, &q, 10)>=0 && *q==0)
			*--p = '/';
		if(parseipmask(mask, p) == ~0UL)
			return -1;
		if(*p != '/')
			*--p = '/';
	}
//fprint(2, "parseipandmask %s => %I %I\n", s, ip, mask);
	return 0;
}

static int
parsetime(char *s, ulong *time)
{
	ulong x;
	char *p;
	int i;
	Tm tm;
	
	/* decimal integer is seconds since 1970 */
	x = strtoul(s, &p, 10);
	if(x > 0 && *p == 0){
		*time = x;
		return 0;
	}
	
	/* otherwise expect yyyy/mmdd/hhmm */
	if(strlen(s) != 14 || s[4] != '/' || s[9] != '/')
		return -1;
	for(i=0; i<4; i++)
		if(!isdigit(s[i]) || !isdigit(s[i+5]) || !isdigit(s[i+10]))
			return -1;
	memset(&tm, 0, sizeof tm);
	tm.year = atoi(s)-1900;
	if(tm.year < 0 || tm.year > 200)
		return -1;
	tm.mon = (s[5]-'0')*10+s[6]-'0' - 1;
	if(tm.mon < 0 || tm.mon > 11)
		return -1; 
	tm.mday = (s[7]-'0')*10+s[8]-'0';
	if(tm.mday < 0 || tm.mday > 31)
		return -1;
	tm.hour = (s[10]-'0')*10+s[11]-'0';
	if(tm.hour < 0 || tm.hour > 23)
		return -1;
	tm.min = (s[12]-'0')*10+s[13]-'0';
	if(tm.min < 0 || tm.min > 59)
		return -1;
	strcpy(tm.zone, "XXX");	/* anything but GMT */
if(0){
print("tm2sec %d/%d/%d/%d/%d\n",
	tm.year, tm.mon, tm.mday, tm.hour, tm.min);
}
	*time = tm2sec(&tm);
if(0) print("time %lud\n", *time);
	return 0;
}


int
readconfigfile(Config *cp)
{
	char *f[10], *image, *p, *pref, *q, *name;
	int nf, line;
	uchar scorebuf[VtScoreSize], *score;
	ulong time;
	Biobuf *b;
	Config c;
	Dir *dir;

	name = configfile;
	c = *cp;
	if((dir = dirstat(name)) == nil)
		return -1;
	if(c.mtime == dir->mtime){
		free(dir);
		return 0;
	}
	c.mtime = dir->mtime;
	free(dir);
	if((b = Bopen(name, OREAD)) == nil){
		free(dir);
		return -1;
	}
	
	/*
	 * Reuse old tree, garbage collecting entries that
	 * are not mentioned in the new config file.
	 */
	if(c.ctree == nil)
		c.ctree = mkctree();

	markctree(c.ctree);
	c.ok = nil;
	c.nok = 0;
	
	line = 0;
	for(; (p=Brdstr(b, '\n', 1)) != nil; free(p)){
		line++;
		if((q = strchr(p, '#')) != nil)
			*q = 0;
		nf = tokenize(p, f, nelem(f));
		if(nf == 0)
			continue;
		if(strcmp(f[0], "mount") == 0){
			if(nf != 4){
				werrstr("syntax error: mount /path /dev|score mtime");
				goto badline;
			}
			if(f[1][0] != '/'){
				werrstr("unrooted path %s", f[1]);
				goto badline;
			}
			score = nil;
			image = nil;
			if(f[2][0] == '/'){
				if(access(f[2], AEXIST) < 0){
					werrstr("image %s does not exist", f[2]);
					goto badline;
				}
				image = f[2];
			}else{
				if(vtparsescore(f[2], &pref, scorebuf) < 0){
					werrstr("bad score %s", f[2]);
					goto badline;
				}
				score = scorebuf;
			}
			if(parsetime(f[3], &time) < 0){
				fprint(2, "%s:%d: bad time %s\n", name, line, f[3]);
				time = 1;
			}
			ctreemountfsys(c.ctree, f[1], time, score, image);
			continue;
		}
		if(strcmp(f[0], "allow") == 0 || strcmp(f[0], "deny") == 0){
			if(nf != 2){
				werrstr("syntax error: allow|deny ip[/mask]"); 
				goto badline;
			}
			c.ok = erealloc(c.ok, (c.nok+1)*sizeof(c.ok[0]));
			if(parseipandmask(f[1], c.ok[c.nok].ip, c.ok[c.nok].mask) < 0){
				werrstr("bad ip[/mask]: %s", f[1]);
				goto badline;
			}
			c.ok[c.nok].okay = (strcmp(f[0], "allow") == 0);
			c.nok++;
			continue;
		}
		werrstr("unknown verb '%s'", f[0]);
	badline:
		fprint(2, "%s:%d: %r\n", name, line);
	}
	Bterm(b);

	sweepctree(c.ctree);
	free(cp->ok);
	*cp = c;
	return 0;
}

int
ipokay(uchar *ip, ushort port)
{
	int i;
	uchar ipx[IPaddrlen];
	Ipokay *ok; 
	
	for(i=0; i<config.nok; i++){
		ok = &config.ok[i];
		maskip(ip, ok->mask, ipx);
if(0) fprint(2, "%I & %I = %I (== %I?)\n",
	ip, ok->mask, ipx, ok->ip);
		if(memcmp(ipx, ok->ip, IPaddrlen) == 0)
			return ok->okay;
	}
	if(config.nok == 0)	/* all is permitted */
		return 1;
	/* otherwise default is none allowed */
	return 0;
}

Nfs3Status
cnodelookup(Ctree *t, Cnode **np, char *name)
{
	Cnode *n, *nn;
	
	n = *np;
	if(n->isblackhole)
		return Nfs3Ok;
	if((nn = cnodewalk(n, name, strlen(name), 0)) == nil){
		if(n->ismtpt || n->fsys){
			if((nn = cnodewalk(n, "", 0, 1)) == nil){
				nn = mkcnode(t, n, "", 0, (char*)n->handle, SHA1dlen);
				nn->isblackhole = 1;
			}
			nn->mark = 0;
		}
	}
	if(nn == nil)
		return Nfs3ErrNoEnt;
	*np = nn;
	return Nfs3Ok;
}

Nfs3Status
cnodegetattr(Cnode *n, Nfs3Attr *attr)
{
	memset(attr, 0, sizeof *attr);
	if(n->read){
		attr->type = Nfs3FileReg;
		attr->mode = 0444;
		attr->size = 512;
		attr->nlink = 1;
	}else{
		attr->type = Nfs3FileDir;
		attr->mode = 0555;
		attr->size = 1024;
		attr->nlink = 10;
	}
	attr->fileid = *(u64int*)n->handle;
	attr->atime.sec = n->mtime;
	attr->mtime.sec = n->mtime;
	attr->ctime.sec = n->mtime;
	return Nfs3Ok;
}

Nfs3Status
cnodereaddir(Cnode *n, u32int count, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
{
	uchar *data, *p, *ep, *np;
	u64int c;
	Nfs3Entry ne;
	
	n = n->kidlist;
	c = cookie;
	for(; c && n; c--)
		n = n->nextsib;
	if(n == nil){
		*pdata = 0;
		*pcount = 0;
		*peof = 1;
		return Nfs3Ok;
	}
	
	data = emalloc(count);
	p = data;
	ep = data+count;
	while(n && p < ep){
		if(n->mark || n->name[0] == '+'){
			n = n->nextsib;
			++cookie;
			continue;
		}
		ne.name = n->name;
		ne.cookie = ++cookie;
		ne.fileid = *(u64int*)n->handle;
		if(nfs3entrypack(p, ep, &np, &ne) < 0)
			break;
		p = np;
		n = n->nextsib;
	}
	*pdata = data;
	*pcount = p - data;
	*peof = n==nil;
	return Nfs3Ok;
}

void
timerproc(void *v)
{
	for(;;){
		sleep(60*1000);
		sendp(timerchan, 0);
	}
}

void
timerthread(void *v)
{
	for(;;){
		recvp(timerchan);
	//	refreshconfig();
	}
}

/*
 * Actually serve the NFS requests.  Called from nfs3srv.c.  
 * Each request runs in its own thread (coroutine).
 *
 * Decrypted handles have the form:
 *
 *	config[20] - SHA1 hash identifying a config tree node
 *	glob[10] - SHA1 hash prefix identifying a glob state
 *	fsyshandle[<=10] - disk file system handle (usually 4 bytes)
 */
 
/*
 * A fid represents a point in the file tree.
 * There are three components, all derived from the handle:
 *
 *	- config tree position (also used to find fsys)
 *	- glob state for exclusions
 *	- file system position
 */
enum
{
	HAccess,
	HAttr,
	HWalk,
	HDotdot,
	HRead
};
typedef struct Fid Fid;
struct Fid
{
	Cnode *cnode;
	Fsys *fsys;
	Nfs3Handle fsyshandle;
};

int
handlecmp(Nfs3Handle *h, Nfs3Handle *h1)
{
	if(h->len != h1->len)
		return h->len - h1->len;
	return memcmp(h->h, h1->h, h->len);
}

Nfs3Status
handletofid(Nfs3Handle *eh, Fid *fid, int mode)
{
	int domount;
	Cnode *n;
	Disk *disk, *cdisk;
	Fsys *fsys;
	Nfs3Status ok;
	Nfs3Handle h2, *h, *fh;
	
	memset(fid, 0, sizeof *fid);

	domount = 1;
	if(mode == HDotdot)
		domount = 0;
	/*
	 * Not necessary, but speeds up ls -l /dump/2005
	 * HAttr and HAccess must be handled the same way
	 * because both can be used to fetch attributes.
	 * Acting differently yields inconsistencies at mount points,
	 * and causes FreeBSD ls -l to fail.
	 */
	if(mode == HAttr || mode == HAccess)
		domount = 0;

	/*
	 * Decrypt handle.
	 */
	h2 = *eh;
	h = &h2;
	if((ok = hdecrypt(h)) != Nfs3Ok)
		return ok;
	trace("handletofid: decrypted %.*lH\n", h->len, h->h);
	if(h->len < FsysHandleOffset)
		return Nfs3ErrBadHandle;

	/*
	 * Find place in config tree.
	 */
	if((n = cnodebyhandle(config.ctree, h->h)) == nil)
		return Nfs3ErrStale;
	fid->cnode = n;

	if(n->ismtpt && domount){
		/*
		 * Open fsys for mount point if needed.
		 */
		if(n->mfsys == nil){
			trace("handletofid: mounting %V/%s\n", n->fsysscore, n->fsysimage);
			if(n->fsysimage){
				if(strcmp(n->fsysimage, "/dev/null") == 0)
					return Nfs3ErrAcces;
				if((disk = diskopenfile(n->fsysimage)) == nil){
					fprint(2, "cannot open disk %s: %r\n", n->fsysimage);
					return Nfs3ErrIo;
				}
				if((cdisk = diskcache(disk, blocksize, 64)) == nil){
					fprint(2, "cannot cache disk %s: %r\n", n->fsysimage);
					diskclose(disk);
				}
				disk = cdisk;
			}else{
				if((disk = diskopenventi(vcache, n->fsysscore)) == nil){
					fprint(2, "cannot open venti disk %V: %r\n", n->fsysscore);
					return Nfs3ErrIo;
				}
			}
			if((fsys = fsysopen(disk)) == nil){
				fprint(2, "cannot open fsys on %V: %r\n", n->fsysscore);
				diskclose(disk);
				return Nfs3ErrIo;
			}
			n->mfsys = fsys;
			fsysroot(fsys, &n->mfsyshandle);
		}
		
		/*
		 * Use inner handle.
		 */
		fid->fsys = n->mfsys;
		fid->fsyshandle = n->mfsyshandle;
	}else{
		/*
		 * Use fsys handle from tree or from handle.
		 * This assumes that fsyshandle was set by fidtohandle
		 * earlier, so it's not okay to reuse handles (except the root)
		 * across sessions.  The encryption above makes and 
		 * enforces the same restriction, so this is okay.
		 */
		fid->fsys = n->fsys;
		fh = &fid->fsyshandle;
		if(n->isblackhole){
			fh->len = h->len-FsysHandleOffset;
			memmove(fh->h, h->h+FsysHandleOffset, fh->len);
		}else
			*fh = n->fsyshandle;
		trace("handletofid: fsyshandle %.*lH\n", fh->len, fh->h);
	}

	/*
	 * TO DO (maybe): some sort of path restriction here.
	 */
	trace("handletofid: cnode %s fsys %p fsyshandle %.*lH\n",
		n->name, fid->fsys, fid->fsyshandle.len, fid->fsyshandle.h);
	return Nfs3Ok;
}

void
_fidtohandle(Fid *fid, Nfs3Handle *h)
{
	Cnode *n;
	
	n = fid->cnode;
	/*
	 * Record fsys handle in n, don't bother sending it to client
	 * for black holes.
	 */
	n->fsys = fid->fsys;
	if(!n->isblackhole){
		n->fsyshandle = fid->fsyshandle;
		fid->fsyshandle.len = 0;
	}
	memmove(h->h, n->handle, CnodeHandleSize);
	memmove(h->h+FsysHandleOffset, fid->fsyshandle.h, fid->fsyshandle.len);
	h->len = FsysHandleOffset+fid->fsyshandle.len;
}

void
fidtohandle(Fid *fid, Nfs3Handle *h)
{
	_fidtohandle(fid, h);
	hencrypt(h);
}

void
setrootfid(void)
{
	Fid fid;
	
	memset(&fid, 0, sizeof fid);
	fid.cnode = config.ctree->root;
	_fidtohandle(&fid, &root);
fprint(2, "handle %.*lH\n", root.len, root.h);
}

void
fsgetroot(Nfs3Handle *h)
{
	*h = root;
	hencrypt(h);
}

Nfs3Status
fsgetattr(SunAuthUnix *au, Nfs3Handle *h, Nfs3Attr *attr)
{
	Fid fid;
	Nfs3Status ok;

	trace("getattr %.*lH\n", h->len, h->h);
	if((ok = handletofid(h, &fid, HAttr)) != Nfs3Ok)
		return ok;
	if(fid.fsys)
		return fsysgetattr(fid.fsys, au, &fid.fsyshandle, attr);
	else
		return cnodegetattr(fid.cnode, attr);
}

/*
 * Lookup is always the hard part.
 */
Nfs3Status
fslookup(SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh)
{
	Fid fid;
	Cnode *n;
	Nfs3Status ok;
	Nfs3Handle xh;
	int mode;
	
	trace("lookup %.*lH %s\n", h->len, h->h, name);

	mode = HWalk;
	if(strcmp(name, "..") == 0 || strcmp(name, ".") == 0)
		mode = HDotdot;
	if((ok = handletofid(h, &fid, mode)) != Nfs3Ok){
		nfs3errstr(ok);
		trace("lookup: handletofid %r\n");
		return ok;
	}
	
	if(strcmp(name, ".") == 0){
		fidtohandle(&fid, nh);
		return Nfs3Ok;
	}

	/*
	 * Walk down file system and cnode simultaneously.
	 * If dotdot and file system doesn't move, need to walk
	 * up cnode.  Save the corresponding fsys handles in
	 * the cnode as we walk down so that we'll have them 
	 * for dotdotting back up.
	 */
	n = fid.cnode;
	if(mode == HWalk){
		/*
		 * Walk down config tree and file system simultaneously.
		 */
		if((ok = cnodelookup(config.ctree, &n, name)) != Nfs3Ok){
			nfs3errstr(ok);
			trace("lookup: cnodelookup: %r\n");
			return ok;
		}
		fid.cnode = n;
		if(fid.fsys){
			if((ok = fsyslookup(fid.fsys, au, &fid.fsyshandle, name, &xh)) != Nfs3Ok){
				nfs3errstr(ok);
				trace("lookup: fsyslookup: %r\n");
				return ok;
			}
			fid.fsyshandle = xh;
		}		
	}else{
		/*
		 * Walking dotdot.  Ick.
		 */
		trace("lookup dotdot fsys=%p\n", fid.fsys);
		if(fid.fsys){
			/*
			 * Walk up file system, then try up config tree.
			 */
			if((ok = fsyslookup(fid.fsys, au, &fid.fsyshandle, "..", &xh)) != Nfs3Ok){
				nfs3errstr(ok);
				trace("lookup fsyslookup: %r\n");
				return ok;
			}
			fid.fsyshandle = xh;

			/*
			 * Usually just go to n->parent.
			 * 
			 * If we're in a subtree of the mounted file system that
			 * isn't represented explicitly by the config tree (instead
			 * the black hole node represents the entire file tree),
			 * then we only go to n->parent when we've dotdotted back
			 * to the right handle.
			 */
			if(n->parent == nil)
				trace("lookup dotdot: no parent\n");
			else{
				trace("lookup dotdot: parent %.*lH, have %.*lH\n",
					n->parent->fsyshandle.len, n->parent->fsyshandle.h,
					xh.len, xh.h);
			}
			
			if(n->isblackhole){
				if(handlecmp(&n->parent->mfsyshandle, &xh) == 0)
					n = n->parent;
			}else{
				if(n->parent)
					n = n->parent;
			}
		}else{
			/*
			 * No file system, just walk up.
			 */
			if(n->parent)
				n = n->parent;
		}
		fid.fsys = n->fsys;
		fid.fsyshandle = n->fsyshandle;
		fid.cnode = n;
	}
	fidtohandle(&fid, nh);
	return Nfs3Ok;
}

Nfs3Status
fsaccess(SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr)
{
	Fid fid;
	Nfs3Status ok;
	
	trace("access %.*lH 0x%ux\n", h->len, h->h, want);
	if((ok = handletofid(h, &fid, HAccess)) != Nfs3Ok)
		return ok;
	if(fid.fsys)
		return fsysaccess(fid.fsys, au, &fid.fsyshandle, want, got, attr);
	*got = want & (Nfs3AccessRead|Nfs3AccessLookup|Nfs3AccessExecute);
	return cnodegetattr(fid.cnode, attr);
}

Nfs3Status
fsreadlink(SunAuthUnix *au, Nfs3Handle *h, char **link)
{
	Fid fid;
	Nfs3Status ok;
	
	trace("readlink %.*lH\n", h->len, h->h);
	if((ok = handletofid(h, &fid, HRead)) != Nfs3Ok)
		return ok;
	if(fid.fsys)
		return fsysreadlink(fid.fsys, au, &fid.fsyshandle, link);
	*link = 0;
	return Nfs3ErrNotSupp;
}

Nfs3Status
fsreadfile(SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
{
	Fid fid;
	Nfs3Status ok;
	
	trace("readfile %.*lH\n", h->len, h->h);
	if((ok = handletofid(h, &fid, HRead)) != Nfs3Ok)
		return ok;
	if(fid.cnode->read)
		return fid.cnode->read(fid.cnode, count, offset, data, pcount, peof);
	if(fid.fsys)
		return fsysreadfile(fid.fsys, au, &fid.fsyshandle, count, offset, data, pcount, peof);
	return Nfs3ErrNotSupp;
}

Nfs3Status
fsreaddir(SunAuthUnix *au, Nfs3Handle *h, u32int len, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
{
	Fid fid;
	Nfs3Status ok;

	trace("readdir %.*lH\n", h->len, h->h);	
	if((ok = handletofid(h, &fid, HRead)) != Nfs3Ok)
		return ok;
	if(fid.fsys)
		return fsysreaddir(fid.fsys, au, &fid.fsyshandle, len, cookie, pdata, pcount, peof);
	return cnodereaddir(fid.cnode, len, cookie, pdata, pcount, peof);
}

Nfs3Status
logread(Cnode *n, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
{
	*pcount = 0;
	*peof = 1;
	return Nfs3Ok;
}

Nfs3Status
refreshdiskread(Cnode *n, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
{
	char buf[128];
	
	if(offset != 0){
		*pcount = 0;
		*peof = 1;
		return Nfs3Ok;
	}
	if(refreshdisk() < 0)
		snprint(buf, sizeof buf, "refreshdisk: %r\n");
	else
		strcpy(buf, "ok\n");
	*data = emalloc(strlen(buf));
	strcpy((char*)*data, buf);
	*pcount = strlen(buf);
	*peof = 1;
	return Nfs3Ok;
}

Nfs3Status
refreshconfigread(Cnode *n, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
{
	char buf[128];
	
	if(offset != 0){
		*pcount = 0;
		*peof = 1;
		return Nfs3Ok;
	}
	if(readconfigfile(&config) < 0)
		snprint(buf, sizeof buf, "readconfig: %r\n");
	else
		strcpy(buf, "ok\n");
	*data = emalloc(strlen(buf));
	strcpy((char*)*data, buf);
	*pcount = strlen(buf);
	*peof = 1;
	return Nfs3Ok;
}

void
abort(void)
{
	for(;;)
		*(int*)0=0;
}
