/*
 * 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);

u64int	unittoull(char*);

void
usage(void)
{
	fprint(2, "usage: vnfs [-LLRVir] [-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':
		if(chattyventi++)
			vttracelevel++;
		break;
	case 'a':
		addr = EARGF(usage());
		break;
	case 'b':
		blocksize = unittoull(EARGF(usage()));
		break;
	case 'c':
		cachesize = unittoull(EARGF(usage()));
		break;
	case 'i':
		insecure = 1;
		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);
}

#define TWID64	((u64int)~(u64int)0)

u64int
unittoull(char *s)
{
	char *es;
	u64int n;

	if(s == nil)
		return TWID64;
	n = strtoul(s, &es, 0);
	if(*es == 'k' || *es == 'K'){
		n *= 1024;
		es++;
	}else if(*es == 'm' || *es == 'M'){
		n *= 1024*1024;
		es++;
	}else if(*es == 'g' || *es == 'G'){
		n *= 1024*1024*1024;
		es++;
	}else if(*es == 't' || *es == 'T'){
		n *= 1024*1024;
		n *= 1024*1024;
	}
	if(*es != '\0')
		return TWID64;
	return n;
}

/*
 * 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:
 *
 *	sessid[8]		random session id chosen at start time
 *	len[4]		length of handle that follows
 *
 * If we're pressed for space in the rest of the handle, we could
 * probably reduce the amount of sessid bytes.  Note that the sessid
 * bytes must be consistent during a run of vnfs, or else some 
 * clients (e.g., Linux 2.4) eventually notice that successive TLookups
 * return different handles, and they return "Stale NFS file handle"
 * errors to system calls in response (even though we never sent
 * that error!).
 *
 * 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
{
	SessidSize = 8,
	HeaderSize = SessidSize+4,
	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);
	memmove(p, sessid, SessidSize);
	*(u32int*)(p+SessidSize) = h->len;
	h->len += HeaderSize;

	if(encryptedhandles){
		while(h->len < MaxHandleSize)
			h->h[h->len++] = 0;
		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, sessid, SessidSize) != 0)
		return Nfs3ErrStale;	/* give benefit of doubt */
	h->len = *(u32int*)(h->h+SessidSize);
	if(h->len >= MaxHandleSize-HeaderSize)
		return Nfs3ErrBadHandle;
	memmove(h->h, h->h+HeaderSize, h->len);
	return Nfs3Ok;
}

void
cryptinit(void)
{
	uchar key[32], ivec[AESbsize];
	int i;
	u32int u32;
	
	u32 = truerand();
	memmove(sessid, &u32, 4);
	for(i=0; i<nelem(key); i+=4) {
		u32 = truerand();
		memmove(key+i, &u32, 4);
	}
	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)
		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)
{
	uint64 u64;

	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;
	}
	memmove(&u64, n->handle, 8);
	attr->fileid = u64;
	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;
	u64int u64;
	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.namelen = strlen(n->name);
		ne.cookie = ++cookie;
		memmove(&u64, n->handle, 8);
		ne.fileid = u64;
		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);
}

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;
		if(!n->isblackhole)
			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;
}

