/*
 * Simple read-only NFS v3 server.
 * Runs every request in its own thread.
 * Expects client to provide the fsxxx routines in nfs3srv.h.
 */
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <sunrpc.h>
#include <nfs3.h>
#include "nfs3srv.h"

static SunStatus
authunixunpack(SunRpc *rpc, SunAuthUnix *au)
{
	uchar *p, *ep;
	SunAuthInfo *ai;

	ai = &rpc->cred;
	if(ai->flavor != SunAuthSys)
		return SunAuthTooWeak;
	p = ai->data;
	ep = p+ai->ndata;
	if(sunauthunixunpack(p, ep, &p, au) < 0)
		return SunGarbageArgs;
	if(au->uid == 0)
		au->uid = -1;
	if(au->gid == 0)
		au->gid = -1;

	return SunSuccess;
}

static int
rnull(SunMsg *m)
{
	NfsMount3RNull rx;

	memset(&rx, 0, sizeof rx);
	return sunmsgreply(m, &rx.call);
}

static int
rmnt(SunMsg *m)
{
	Nfs3Handle nh;
	NfsMount3RMnt rx;
	SunAuthUnix au;
	int ok;

	if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
		return sunmsgreplyerror(m, ok);

	/* ignore file system path and return the dump tree */

	memset(&rx, 0, sizeof rx);
	rx.nauth = 0;
	rx.status = 0;
	memset(&nh, 0, sizeof nh);
	fsgetroot(&nh);
	rx.handle = nh.h;
	rx.len = nh.len;

	return sunmsgreply(m, &rx.call);
}

static int
rumnt(SunMsg *m)
{
	NfsMount3RUmnt rx;

	/* ignore */
	
	memset(&rx, 0, sizeof rx);
	return sunmsgreply(m, &rx.call);
}

static int
rumntall(SunMsg *m)
{
	NfsMount3RUmntall rx;

	/* ignore */

	memset(&rx, 0, sizeof rx);
	return sunmsgreply(m, &rx.call);
}

static int
rexport(SunMsg *m)
{
	NfsMount3RExport rx;

	/* ignore */

	memset(&rx, 0, sizeof rx);
	rx.count = 0;
	return sunmsgreply(m, &rx.call);
}

static void
rmount3(void *v)
{
	SunMsg *m;

	m = v;
	switch(m->call->type){
	default:
		sunmsgreplyerror(m, SunProcUnavail);
	case NfsMount3CallTNull:
		rnull(m);
		break;
	case NfsMount3CallTMnt:
		rmnt(m);
		break;
	case NfsMount3CallTDump:
		rmnt(m);
		break;
	case NfsMount3CallTUmnt:
		rumnt(m);
		break;
	case NfsMount3CallTUmntall:
		rumntall(m);
		break;
	case NfsMount3CallTExport:
		rexport(m);
		break;
	}
}

void
mount3proc(void *v)
{
	Channel *c;
	SunMsg *m;

	threadsetname("mount1");
	c = v;
	while((m=recvp(c)) != nil)
		threadcreate(rmount3, m, SunStackSize);
}

static int
senderror(SunMsg *m, SunCall *rc, Nfs3Status status)
{
	/* knows that status is first field in all replies */
	((Nfs3RGetattr*)rc)->status = status;
	return sunmsgreply(m, rc);
}

static int
rnull0(SunMsg *m)
{
	Nfs3RNull rx;

	memset(&rx, 0, sizeof rx);
	return sunmsgreply(m, &rx.call);
}

static int
rgetattr(SunMsg *m)
{
	Nfs3TGetattr *tx = (Nfs3TGetattr*)m->call;
	Nfs3RGetattr rx;
	SunAuthUnix au;
	int ok;

	if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
		return sunmsgreplyerror(m, ok);

	memset(&rx, 0, sizeof rx);
	rx.status = fsgetattr(&au, &tx->handle, &rx.attr);
	return sunmsgreply(m, &rx.call);
}

static int
rlookup(SunMsg *m)
{
	Nfs3TLookup *tx = (Nfs3TLookup*)m->call;
	Nfs3RLookup rx;
	SunAuthUnix au;
	int ok;

	if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
		return sunmsgreplyerror(m, ok);

	memset(&rx, 0, sizeof rx);
	rx.status = fsgetattr(&au, &tx->handle, &rx.dirAttr);
	if(rx.status != Nfs3Ok)
		return sunmsgreply(m, &rx.call);
	rx.haveDirAttr = 1;
	rx.status = fslookup(&au, &tx->handle, tx->name, &rx.handle);
	if(rx.status != Nfs3Ok)
		return sunmsgreply(m, &rx.call);
	rx.status = fsgetattr(&au, &rx.handle, &rx.attr);
	if(rx.status != Nfs3Ok)
		return sunmsgreply(m, &rx.call);
	rx.haveAttr = 1;
	return sunmsgreply(m, &rx.call);
}

static int
raccess(SunMsg *m)
{
	Nfs3TAccess *tx = (Nfs3TAccess*)m->call;
	Nfs3RAccess rx;
	SunAuthUnix au;
	int ok;

	if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
		return sunmsgreplyerror(m, ok);

	memset(&rx, 0, sizeof rx);
	rx.haveAttr = 1;
	rx.status = fsaccess(&au, &tx->handle, tx->access, &rx.access, &rx.attr);
	return sunmsgreply(m, &rx.call);
}

static int
rreadlink(SunMsg *m)
{
	Nfs3RReadlink rx;
	Nfs3TReadlink *tx = (Nfs3TReadlink*)m->call;
	SunAuthUnix au;
	int ok;

	if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
		return sunmsgreplyerror(m, ok);

	memset(&rx, 0, sizeof rx);
	rx.haveAttr = 0;
	rx.data = nil;
	rx.status = fsreadlink(&au, &tx->handle, &rx.data);
	sunmsgreply(m, &rx.call);
	free(rx.data);
	return 0;
}

static int
rread(SunMsg *m)
{
	Nfs3TRead *tx = (Nfs3TRead*)m->call;
	Nfs3RRead rx;
	SunAuthUnix au;
	int ok;

	if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
		return sunmsgreplyerror(m, ok);

	memset(&rx, 0, sizeof rx);
	rx.haveAttr = 0;
	rx.data = nil;
	rx.status = fsreadfile(&au, &tx->handle, tx->count, tx->offset, &rx.data, &rx.count, &rx.eof);
	if(rx.status == Nfs3Ok)
		rx.ndata = rx.count;

	sunmsgreply(m, &rx.call);
	free(rx.data);
	return 0;
}

static int
rreaddir(SunMsg *m)
{
	Nfs3TReadDir *tx = (Nfs3TReadDir*)m->call;
	Nfs3RReadDir rx;
	SunAuthUnix au;
	int ok;

	if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
		return sunmsgreplyerror(m, ok);

	memset(&rx, 0, sizeof rx);
	rx.status = fsreaddir(&au, &tx->handle, tx->count, tx->cookie, &rx.data, &rx.count, &rx.eof);
	sunmsgreply(m, &rx.call);
	free(rx.data);
	return 0;
}

static int
rreaddirplus(SunMsg *m)
{
	Nfs3RReadDirPlus rx;

	memset(&rx, 0, sizeof rx);
	rx.status = Nfs3ErrNotSupp;
	sunmsgreply(m, &rx.call);
	return 0;
}

static int
rfsstat(SunMsg *m)
{
	Nfs3RFsStat rx;

	/* just make something up */
	memset(&rx, 0, sizeof rx);
	rx.status = Nfs3Ok;
	rx.haveAttr = 0;
	rx.totalBytes = 1000000000;
	rx.freeBytes = 0;
	rx.availBytes = 0;
	rx.totalFiles = 100000;
	rx.freeFiles = 0;
	rx.availFiles = 0;
	rx.invarSec = 0;
	return sunmsgreply(m, &rx.call);
}

static int
rfsinfo(SunMsg *m)
{
	Nfs3RFsInfo rx;

	/* just make something up */
	memset(&rx, 0, sizeof rx);
	rx.status = Nfs3Ok;
	rx.haveAttr = 0;
	rx.readMax = MaxDataSize;
	rx.readPref = MaxDataSize;
	rx.readMult = MaxDataSize;
	rx.writeMax = MaxDataSize;
	rx.writePref = MaxDataSize;
	rx.writeMult = MaxDataSize;
	rx.readDirPref = MaxDataSize;
	rx.maxFileSize = 1LL<<60;
	rx.timePrec.sec = 1;
	rx.timePrec.nsec = 0;
	rx.flags = Nfs3FsHomogeneous|Nfs3FsCanSetTime;
	return sunmsgreply(m, &rx.call);
}

static int
rpathconf(SunMsg *m)
{
	Nfs3RPathconf rx;

	memset(&rx, 0, sizeof rx);
	rx.status = Nfs3Ok;
	rx.haveAttr = 0;
	rx.maxLink = 1;
	rx.maxName = 1024;
	rx.noTrunc = 1;
	rx.chownRestricted = 0;
	rx.caseInsensitive = 0;
	rx.casePreserving = 1;
	return sunmsgreply(m, &rx.call);
}

static int
rrofs(SunMsg *m)
{
	uchar buf[512];	/* clumsy hack*/

	memset(buf, 0, sizeof buf);
	return senderror(m, (SunCall*)buf, Nfs3ErrRoFs);
}
	

static void
rnfs3(void *v)
{
	SunMsg *m;

	m = v;
	switch(m->call->type){
	default:
		abort();
	case Nfs3CallTNull:
		rnull0(m);
		break;
	case Nfs3CallTGetattr:
		rgetattr(m);
		break;
	case Nfs3CallTLookup:
		rlookup(m);
		break;
	case Nfs3CallTAccess:
		raccess(m);
		break;
	case Nfs3CallTReadlink:
		rreadlink(m);
		break;
	case Nfs3CallTRead:
		rread(m);
		break;
	case Nfs3CallTReadDir:
		rreaddir(m);
		break;
	case Nfs3CallTReadDirPlus:
		rreaddirplus(m);
		break;
	case Nfs3CallTFsStat:
		rfsstat(m);
		break;
	case Nfs3CallTFsInfo:
		rfsinfo(m);
		break;
	case Nfs3CallTPathconf:
		rpathconf(m);
		break;
	case Nfs3CallTSetattr:
	case Nfs3CallTWrite:
	case Nfs3CallTCreate:
	case Nfs3CallTMkdir:
	case Nfs3CallTSymlink:
	case Nfs3CallTMknod:
	case Nfs3CallTRemove:
	case Nfs3CallTRmdir:
	case Nfs3CallTLink:
	case Nfs3CallTCommit:
		rrofs(m);
		break;
	}
}

void
nfs3proc(void *v)
{
	Channel *c;
	SunMsg *m;

	c = v;
	threadsetname("nfs3");
	while((m = recvp(c)) != nil)
		threadcreate(rnfs3, m, SunStackSize);
}

