#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <thread.h>

int debug;
char *aname = "";
char *keypattern = "";
int fd;
int msize;
int doauth;
u32int afid = NOFID;
extern char *post9parg;	/* clumsy hack */
void xauth(void);
AuthInfo* xauth_proxy(AuthGetkey *getkey, char *fmt, ...);

void
usage(void)
{
	fprint(2, "usage: srv [-a] [-A aname] [-k keypattern] addr [srvname]\n");
	threadexitsall("usage");
}

void
threadmain(int argc, char **argv)
{
	char *addr, *service;

	fmtinstall('F', fcallfmt);
	fmtinstall('M', dirmodefmt);
	
	ARGBEGIN{
	case 'D':
		debug = 1;
		break;
	case 'A':
		/* BUG: should be able to repeat this and establish multiple afids */
		aname = EARGF(usage());
		break;
	case 'a':
		doauth = 1;
		break;
	case 'k':
		keypattern = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND
	
	if(argc != 1 && argc != 2)
		usage();

	addr = netmkaddr(argv[0], "tcp", "9fs");
	if((fd = dial(addr, nil, nil, nil)) < 0)
		sysfatal("dial %s: %r", addr);

	if(doauth)
		xauth();

	if(argc == 2)
		service = argv[1];
	else
		service = argv[0];

	if(post9pservice(fd, service) < 0)
		sysfatal("post9pservice: %r");

	threadexitsall(0);
}

void
do9p(Fcall *tx, Fcall *rx)
{
	static uchar buf[9000];
	static char ebuf[200];
	int n;
	
	n = convS2M(tx, buf, sizeof buf);
	if(n == BIT16SZ){
		werrstr("convS2M failed");
		goto err;
	}
	if(debug)
		fprint(2, "<- %F\n", tx);
	if(write(fd, buf, n) != n)
		goto err;
	if((n = read9pmsg(fd, buf, sizeof buf)) < 0)
		goto err;
	if(n == 0){
		werrstr("unexpected eof");
		goto err;
	}
	if(convM2S(buf, n, rx) != n){
		werrstr("convM2S failed");
		goto err;
	}
	if(debug)
		fprint(2, "-> %F\n", rx);
	if(rx->type != Rerror && rx->type != tx->type+1){
		werrstr("unexpected type");
		goto err;
	}
	if(rx->tag != tx->tag){
		werrstr("unexpected tag");
		goto err;
	}
	return;

err:
	rerrstr(ebuf, sizeof ebuf);
	rx->ename = ebuf;
	rx->type = Rerror;
	return;
}

void
xauth(void)
{
	Fcall tx, rx;

	afid = 0;
	tx.type = Tversion;
	tx.tag = NOTAG;
	tx.version = "9P2000";
	tx.msize = 8192;
	do9p(&tx, &rx);
	if(rx.type == Rerror)
		sysfatal("Tversion: %s", rx.ename);
	msize = rx.msize;
	
	tx.type = Tauth;
	tx.tag = 1;
	tx.afid = afid;
	tx.uname = getuser();
	tx.aname = aname;
	do9p(&tx, &rx);
	if(rx.type == Rerror){
		fprint(2, "rx: %s\n", rx.ename);
		afid = NOFID;
		return;
	}

	if(xauth_proxy(auth_getkey, "proto=p9any role=client %s", keypattern) == nil)
		sysfatal("authproxy: %r");
}

int
xread(void *buf, int n)
{
	Fcall tx, rx;
	
	tx.type = Tread;
	tx.tag = 1;
	tx.fid = 0;	/* afid above */
	tx.count = n;
	tx.offset = 0;
	do9p(&tx, &rx);
	if(rx.type == Rerror){
		werrstr("%s", rx.ename);
		return -1;
	}
	
	if(rx.count > n){
		werrstr("too much data returned");
		return -1;
	}
	memmove(buf, rx.data, rx.count);
	return rx.count;
}

int
xwrite(void *buf, int n)
{
	Fcall tx, rx;
	
	tx.type = Twrite;
	tx.tag = 1;
	tx.fid = 0;	/* afid above */
	tx.data = buf;
	tx.count = n;
	tx.offset = 0;
	do9p(&tx, &rx);
	if(rx.type == Rerror){
		werrstr("%s", rx.ename);
		return -1;
	}
	return n;
}


/*
 * changed to add -A below
 */
#undef _exits
int
post9pservice(int fd, char *name)
{
	int i;
	char *ns, *s;
	Waitmsg *w;

	if((ns = getns()) == nil)
		return -1;

	s = smprint("unix!%s/%s", ns, name);
	free(ns);
	if(s == nil)
		return -1;
	switch(fork()){
	case -1:
		return -1;
	case 0:
		dup(fd, 0);
		dup(fd, 1);
		for(i=3; i<20; i++)
			close(i);
		if(doauth)
			execlp("9pserve", "9pserve", "-u",
				"-M",
					smprint("%d", msize),
				"-A",
					aname,
					smprint("%d", afid),
				s, (char*)0);
		else		
			execlp("9pserve", "9pserve", "-u", s, (char*)0);
		fprint(2, "exec 9pserve: %r\n");
		_exits("exec");
	default:
		w = wait();
		if(w == nil)
			return -1;
		close(fd);
		free(s);
		if(w->msg && w->msg[0]){
			free(w);
			werrstr("9pserve failed");
			return -1;
		}
		free(w);
		return 0;
	}
}

enum { ARgiveup = 100 };
static int
dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
{
	int ret;

	for(;;){
		if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
			return ret;
		if(getkey == nil)
			return ARgiveup;	/* don't know how */
		if((*getkey)(rpc->arg) < 0)
			return ARgiveup;	/* user punted */
	}
}


/*
 *  this just proxies what the factotum tells it to.
 */
AuthInfo*
xfauth_proxy(AuthRpc *rpc, AuthGetkey *getkey, char *params)
{
	char *buf;
	int m, n, ret;
	AuthInfo *a;
	char oerr[ERRMAX];

	rerrstr(oerr, sizeof oerr);
	werrstr("UNKNOWN AUTH ERROR");

	if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
		werrstr("fauth_proxy start: %r");
		return nil;
	}

	buf = malloc(AuthRpcMax);
	if(buf == nil)
		return nil;
	for(;;){
		switch(dorpc(rpc, "read", nil, 0, getkey)){
		case ARdone:
			free(buf);
			a = auth_getinfo(rpc);
			errstr(oerr, sizeof oerr);	/* no error, restore whatever was there */
			return a;
		case ARok:
			if(xwrite(rpc->arg, rpc->narg) != rpc->narg){
				werrstr("auth_proxy write fid: %r");
				goto Error;
			}
			break;
		case ARphase:
			n = 0;
			memset(buf, 0, AuthRpcMax);
			while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
				if(atoi(rpc->arg) > AuthRpcMax)
					break;
				m = xread(buf+n, atoi(rpc->arg)-n);
				if(m <= 0){
					if(m == 0)
						werrstr("auth_proxy short read: %s", buf);
					goto Error;
				}
				n += m;
			}
			if(ret != ARok){
				werrstr("auth_proxy rpc write: %s: %r", buf);
				goto Error;
			}
			break;
		default:
			werrstr("auth_proxy rpc: %r");
			goto Error;
		}
	}
Error:
	free(buf);
	return nil;
}

AuthInfo*
xauth_proxy(AuthGetkey *getkey, char *fmt, ...)
{
	char *p;
	va_list arg;
	AuthInfo *ai;
	AuthRpc *rpc;

	quotefmtinstall();	/* just in case */
	va_start(arg, fmt);
	p = vsmprint(fmt, arg);
	va_end(arg);

	rpc = auth_allocrpc();
	if(rpc == nil){
		free(p);
		return nil;
	}

	ai = xfauth_proxy(rpc, getkey, p);
	free(p);
	auth_freerpc(rpc);
	return ai;
}

