#ifndef lint
static char *sccsid = "@(#)rfscalls.c	1.4 (UKC) 24/5/85";
#endif  lint
/*	rfscalls.c
 *		the fake system calls for the remote file system system.
 *		requires: syscalls.c, interface to real system calls
 *			  rpccalls.c, the remote system calls
 *			  rfsutils.c, routines which need real syscalls
 */

#include "rfs.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>

extern int rfsfirstcall;	/* from rfsutils.c */
extern rfsufile_t rfsufile[];

long rpc_lseek(), sys_lseek();

/* VARARGS2 */
int
open(path,flags,mode)
char *path;
{
	struct rfsfile rfsfile;
	register int fd;

	if (rfsfirstcall) rfsinitialise();

	rfsfile = rfsparse(path);
	switch (rfsfile.tsfd) {
	case CLOSED:
		return(-1);
	case LOCAL:
		fd = sys_open(path, flags, mode);
		break;
	default:
		fd = rpc_open(rfsfile.tsfd, rfsfile.name, flags, mode);
	}
	if (fd == -1) return(-1);
	return (rfsufalloc(rfsfile.tsfd, fd));
}

int
creat(path,mode)
char *path;
{
	struct rfsfile rfsfile;
	register int fd;

	if (rfsfirstcall) rfsinitialise();

	rfsfile = rfsparse(path);
	switch (rfsfile.tsfd) {
	case CLOSED:
		return(-1);
	case LOCAL:
		fd = sys_creat(path, mode);
		break;
	default:
		fd = rpc_creat(rfsfile.tsfd, rfsfile.name, mode);
	}
	if (fd == -1) return(-1);
	return (rfsufalloc(rfsfile.tsfd, fd));
}

int
mkdir(path,mode)
char *path;
{
	struct rfsfile rfsfile;
	register int fd;

	if (rfsfirstcall) rfsinitialise();

	rfsfile = rfsparse(path);
	switch (rfsfile.tsfd) {
	case CLOSED:
		return(-1);
	case LOCAL:
		fd = sys_mkdir(path, mode);
		break;
	default:
		fd = rpc_mkdir(rfsfile.tsfd, rfsfile.name, mode);
	}
	if (fd == -1) return(-1);
	return (rfsufalloc(rfsfile.tsfd, fd));
}

int
read(ufd,buf,nbytes)
char *buf;
{
	if (rfsfirstcall) rfsinitialise();

	if (ISLOCAL(ufd))
		return(sys_read(REALFD(ufd), buf, nbytes));
	else
		return(rpc_read(WHERE(ufd), REALFD(ufd), buf, nbytes));
}

int
write(ufd,buf,nbytes)
char *buf;
{
	if (rfsfirstcall) rfsinitialise();

	if (ISLOCAL(ufd))
		return(sys_write(REALFD(ufd), buf, nbytes));
	else
		return(rpc_write(WHERE(ufd), REALFD(ufd), buf, nbytes));
}

int
close(ufd)
{
	int retval;

	if (rfsfirstcall) rfsinitialise();

	if (ISLOCAL(ufd))
		retval = sys_close(REALFD(ufd));
	else
		retval = rpc_close(WHERE(ufd), REALFD(ufd));
	if (retval != -1) rfsufree(ufd);
	return(retval);
}

int
writev(ufd,iov,ioveclen)
struct iovec *iov;
{
	if (rfsfirstcall) rfsinitialise();

	if (ISLOCAL(ufd))
		return(sys_writev(REALFD(ufd), iov, ioveclen));
	else
		return(rpc_writev(WHERE(ufd), REALFD(ufd), iov, ioveclen));
}

int
stat (path, stbuf)
char *path;
struct stat *stbuf;
{
	struct rfsfile rfsfile;
	register int fd;

	if (rfsfirstcall) rfsinitialise();

	rfsfile = rfsparse(path);
	switch (rfsfile.tsfd) {
	case CLOSED:
		return(-1);
	case LOCAL:
		fd = sys_stat(path, stbuf);
		break;
	default:
		fd = rpc_stat(rfsfile.tsfd, rfsfile.name, stbuf);
	}
	if (fd == -1) return(-1);
	return (rfsufalloc(rfsfile.tsfd, fd));
}

int
lstat (path, stbuf)
char *path;
struct stat *stbuf;
{
	struct rfsfile rfsfile;
	register int fd;

	if (rfsfirstcall) rfsinitialise();

	rfsfile = rfsparse(path);
	switch (rfsfile.tsfd) {
	case CLOSED:
		return(-1);
	case LOCAL:
		fd = sys_lstat(path, stbuf);
		break;
	default:
		fd = rpc_lstat(rfsfile.tsfd, rfsfile.name, stbuf);
	}
	if (fd == -1) return(-1);
	return (rfsufalloc(rfsfile.tsfd, fd));
}

int
fstat(ufd,stbuf)
struct stat *stbuf;
{
	if (rfsfirstcall) rfsinitialise();

	if (ISLOCAL(ufd))
		return(sys_fstat(REALFD(ufd), stbuf));
	else
		return(rpc_fstat(WHERE(ufd), REALFD(ufd), stbuf));
}

int
ioctl(ufd,request,argp)
char *argp;
{
	if (rfsfirstcall) rfsinitialise();

	if (ISLOCAL(ufd))
		return(sys_ioctl(REALFD(ufd), request, argp));
	else
		return(rpc_ioctl(WHERE(ufd), REALFD(ufd), request, argp));
}

long
lseek(ufd,offset,whence)
long offset;
{
	if (rfsfirstcall) rfsinitialise();

	if (ISLOCAL(ufd))
		return(sys_lseek(REALFD(ufd), offset, whence));
	else
		return(rpc_lseek(WHERE(ufd), REALFD(ufd), offset, whence));
}

int
readlink(path, buf, bufsiz)
char *path;
char *buf;
{
	struct rfsfile rfsfile;
	register int fd;

	if (rfsfirstcall) rfsinitialise();

	rfsfile = rfsparse(path);
	switch (rfsfile.tsfd) {
	case CLOSED:
		return(-1);
	case LOCAL:
		fd = sys_readlink(path, buf, bufsiz);
		break;
	default:
		fd = rpc_readlink(rfsfile.tsfd, rfsfile.name, buf, bufsiz);
	}
	if (fd == -1) return(-1);
	return (rfsufalloc(rfsfile.tsfd, fd));
}
