#ifndef lint
static char sccsid[] = "@(#)rpccalls.c	1.15 (UKC) 26/9/86";
#endif  lint
/*
 *	The top level of the rpc chain - the pseudo-system calls themselves.
 */

#include <errno.h>	/* for denying access to unimplemented calls */
#include <sys/types.h>	/* for the next two includes */
#include <sys/stat.h>	/* for stat, lstat, fstat */
#include <sys/uio.h>	/* for writev */
#include <sys/ioctl.h>	/* for IOC_{IN,OUT} */
#include <sys/time.h>	/* for gettimeofday */
#include "cmds.h"	/* command tokens */
#include "trans.h"	/* declarations of {send,recv}* */

extern int errno;

#ifdef REX
# define tsfd 0
#endif

int
#ifdef REX
/* VARARGS2 */
open(path, flags, mode)
#else
/* VARGARGS3 */
rpc_open(tsfd,path,flags,mode)
#endif
char *path;
{
	register int retval;

	sendcmd(tsfd,SYS_open);
	sendstring(tsfd,path, strlen(path)+1); /* one for the null */
	sendint(tsfd,flags);
	sendint(tsfd,mode);
	
	retval = recvint(tsfd);
	if (retval < 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
creat(path, mode)
#else
rpc_creat(tsfd,path,mode)
#endif
char *path;
{
	register int retval;

	sendcmd(tsfd,SYS_creat);
	sendstring(tsfd,path, strlen(path)+1); /* one for the null */
	sendint(tsfd,mode);
	
	retval = recvint(tsfd);
	if (retval < 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
mkdir(path, mode)
#else
rpc_mkdir(tsfd,path,mode)
#endif
char *path;
{
	register int retval;

	sendcmd(tsfd,SYS_mkdir);
	sendstring(tsfd,path, strlen(path)+1); /* one for the null */
	sendint(tsfd,mode);
	
	retval = recvint(tsfd);
	if (retval != 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
chmod(path, mode)
#else
rpc_chmod(tsfd,path,mode)
#endif
char *path;
{
	register int retval;

	sendcmd(tsfd,SYS_chmod);
	sendstring(tsfd,path, strlen(path)+1); /* one for the null */
	sendint(tsfd,mode);
	
	retval = recvint(tsfd);
	if (retval != 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
unlink(path)
#else
rpc_unlink(tsfd,path)
#endif
char *path;
{
	register int retval;

	sendcmd(tsfd,SYS_unlink);
	sendstring(tsfd,path, strlen(path)+1); /* one for the null */
	
	retval = recvint(tsfd);
	if (retval != 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
rmdir(path)
#else
rpc_rmdir(tsfd,path)
#endif
char *path;
{
	register int retval;

	sendcmd(tsfd,SYS_rmdir);
	sendstring(tsfd,path, strlen(path)+1); /* one for the null */
	
	retval = recvint(tsfd);
	if (retval != 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
chdir(path)
#else
rpc_chdir(tsfd,path)
#endif
char *path;
{
	register int retval;

	sendcmd(tsfd,SYS_chdir);
	sendstring(tsfd,path, strlen(path)+1); /* one for the null */
	
	retval = recvint(tsfd);
	if (retval != 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
read(fd, buf, nbytes)
#else
rpc_read(tsfd,fd, buf, nbytes)
#endif
char *buf;
{
	register int retval;

	sendcmd(tsfd,SYS_read);
	sendint(tsfd,fd);
	sendint(tsfd,nbytes);

	retval = recvint(tsfd);
	if (retval > 0) {
		(void) recvbuf(tsfd,&buf, retval);
	} else if (retval < 0) {
		errno = recvint(tsfd);
	}
	/* (retval == 0) => EOF => no further info required */
	return(retval);
}

int
#ifdef REX
write(fd,buf,nbytes)
#else
rpc_write(tsfd,fd,buf,nbytes)
#endif
char *buf;
{
	register int retval;

	sendcmd(tsfd,SYS_write);
	sendint(tsfd,fd);
	sendint(tsfd,nbytes);
	sendbuf(tsfd,buf,nbytes);

	retval = recvint(tsfd);
	if (retval == -1)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
writev(fd, iov, ioveclen)
#else
rpc_writev(tsfd,fd, iov, ioveclen)
#endif
struct iovec *iov;
{
	register int retval;
	register int i;

	sendcmd(tsfd,SYS_writev);
	sendint(tsfd,fd);
	sendint(tsfd,ioveclen);
	for (i=0; i<ioveclen; i++) {
		sendbuf(tsfd,iov[i].iov_base,
			iov[i].iov_len);
	}

	retval = recvint(tsfd);
	if (retval == -1)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
close(fd)
#else
rpc_close(tsfd,fd)
#endif
int fd;
{
	register int retval;

	sendcmd(tsfd,SYS_close);
	sendint(tsfd,fd);
	
	retval = recvint(tsfd);
	if (retval != 0) {
		errno = recvint(tsfd);
	}
	return(retval);
}

int
#ifdef REX
dup(fd)
#else
rpc_dup(tsfd,fd)
#endif
int fd;
{
	register int retval;

	sendcmd(tsfd,SYS_dup);
	sendint(tsfd,fd);
	
	retval = recvint(tsfd);
	if (retval == -1) {
		errno = recvint(tsfd);
	}
	return(retval);
}

#ifdef REX
_exit(status)
#else
rpc__exit(tsfd,status)
#endif
{
	sendcmd(tsfd,SYS_exit);
	sendint(tsfd,status);
	status = recvint(tsfd); /* pick up the disconnect */
	syscall(SYS_exit, -1); /* just in case */
}

#ifdef REX
stat(path,stbuf)
#else
rpc_stat(tsfd,path,stbuf)
#endif
char *path;
struct stat *stbuf;
{
	register int retval;

	sendcmd(tsfd,SYS_stat);
	sendstring(tsfd,path,strlen(path)+1);
	retval = recvint(tsfd);
	if (retval == 0)
		recvstat(tsfd,stbuf);
	else
		errno = recvint(tsfd);
	return(retval);
}

#ifdef REX
lstat(path,stbuf)
#else
rpc_lstat(tsfd,path,stbuf)
#endif
char *path;
struct stat *stbuf;
{
	register int retval;

	sendcmd(tsfd,SYS_lstat);
	sendstring(tsfd,path,strlen(path)+1);
	retval = recvint(tsfd);
	if (retval == 0)
		recvstat(tsfd,stbuf);
	else
		errno = recvint(tsfd);
	return(retval);
}

#ifdef REX
fstat(fd,stbuf)
#else
rpc_fstat(tsfd,fd,stbuf)
#endif
int fd;
struct stat *stbuf;
{
	register int retval;

	sendcmd(tsfd,SYS_fstat);
	sendint(tsfd,fd);
	retval = recvint(tsfd);
	if (retval == 0)
		recvstat(tsfd,stbuf);
	else
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
ioctl(fd, request, argp)
#else
rpc_ioctl(tsfd,fd, request, argp)
#endif
char *argp;
{
	register long retval;

	sendcmd(tsfd,SYS_ioctl);
	sendint(tsfd,fd);
	sendint(tsfd,request);
	if (request & IOC_IN)
		sendbuf(tsfd,argp, IOC_SIZE(request));
	
	retval = recvint(tsfd);
	if (retval==-1)
		errno = recvint(tsfd);
	if (request & IOC_OUT)
		(void) recvbuf(tsfd,&argp, IOC_SIZE(request));
	return(retval);
}

long
#ifdef REX
lseek(fd, offset, whence)
#else
rpc_lseek(tsfd,fd, offset, whence)
#endif
long offset;
{
	register int retval;

	sendcmd(tsfd,SYS_lseek);
	sendint(tsfd,fd);
	sendint(tsfd,offset);
	sendint(tsfd,whence);

	retval=recvint(tsfd);
	if (retval < 0)
		errno = recvint(tsfd);
	return(retval);
}

int
#ifdef REX
readlink(name,buf,bufsiz)
#else
rpc_readlink(tsfd,name,buf,bufsiz)
#endif
char *name, *buf;
{
	register int retval;

	sendcmd(tsfd,SYS_readlink);
	sendstring(tsfd,name, strlen(name)+1);
	sendint(tsfd,bufsiz);

	retval=recvint(tsfd);
	if (retval == -1)
		errno = recvint(tsfd);
	else
		(void) recvstring(tsfd,&buf,retval);
	return(retval);
}

int
#ifdef REX
gettimeofday(tp, tzp)
#else
rpc_gettimeofday(tsfd, tp, tzp)
#endif
struct timeval *tp;
struct timezone *tzp;
{
	register int retval;

	sendcmd(tsfd,SYS_gettimeofday);
	sendint(tsfd, (int)tzp);

	retval=recvint(tsfd);
	if (retval != 0)
		errno = recvint(tsfd);
	else {
		tp->tv_sec = (u_long) recvlong(tsfd);
		tp->tv_usec = recvlong(tsfd);
		if (tzp != 0) {
			tzp->tz_minuteswest = recvint(tsfd);
			tzp->tz_dsttime = recvint(tsfd);
		}
	}
	return(retval);
}

/*
 *	Functions NOT wanted for Remote file system
 */

#ifdef REX
int
getuid()
{
	sendcmd(tsfd,SYS_getuid);
	return(recvint(tsfd));
}

int
getgid()
{
	sendcmd(tsfd,SYS_getgid);
	return(recvint(tsfd));
}

int
geteuid()
{
	sendcmd(tsfd,SYS_geteuid);
	return(recvint(tsfd));
}

int
getegid()
{
	sendcmd(tsfd,SYS_getegid);
	return(recvint(tsfd));
}

int
getpid()
{
	sendcmd(tsfd,SYS_getpid);
	return(recvint(tsfd));
}

int
getppid()
{
	sendcmd(tsfd,SYS_getppid);
	return(recvint(tsfd));
}

#endif

/*
 *	Functions we cannot do; fail always.
 *	EINTR is "Interrupted system call", the nearest we can get.
 */

execve()
{
	errno = EINTR;
	return(-1);
}

fork()
{
	errno = EINTR;
	return(-1);
}

vfork()
{
	errno = EINTR;
	return(-1);
}


#ifdef DEBUG
debugmess(format,a1,a2,a3)
char *format;
{
	char mess[64];

	sprintf(mess,format,a1,a2,a3);
	syscall(SYS_write,2,mess,strlen(mess));
}
#endif
