#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"

#include	<authsrv.h>

char	*eve;
char	hostdomain[DOMLEN];

/*
 *  return true if current user is eve
 */
int
iseve(void)
{
	return strcmp(eve, up->user) == 0;
}

uintptr
sysfversion(va_list list)
{
	int msize, arglen, fd;
	char *vers;
	Chan *c;

	fd = va_arg(list, int);
	msize = va_arg(list, int);
	vers = va_arg(list, char*);
	arglen = va_arg(list, int);
	validaddr((uintptr)vers, arglen, 1);
	/* check there's a NUL in the version string */
	if(arglen <= 0 || memchr(vers, 0, arglen) == nil)
		error(Ebadarg);
	c = fdtochan(fd, ORDWR, 0, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	msize = mntversion(c, vers, msize, arglen);
	cclose(c);
	poperror();
	return msize;
}

uintptr
sys_fsession(va_list list)
{
	int fd;
	char *str;
	uint len;

	/* deprecated; backwards compatibility only */
	fd = va_arg(list, int);
	str = va_arg(list, char*);
	len = va_arg(list, uint);
	if(len == 0)
		error(Ebadarg);
	validaddr((uintptr)str, len, 1);
	*str = '\0';
	USED(fd);
	return 0;
}

uintptr
sysfauth(va_list list)
{
	Chan *c, *ac;
	char *aname;
	int fd;

	fd = va_arg(list, int);
	aname = va_arg(list, char*);
	validaddr((uintptr)aname, 1, 0);
	aname = validnamedup(aname, 1);
	if(waserror()){
		free(aname);
		nexterror();
	}
	c = fdtochan(fd, ORDWR, 0, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}

	ac = mntauth(c, aname);
	/* at this point ac is responsible for keeping c alive */
	poperror();	/* c */
	cclose(c);
	poperror();	/* aname */
	free(aname);

	if(waserror()){
		cclose(ac);
		nexterror();
	}

	/* always mark it close on exec */
	fd = newfd(ac, OCEXEC);
	if(fd < 0)
		error(Enofd);
	poperror();	/* ac */

	return (uintptr)fd;
}

/*
 *  called by devcons() for user device
 *
 *  anyone can become none
 */
long
userwrite(char *a, int n)
{
	if(n!=4 || strncmp(a, "none", 4)!=0)
		error(Eperm);
	procsetuser("none");
	return n;
}

/*
 *  called by devcons() for host owner/domain
 *
 *  writing hostowner also sets user
 */
long
hostownerwrite(char *a, int n)
{
	char buf[KNAMELEN];

	if(!iseve())
		error(Eperm);
	if(n <= 0)
		error(Ebadarg);
	if(n >= sizeof buf)
		error(Etoolong);
	memmove(buf, a, n);
	buf[n] = 0;

	renameuser(eve, buf);
	srvrenameuser(eve, buf);
	shrrenameuser(eve, buf);
	kstrdup(&eve, buf);
	procsetuser(buf);
	return n;
}

long
hostdomainwrite(char *a, int n)
{
	char buf[DOMLEN];

	if(!iseve())
		error(Eperm);
	if(n <= 0 || n >= DOMLEN)
		error(Ebadarg);
	memset(buf, 0, DOMLEN);
	strncpy(buf, a, n);
	if(buf[0] == 0)
		error(Ebadarg);
	memmove(hostdomain, buf, DOMLEN);
	return n;
}
