/*
 * 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 = strtoull(EARGF(usage()), 0, 0);
		break;
	case 'c':
		cachesize = strtoull(EARGF(usage()), 0, 0);
		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)) == 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((uchar)*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((uchar)s[i]) || !isdigit((uchar)s[i+5]) || !isdigit((uchar)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;
}

