Prechádzať zdrojové kódy

add NFS v3 filesystem implementation.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@721 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 15 rokov pred
rodič
commit
0fbfdec40d

+ 40 - 0
components/dfs/filesystems/nfs/SConscript

@@ -0,0 +1,40 @@
+Import('env')
+Import('projects')
+Import('RTT_ROOT')
+Import('rtconfig')
+
+src = Split('''
+mount_clnt.c
+mount_xdr.c
+nfs_clnt.c
+nfs_xdr.c
+dfs_nfs.c
+rpc/auth_none.c
+rpc/clnt_generic.c
+rpc/clnt_udp.c
+rpc/rpc_prot.c
+rpc/pmap.c
+rpc/xdr.c
+rpc/xdr_mem.c
+''')
+
+# group definitions
+group = {}
+group['name'] = 'nfsclient'
+group['src'] = File(src) #Glob('*.c')
+group['CCFLAGS'] = ''
+group['CPPPATH'] = [RTT_ROOT + '/components/dfs/filesystems/nfs']
+group['CPPDEFINES'] = ''
+group['LINKFLAGS'] = ''
+
+# add group to project list
+projects.append(group)
+
+env.Append(CCFLAGS = group['CCFLAGS'])
+env.Append(CPPPATH = group['CPPPATH'])
+env.Append(CPPDEFINES = group['CPPDEFINES'])
+env.Append(LINKFLAGS = group['LINKFLAGS'])
+
+objs = env.Object(group['src'])
+
+Return('objs')

+ 975 - 0
components/dfs/filesystems/nfs/dfs_nfs.c

@@ -0,0 +1,975 @@
+#include <stdio.h>
+#include <rtthread.h>
+#include <dfs_fs.h>
+#include <dfs_def.h>
+
+#ifdef RT_USING_LWIP /* NFSv3 must use lwip as network protocol */
+#include <rpc/rpc.h>
+
+#include "mount.h"
+#include "nfs.h"
+
+#define NAME_MAX	64
+
+struct nfs_file
+{
+	nfs_fh3 handle;		/* handle */
+	size_t offset;		/* current offset */
+
+	size_t size;		/* total size */
+};
+
+struct nfs_dir
+{
+	nfs_fh3 handle;
+	cookie3 cookie;
+	cookieverf3 cookieverf;
+	entry3 *entry;
+	bool_t eof;
+	READDIR3res res;
+};
+
+#define HOST_LENGTH			32
+#define EXPORT_PATH_LENGTH	32
+struct nfs_filesystem
+{
+	nfs_fh3 root_handle;
+	nfs_fh3 current_handle;
+	CLIENT *nfs_client;
+	CLIENT *mount_client;
+
+	char host[HOST_LENGTH];
+	char export[EXPORT_PATH_LENGTH];
+};
+typedef struct nfs_file nfs_file;
+typedef struct nfs_dir nfs_dir;
+nfs_dir *nfs_opendir(struct nfs_filesystem* nfs, const char *path);
+
+static int nfs_parse_host_export(const char* host_export, 
+	char* host, size_t host_len, 
+	char* export, size_t export_len)
+{
+	int index;
+
+	for (index = 0; index < host_len; index ++)
+	{
+		/* it's end of string, failed */
+		if (host_export[index] == 0) return -1;
+
+		/* copy to host buffer */
+		if (host_export[index] != ':')
+			host[index] = host_export[index];
+		else break;
+	}
+
+	/* host buffer is not enough, failed */
+	if (index == host_len) return -1;
+
+	/* make RT_NULL */
+	host_len = index;
+	host[host_len] = '\0';
+
+	host_len ++;
+
+	/* copy export path */
+	for (index = host_len; index < host_len + export_len; index ++)
+	{
+		if (host_export[index] == 0) 
+		{
+			export[index - host_len] = '\0';
+			return 0;
+		}
+
+		export[index - host_len] = host_export[index];
+	}
+
+	return -1;
+}
+
+static void copy_handle(nfs_fh3 *dest, const nfs_fh3 *source)
+{
+	dest->data.data_len = source->data.data_len;
+	dest->data.data_val = rt_malloc(dest->data.data_len);
+	if(dest->data.data_val==RT_NULL)
+	{
+		dest->data.data_len=0;
+		return;
+	}
+
+	memcpy(dest->data.data_val, source->data.data_val, dest->data.data_len);
+}
+
+static nfs_fh3 *get_handle(struct nfs_filesystem* nfs, const char *name)
+{
+	nfs_fh3 *handle=RT_NULL;
+	char *file;
+	char *path;
+	char *init;
+
+	init = path = rt_malloc(strlen(name)+1);
+	if(init==RT_NULL)
+		return RT_NULL;
+
+	memcpy(init, name, strlen(name)+1);
+
+	handle = rt_malloc(sizeof(nfs_fh3));
+	if(handle==RT_NULL)
+	{
+		rt_free(init);
+		return RT_NULL;
+	}
+
+	if(path[0]=='/')
+	{
+		path++;
+		copy_handle(handle, &nfs->root_handle);
+	}
+	else
+	{
+		copy_handle(handle, &nfs->current_handle);
+	}
+
+	while((file=strtok_r(RT_NULL, "/", &path))!=RT_NULL)
+	{
+		LOOKUP3args args;
+		LOOKUP3res res;
+		memset(&res, 0, sizeof(res));
+		copy_handle(&args.what.dir, handle);
+		xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+		args.what.name=file;
+
+		if(nfsproc3_lookup_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+		{
+			rt_kprintf("Lookup failed\n");
+			rt_free(init);
+			rt_free(handle);
+			xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
+			return RT_NULL;
+		}
+		else if(res.status!=NFS3_OK)
+		{
+			rt_kprintf("Lookup failed: %d\n", res.status);
+			rt_free(init);
+			rt_free(handle);
+			xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
+			xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
+			return RT_NULL;
+		}
+		copy_handle(handle, &res.LOOKUP3res_u.resok.object);
+		xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
+		xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
+	}
+
+	rt_free(init);
+	return handle;
+}
+
+static nfs_fh3 *get_dir_handle(struct nfs_filesystem* nfs, const char *name)
+{
+	nfs_fh3 *handle=RT_NULL;
+	char *file;
+	char *path;
+	char *init;
+
+	init = path = rt_malloc(strlen(name)+1);
+	if(init==RT_NULL)
+		return RT_NULL;
+	memcpy(init, name, strlen(name)+1);
+
+	handle = rt_malloc(sizeof(nfs_fh3));
+	if(handle == RT_NULL)
+	{
+		rt_free(init);
+		return RT_NULL;
+	}
+
+	if(path[0]=='/')
+	{
+		path++;
+		copy_handle(handle, &nfs->root_handle);
+	}
+	else
+	{
+		copy_handle(handle, &nfs->current_handle);
+	}
+
+	while((file=strtok_r(RT_NULL, "/", &path))!=RT_NULL && path[0]!='\0')
+	{
+		LOOKUP3args args;
+		LOOKUP3res res;
+		memset(&res, 0, sizeof(res));
+		copy_handle(&args.what.dir, handle);
+		xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+		args.what.name=file;
+
+		if(nfsproc3_lookup_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+		{
+			rt_kprintf("Lookup failed\n");
+			rt_free(init);
+			rt_free(handle);
+			xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
+			return RT_NULL;
+		}
+		else if(res.status!=NFS3_OK)
+		{
+			rt_kprintf("Lookup failed: %d\n", res.status);
+			rt_free(init);
+			rt_free(handle);
+			xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
+			xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
+			return RT_NULL;
+		}
+		copy_handle(handle, &res.LOOKUP3res_u.resok.object);
+		xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
+		xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
+	}
+
+	rt_free(init);
+	return handle;
+}
+
+static size_t nfs_get_filesize(struct nfs_filesystem* nfs, nfs_fh3 *handle)
+{
+	GETATTR3args args;
+	GETATTR3res res;
+	fattr3 *info;
+	size_t size;
+
+	args.object = *handle;
+
+	memset(&res, '\0', sizeof(res));
+
+	if ((nfsproc3_getattr_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS) ||
+		res.status != NFS3_OK)
+	{
+		rt_kprintf("GetAttr failed: %d\n", res.status);
+		return 0;
+	}
+
+	info=&res.GETATTR3res_u.resok.obj_attributes;
+	size = info->size;
+	xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res);
+	
+	return size;
+}
+
+int nfs_create(struct nfs_filesystem* nfs, const char *name, mode_t mode)
+{
+	CREATE3args args;
+	CREATE3res res;
+	int ret=0;
+	nfs_fh3 *handle;
+
+	if(nfs->nfs_client==RT_NULL)
+	{
+		return -1;
+	}
+
+	handle=get_dir_handle(nfs, name);
+	if(handle==RT_NULL)
+	{
+		return -1;
+	}
+	args.where.dir=*handle;
+	args.where.name=strrchr(name, '/');
+	if(args.where.name==RT_NULL)
+	{
+		args.where.name=(char *)name;
+	}
+	args.how.mode=GUARDED;
+
+	args.how.createhow3_u.obj_attributes.mode.set_it=TRUE;
+	args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode=mode;
+	args.how.createhow3_u.obj_attributes.uid.set_it=FALSE;
+	args.how.createhow3_u.obj_attributes.gid.set_it=FALSE;
+	args.how.createhow3_u.obj_attributes.size.set_it=FALSE;
+	args.how.createhow3_u.obj_attributes.atime.set_it=DONT_CHANGE;
+	args.how.createhow3_u.obj_attributes.mtime.set_it=DONT_CHANGE;
+
+	memset(&res, 0, sizeof(res));
+
+	if(nfsproc3_create_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("Create failed\n");
+		ret = -1;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Create failed: %d\n", res.status);
+		ret = -1;
+	}
+	xdr_free((xdrproc_t)xdr_CREATE3res, (char *)&res);
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+
+	return ret;
+}
+
+int nfs_mkdir(struct nfs_filesystem* nfs, const char *name, mode_t mode)
+{
+	MKDIR3args args;
+	MKDIR3res res;
+	int ret=0;
+	nfs_fh3 *handle;
+
+	if(nfs->nfs_client==RT_NULL)
+		return -1;
+
+	handle=get_dir_handle(nfs, name);
+	if(handle==RT_NULL)
+		return -1;
+
+	args.where.dir=*handle;
+	args.where.name=strrchr(name, '/');
+	if(args.where.name==RT_NULL)
+	{
+		args.where.name=(char *)name;
+	}
+
+	args.attributes.mode.set_it=TRUE;
+	args.attributes.mode.set_mode3_u.mode=mode;
+	args.attributes.uid.set_it=FALSE;
+	args.attributes.gid.set_it=FALSE;
+	args.attributes.size.set_it=FALSE;
+	args.attributes.atime.set_it=DONT_CHANGE;
+	args.attributes.mtime.set_it=DONT_CHANGE;
+
+	memset(&res, 0, sizeof(res));
+
+	if(nfsproc3_mkdir_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("Mkdir failed\n");
+		ret=-1;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Mkdir failed: %d\n", res.status);
+		ret=-1;
+	}
+	xdr_free((xdrproc_t)xdr_MKDIR3res, (char *)&res);
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+	return ret;
+}
+
+/* mount(RT_NULL, "/mnt", "nfs", 0, "192.168.1.1:/export") */
+int nfs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
+{
+	mountres3 res;
+	struct nfs_filesystem* nfs;
+
+	nfs = (struct nfs_filesystem*)rt_malloc(sizeof(struct nfs_filesystem));
+	memset(nfs, 0, sizeof(struct nfs_filesystem));
+
+	if (nfs_parse_host_export((const char*)data, nfs->host, HOST_LENGTH,
+		nfs->export, EXPORT_PATH_LENGTH) < 0)
+	{
+		rt_kprintf("host or export path error\n");
+		goto __return;
+	}
+
+	nfs->mount_client=clnt_create((char *)nfs->host, MOUNT_PROGRAM, MOUNT_V3, "udp");
+	if(nfs->mount_client==RT_NULL)
+	{
+		rt_kprintf("create mount client failed\n");
+		goto __return;
+	}
+
+	memset(&res, '\0', sizeof(mountres3));
+	if(mountproc3_mnt_3((char *)nfs->export, &res, nfs->mount_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("nfs mount failed\n");
+		goto __return;
+	}
+	else if(res.fhs_status!=MNT3_OK)
+	{
+		rt_kprintf("nfs mount failed\n");
+		goto __return;
+	}
+	nfs->nfs_client=clnt_create((char *)nfs->host, NFS_PROGRAM, NFS_V3, "udp");
+	if(nfs->nfs_client == RT_NULL)
+	{
+		rt_kprintf("creat nfs client failed\n");
+		goto __return;
+	}
+	copy_handle(&nfs->root_handle, (nfs_fh3 *)&res.mountres3_u.mountinfo.fhandle);
+	copy_handle(&nfs->current_handle, &nfs->root_handle);
+
+	nfs->nfs_client->cl_auth=authnone_create();
+	fs->data = nfs;
+
+	return 0;
+
+__return:
+	if (nfs != RT_NULL)
+	{
+		if (nfs->mount_client != RT_NULL)
+		{
+			clnt_destroy(nfs->mount_client);
+		}
+		if (nfs->nfs_client != RT_NULL)
+		{
+			if (nfs->nfs_client->cl_auth != RT_NULL)
+			{
+				auth_destroy(nfs->nfs_client->cl_auth);
+			}
+			clnt_destroy(nfs->nfs_client);
+		}
+		rt_free(nfs);
+	}
+
+	return -1;
+}
+
+int nfs_unmount(struct dfs_filesystem* fs)
+{
+	struct nfs_filesystem* nfs;
+
+	RT_ASSERT(fs != RT_NULL);
+	RT_ASSERT(fs->data != RT_NULL);
+	nfs = (struct nfs_filesystem *)fs->data;
+
+	if (nfs->mount_client != RT_NULL && 
+		mountproc3_umnt_3((char *)nfs->export, RT_NULL, nfs->mount_client) != RPC_SUCCESS)
+	{
+		rt_kprintf("umount failed\n");
+		return -1;
+	}
+
+	/* destroy nfs client */
+	if(nfs->nfs_client != RT_NULL)
+	{
+		if(nfs->nfs_client->cl_auth!=RT_NULL)
+		{
+			auth_destroy(nfs->nfs_client->cl_auth);
+			nfs->nfs_client->cl_auth = RT_NULL;
+		}
+		clnt_destroy(nfs->nfs_client);
+		nfs->nfs_client = RT_NULL;
+	}
+
+	/* destroy mount client */
+	if(nfs->mount_client != RT_NULL)
+	{
+		if(nfs->mount_client->cl_auth != RT_NULL)
+		{
+			auth_destroy(nfs->mount_client->cl_auth);
+			nfs->mount_client->cl_auth = RT_NULL;
+		}
+		clnt_destroy(nfs->mount_client);
+		nfs->mount_client=RT_NULL;
+	}
+
+	rt_free(nfs);
+	fs->data = RT_NULL;
+
+	return 0;
+}
+
+int nfs_ioctl(struct dfs_fd* file, int cmd,	void* args)
+{
+	return -DFS_STATUS_ENOSYS;
+}
+
+int nfs_read(struct dfs_fd* file, void *buf, rt_size_t count)
+{
+	READ3args args;
+	READ3res res;
+	ssize_t bytes;
+	nfs_file *fd;
+	struct nfs_filesystem* nfs;
+
+	if (file->type == FT_DIRECTORY)
+		return -DFS_STATUS_EISDIR;
+
+	fd = (nfs_file *)(file->data);
+	RT_ASSERT(fd != RT_NULL);
+	RT_ASSERT(file->fs != RT_NULL);
+	RT_ASSERT(file->fs->data != RT_NULL);
+	nfs = (struct nfs_filesystem *)file->fs->data;
+
+	if(nfs->nfs_client==RT_NULL)
+		return -1;
+
+	args.file=fd->handle;
+	args.offset=fd->offset;
+	args.count=count;
+
+	memset(&res, 0, sizeof(res));
+	if(nfsproc3_read_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("Read failed\n");
+		bytes = 0;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Read failed: %d\n", res.status);
+		bytes = 0;
+	}
+	else
+	{
+		if(res.READ3res_u.resok.eof)
+		{
+			/* something should probably be here */
+		}
+		bytes=res.READ3res_u.resok.count;
+		fd->offset += bytes;
+		memcpy(buf, res.READ3res_u.resok.data.data_val, bytes);
+	}
+	xdr_free((xdrproc_t)xdr_READ3res, (char *)&res);
+
+	return bytes;
+}
+
+int nfs_write(struct dfs_fd* file, const void *buf, rt_size_t count)
+{
+	WRITE3args args;
+	WRITE3res res;
+	ssize_t bytes;
+	nfs_file *fd;
+	struct nfs_filesystem* nfs;
+
+	if (file->type == FT_DIRECTORY)
+		return -DFS_STATUS_EISDIR;
+
+	fd = (nfs_file *)(file->data);
+	RT_ASSERT(fd != RT_NULL);
+	RT_ASSERT(file->fs != RT_NULL);
+	RT_ASSERT(file->fs->data != RT_NULL);
+	nfs = (struct nfs_filesystem *)file->fs->data;
+
+	if(nfs->nfs_client==RT_NULL)
+		return -1;
+
+	args.file=fd->handle;
+	args.stable=FILE_SYNC;
+	args.offset=fd->offset;
+
+	memset(&res, 0, sizeof(res));
+	args.data.data_val=(void *)buf;
+	args.count=args.data.data_len=count;
+
+	if(nfsproc3_write_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("Write failed\n");
+		bytes = 0;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Write failed: %d\n", res.status);
+		bytes = 0;
+	}
+	else
+	{
+		bytes=res.WRITE3res_u.resok.count;
+		fd->offset+=bytes;
+	}
+	xdr_free((xdrproc_t)xdr_WRITE3res, (char *)&res);
+
+	return bytes;
+}
+
+int nfs_lseek(struct dfs_fd* file, rt_off_t offset)
+{
+	nfs_file *fd;
+
+	if (file->type == FT_DIRECTORY)
+		return -DFS_STATUS_EISDIR;
+
+	fd = (nfs_file *)(file->data);
+	RT_ASSERT(fd != RT_NULL);
+
+	if (offset < fd->size)
+	{
+		fd->offset = offset;
+		return offset;
+	}
+
+	return -DFS_STATUS_EIO;
+}
+
+int nfs_close(struct dfs_fd* file)
+{
+	if (file->type == FT_DIRECTORY)
+	{
+		struct nfs_dir* dir;
+
+		dir = (struct nfs_dir*)file->data;
+		xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&dir->handle);
+		xdr_free((xdrproc_t)xdr_READDIR3res, (char *)&dir->res);
+		rt_free(dir);
+	}
+	else if (file->type == FT_REGULAR)
+	{
+		struct nfs_file* fd;
+
+		fd = (struct nfs_file*)file->data;
+
+		xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&fd->handle);
+		rt_free(fd);
+	}
+
+	file->data = RT_NULL;
+	return 0;
+}
+
+int nfs_open(struct dfs_fd* file)
+{
+	struct nfs_filesystem* nfs;
+
+	RT_ASSERT(file->fs != RT_NULL);
+	RT_ASSERT(file->fs->data != RT_NULL);
+	nfs = (struct nfs_filesystem *)file->fs->data;
+
+	if (file->flags & DFS_O_DIRECTORY)
+	{
+		nfs_dir *dir;
+	
+		if (file->flags & DFS_O_CREAT)
+		{
+			if (nfs_mkdir(nfs, file->path, 555) < 0)
+				return -1;
+		}
+
+		/* open directory */
+		dir = nfs_opendir(nfs, file->path);
+		file->data = dir;
+	}
+	else
+	{
+		nfs_file *fp;
+		nfs_fh3 *handle;
+
+		/* create file */
+		if (file->flags & DFS_O_CREAT)
+		{
+			if (nfs_create(nfs, file->path, 555) < 0) return -1;
+		}
+
+		/* open file (get file handle ) */
+		fp=rt_malloc(sizeof(nfs_file));
+		if(fp == RT_NULL)
+			return -1;
+
+		handle = get_handle(nfs, file->path);
+		if(handle == RT_NULL)
+		{
+			rt_free(fp);
+			return -1;
+		}
+
+		/* get size of file */
+		fp->size = nfs_get_filesize(nfs, handle);
+		fp->offset=0;
+
+		copy_handle(&fp->handle, handle);
+		xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+
+		if (file->flags & DFS_O_APPEND)
+		{
+			fp->offset = fp->size;
+		}
+
+		/* set private file */
+		file->data = fp;
+	}
+
+	return 0;
+}
+
+int nfs_stat(struct dfs_filesystem* fs, const char *path, struct dfs_stat *st)
+{
+	GETATTR3args args;
+	GETATTR3res res;
+	fattr3 *info;
+	nfs_fh3 *handle;
+	struct nfs_filesystem* nfs;
+
+	RT_ASSERT(fs != RT_NULL);
+	RT_ASSERT(fs->data != RT_NULL);
+	nfs = (struct nfs_filesystem *)fs->data;
+
+	handle = get_handle(nfs, path);
+	if(handle == RT_NULL)
+		return -1;
+
+	args.object = *handle;
+
+	memset(&res, '\0', sizeof(res));
+
+	if (nfsproc3_getattr_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("GetAttr failed\n");
+		return -1;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Getattr failed: %d\n", res.status);
+		return -1;
+	}
+
+	info=&res.GETATTR3res_u.resok.obj_attributes;
+
+	st->st_dev   = 0;
+
+	st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
+	DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
+	if (info->type == NFS3DIR)
+	{
+		st->st_mode &= ~DFS_S_IFREG;
+		st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
+	}
+
+	st->st_size  = info->size;
+	st->st_mtime = info->mtime.seconds;
+	st->st_blksize = 512;
+
+	xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res);
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+
+	return 0;
+}
+
+nfs_dir *nfs_opendir(struct nfs_filesystem* nfs, const char *path)
+{
+	nfs_dir *dir;
+	nfs_fh3 *handle;
+
+	dir=rt_malloc(sizeof(nfs_dir));
+	if(dir==RT_NULL)
+	{
+		return RT_NULL;
+	}
+
+	handle = get_handle(nfs, path);
+	if(handle == RT_NULL)
+	{
+		rt_free(dir);
+		return RT_NULL;
+	}
+
+	copy_handle(&dir->handle, handle);
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+
+	dir->cookie=0;
+	memset(&dir->cookieverf, '\0', sizeof(cookieverf3));
+	dir->entry=RT_NULL;
+	dir->eof=FALSE;
+	memset(&dir->res, '\0', sizeof(dir->res));
+
+	return dir;
+}
+
+char *nfs_readdir(struct nfs_filesystem* nfs, nfs_dir *dir)
+{
+	static char name[NAME_MAX];
+
+	if(nfs->nfs_client==RT_NULL || dir == RT_NULL)
+		return RT_NULL;
+
+	if(dir->entry==RT_NULL)
+	{
+		READDIR3args args;
+
+		xdr_free((xdrproc_t)xdr_READDIR3res, (char *)&dir->res);
+		memset(&dir->res, '\0', sizeof(dir->res));
+
+		args.dir=dir->handle;
+		args.cookie=dir->cookie;
+		memcpy(&args.cookieverf, &dir->cookieverf, sizeof(cookieverf3));
+		args.count=1024;
+
+		if(nfsproc3_readdir_3(args, &dir->res, nfs->nfs_client)!=RPC_SUCCESS)
+		{
+			rt_kprintf("Readdir failed\n");
+			return RT_NULL;
+		}
+		else if(dir->res.status!=NFS3_OK)
+		{
+			rt_kprintf("Readdir failed: %d\n", dir->res.status);
+			return RT_NULL;
+		}
+
+		memcpy(&dir->cookieverf, &dir->res.READDIR3res_u.resok.cookieverf, sizeof(cookieverf3));
+		dir->eof=dir->res.READDIR3res_u.resok.reply.eof;
+		dir->entry=dir->res.READDIR3res_u.resok.reply.entries;
+	}
+	if(dir->eof==TRUE && dir->entry==RT_NULL)
+		return RT_NULL;
+
+	dir->cookie=dir->entry->cookie;
+	strncpy(name, dir->entry->name, NAME_MAX-1);
+	dir->entry=dir->entry->nextentry;
+	name[NAME_MAX - 1]='\0';
+	return name;
+}
+
+int nfs_unlink(struct dfs_filesystem* fs, const char* path)
+{
+	REMOVE3args args;
+	REMOVE3res res;
+	int ret=0;
+	nfs_fh3 *handle;
+	struct nfs_filesystem* nfs;
+
+	RT_ASSERT(fs != RT_NULL);
+	RT_ASSERT(fs->data != RT_NULL);
+	nfs = (struct nfs_filesystem *)fs->data;
+
+	if(nfs->nfs_client==RT_NULL)
+		return -1;
+
+	handle = get_dir_handle(nfs, path);
+	if(handle == RT_NULL)
+		return -1;
+
+	args.object.dir=*handle;
+	args.object.name=strrchr(path, '/');
+	if(args.object.name==RT_NULL)
+	{
+		args.object.name=(char *)path;
+	}
+
+	memset(&res, 0, sizeof(res));
+
+	if(nfsproc3_remove_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("Remove failed\n");
+		ret=-1;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Remove failed: %d\n", res.status);
+		ret=-1;
+	}
+	xdr_free((xdrproc_t)xdr_REMOVE3res, (char *)&res);
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+	return ret;
+}
+
+int nfs_rmdir(struct nfs_filesystem* nfs, const char *name)
+{
+	RMDIR3args args;
+	RMDIR3res res;
+	int ret=0;
+	nfs_fh3 *handle;
+
+	if(nfs->nfs_client==RT_NULL)
+		return -1;
+
+	handle=get_dir_handle(nfs, name);
+	if(handle==RT_NULL)
+		return -1;
+
+	args.object.dir=*handle;
+	args.object.name=strrchr(name, '/');
+	if(args.object.name==RT_NULL)
+	{
+		args.object.name=(char *)name;
+	}
+
+	memset(&res, 0, sizeof(res));
+
+	if(nfsproc3_rmdir_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("Rmdir failed\n");
+		ret = -1;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Rmdir failed: %d\n", res.status);
+		ret = -1;
+	}
+	xdr_free((xdrproc_t)xdr_RMDIR3res, (char *)&res);
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
+	return ret;
+}
+
+int nfs_rename(struct dfs_filesystem* fs, const char *src, const char *dest)
+{
+	RENAME3args args;
+	RENAME3res res;
+	nfs_fh3 *sHandle;
+	nfs_fh3 *dHandle;
+	int ret=0;
+	struct nfs_filesystem* nfs;
+
+	RT_ASSERT(fs != RT_NULL);
+	RT_ASSERT(fs->data != RT_NULL);
+	nfs = (struct nfs_filesystem *)fs->data;
+
+	if(nfs->nfs_client==RT_NULL)
+		return -1;
+
+	sHandle=get_dir_handle(nfs, src);
+	if(sHandle==RT_NULL)
+		return -1;
+
+	dHandle=get_dir_handle(nfs, dest);
+	if(dHandle==RT_NULL)
+		return -1;
+
+	args.from.dir=*sHandle;
+	args.from.name=strrchr(src, '/');
+	if(args.from.name==RT_NULL)
+		args.from.name=(char *)src;
+
+	args.to.dir=*dHandle;
+	args.to.name=strrchr(src, '/');
+	if(args.to.name==RT_NULL)
+		args.to.name=(char *)dest;
+
+	memset(&res, '\0', sizeof(res));
+
+	if(nfsproc3_rename_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
+	{
+		rt_kprintf("Rename failed\n");
+		ret = -1;
+	}
+	else if(res.status!=NFS3_OK)
+	{
+		rt_kprintf("Rename failed: %d\n", res.status);
+		ret = -1;
+	}
+
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)sHandle);
+	xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)dHandle);
+	xdr_free((xdrproc_t)xdr_RENAME3res, (char *)&res);
+	return ret;
+}
+
+int nfs_getdents(struct dfs_fd* file, struct dfs_dirent* dirp, rt_uint32_t count)
+{
+	return 0;
+}
+
+static struct dfs_filesystem_operation _nfs;
+int nfs_init(void)
+{
+	rt_strncpy(_nfs.name, "nfs", DFS_FS_NAME_MAX);
+
+	_nfs.mount 		= nfs_mount;
+	_nfs.unmount	= nfs_unmount;
+	_nfs.open		= nfs_open;
+	_nfs.close 		= nfs_close;
+	_nfs.ioctl 		= nfs_ioctl;
+	_nfs.read		= nfs_read;
+	_nfs.write 		= nfs_write;
+	_nfs.lseek 		= nfs_lseek;
+	_nfs.getdents	= nfs_getdents;
+	_nfs.unlink 	= nfs_unlink;
+	_nfs.stat		= nfs_stat;
+	_nfs.rename 	= nfs_rename;
+
+	/* register fatfs file system */
+	dfs_register(&_nfs);
+
+	return RT_EOK;
+}
+
+#include <finsh.h>
+void nfs_test(char* host)
+{
+	dfs_mount(RT_NULL, "/nfs", "nfs", 0, (void*)host);
+}
+FINSH_FUNCTION_EXPORT(nfs_test, test nfs mount);
+
+#endif

+ 6 - 0
components/dfs/filesystems/nfs/dfs_nfs.h

@@ -0,0 +1,6 @@
+#ifndef __NFS_H__
+#define __NFS_H__
+
+int nfs_init(void);
+
+#endif

+ 123 - 0
components/dfs/filesystems/nfs/mount.h

@@ -0,0 +1,123 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _MOUNT_H_RPCGEN
+#define	_MOUNT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This file is copied from RFC1813
+ * Copyright 1995 Sun Micrososystems (I assume)
+ */
+#define	MNTPATHLEN 1024
+#define	MNTNAMLEN 255
+#define	FHSIZE3 64
+
+typedef struct {
+	u_int fhandle3_len;
+	char *fhandle3_val;
+} fhandle3;
+
+typedef char *dirpath;
+
+typedef char *name;
+
+typedef struct exportnode *exports;
+
+typedef struct groupnode *groups;
+
+typedef struct mountbody *mountlist;
+
+enum mountstat3 {
+	MNT3_OK = 0,
+	MNT3ERR_PERM = 1,
+	MNT3ERR_NOENT = 2,
+	MNT3ERR_IO = 5,
+	MNT3ERR_ACCES = 13,
+	MNT3ERR_NOTDIR = 20,
+	MNT3ERR_INVAL = 22,
+	MNT3ERR_NAMETOOLONG = 63,
+	MNT3ERR_NOTSUPP = 10004,
+	MNT3ERR_SERVERFAULT = 10006
+};
+typedef enum mountstat3 mountstat3;
+
+struct mountres3_ok {
+	fhandle3 fhandle;
+	struct {
+		u_int auth_flavors_len;
+		int *auth_flavors_val;
+	} auth_flavors;
+};
+typedef struct mountres3_ok mountres3_ok;
+
+struct mountres3 {
+	mountstat3 fhs_status;
+	union {
+		mountres3_ok mountinfo;
+	} mountres3_u;
+};
+typedef struct mountres3 mountres3;
+
+struct mountbody {
+	name ml_hostname;
+	dirpath ml_directory;
+	mountlist ml_next;
+};
+typedef struct mountbody mountbody;
+
+struct groupnode {
+	name gr_name;
+	groups gr_next;
+};
+typedef struct groupnode groupnode;
+
+struct exportnode {
+	dirpath ex_dir;
+	groups ex_groups;
+	exports ex_next;
+};
+typedef struct exportnode exportnode;
+
+#define	MOUNT_PROGRAM	100005
+#define	MOUNT_V3	3
+
+#define	MOUNTPROC3_NULL	0
+extern  enum clnt_stat mountproc3_null_3(void *, CLIENT *);
+#define	MOUNTPROC3_MNT	1
+extern  enum clnt_stat mountproc3_mnt_3(dirpath , mountres3 *, CLIENT *);
+#define	MOUNTPROC3_DUMP	2
+extern  enum clnt_stat mountproc3_dump_3(mountlist *, CLIENT *);
+#define	MOUNTPROC3_UMNT	3
+extern  enum clnt_stat mountproc3_umnt_3(dirpath , void *, CLIENT *);
+#define	MOUNTPROC3_UMNTALL	4
+extern  enum clnt_stat mountproc3_umntall_3(void *, CLIENT *);
+#define	MOUNTPROC3_EXPORT	5
+extern  enum clnt_stat mountproc3_export_3(exports *, CLIENT *);
+
+/* the xdr functions */
+
+extern  bool_t xdr_fhandle3(XDR *, fhandle3*);
+extern  bool_t xdr_dirpath(XDR *, dirpath*);
+extern  bool_t xdr_name(XDR *, name*);
+extern  bool_t xdr_exports(XDR *, exports*);
+extern  bool_t xdr_groups(XDR *, groups*);
+extern  bool_t xdr_mountlist(XDR *, mountlist*);
+extern  bool_t xdr_mountstat3(XDR *, mountstat3*);
+extern  bool_t xdr_mountres3_ok(XDR *, mountres3_ok*);
+extern  bool_t xdr_mountres3(XDR *, mountres3*);
+extern  bool_t xdr_mountbody(XDR *, mountbody*);
+extern  bool_t xdr_groupnode(XDR *, groupnode*);
+extern  bool_t xdr_exportnode(XDR *, exportnode*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_MOUNT_H_RPCGEN */

+ 68 - 0
components/dfs/filesystems/nfs/mount.x

@@ -0,0 +1,68 @@
+%/* This file is copied from RFC1813
+% * Copyright 1995 Sun Micrososystems (I assume)
+% */
+
+const MNTPATHLEN = 1024;  /* Maximum bytes in a path name */
+const MNTNAMLEN = 255;   /* Maximum bytes in a name */
+const FHSIZE3 = 64;    /* Maximum bytes in a V3 file handle */
+
+typedef opaque fhandle3<FHSIZE3>;
+typedef string dirpath<MNTPATHLEN>;
+typedef string name<MNTNAMLEN>;
+
+typedef struct exportnode *exports;
+typedef struct groupnode *groups;
+typedef struct mountbody *mountlist;
+
+enum mountstat3 {
+	MNT3_OK = 0,                 /* no error */
+	MNT3ERR_PERM = 1,            /* Not owner */
+	MNT3ERR_NOENT = 2,           /* No such file or directory */
+	MNT3ERR_IO = 5,              /* I/O error */
+	MNT3ERR_ACCES = 13,          /* Permission denied */
+	MNT3ERR_NOTDIR = 20,         /* Not a directory */
+	MNT3ERR_INVAL = 22,          /* Invalid argument */
+	MNT3ERR_NAMETOOLONG = 63,    /* Filename too long */
+	MNT3ERR_NOTSUPP = 10004,     /* Operation not supported */
+	MNT3ERR_SERVERFAULT = 10006  /* A failure on the server */
+};
+
+struct mountres3_ok {
+	fhandle3 fhandle;
+	int auth_flavors<>;
+};
+
+union mountres3 switch (mountstat3 fhs_status) {
+case MNT3_OK:
+	mountres3_ok  mountinfo;
+default:
+	void;
+};
+
+struct mountbody {
+	name ml_hostname;
+	dirpath ml_directory;
+	mountlist ml_next;
+};
+
+struct groupnode {
+	name gr_name;
+	groups gr_next;
+};
+
+struct exportnode {
+	dirpath ex_dir;
+	groups ex_groups;
+ 	exports ex_next;
+};
+
+program MOUNT_PROGRAM {
+	version MOUNT_V3 {
+		void MOUNTPROC3_NULL(void) = 0;
+		mountres3 MOUNTPROC3_MNT(dirpath) = 1;
+		mountlist MOUNTPROC3_DUMP(void) = 2;
+		void MOUNTPROC3_UMNT(dirpath) = 3;
+		void MOUNTPROC3_UMNTALL(void) = 4;
+		exports MOUNTPROC3_EXPORT(void)  = 5;
+	} = 3;
+} = 100005;

+ 70 - 0
components/dfs/filesystems/nfs/mount_clnt.c

@@ -0,0 +1,70 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include <string.h> /* for memset */
+#include "mount.h"
+
+/* This file is copied from RFC1813
+ * Copyright 1995 Sun Micrososystems (I assume)
+ */
+
+typedef char* caddr_t;
+
+/* Default timeout can be changed using clnt_control() */
+static struct timeval TIMEOUT = { 25, 0 };
+
+enum clnt_stat 
+mountproc3_null_3(void *clnt_res, CLIENT *clnt)
+{
+	 return (clnt_call(clnt, MOUNTPROC3_NULL,
+		(xdrproc_t) xdr_void, (caddr_t) NULL,
+		(xdrproc_t) xdr_void, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+mountproc3_mnt_3(dirpath arg1, mountres3 *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, MOUNTPROC3_MNT,
+		(xdrproc_t) xdr_dirpath, (caddr_t) &arg1,
+		(xdrproc_t) xdr_mountres3, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+mountproc3_dump_3(mountlist *clnt_res, CLIENT *clnt)
+{
+	 return (clnt_call(clnt, MOUNTPROC3_DUMP,
+		(xdrproc_t) xdr_void, (caddr_t) NULL,
+		(xdrproc_t) xdr_mountlist, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+mountproc3_umnt_3(dirpath arg1, void *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, MOUNTPROC3_UMNT,
+		(xdrproc_t) xdr_dirpath, (caddr_t) &arg1,
+		(xdrproc_t) xdr_void, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+mountproc3_umntall_3(void *clnt_res, CLIENT *clnt)
+{
+	 return (clnt_call(clnt, MOUNTPROC3_UMNTALL,
+		(xdrproc_t) xdr_void, (caddr_t) NULL,
+		(xdrproc_t) xdr_void, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+mountproc3_export_3(exports *clnt_res, CLIENT *clnt)
+{
+	 return (clnt_call(clnt, MOUNTPROC3_EXPORT,
+		(xdrproc_t) xdr_void, (caddr_t) NULL,
+		(xdrproc_t) xdr_exports, (caddr_t) clnt_res,
+		TIMEOUT));
+}

+ 216 - 0
components/dfs/filesystems/nfs/mount_xdr.c

@@ -0,0 +1,216 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "mount.h"
+/* This file is copied from RFC1813
+ * Copyright 1995 Sun Micrososystems (I assume)
+ */
+
+bool_t
+xdr_fhandle3(register XDR *xdrs, fhandle3 *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_bytes(xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_dirpath(register XDR *xdrs, dirpath *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_string(xdrs, objp, MNTPATHLEN))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_name(register XDR *xdrs, name *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_string(xdrs, objp, MNTNAMLEN))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_exports(register XDR *xdrs, exports *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_groups(register XDR *xdrs, groups *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_mountlist(register XDR *xdrs, mountlist *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_mountstat3(register XDR *xdrs, mountstat3 *objp)
+{
+	int enum_objp;
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	enum_objp = *objp;
+
+	if (!xdr_enum(xdrs, (enum_t *)&enum_objp))
+	{
+		*objp = enum_objp;
+		return (FALSE);
+	}
+
+	*objp = enum_objp;
+	return (TRUE);
+}
+
+bool_t
+xdr_mountres3_ok(register XDR *xdrs, mountres3_ok *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_fhandle3(xdrs, &objp->fhandle))
+		return (FALSE);
+	if (!xdr_array(xdrs, (char **)&objp->auth_flavors.auth_flavors_val, (u_int *) &objp->auth_flavors.auth_flavors_len, ~0,
+		sizeof (int), (xdrproc_t) xdr_int))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_mountres3(register XDR *xdrs, mountres3 *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_mountstat3(xdrs, &objp->fhs_status))
+		return (FALSE);
+	switch (objp->fhs_status) {
+	case MNT3_OK:
+		if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_mountbody(register XDR *xdrs, mountbody *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_name(xdrs, &objp->ml_hostname))
+		return (FALSE);
+	if (!xdr_dirpath(xdrs, &objp->ml_directory))
+		return (FALSE);
+	if (!xdr_mountlist(xdrs, &objp->ml_next))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_groupnode(register XDR *xdrs, groupnode *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_name(xdrs, &objp->gr_name))
+		return (FALSE);
+	if (!xdr_groups(xdrs, &objp->gr_next))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_exportnode(register XDR *xdrs, exportnode *objp)
+{
+
+#if defined(_LP64) || defined(_KERNEL)
+	register int *buf;
+#else
+	register long *buf;
+#endif
+
+	if (!xdr_dirpath(xdrs, &objp->ex_dir))
+		return (FALSE);
+	if (!xdr_groups(xdrs, &objp->ex_groups))
+		return (FALSE);
+	if (!xdr_exports(xdrs, &objp->ex_next))
+		return (FALSE);
+	return (TRUE);
+}

+ 1102 - 0
components/dfs/filesystems/nfs/nfs.h

@@ -0,0 +1,1102 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NFS_H_RPCGEN
+#define	_NFS_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This file is copied from RFC1813
+ * Copyright 1995 Sun Micrososystems (I assume)
+ */
+#define	NFS3_FHSIZE 64
+#define	NFS3_COOKIEVERFSIZE 8
+#define	NFS3_CREATEVERFSIZE 8
+#define	NFS3_WRITEVERFSIZE 8
+#define	ACCESS3_READ 0x0001
+#define	ACCESS3_LOOKUP 0x0002
+#define	ACCESS3_MODIFY 0x0004
+#define	ACCESS3_EXTEND 0x0008
+#define	ACCESS3_DELETE 0x0010
+#define	ACCESS3_EXECUTE 0x0020
+#define	FSF3_LINK 0x0001
+#define	FSF3_SYMLINK 0x0002
+#define	FSF3_HOMOGENEOUS 0x0008
+#define	FSF3_CANSETTIME 0x0010
+
+typedef unsigned long long uint64;
+
+typedef long long int64;
+
+typedef u_long uint32;
+
+typedef long int32;
+
+typedef char *filename3;
+
+typedef char *nfspath3;
+
+typedef uint64 fileid3;
+
+typedef uint64 cookie3;
+
+typedef char cookieverf3[NFS3_COOKIEVERFSIZE];
+
+typedef char createverf3[NFS3_CREATEVERFSIZE];
+
+typedef char writeverf3[NFS3_WRITEVERFSIZE];
+
+typedef uint32 uid3;
+
+typedef uint32 gid3;
+
+typedef uint64 size3;
+
+typedef uint64 offset3;
+
+typedef uint32 mode3;
+
+typedef uint32 count3;
+
+enum nfsstat3 {
+	NFS3_OK = 0,
+	NFS3ERR_PERM = 1,
+	NFS3ERR_NOENT = 2,
+	NFS3ERR_IO = 5,
+	NFS3ERR_NXIO = 6,
+	NFS3ERR_ACCES = 13,
+	NFS3ERR_EXIST = 17,
+	NFS3ERR_XDEV = 18,
+	NFS3ERR_NODEV = 19,
+	NFS3ERR_NOTDIR = 20,
+	NFS3ERR_ISDIR = 21,
+	NFS3ERR_INVAL = 22,
+	NFS3ERR_FBIG = 27,
+	NFS3ERR_NOSPC = 28,
+	NFS3ERR_ROFS = 30,
+	NFS3ERR_MLINK = 31,
+	NFS3ERR_NAMETOOLONG = 63,
+	NFS3ERR_NOTEMPTY = 66,
+	NFS3ERR_DQUOT = 69,
+	NFS3ERR_STALE = 70,
+	NFS3ERR_REMOTE = 71,
+	NFS3ERR_BADHANDLE = 10001,
+	NFS3ERR_NOT_SYNC = 10002,
+	NFS3ERR_BAD_COOKIE = 10003,
+	NFS3ERR_NOTSUPP = 10004,
+	NFS3ERR_TOOSMALL = 10005,
+	NFS3ERR_SERVERFAULT = 10006,
+	NFS3ERR_BADTYPE = 10007,
+	NFS3ERR_JUKEBOX = 10008
+};
+typedef enum nfsstat3 nfsstat3;
+
+enum ftype3 {
+	NFS3REG = 1,
+	NFS3DIR = 2,
+	NFS3BLK = 3,
+	NFS3CHR = 4,
+	NFS3LNK = 5,
+	NFS3SOCK = 6,
+	NFS3FIFO = 7
+};
+typedef enum ftype3 ftype3;
+
+enum stable_how {
+	UNSTABLE = 0,
+	DATA_SYNC = 1,
+	FILE_SYNC = 2
+};
+typedef enum stable_how stable_how;
+
+enum createmode3 {
+	UNCHECKED = 0,
+	GUARDED = 1,
+	EXCLUSIVE = 2
+};
+typedef enum createmode3 createmode3;
+
+struct specdata3 {
+	uint32 specdata1;
+	uint32 specdata2;
+};
+typedef struct specdata3 specdata3;
+
+struct nfs_fh3 {
+	struct {
+		u_int data_len;
+		char *data_val;
+	} data;
+};
+typedef struct nfs_fh3 nfs_fh3;
+
+struct nfstime3 {
+	uint32 seconds;
+	uint32 nseconds;
+};
+typedef struct nfstime3 nfstime3;
+
+struct fattr3 {
+	ftype3 type;
+	mode3 mode;
+	uint32 nlink;
+	uid3 uid;
+	gid3 gid;
+	size3 size;
+	size3 used;
+	specdata3 rdev;
+	uint64 fsid;
+	fileid3 fileid;
+	nfstime3 atime;
+	nfstime3 mtime;
+	nfstime3 ctime;
+};
+typedef struct fattr3 fattr3;
+
+struct post_op_attr {
+	bool_t attributes_follow;
+	union {
+		fattr3 attributes;
+	} post_op_attr_u;
+};
+typedef struct post_op_attr post_op_attr;
+
+struct wcc_attr {
+	size3 size;
+	nfstime3 mtime;
+	nfstime3 ctime;
+};
+typedef struct wcc_attr wcc_attr;
+
+struct pre_op_attr {
+	bool_t attributes_follow;
+	union {
+		wcc_attr attributes;
+	} pre_op_attr_u;
+};
+typedef struct pre_op_attr pre_op_attr;
+
+struct wcc_data {
+	pre_op_attr before;
+	post_op_attr after;
+};
+typedef struct wcc_data wcc_data;
+
+struct post_op_fh3 {
+	bool_t handle_follows;
+	union {
+		nfs_fh3 handle;
+	} post_op_fh3_u;
+};
+typedef struct post_op_fh3 post_op_fh3;
+
+enum time_how {
+	DONT_CHANGE = 0,
+	SET_TO_SERVER_TIME = 1,
+	SET_TO_CLIENT_TIME = 2
+};
+typedef enum time_how time_how;
+
+struct set_mode3 {
+	bool_t set_it;
+	union {
+		mode3 mode;
+	} set_mode3_u;
+};
+typedef struct set_mode3 set_mode3;
+
+struct set_uid3 {
+	bool_t set_it;
+	union {
+		uid3 uid;
+	} set_uid3_u;
+};
+typedef struct set_uid3 set_uid3;
+
+struct set_gid3 {
+	bool_t set_it;
+	union {
+		gid3 gid;
+	} set_gid3_u;
+};
+typedef struct set_gid3 set_gid3;
+
+struct set_size3 {
+	bool_t set_it;
+	union {
+		size3 size;
+	} set_size3_u;
+};
+typedef struct set_size3 set_size3;
+
+struct set_atime {
+	time_how set_it;
+	union {
+		nfstime3 atime;
+	} set_atime_u;
+};
+typedef struct set_atime set_atime;
+
+struct set_mtime {
+	time_how set_it;
+	union {
+		nfstime3 mtime;
+	} set_mtime_u;
+};
+typedef struct set_mtime set_mtime;
+
+struct sattr3 {
+	set_mode3 mode;
+	set_uid3 uid;
+	set_gid3 gid;
+	set_size3 size;
+	set_atime atime;
+	set_mtime mtime;
+};
+typedef struct sattr3 sattr3;
+
+struct diropargs3 {
+	nfs_fh3 dir;
+	filename3 name;
+};
+typedef struct diropargs3 diropargs3;
+
+struct GETATTR3args {
+	nfs_fh3 object;
+};
+typedef struct GETATTR3args GETATTR3args;
+
+struct GETATTR3resok {
+	fattr3 obj_attributes;
+};
+typedef struct GETATTR3resok GETATTR3resok;
+
+struct GETATTR3res {
+	nfsstat3 status;
+	union {
+		GETATTR3resok resok;
+	} GETATTR3res_u;
+};
+typedef struct GETATTR3res GETATTR3res;
+
+struct sattrguard3 {
+	bool_t check;
+	union {
+		nfstime3 obj_ctime;
+	} sattrguard3_u;
+};
+typedef struct sattrguard3 sattrguard3;
+
+struct SETATTR3args {
+	nfs_fh3 object;
+	sattr3 new_attributes;
+	sattrguard3 guard;
+};
+typedef struct SETATTR3args SETATTR3args;
+
+struct SETATTR3resok {
+	wcc_data obj_wcc;
+};
+typedef struct SETATTR3resok SETATTR3resok;
+
+struct SETATTR3resfail {
+	wcc_data obj_wcc;
+};
+typedef struct SETATTR3resfail SETATTR3resfail;
+
+struct SETATTR3res {
+	nfsstat3 status;
+	union {
+		SETATTR3resok resok;
+		SETATTR3resfail resfail;
+	} SETATTR3res_u;
+};
+typedef struct SETATTR3res SETATTR3res;
+
+struct LOOKUP3args {
+	diropargs3 what;
+};
+typedef struct LOOKUP3args LOOKUP3args;
+
+struct LOOKUP3resok {
+	nfs_fh3 object;
+	post_op_attr obj_attributes;
+	post_op_attr dir_attributes;
+};
+typedef struct LOOKUP3resok LOOKUP3resok;
+
+struct LOOKUP3resfail {
+	post_op_attr dir_attributes;
+};
+typedef struct LOOKUP3resfail LOOKUP3resfail;
+
+struct LOOKUP3res {
+	nfsstat3 status;
+	union {
+		LOOKUP3resok resok;
+		LOOKUP3resfail resfail;
+	} LOOKUP3res_u;
+};
+typedef struct LOOKUP3res LOOKUP3res;
+
+struct ACCESS3args {
+	nfs_fh3 object;
+	uint32 access;
+};
+typedef struct ACCESS3args ACCESS3args;
+
+struct ACCESS3resok {
+	post_op_attr obj_attributes;
+	uint32 access;
+};
+typedef struct ACCESS3resok ACCESS3resok;
+
+struct ACCESS3resfail {
+	post_op_attr obj_attributes;
+};
+typedef struct ACCESS3resfail ACCESS3resfail;
+
+struct ACCESS3res {
+	nfsstat3 status;
+	union {
+		ACCESS3resok resok;
+		ACCESS3resfail resfail;
+	} ACCESS3res_u;
+};
+typedef struct ACCESS3res ACCESS3res;
+
+struct READLINK3args {
+	nfs_fh3 symlink;
+};
+typedef struct READLINK3args READLINK3args;
+
+struct READLINK3resok {
+	post_op_attr symlink_attributes;
+	nfspath3 data;
+};
+typedef struct READLINK3resok READLINK3resok;
+
+struct READLINK3resfail {
+	post_op_attr symlink_attributes;
+};
+typedef struct READLINK3resfail READLINK3resfail;
+
+struct READLINK3res {
+	nfsstat3 status;
+	union {
+		READLINK3resok resok;
+		READLINK3resfail resfail;
+	} READLINK3res_u;
+};
+typedef struct READLINK3res READLINK3res;
+
+struct READ3args {
+	nfs_fh3 file;
+	offset3 offset;
+	count3 count;
+};
+typedef struct READ3args READ3args;
+
+struct READ3resok {
+	post_op_attr file_attributes;
+	count3 count;
+	bool_t eof;
+	struct {
+		u_int data_len;
+		char *data_val;
+	} data;
+};
+typedef struct READ3resok READ3resok;
+
+struct READ3resfail {
+	post_op_attr file_attributes;
+};
+typedef struct READ3resfail READ3resfail;
+
+struct READ3res {
+	nfsstat3 status;
+	union {
+		READ3resok resok;
+		READ3resfail resfail;
+	} READ3res_u;
+};
+typedef struct READ3res READ3res;
+
+struct WRITE3args {
+	nfs_fh3 file;
+	offset3 offset;
+	count3 count;
+	stable_how stable;
+	struct {
+		u_int data_len;
+		char *data_val;
+	} data;
+};
+typedef struct WRITE3args WRITE3args;
+
+struct WRITE3resok {
+	wcc_data file_wcc;
+	count3 count;
+	stable_how committed;
+	writeverf3 verf;
+};
+typedef struct WRITE3resok WRITE3resok;
+
+struct WRITE3resfail {
+	wcc_data file_wcc;
+};
+typedef struct WRITE3resfail WRITE3resfail;
+
+struct WRITE3res {
+	nfsstat3 status;
+	union {
+		WRITE3resok resok;
+		WRITE3resfail resfail;
+	} WRITE3res_u;
+};
+typedef struct WRITE3res WRITE3res;
+
+struct createhow3 {
+	createmode3 mode;
+	union {
+		sattr3 obj_attributes;
+		createverf3 verf;
+	} createhow3_u;
+};
+typedef struct createhow3 createhow3;
+
+struct CREATE3args {
+	diropargs3 where;
+	createhow3 how;
+};
+typedef struct CREATE3args CREATE3args;
+
+struct CREATE3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+typedef struct CREATE3resok CREATE3resok;
+
+struct CREATE3resfail {
+	wcc_data dir_wcc;
+};
+typedef struct CREATE3resfail CREATE3resfail;
+
+struct CREATE3res {
+	nfsstat3 status;
+	union {
+		CREATE3resok resok;
+		CREATE3resfail resfail;
+	} CREATE3res_u;
+};
+typedef struct CREATE3res CREATE3res;
+
+struct MKDIR3args {
+	diropargs3 where;
+	sattr3 attributes;
+};
+typedef struct MKDIR3args MKDIR3args;
+
+struct MKDIR3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+typedef struct MKDIR3resok MKDIR3resok;
+
+struct MKDIR3resfail {
+	wcc_data dir_wcc;
+};
+typedef struct MKDIR3resfail MKDIR3resfail;
+
+struct MKDIR3res {
+	nfsstat3 status;
+	union {
+		MKDIR3resok resok;
+		MKDIR3resfail resfail;
+	} MKDIR3res_u;
+};
+typedef struct MKDIR3res MKDIR3res;
+
+struct symlinkdata3 {
+	sattr3 symlink_attributes;
+	nfspath3 symlink_data;
+};
+typedef struct symlinkdata3 symlinkdata3;
+
+struct SYMLINK3args {
+	diropargs3 where;
+	symlinkdata3 symlink;
+};
+typedef struct SYMLINK3args SYMLINK3args;
+
+struct SYMLINK3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+typedef struct SYMLINK3resok SYMLINK3resok;
+
+struct SYMLINK3resfail {
+	wcc_data dir_wcc;
+};
+typedef struct SYMLINK3resfail SYMLINK3resfail;
+
+struct SYMLINK3res {
+	nfsstat3 status;
+	union {
+		SYMLINK3resok resok;
+		SYMLINK3resfail resfail;
+	} SYMLINK3res_u;
+};
+typedef struct SYMLINK3res SYMLINK3res;
+
+struct devicedata3 {
+	sattr3 dev_attributes;
+	specdata3 spec;
+};
+typedef struct devicedata3 devicedata3;
+
+struct mknoddata3 {
+	ftype3 type;
+	union {
+		devicedata3 device;
+		sattr3 pipe_attributes;
+	} mknoddata3_u;
+};
+typedef struct mknoddata3 mknoddata3;
+
+struct MKNOD3args {
+	diropargs3 where;
+	mknoddata3 what;
+};
+typedef struct MKNOD3args MKNOD3args;
+
+struct MKNOD3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+typedef struct MKNOD3resok MKNOD3resok;
+
+struct MKNOD3resfail {
+	wcc_data dir_wcc;
+};
+typedef struct MKNOD3resfail MKNOD3resfail;
+
+struct MKNOD3res {
+	nfsstat3 status;
+	union {
+		MKNOD3resok resok;
+		MKNOD3resfail resfail;
+	} MKNOD3res_u;
+};
+typedef struct MKNOD3res MKNOD3res;
+
+struct REMOVE3args {
+	diropargs3 object;
+};
+typedef struct REMOVE3args REMOVE3args;
+
+struct REMOVE3resok {
+	wcc_data dir_wcc;
+};
+typedef struct REMOVE3resok REMOVE3resok;
+
+struct REMOVE3resfail {
+	wcc_data dir_wcc;
+};
+typedef struct REMOVE3resfail REMOVE3resfail;
+
+struct REMOVE3res {
+	nfsstat3 status;
+	union {
+		REMOVE3resok resok;
+		REMOVE3resfail resfail;
+	} REMOVE3res_u;
+};
+typedef struct REMOVE3res REMOVE3res;
+
+struct RMDIR3args {
+	diropargs3 object;
+};
+typedef struct RMDIR3args RMDIR3args;
+
+struct RMDIR3resok {
+	wcc_data dir_wcc;
+};
+typedef struct RMDIR3resok RMDIR3resok;
+
+struct RMDIR3resfail {
+	wcc_data dir_wcc;
+};
+typedef struct RMDIR3resfail RMDIR3resfail;
+
+struct RMDIR3res {
+	nfsstat3 status;
+	union {
+		RMDIR3resok resok;
+		RMDIR3resfail resfail;
+	} RMDIR3res_u;
+};
+typedef struct RMDIR3res RMDIR3res;
+
+struct RENAME3args {
+	diropargs3 from;
+	diropargs3 to;
+};
+typedef struct RENAME3args RENAME3args;
+
+struct RENAME3resok {
+	wcc_data fromdir_wcc;
+	wcc_data todir_wcc;
+};
+typedef struct RENAME3resok RENAME3resok;
+
+struct RENAME3resfail {
+	wcc_data fromdir_wcc;
+	wcc_data todir_wcc;
+};
+typedef struct RENAME3resfail RENAME3resfail;
+
+struct RENAME3res {
+	nfsstat3 status;
+	union {
+		RENAME3resok resok;
+		RENAME3resfail resfail;
+	} RENAME3res_u;
+};
+typedef struct RENAME3res RENAME3res;
+
+struct LINK3args {
+	nfs_fh3 file;
+	diropargs3 link;
+};
+typedef struct LINK3args LINK3args;
+
+struct LINK3resok {
+	post_op_attr file_attributes;
+	wcc_data linkdir_wcc;
+};
+typedef struct LINK3resok LINK3resok;
+
+struct LINK3resfail {
+	post_op_attr file_attributes;
+	wcc_data linkdir_wcc;
+};
+typedef struct LINK3resfail LINK3resfail;
+
+struct LINK3res {
+	nfsstat3 status;
+	union {
+		LINK3resok resok;
+		LINK3resfail resfail;
+	} LINK3res_u;
+};
+typedef struct LINK3res LINK3res;
+
+struct READDIR3args {
+	nfs_fh3 dir;
+	cookie3 cookie;
+	cookieverf3 cookieverf;
+	count3 count;
+};
+typedef struct READDIR3args READDIR3args;
+
+struct entry3 {
+	fileid3 fileid;
+	filename3 name;
+	cookie3 cookie;
+	struct entry3 *nextentry;
+};
+typedef struct entry3 entry3;
+
+struct dirlist3 {
+	entry3 *entries;
+	bool_t eof;
+};
+typedef struct dirlist3 dirlist3;
+
+struct READDIR3resok {
+	post_op_attr dir_attributes;
+	cookieverf3 cookieverf;
+	dirlist3 reply;
+};
+typedef struct READDIR3resok READDIR3resok;
+
+struct READDIR3resfail {
+	post_op_attr dir_attributes;
+};
+typedef struct READDIR3resfail READDIR3resfail;
+
+struct READDIR3res {
+	nfsstat3 status;
+	union {
+		READDIR3resok resok;
+		READDIR3resfail resfail;
+	} READDIR3res_u;
+};
+typedef struct READDIR3res READDIR3res;
+
+struct READDIRPLUS3args {
+	nfs_fh3 dir;
+	cookie3 cookie;
+	cookieverf3 cookieverf;
+	count3 dircount;
+	count3 maxcount;
+};
+typedef struct READDIRPLUS3args READDIRPLUS3args;
+
+struct entryplus3 {
+	fileid3 fileid;
+	filename3 name;
+	cookie3 cookie;
+	post_op_attr name_attributes;
+	post_op_fh3 name_handle;
+	struct entryplus3 *nextentry;
+};
+typedef struct entryplus3 entryplus3;
+
+struct dirlistplus3 {
+	entryplus3 *entries;
+	bool_t eof;
+};
+typedef struct dirlistplus3 dirlistplus3;
+
+struct READDIRPLUS3resok {
+	post_op_attr dir_attributes;
+	cookieverf3 cookieverf;
+	dirlistplus3 reply;
+};
+typedef struct READDIRPLUS3resok READDIRPLUS3resok;
+
+struct READDIRPLUS3resfail {
+	post_op_attr dir_attributes;
+};
+typedef struct READDIRPLUS3resfail READDIRPLUS3resfail;
+
+struct READDIRPLUS3res {
+	nfsstat3 status;
+	union {
+		READDIRPLUS3resok resok;
+		READDIRPLUS3resfail resfail;
+	} READDIRPLUS3res_u;
+};
+typedef struct READDIRPLUS3res READDIRPLUS3res;
+
+struct FSSTAT3args {
+	nfs_fh3 fsroot;
+};
+typedef struct FSSTAT3args FSSTAT3args;
+
+struct FSSTAT3resok {
+	post_op_attr obj_attributes;
+	size3 tbytes;
+	size3 fbytes;
+	size3 abytes;
+	size3 tfiles;
+	size3 ffiles;
+	size3 afiles;
+	uint32 invarsec;
+};
+typedef struct FSSTAT3resok FSSTAT3resok;
+
+struct FSSTAT3resfail {
+	post_op_attr obj_attributes;
+};
+typedef struct FSSTAT3resfail FSSTAT3resfail;
+
+struct FSSTAT3res {
+	nfsstat3 status;
+	union {
+		FSSTAT3resok resok;
+		FSSTAT3resfail resfail;
+	} FSSTAT3res_u;
+};
+typedef struct FSSTAT3res FSSTAT3res;
+
+struct FSINFO3args {
+	nfs_fh3 fsroot;
+};
+typedef struct FSINFO3args FSINFO3args;
+
+struct FSINFO3resok {
+	post_op_attr obj_attributes;
+	uint32 rtmax;
+	uint32 rtpref;
+	uint32 rtmult;
+	uint32 wtmax;
+	uint32 wtpref;
+	uint32 wtmult;
+	uint32 dtpref;
+	size3 maxfilesize;
+	nfstime3 time_delta;
+	uint32 properties;
+};
+typedef struct FSINFO3resok FSINFO3resok;
+
+struct FSINFO3resfail {
+	post_op_attr obj_attributes;
+};
+typedef struct FSINFO3resfail FSINFO3resfail;
+
+struct FSINFO3res {
+	nfsstat3 status;
+	union {
+		FSINFO3resok resok;
+		FSINFO3resfail resfail;
+	} FSINFO3res_u;
+};
+typedef struct FSINFO3res FSINFO3res;
+
+struct PATHCONF3args {
+	nfs_fh3 object;
+};
+typedef struct PATHCONF3args PATHCONF3args;
+
+struct PATHCONF3resok {
+	post_op_attr obj_attributes;
+	uint32 linkmax;
+	uint32 name_max;
+	bool_t no_trunc;
+	bool_t chown_restricted;
+	bool_t case_insensitive;
+	bool_t case_preserving;
+};
+typedef struct PATHCONF3resok PATHCONF3resok;
+
+struct PATHCONF3resfail {
+	post_op_attr obj_attributes;
+};
+typedef struct PATHCONF3resfail PATHCONF3resfail;
+
+struct PATHCONF3res {
+	nfsstat3 status;
+	union {
+		PATHCONF3resok resok;
+		PATHCONF3resfail resfail;
+	} PATHCONF3res_u;
+};
+typedef struct PATHCONF3res PATHCONF3res;
+
+struct COMMIT3args {
+	nfs_fh3 file;
+	offset3 offset;
+	count3 count;
+};
+typedef struct COMMIT3args COMMIT3args;
+
+struct COMMIT3resok {
+	wcc_data file_wcc;
+	writeverf3 verf;
+};
+typedef struct COMMIT3resok COMMIT3resok;
+
+struct COMMIT3resfail {
+	wcc_data file_wcc;
+};
+typedef struct COMMIT3resfail COMMIT3resfail;
+
+struct COMMIT3res {
+	nfsstat3 status;
+	union {
+		COMMIT3resok resok;
+		COMMIT3resfail resfail;
+	} COMMIT3res_u;
+};
+typedef struct COMMIT3res COMMIT3res;
+
+#define	NFS_PROGRAM	100003
+#define	NFS_V3	3
+
+#define	NFSPROC3_NULL	0
+extern  enum clnt_stat nfsproc3_null_3(void *, CLIENT *);
+#define	NFSPROC3_GETATTR	1
+extern  enum clnt_stat nfsproc3_getattr_3(GETATTR3args , GETATTR3res *, CLIENT *);
+#define	NFSPROC3_SETATTR	2
+extern  enum clnt_stat nfsproc3_setattr_3(SETATTR3args , SETATTR3res *, CLIENT *);
+#define	NFSPROC3_LOOKUP	3
+extern  enum clnt_stat nfsproc3_lookup_3(LOOKUP3args , LOOKUP3res *, CLIENT *);
+#define	NFSPROC3_ACCESS	4
+extern  enum clnt_stat nfsproc3_access_3(ACCESS3args , ACCESS3res *, CLIENT *);
+#define	NFSPROC3_READLINK	5
+extern  enum clnt_stat nfsproc3_readlink_3(READLINK3args , READLINK3res *, CLIENT *);
+#define	NFSPROC3_READ	6
+extern  enum clnt_stat nfsproc3_read_3(READ3args , READ3res *, CLIENT *);
+#define	NFSPROC3_WRITE	7
+extern  enum clnt_stat nfsproc3_write_3(WRITE3args , WRITE3res *, CLIENT *);
+#define	NFSPROC3_CREATE	8
+extern  enum clnt_stat nfsproc3_create_3(CREATE3args , CREATE3res *, CLIENT *);
+#define	NFSPROC3_MKDIR	9
+extern  enum clnt_stat nfsproc3_mkdir_3(MKDIR3args , MKDIR3res *, CLIENT *);
+#define	NFSPROC3_SYMLINK	10
+extern  enum clnt_stat nfsproc3_symlink_3(SYMLINK3args , SYMLINK3res *, CLIENT *);
+#define	NFSPROC3_MKNOD	11
+extern  enum clnt_stat nfsproc3_mknod_3(MKNOD3args , MKNOD3res *, CLIENT *);
+#define	NFSPROC3_REMOVE	12
+extern  enum clnt_stat nfsproc3_remove_3(REMOVE3args , REMOVE3res *, CLIENT *);
+#define	NFSPROC3_RMDIR	13
+extern  enum clnt_stat nfsproc3_rmdir_3(RMDIR3args , RMDIR3res *, CLIENT *);
+#define	NFSPROC3_RENAME	14
+extern  enum clnt_stat nfsproc3_rename_3(RENAME3args , RENAME3res *, CLIENT *);
+#define	NFSPROC3_LINK	15
+extern  enum clnt_stat nfsproc3_link_3(LINK3args , LINK3res *, CLIENT *);
+#define	NFSPROC3_READDIR	16
+extern  enum clnt_stat nfsproc3_readdir_3(READDIR3args , READDIR3res *, CLIENT *);
+#define	NFSPROC3_READDIRPLUS	17
+extern  enum clnt_stat nfsproc3_readdirplus_3(READDIRPLUS3args , READDIRPLUS3res *, CLIENT *);
+#define	NFSPROC3_FSSTAT	18
+extern  enum clnt_stat nfsproc3_fsstat_3(FSSTAT3args , FSSTAT3res *, CLIENT *);
+#define	NFSPROC3_FSINFO	19
+extern  enum clnt_stat nfsproc3_fsinfo_3(FSINFO3args , FSINFO3res *, CLIENT *);
+#define	NFSPROC3_PATHCONF	20
+extern  enum clnt_stat nfsproc3_pathconf_3(PATHCONF3args , PATHCONF3res *, CLIENT *);
+#define	NFSPROC3_COMMIT	21
+extern  enum clnt_stat nfsproc3_commit_3(COMMIT3args , COMMIT3res *, CLIENT *);
+
+/* the xdr functions */
+
+extern  bool_t xdr_uint64(XDR *, uint64*);
+extern  bool_t xdr_int64(XDR *, int64*);
+extern  bool_t xdr_uint32(XDR *, uint32*);
+extern  bool_t xdr_int32(XDR *, int32*);
+extern  bool_t xdr_filename3(XDR *, filename3*);
+extern  bool_t xdr_nfspath3(XDR *, nfspath3*);
+extern  bool_t xdr_fileid3(XDR *, fileid3*);
+extern  bool_t xdr_cookie3(XDR *, cookie3*);
+extern  bool_t xdr_cookieverf3(XDR *, cookieverf3);
+extern  bool_t xdr_createverf3(XDR *, createverf3);
+extern  bool_t xdr_writeverf3(XDR *, writeverf3);
+extern  bool_t xdr_uid3(XDR *, uid3*);
+extern  bool_t xdr_gid3(XDR *, gid3*);
+extern  bool_t xdr_size3(XDR *, size3*);
+extern  bool_t xdr_offset3(XDR *, offset3*);
+extern  bool_t xdr_mode3(XDR *, mode3*);
+extern  bool_t xdr_count3(XDR *, count3*);
+extern  bool_t xdr_nfsstat3(XDR *, nfsstat3*);
+extern  bool_t xdr_ftype3(XDR *, ftype3*);
+extern  bool_t xdr_stable_how(XDR *, stable_how*);
+extern  bool_t xdr_createmode3(XDR *, createmode3*);
+extern  bool_t xdr_specdata3(XDR *, specdata3*);
+extern  bool_t xdr_nfs_fh3(XDR *, nfs_fh3*);
+extern  bool_t xdr_nfstime3(XDR *, nfstime3*);
+extern  bool_t xdr_fattr3(XDR *, fattr3*);
+extern  bool_t xdr_post_op_attr(XDR *, post_op_attr*);
+extern  bool_t xdr_wcc_attr(XDR *, wcc_attr*);
+extern  bool_t xdr_pre_op_attr(XDR *, pre_op_attr*);
+extern  bool_t xdr_wcc_data(XDR *, wcc_data*);
+extern  bool_t xdr_post_op_fh3(XDR *, post_op_fh3*);
+extern  bool_t xdr_time_how(XDR *, time_how*);
+extern  bool_t xdr_set_mode3(XDR *, set_mode3*);
+extern  bool_t xdr_set_uid3(XDR *, set_uid3*);
+extern  bool_t xdr_set_gid3(XDR *, set_gid3*);
+extern  bool_t xdr_set_size3(XDR *, set_size3*);
+extern  bool_t xdr_set_atime(XDR *, set_atime*);
+extern  bool_t xdr_set_mtime(XDR *, set_mtime*);
+extern  bool_t xdr_sattr3(XDR *, sattr3*);
+extern  bool_t xdr_diropargs3(XDR *, diropargs3*);
+extern  bool_t xdr_GETATTR3args(XDR *, GETATTR3args*);
+extern  bool_t xdr_GETATTR3resok(XDR *, GETATTR3resok*);
+extern  bool_t xdr_GETATTR3res(XDR *, GETATTR3res*);
+extern  bool_t xdr_sattrguard3(XDR *, sattrguard3*);
+extern  bool_t xdr_SETATTR3args(XDR *, SETATTR3args*);
+extern  bool_t xdr_SETATTR3resok(XDR *, SETATTR3resok*);
+extern  bool_t xdr_SETATTR3resfail(XDR *, SETATTR3resfail*);
+extern  bool_t xdr_SETATTR3res(XDR *, SETATTR3res*);
+extern  bool_t xdr_LOOKUP3args(XDR *, LOOKUP3args*);
+extern  bool_t xdr_LOOKUP3resok(XDR *, LOOKUP3resok*);
+extern  bool_t xdr_LOOKUP3resfail(XDR *, LOOKUP3resfail*);
+extern  bool_t xdr_LOOKUP3res(XDR *, LOOKUP3res*);
+extern  bool_t xdr_ACCESS3args(XDR *, ACCESS3args*);
+extern  bool_t xdr_ACCESS3resok(XDR *, ACCESS3resok*);
+extern  bool_t xdr_ACCESS3resfail(XDR *, ACCESS3resfail*);
+extern  bool_t xdr_ACCESS3res(XDR *, ACCESS3res*);
+extern  bool_t xdr_READLINK3args(XDR *, READLINK3args*);
+extern  bool_t xdr_READLINK3resok(XDR *, READLINK3resok*);
+extern  bool_t xdr_READLINK3resfail(XDR *, READLINK3resfail*);
+extern  bool_t xdr_READLINK3res(XDR *, READLINK3res*);
+extern  bool_t xdr_READ3args(XDR *, READ3args*);
+extern  bool_t xdr_READ3resok(XDR *, READ3resok*);
+extern  bool_t xdr_READ3resfail(XDR *, READ3resfail*);
+extern  bool_t xdr_READ3res(XDR *, READ3res*);
+extern  bool_t xdr_WRITE3args(XDR *, WRITE3args*);
+extern  bool_t xdr_WRITE3resok(XDR *, WRITE3resok*);
+extern  bool_t xdr_WRITE3resfail(XDR *, WRITE3resfail*);
+extern  bool_t xdr_WRITE3res(XDR *, WRITE3res*);
+extern  bool_t xdr_createhow3(XDR *, createhow3*);
+extern  bool_t xdr_CREATE3args(XDR *, CREATE3args*);
+extern  bool_t xdr_CREATE3resok(XDR *, CREATE3resok*);
+extern  bool_t xdr_CREATE3resfail(XDR *, CREATE3resfail*);
+extern  bool_t xdr_CREATE3res(XDR *, CREATE3res*);
+extern  bool_t xdr_MKDIR3args(XDR *, MKDIR3args*);
+extern  bool_t xdr_MKDIR3resok(XDR *, MKDIR3resok*);
+extern  bool_t xdr_MKDIR3resfail(XDR *, MKDIR3resfail*);
+extern  bool_t xdr_MKDIR3res(XDR *, MKDIR3res*);
+extern  bool_t xdr_symlinkdata3(XDR *, symlinkdata3*);
+extern  bool_t xdr_SYMLINK3args(XDR *, SYMLINK3args*);
+extern  bool_t xdr_SYMLINK3resok(XDR *, SYMLINK3resok*);
+extern  bool_t xdr_SYMLINK3resfail(XDR *, SYMLINK3resfail*);
+extern  bool_t xdr_SYMLINK3res(XDR *, SYMLINK3res*);
+extern  bool_t xdr_devicedata3(XDR *, devicedata3*);
+extern  bool_t xdr_mknoddata3(XDR *, mknoddata3*);
+extern  bool_t xdr_MKNOD3args(XDR *, MKNOD3args*);
+extern  bool_t xdr_MKNOD3resok(XDR *, MKNOD3resok*);
+extern  bool_t xdr_MKNOD3resfail(XDR *, MKNOD3resfail*);
+extern  bool_t xdr_MKNOD3res(XDR *, MKNOD3res*);
+extern  bool_t xdr_REMOVE3args(XDR *, REMOVE3args*);
+extern  bool_t xdr_REMOVE3resok(XDR *, REMOVE3resok*);
+extern  bool_t xdr_REMOVE3resfail(XDR *, REMOVE3resfail*);
+extern  bool_t xdr_REMOVE3res(XDR *, REMOVE3res*);
+extern  bool_t xdr_RMDIR3args(XDR *, RMDIR3args*);
+extern  bool_t xdr_RMDIR3resok(XDR *, RMDIR3resok*);
+extern  bool_t xdr_RMDIR3resfail(XDR *, RMDIR3resfail*);
+extern  bool_t xdr_RMDIR3res(XDR *, RMDIR3res*);
+extern  bool_t xdr_RENAME3args(XDR *, RENAME3args*);
+extern  bool_t xdr_RENAME3resok(XDR *, RENAME3resok*);
+extern  bool_t xdr_RENAME3resfail(XDR *, RENAME3resfail*);
+extern  bool_t xdr_RENAME3res(XDR *, RENAME3res*);
+extern  bool_t xdr_LINK3args(XDR *, LINK3args*);
+extern  bool_t xdr_LINK3resok(XDR *, LINK3resok*);
+extern  bool_t xdr_LINK3resfail(XDR *, LINK3resfail*);
+extern  bool_t xdr_LINK3res(XDR *, LINK3res*);
+extern  bool_t xdr_READDIR3args(XDR *, READDIR3args*);
+extern  bool_t xdr_entry3(XDR *, entry3*);
+extern  bool_t xdr_dirlist3(XDR *, dirlist3*);
+extern  bool_t xdr_READDIR3resok(XDR *, READDIR3resok*);
+extern  bool_t xdr_READDIR3resfail(XDR *, READDIR3resfail*);
+extern  bool_t xdr_READDIR3res(XDR *, READDIR3res*);
+extern  bool_t xdr_READDIRPLUS3args(XDR *, READDIRPLUS3args*);
+extern  bool_t xdr_entryplus3(XDR *, entryplus3*);
+extern  bool_t xdr_dirlistplus3(XDR *, dirlistplus3*);
+extern  bool_t xdr_READDIRPLUS3resok(XDR *, READDIRPLUS3resok*);
+extern  bool_t xdr_READDIRPLUS3resfail(XDR *, READDIRPLUS3resfail*);
+extern  bool_t xdr_READDIRPLUS3res(XDR *, READDIRPLUS3res*);
+extern  bool_t xdr_FSSTAT3args(XDR *, FSSTAT3args*);
+extern  bool_t xdr_FSSTAT3resok(XDR *, FSSTAT3resok*);
+extern  bool_t xdr_FSSTAT3resfail(XDR *, FSSTAT3resfail*);
+extern  bool_t xdr_FSSTAT3res(XDR *, FSSTAT3res*);
+extern  bool_t xdr_FSINFO3args(XDR *, FSINFO3args*);
+extern  bool_t xdr_FSINFO3resok(XDR *, FSINFO3resok*);
+extern  bool_t xdr_FSINFO3resfail(XDR *, FSINFO3resfail*);
+extern  bool_t xdr_FSINFO3res(XDR *, FSINFO3res*);
+extern  bool_t xdr_PATHCONF3args(XDR *, PATHCONF3args*);
+extern  bool_t xdr_PATHCONF3resok(XDR *, PATHCONF3resok*);
+extern  bool_t xdr_PATHCONF3resfail(XDR *, PATHCONF3resfail*);
+extern  bool_t xdr_PATHCONF3res(XDR *, PATHCONF3res*);
+extern  bool_t xdr_COMMIT3args(XDR *, COMMIT3args*);
+extern  bool_t xdr_COMMIT3resok(XDR *, COMMIT3resok*);
+extern  bool_t xdr_COMMIT3resfail(XDR *, COMMIT3resfail*);
+extern  bool_t xdr_COMMIT3res(XDR *, COMMIT3res*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_NFS_H_RPCGEN */

+ 774 - 0
components/dfs/filesystems/nfs/nfs.x

@@ -0,0 +1,774 @@
+%/* This file is copied from RFC1813
+% * Copyright 1995 Sun Micrososystems (I assume)
+% */
+
+const NFS3_FHSIZE = 64;
+const NFS3_COOKIEVERFSIZE = 8;
+const NFS3_CREATEVERFSIZE = 8;
+const NFS3_WRITEVERFSIZE = 8;
+
+const ACCESS3_READ = 0x0001;
+const ACCESS3_LOOKUP = 0x0002;
+const ACCESS3_MODIFY = 0x0004;
+const ACCESS3_EXTEND = 0x0008;
+const ACCESS3_DELETE = 0x0010;
+const ACCESS3_EXECUTE = 0x0020;
+
+const FSF3_LINK = 0x0001;
+const FSF3_SYMLINK = 0x0002;
+const FSF3_HOMOGENEOUS = 0x0008;
+const FSF3_CANSETTIME = 0x0010;
+
+typedef unsigned hyper uint64;
+typedef hyper int64;
+typedef unsigned long uint32;
+typedef long int32;
+typedef string filename3<>;
+typedef string nfspath3<>;
+typedef uint64 fileid3;
+typedef uint64 cookie3;
+typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
+typedef opaque createverf3[NFS3_CREATEVERFSIZE];
+typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
+typedef uint32 uid3;
+typedef uint32 gid3;
+typedef uint64 size3;
+typedef uint64 offset3;
+typedef uint32 mode3;
+typedef uint32 count3;
+
+enum nfsstat3 {
+	NFS3_OK = 0,
+	NFS3ERR_PERM = 1,
+	NFS3ERR_NOENT = 2,
+	NFS3ERR_IO = 5,
+	NFS3ERR_NXIO = 6,
+	NFS3ERR_ACCES = 13,
+	NFS3ERR_EXIST = 17,
+	NFS3ERR_XDEV = 18,
+	NFS3ERR_NODEV = 19,
+	NFS3ERR_NOTDIR = 20,
+	NFS3ERR_ISDIR = 21,
+	NFS3ERR_INVAL = 22,
+	NFS3ERR_FBIG = 27,
+	NFS3ERR_NOSPC = 28,
+	NFS3ERR_ROFS = 30,
+	NFS3ERR_MLINK = 31,
+	NFS3ERR_NAMETOOLONG = 63,
+	NFS3ERR_NOTEMPTY = 66,
+	NFS3ERR_DQUOT = 69,
+	NFS3ERR_STALE = 70,
+	NFS3ERR_REMOTE = 71,
+	NFS3ERR_BADHANDLE = 10001,
+	NFS3ERR_NOT_SYNC = 10002,
+	NFS3ERR_BAD_COOKIE = 10003,
+	NFS3ERR_NOTSUPP = 10004,
+	NFS3ERR_TOOSMALL = 10005,
+	NFS3ERR_SERVERFAULT = 10006,
+	NFS3ERR_BADTYPE = 10007,
+	NFS3ERR_JUKEBOX = 10008
+};
+
+enum ftype3 {
+	NFS3REG = 1,
+	NFS3DIR = 2,
+	NFS3BLK = 3,
+	NFS3CHR = 4,
+	NFS3LNK = 5,
+	NFS3SOCK = 6,
+	NFS3FIFO = 7
+};
+enum stable_how {
+	UNSTABLE = 0,
+	DATA_SYNC = 1,
+	FILE_SYNC = 2
+};
+
+enum createmode3 {
+	UNCHECKED = 0,
+	GUARDED = 1,
+	EXCLUSIVE = 2
+};
+
+struct specdata3 {
+	uint32 specdata1;
+	uint32 specdata2;
+};
+
+struct nfs_fh3 {
+	opaque data<NFS3_FHSIZE>;
+};
+
+struct nfstime3 {
+	uint32 seconds;
+	uint32 nseconds;
+};
+
+struct fattr3 {
+	ftype3 type;
+	mode3 mode;
+	uint32 nlink;
+	uid3 uid;
+	gid3 gid;
+	size3 size;
+	size3 used;
+	specdata3 rdev;
+	uint64 fsid;
+	fileid3 fileid;
+	nfstime3 atime;
+	nfstime3 mtime;
+	nfstime3 ctime;
+};
+
+union post_op_attr switch (bool attributes_follow) {
+case TRUE:
+	fattr3 attributes;
+case FALSE:
+	void;
+};
+
+struct wcc_attr {
+	size3 size;
+	nfstime3 mtime;
+	nfstime3 ctime;
+};
+
+union pre_op_attr switch (bool attributes_follow) {
+case TRUE:
+	wcc_attr attributes;
+case FALSE:
+	void;
+};
+
+struct wcc_data {
+	pre_op_attr before;
+	post_op_attr after;
+};
+
+union post_op_fh3 switch (bool handle_follows) {
+case TRUE:
+	nfs_fh3 handle;
+case FALSE:
+	void;
+};
+
+enum time_how {
+	DONT_CHANGE = 0,
+	SET_TO_SERVER_TIME = 1,
+	SET_TO_CLIENT_TIME = 2
+};
+
+union set_mode3 switch (bool set_it) {
+case TRUE:
+	mode3 mode;
+default:
+	void;
+};
+
+union set_uid3 switch (bool set_it) {
+case TRUE:
+	uid3 uid;
+default:
+	void;
+};
+
+union set_gid3 switch (bool set_it) {
+case TRUE:
+	gid3 gid;
+default:
+	void;
+};
+
+union set_size3 switch (bool set_it) {
+case TRUE:
+	size3 size;
+default:
+	void;
+};
+
+union set_atime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+	nfstime3 atime;
+default:
+	void;
+};
+
+union set_mtime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+	nfstime3 mtime;
+default:
+	void;
+};
+
+struct sattr3 {
+	set_mode3 mode;
+	set_uid3 uid;
+	set_gid3 gid;
+	set_size3 size;
+	set_atime atime;
+	set_mtime mtime;
+};
+
+struct diropargs3 {
+	nfs_fh3 dir;
+	filename3 name;
+};
+
+
+struct GETATTR3args {
+	nfs_fh3 object;
+};
+
+struct GETATTR3resok {
+	fattr3 obj_attributes;
+};
+
+union GETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+	GETATTR3resok resok;
+default:
+	void;
+};
+
+union sattrguard3 switch (bool check) {
+case TRUE:
+	nfstime3 obj_ctime;
+case FALSE:
+	void;
+};
+
+struct SETATTR3args {
+	nfs_fh3 object;
+	sattr3 new_attributes;
+	sattrguard3 guard;
+};
+
+struct SETATTR3resok {
+	wcc_data obj_wcc;
+};
+
+struct SETATTR3resfail {
+	wcc_data obj_wcc;
+};
+
+union SETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+	SETATTR3resok resok;
+default:
+	SETATTR3resfail resfail;
+};
+
+struct LOOKUP3args {
+	diropargs3 what;
+};
+
+struct LOOKUP3resok {
+	nfs_fh3 object;
+	post_op_attr obj_attributes;
+	post_op_attr dir_attributes;
+};
+
+struct LOOKUP3resfail {
+	post_op_attr dir_attributes;
+};
+
+union LOOKUP3res switch (nfsstat3 status) {
+case NFS3_OK:
+	LOOKUP3resok resok;
+default:
+	LOOKUP3resfail resfail;
+};
+
+struct ACCESS3args {
+	nfs_fh3 object;
+	uint32 access;
+};
+
+struct ACCESS3resok {
+	post_op_attr obj_attributes;
+	uint32 access;
+};
+
+struct ACCESS3resfail {
+	post_op_attr obj_attributes;
+};
+
+union ACCESS3res switch (nfsstat3 status) {
+case NFS3_OK:
+	ACCESS3resok resok;
+default:
+	ACCESS3resfail resfail;
+};
+
+struct READLINK3args {
+	nfs_fh3 symlink;
+};
+
+struct READLINK3resok {
+	post_op_attr symlink_attributes;
+	nfspath3 data;
+};
+
+struct READLINK3resfail {
+	post_op_attr symlink_attributes;
+};
+
+union READLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+	READLINK3resok resok;
+default:
+	READLINK3resfail resfail;
+};
+
+struct READ3args {
+	nfs_fh3 file;
+	offset3 offset;
+	count3 count;
+};
+
+struct READ3resok {
+	post_op_attr file_attributes;
+	count3 count;
+	bool eof;
+	opaque data<>;
+};
+
+struct READ3resfail {
+	post_op_attr file_attributes;
+};
+
+union READ3res switch (nfsstat3 status) {
+case NFS3_OK:
+	READ3resok resok;
+default:
+	READ3resfail resfail;
+};
+
+struct WRITE3args {
+	nfs_fh3	file;
+	offset3	offset;
+	count3 count;
+	stable_how stable;
+	opaque data<>;
+};
+
+struct WRITE3resok {
+	wcc_data file_wcc;
+	count3 count;
+	stable_how committed;
+	writeverf3 verf;
+};
+
+struct WRITE3resfail {
+	wcc_data file_wcc;
+};
+
+union WRITE3res switch (nfsstat3 status) {
+case NFS3_OK:
+	WRITE3resok resok;
+default:
+	WRITE3resfail resfail;
+};
+
+
+union createhow3 switch (createmode3 mode) {
+case UNCHECKED:
+case GUARDED:
+	sattr3 obj_attributes;
+case EXCLUSIVE:
+	createverf3 verf;
+};
+
+struct CREATE3args {
+	diropargs3 where;
+	createhow3 how;
+};
+
+struct CREATE3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+
+struct CREATE3resfail {
+	wcc_data dir_wcc;
+};
+
+union CREATE3res switch (nfsstat3 status) {
+case NFS3_OK:
+	CREATE3resok resok;
+default:
+	CREATE3resfail resfail;
+};
+
+struct MKDIR3args {
+	diropargs3 where;
+	sattr3 attributes;
+};
+
+struct MKDIR3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+
+struct MKDIR3resfail {
+	wcc_data dir_wcc;
+};
+
+union MKDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+	MKDIR3resok resok;
+default:
+	MKDIR3resfail resfail;
+};
+
+struct symlinkdata3 {
+	sattr3 symlink_attributes;
+	nfspath3 symlink_data;
+};
+
+struct SYMLINK3args {
+	diropargs3 where;
+	symlinkdata3 symlink;
+};
+
+struct SYMLINK3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+
+struct SYMLINK3resfail {
+	wcc_data dir_wcc;
+};
+
+union SYMLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+	SYMLINK3resok resok;
+default:
+	SYMLINK3resfail resfail;
+};
+
+struct devicedata3 {
+	sattr3 dev_attributes;
+	specdata3 spec;
+};
+
+union mknoddata3 switch (ftype3 type) {
+case NFS3CHR:
+case NFS3BLK:
+	devicedata3 device;
+case NFS3SOCK:
+case NFS3FIFO:
+	sattr3 pipe_attributes;
+default:
+	void;
+};
+
+struct MKNOD3args {
+	diropargs3 where;
+	mknoddata3 what;
+};
+
+struct MKNOD3resok {
+	post_op_fh3 obj;
+	post_op_attr obj_attributes;
+	wcc_data dir_wcc;
+};
+
+struct MKNOD3resfail {
+	wcc_data dir_wcc;
+};
+
+union MKNOD3res switch (nfsstat3 status) {
+case NFS3_OK:
+	MKNOD3resok resok;
+default:
+	MKNOD3resfail resfail;
+};
+
+struct REMOVE3args {
+	diropargs3 object;
+};
+
+struct REMOVE3resok {
+	wcc_data dir_wcc;
+};
+
+struct REMOVE3resfail {
+	wcc_data dir_wcc;
+};
+
+union REMOVE3res switch (nfsstat3 status) {
+case NFS3_OK:
+	REMOVE3resok resok;
+default:
+	REMOVE3resfail resfail;
+};
+
+struct RMDIR3args {
+	diropargs3 object;
+};
+
+struct RMDIR3resok {
+	wcc_data dir_wcc;
+};
+
+struct RMDIR3resfail {
+	wcc_data dir_wcc;
+};
+
+union RMDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+	RMDIR3resok resok;
+default:
+	RMDIR3resfail resfail;
+};
+
+struct RENAME3args {
+	diropargs3 from;
+	diropargs3 to;
+};
+
+struct RENAME3resok {
+	wcc_data fromdir_wcc;
+	wcc_data todir_wcc;
+};
+
+struct RENAME3resfail {
+	wcc_data fromdir_wcc;
+	wcc_data todir_wcc;
+};
+
+union RENAME3res switch (nfsstat3 status) {
+case NFS3_OK:
+	RENAME3resok resok;
+default:
+	RENAME3resfail resfail;
+};
+struct LINK3args {
+	nfs_fh3	file;
+	diropargs3 link;
+};
+
+struct LINK3resok {
+	post_op_attr file_attributes;
+	wcc_data linkdir_wcc;
+};
+
+struct LINK3resfail {
+	post_op_attr file_attributes;
+	wcc_data linkdir_wcc;
+};
+
+union LINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+	LINK3resok resok;
+default:
+	LINK3resfail resfail;
+};
+
+struct READDIR3args {
+	nfs_fh3 dir;
+	cookie3 cookie;
+	cookieverf3 cookieverf;
+	count3 count;
+};
+
+struct entry3 {
+	fileid3 fileid;
+	filename3 name;
+	cookie3 cookie;
+	entry3 *nextentry;
+};
+
+struct dirlist3 {
+	entry3 *entries;
+	bool eof;
+};
+
+struct READDIR3resok {
+	post_op_attr dir_attributes;
+	cookieverf3 cookieverf;
+	dirlist3 reply;
+};
+
+struct READDIR3resfail {
+	post_op_attr dir_attributes;
+};
+
+union READDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+	READDIR3resok resok;
+default:
+	READDIR3resfail resfail;
+};
+
+struct READDIRPLUS3args {
+	nfs_fh3 dir;
+	cookie3 cookie;
+	cookieverf3 cookieverf;
+	count3 dircount;
+	count3 maxcount;
+};
+
+struct entryplus3 {
+	fileid3 fileid;
+	filename3 name;
+	cookie3 cookie;
+	post_op_attr name_attributes;
+	post_op_fh3 name_handle;
+	entryplus3 *nextentry;
+};
+
+struct dirlistplus3 {
+	entryplus3 *entries;
+	bool eof;
+};
+
+struct READDIRPLUS3resok {
+	post_op_attr dir_attributes;
+	cookieverf3 cookieverf;
+	dirlistplus3 reply;
+};
+
+struct READDIRPLUS3resfail {
+	post_op_attr dir_attributes;
+};
+
+union READDIRPLUS3res switch (nfsstat3 status) {
+case NFS3_OK:
+	READDIRPLUS3resok resok;
+default:
+	READDIRPLUS3resfail resfail;
+};
+
+struct FSSTAT3args {
+	nfs_fh3 fsroot;
+};
+
+struct FSSTAT3resok {
+	post_op_attr obj_attributes;
+	size3 tbytes;
+	size3 fbytes;
+	size3 abytes;
+	size3 tfiles;
+	size3 ffiles;
+	size3 afiles;
+	uint32 invarsec;
+};
+
+struct FSSTAT3resfail {
+	post_op_attr obj_attributes;
+};
+
+union FSSTAT3res switch (nfsstat3 status) {
+case NFS3_OK:
+	FSSTAT3resok resok;
+default:
+	FSSTAT3resfail resfail;
+};
+
+struct FSINFO3args {
+	nfs_fh3 fsroot;
+};
+
+struct FSINFO3resok {
+	post_op_attr obj_attributes;
+	uint32 rtmax;
+	uint32 rtpref;
+	uint32 rtmult;
+	uint32 wtmax;
+	uint32 wtpref;
+	uint32 wtmult;
+	uint32 dtpref;
+	size3 maxfilesize;
+	nfstime3 time_delta;
+	uint32 properties;
+};
+
+struct FSINFO3resfail {
+	post_op_attr obj_attributes;
+};
+
+union FSINFO3res switch (nfsstat3 status) {
+case NFS3_OK:
+	FSINFO3resok resok;
+default:
+	FSINFO3resfail resfail;
+};
+
+struct PATHCONF3args {
+	nfs_fh3 object;
+};
+
+struct PATHCONF3resok {
+	post_op_attr obj_attributes;
+	uint32 linkmax;
+	uint32 name_max;
+	bool no_trunc;
+	bool chown_restricted;
+	bool case_insensitive;
+	bool case_preserving;
+};
+
+struct PATHCONF3resfail {
+	post_op_attr obj_attributes;
+};
+
+union PATHCONF3res switch (nfsstat3 status) {
+case NFS3_OK:
+	PATHCONF3resok resok;
+default:
+	PATHCONF3resfail resfail;
+};
+
+struct COMMIT3args {
+	nfs_fh3 file;
+	offset3 offset;
+	count3 count;
+};
+
+struct COMMIT3resok {
+	wcc_data file_wcc;
+	writeverf3 verf;
+};
+
+struct COMMIT3resfail {
+	wcc_data file_wcc;
+};
+
+union COMMIT3res switch (nfsstat3 status) {
+case NFS3_OK:
+	COMMIT3resok resok;
+default:
+	COMMIT3resfail resfail;
+};
+
+program NFS_PROGRAM {
+	version NFS_V3 {
+		void NFSPROC3_NULL(void) = 0;
+		GETATTR3res NFSPROC3_GETATTR(GETATTR3args) = 1;
+		SETATTR3res NFSPROC3_SETATTR(SETATTR3args) = 2;
+		LOOKUP3res NFSPROC3_LOOKUP(LOOKUP3args) = 3;
+		ACCESS3res NFSPROC3_ACCESS(ACCESS3args) = 4;
+		READLINK3res NFSPROC3_READLINK(READLINK3args) = 5;
+		READ3res NFSPROC3_READ(READ3args) = 6;
+		WRITE3res NFSPROC3_WRITE(WRITE3args) = 7;
+		CREATE3res NFSPROC3_CREATE(CREATE3args) = 8;
+		MKDIR3res NFSPROC3_MKDIR(MKDIR3args) = 9;
+		SYMLINK3res NFSPROC3_SYMLINK(SYMLINK3args) = 10;
+		MKNOD3res NFSPROC3_MKNOD(MKNOD3args) = 11;
+		REMOVE3res NFSPROC3_REMOVE(REMOVE3args) = 12;
+		RMDIR3res NFSPROC3_RMDIR(RMDIR3args) = 13;
+		RENAME3res NFSPROC3_RENAME(RENAME3args) = 14;
+		LINK3res NFSPROC3_LINK(LINK3args) = 15;
+		READDIR3res NFSPROC3_READDIR(READDIR3args) = 16;
+		READDIRPLUS3res NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17;
+		FSSTAT3res NFSPROC3_FSSTAT(FSSTAT3args) = 18;
+		FSINFO3res NFSPROC3_FSINFO(FSINFO3args) = 19;
+		PATHCONF3res NFSPROC3_PATHCONF(PATHCONF3args) = 20;
+		COMMIT3res NFSPROC3_COMMIT(COMMIT3args) = 21;
+	} = 3;
+} = 100003;

+ 214 - 0
components/dfs/filesystems/nfs/nfs_clnt.c

@@ -0,0 +1,214 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include <string.h> /* for memset */
+#include "nfs.h"
+
+/* This file is copied from RFC1813
+ * Copyright 1995 Sun Micrososystems (I assume)
+ */
+
+typedef char* caddr_t;
+
+/* Default timeout can be changed using clnt_control() */
+static struct timeval TIMEOUT = { 25, 0 };
+
+enum clnt_stat 
+nfsproc3_null_3(void *clnt_res, CLIENT *clnt)
+{
+	 return (clnt_call(clnt, NFSPROC3_NULL,
+		(xdrproc_t) xdr_void, (caddr_t) NULL,
+		(xdrproc_t) xdr_void, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_getattr_3(GETATTR3args arg1, GETATTR3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_GETATTR,
+		(xdrproc_t) xdr_GETATTR3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_GETATTR3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_setattr_3(SETATTR3args arg1, SETATTR3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_SETATTR,
+		(xdrproc_t) xdr_SETATTR3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_SETATTR3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_lookup_3(LOOKUP3args arg1, LOOKUP3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_LOOKUP,
+		(xdrproc_t) xdr_LOOKUP3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_LOOKUP3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_access_3(ACCESS3args arg1, ACCESS3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_ACCESS,
+		(xdrproc_t) xdr_ACCESS3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_ACCESS3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_readlink_3(READLINK3args arg1, READLINK3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_READLINK,
+		(xdrproc_t) xdr_READLINK3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_READLINK3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_read_3(READ3args arg1, READ3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_READ,
+		(xdrproc_t) xdr_READ3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_READ3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_write_3(WRITE3args arg1, WRITE3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_WRITE,
+		(xdrproc_t) xdr_WRITE3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_WRITE3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_create_3(CREATE3args arg1, CREATE3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_CREATE,
+		(xdrproc_t) xdr_CREATE3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_CREATE3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_mkdir_3(MKDIR3args arg1, MKDIR3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_MKDIR,
+		(xdrproc_t) xdr_MKDIR3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_MKDIR3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_symlink_3(SYMLINK3args arg1, SYMLINK3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_SYMLINK,
+		(xdrproc_t) xdr_SYMLINK3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_SYMLINK3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_mknod_3(MKNOD3args arg1, MKNOD3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_MKNOD,
+		(xdrproc_t) xdr_MKNOD3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_MKNOD3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_remove_3(REMOVE3args arg1, REMOVE3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_REMOVE,
+		(xdrproc_t) xdr_REMOVE3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_REMOVE3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_rmdir_3(RMDIR3args arg1, RMDIR3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_RMDIR,
+		(xdrproc_t) xdr_RMDIR3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_RMDIR3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_rename_3(RENAME3args arg1, RENAME3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_RENAME,
+		(xdrproc_t) xdr_RENAME3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_RENAME3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_link_3(LINK3args arg1, LINK3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_LINK,
+		(xdrproc_t) xdr_LINK3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_LINK3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_readdir_3(READDIR3args arg1, READDIR3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_READDIR,
+		(xdrproc_t) xdr_READDIR3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_READDIR3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_readdirplus_3(READDIRPLUS3args arg1, READDIRPLUS3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_READDIRPLUS,
+		(xdrproc_t) xdr_READDIRPLUS3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_READDIRPLUS3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_fsstat_3(FSSTAT3args arg1, FSSTAT3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_FSSTAT,
+		(xdrproc_t) xdr_FSSTAT3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_FSSTAT3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_fsinfo_3(FSINFO3args arg1, FSINFO3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_FSINFO,
+		(xdrproc_t) xdr_FSINFO3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_FSINFO3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_pathconf_3(PATHCONF3args arg1, PATHCONF3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_PATHCONF,
+		(xdrproc_t) xdr_PATHCONF3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_PATHCONF3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}
+
+enum clnt_stat 
+nfsproc3_commit_3(COMMIT3args arg1, COMMIT3res *clnt_res, CLIENT *clnt)
+{
+	return (clnt_call(clnt, NFSPROC3_COMMIT,
+		(xdrproc_t) xdr_COMMIT3args, (caddr_t) &arg1,
+		(xdrproc_t) xdr_COMMIT3res, (caddr_t) clnt_res,
+		TIMEOUT));
+}

+ 1617 - 0
components/dfs/filesystems/nfs/nfs_xdr.c

@@ -0,0 +1,1617 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "nfs.h"
+/* This file is copied from RFC1813
+ * Copyright 1995 Sun Micrososystems (I assume)
+ */
+
+bool_t
+xdr_uint64(register XDR *xdrs, uint64 *objp)
+{
+	if (!xdr_u_longlong_t(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_int64(register XDR *xdrs, int64 *objp)
+{
+	if (!xdr_longlong_t(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_uint32(register XDR *xdrs, uint32 *objp)
+{
+	if (!xdr_u_long(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_int32(register XDR *xdrs, int32 *objp)
+{
+	if (!xdr_long(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_filename3(register XDR *xdrs, filename3 *objp)
+{
+	if (!xdr_string(xdrs, objp, ~0))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_nfspath3(register XDR *xdrs, nfspath3 *objp)
+{
+	if (!xdr_string(xdrs, objp, ~0))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_fileid3(register XDR *xdrs, fileid3 *objp)
+{
+	if (!xdr_uint64(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_cookie3(register XDR *xdrs, cookie3 *objp)
+{
+	if (!xdr_uint64(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_cookieverf3(register XDR *xdrs, cookieverf3 objp)
+{
+	if (!xdr_opaque(xdrs, objp, NFS3_COOKIEVERFSIZE))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_createverf3(register XDR *xdrs, createverf3 objp)
+{
+	if (!xdr_opaque(xdrs, objp, NFS3_CREATEVERFSIZE))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_writeverf3(register XDR *xdrs, writeverf3 objp)
+{
+	if (!xdr_opaque(xdrs, objp, NFS3_WRITEVERFSIZE))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_uid3(register XDR *xdrs, uid3 *objp)
+{
+	if (!xdr_uint32(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_gid3(register XDR *xdrs, gid3 *objp)
+{
+	if (!xdr_uint32(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_size3(register XDR *xdrs, size3 *objp)
+{
+	if (!xdr_uint64(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_offset3(register XDR *xdrs, offset3 *objp)
+{
+	if (!xdr_uint64(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_mode3(register XDR *xdrs, mode3 *objp)
+{
+	if (!xdr_uint32(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_count3(register XDR *xdrs, count3 *objp)
+{
+	if (!xdr_uint32(xdrs, objp))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_nfsstat3(register XDR *xdrs, nfsstat3 *objp)
+{
+	int enum_objp;
+	enum_objp = *objp;
+	if (!xdr_enum(xdrs, (enum_t *)objp))
+	{
+		*objp = enum_objp;
+		return (FALSE);
+	}
+
+	*objp = enum_objp;
+	return (TRUE);
+}
+
+bool_t
+xdr_ftype3(register XDR *xdrs, ftype3 *objp)
+{
+	int enum_objp;
+	enum_objp = *objp;
+	if (!xdr_enum(xdrs, (enum_t *)objp))
+	{
+		*objp = enum_objp;
+		return (FALSE);
+	}
+	
+	*objp = enum_objp;
+	return (TRUE);
+}
+
+bool_t
+xdr_stable_how(register XDR *xdrs, stable_how *objp)
+{
+	int enum_objp;
+	enum_objp = *objp;
+	if (!xdr_enum(xdrs, (enum_t *)objp))
+	{
+		*objp = enum_objp;
+		return (FALSE);
+	}
+	
+	*objp = enum_objp;
+	return (TRUE);
+}
+
+bool_t
+xdr_createmode3(register XDR *xdrs, createmode3 *objp)
+{
+	int enum_objp;
+	enum_objp = *objp;
+	if (!xdr_enum(xdrs, (enum_t *)objp))
+	{
+		*objp = enum_objp;
+		return (FALSE);
+	}
+	
+	*objp = enum_objp;
+	return (TRUE);
+}
+
+bool_t
+xdr_specdata3(register XDR *xdrs, specdata3 *objp)
+{
+	if (!xdr_uint32(xdrs, &objp->specdata1))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->specdata2))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_nfs_fh3(register XDR *xdrs, nfs_fh3 *objp)
+{
+	if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS3_FHSIZE))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_nfstime3(register XDR *xdrs, nfstime3 *objp)
+{
+	if (!xdr_uint32(xdrs, &objp->seconds))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->nseconds))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_fattr3(register XDR *xdrs, fattr3 *objp)
+{
+	if (!xdr_ftype3(xdrs, &objp->type))
+		return (FALSE);
+	if (!xdr_mode3(xdrs, &objp->mode))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->nlink))
+		return (FALSE);
+	if (!xdr_uid3(xdrs, &objp->uid))
+		return (FALSE);
+	if (!xdr_gid3(xdrs, &objp->gid))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->size))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->used))
+		return (FALSE);
+	if (!xdr_specdata3(xdrs, &objp->rdev))
+		return (FALSE);
+	if (!xdr_uint64(xdrs, &objp->fsid))
+		return (FALSE);
+	if (!xdr_fileid3(xdrs, &objp->fileid))
+		return (FALSE);
+	if (!xdr_nfstime3(xdrs, &objp->atime))
+		return (FALSE);
+	if (!xdr_nfstime3(xdrs, &objp->mtime))
+		return (FALSE);
+	if (!xdr_nfstime3(xdrs, &objp->ctime))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_post_op_attr(register XDR *xdrs, post_op_attr *objp)
+{
+	if (!xdr_bool(xdrs, &objp->attributes_follow))
+		return (FALSE);
+	switch (objp->attributes_follow) {
+	case TRUE:
+		if (!xdr_fattr3(xdrs, &objp->post_op_attr_u.attributes))
+			return (FALSE);
+		break;
+	case FALSE:
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_wcc_attr(register XDR *xdrs, wcc_attr *objp)
+{
+	if (!xdr_size3(xdrs, &objp->size))
+		return (FALSE);
+	if (!xdr_nfstime3(xdrs, &objp->mtime))
+		return (FALSE);
+	if (!xdr_nfstime3(xdrs, &objp->ctime))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_pre_op_attr(register XDR *xdrs, pre_op_attr *objp)
+{
+	if (!xdr_bool(xdrs, &objp->attributes_follow))
+		return (FALSE);
+	switch (objp->attributes_follow) {
+	case TRUE:
+		if (!xdr_wcc_attr(xdrs, &objp->pre_op_attr_u.attributes))
+			return (FALSE);
+		break;
+	case FALSE:
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_wcc_data(register XDR *xdrs, wcc_data *objp)
+{
+	if (!xdr_pre_op_attr(xdrs, &objp->before))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->after))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_post_op_fh3(register XDR *xdrs, post_op_fh3 *objp)
+{
+	if (!xdr_bool(xdrs, &objp->handle_follows))
+		return (FALSE);
+	switch (objp->handle_follows) {
+	case TRUE:
+		if (!xdr_nfs_fh3(xdrs, &objp->post_op_fh3_u.handle))
+			return (FALSE);
+		break;
+	case FALSE:
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_time_how(register XDR *xdrs, time_how *objp)
+{
+	int enum_objp;
+	enum_objp = *objp;
+	if (!xdr_enum(xdrs, (enum_t *)objp))
+	{
+		*objp = enum_objp;
+		return (FALSE);
+	}
+	
+	*objp = enum_objp;
+	return (TRUE);
+}
+
+bool_t
+xdr_set_mode3(register XDR *xdrs, set_mode3 *objp)
+{
+	if (!xdr_bool(xdrs, &objp->set_it))
+		return (FALSE);
+	switch (objp->set_it) {
+	case TRUE:
+		if (!xdr_mode3(xdrs, &objp->set_mode3_u.mode))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_set_uid3(register XDR *xdrs, set_uid3 *objp)
+{
+	if (!xdr_bool(xdrs, &objp->set_it))
+		return (FALSE);
+	switch (objp->set_it) {
+	case TRUE:
+		if (!xdr_uid3(xdrs, &objp->set_uid3_u.uid))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_set_gid3(register XDR *xdrs, set_gid3 *objp)
+{
+	if (!xdr_bool(xdrs, &objp->set_it))
+		return (FALSE);
+	switch (objp->set_it) {
+	case TRUE:
+		if (!xdr_gid3(xdrs, &objp->set_gid3_u.gid))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_set_size3(register XDR *xdrs, set_size3 *objp)
+{
+	if (!xdr_bool(xdrs, &objp->set_it))
+		return (FALSE);
+	switch (objp->set_it) {
+	case TRUE:
+		if (!xdr_size3(xdrs, &objp->set_size3_u.size))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_set_atime(register XDR *xdrs, set_atime *objp)
+{
+	if (!xdr_time_how(xdrs, &objp->set_it))
+		return (FALSE);
+	switch (objp->set_it) {
+	case SET_TO_CLIENT_TIME:
+		if (!xdr_nfstime3(xdrs, &objp->set_atime_u.atime))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_set_mtime(register XDR *xdrs, set_mtime *objp)
+{
+	if (!xdr_time_how(xdrs, &objp->set_it))
+		return (FALSE);
+	switch (objp->set_it) {
+	case SET_TO_CLIENT_TIME:
+		if (!xdr_nfstime3(xdrs, &objp->set_mtime_u.mtime))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_sattr3(register XDR *xdrs, sattr3 *objp)
+{
+	if (!xdr_set_mode3(xdrs, &objp->mode))
+		return (FALSE);
+	if (!xdr_set_uid3(xdrs, &objp->uid))
+		return (FALSE);
+	if (!xdr_set_gid3(xdrs, &objp->gid))
+		return (FALSE);
+	if (!xdr_set_size3(xdrs, &objp->size))
+		return (FALSE);
+	if (!xdr_set_atime(xdrs, &objp->atime))
+		return (FALSE);
+	if (!xdr_set_mtime(xdrs, &objp->mtime))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_diropargs3(register XDR *xdrs, diropargs3 *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->dir))
+		return (FALSE);
+	if (!xdr_filename3(xdrs, &objp->name))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_GETATTR3args(register XDR *xdrs, GETATTR3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->object))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_GETATTR3resok(register XDR *xdrs, GETATTR3resok *objp)
+{
+	if (!xdr_fattr3(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_GETATTR3res(register XDR *xdrs, GETATTR3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_GETATTR3resok(xdrs, &objp->GETATTR3res_u.resok))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_sattrguard3(register XDR *xdrs, sattrguard3 *objp)
+{
+	if (!xdr_bool(xdrs, &objp->check))
+		return (FALSE);
+	switch (objp->check) {
+	case TRUE:
+		if (!xdr_nfstime3(xdrs, &objp->sattrguard3_u.obj_ctime))
+			return (FALSE);
+		break;
+	case FALSE:
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_SETATTR3args(register XDR *xdrs, SETATTR3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->object))
+		return (FALSE);
+	if (!xdr_sattr3(xdrs, &objp->new_attributes))
+		return (FALSE);
+	if (!xdr_sattrguard3(xdrs, &objp->guard))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_SETATTR3resok(register XDR *xdrs, SETATTR3resok *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->obj_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_SETATTR3resfail(register XDR *xdrs, SETATTR3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->obj_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_SETATTR3res(register XDR *xdrs, SETATTR3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_SETATTR3resok(xdrs, &objp->SETATTR3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_SETATTR3resfail(xdrs, &objp->SETATTR3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_LOOKUP3args(register XDR *xdrs, LOOKUP3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->what))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_LOOKUP3resok(register XDR *xdrs, LOOKUP3resok *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->object))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_LOOKUP3resfail(register XDR *xdrs, LOOKUP3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_LOOKUP3res(register XDR *xdrs, LOOKUP3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_LOOKUP3resok(xdrs, &objp->LOOKUP3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_LOOKUP3resfail(xdrs, &objp->LOOKUP3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_ACCESS3args(register XDR *xdrs, ACCESS3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->object))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->access))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_ACCESS3resok(register XDR *xdrs, ACCESS3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->access))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_ACCESS3resfail(register XDR *xdrs, ACCESS3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_ACCESS3res(register XDR *xdrs, ACCESS3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_ACCESS3resok(xdrs, &objp->ACCESS3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_ACCESS3resfail(xdrs, &objp->ACCESS3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_READLINK3args(register XDR *xdrs, READLINK3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->symlink))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READLINK3resok(register XDR *xdrs, READLINK3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->symlink_attributes))
+		return (FALSE);
+	if (!xdr_nfspath3(xdrs, &objp->data))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READLINK3resfail(register XDR *xdrs, READLINK3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->symlink_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READLINK3res(register XDR *xdrs, READLINK3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_READLINK3resok(xdrs, &objp->READLINK3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_READLINK3resfail(xdrs, &objp->READLINK3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_READ3args(register XDR *xdrs, READ3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->file))
+		return (FALSE);
+	if (!xdr_offset3(xdrs, &objp->offset))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->count))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READ3resok(register XDR *xdrs, READ3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->count))
+		return (FALSE);
+	if (!xdr_bool(xdrs, &objp->eof))
+		return (FALSE);
+	if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READ3resfail(register XDR *xdrs, READ3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READ3res(register XDR *xdrs, READ3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_READ3resok(xdrs, &objp->READ3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_READ3resfail(xdrs, &objp->READ3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_WRITE3args(register XDR *xdrs, WRITE3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->file))
+		return (FALSE);
+	if (!xdr_offset3(xdrs, &objp->offset))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->count))
+		return (FALSE);
+	if (!xdr_stable_how(xdrs, &objp->stable))
+		return (FALSE);
+	if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_WRITE3resok(register XDR *xdrs, WRITE3resok *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->count))
+		return (FALSE);
+	if (!xdr_stable_how(xdrs, &objp->committed))
+		return (FALSE);
+	if (!xdr_writeverf3(xdrs, objp->verf))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_WRITE3resfail(register XDR *xdrs, WRITE3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_WRITE3res(register XDR *xdrs, WRITE3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_WRITE3resok(xdrs, &objp->WRITE3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_WRITE3resfail(xdrs, &objp->WRITE3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_createhow3(register XDR *xdrs, createhow3 *objp)
+{
+	if (!xdr_createmode3(xdrs, &objp->mode))
+		return (FALSE);
+	switch (objp->mode) {
+	case UNCHECKED:
+	case GUARDED:
+		if (!xdr_sattr3(xdrs, &objp->createhow3_u.obj_attributes))
+			return (FALSE);
+		break;
+	case EXCLUSIVE:
+		if (!xdr_createverf3(xdrs, objp->createhow3_u.verf))
+			return (FALSE);
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_CREATE3args(register XDR *xdrs, CREATE3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->where))
+		return (FALSE);
+	if (!xdr_createhow3(xdrs, &objp->how))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_CREATE3resok(register XDR *xdrs, CREATE3resok *objp)
+{
+	if (!xdr_post_op_fh3(xdrs, &objp->obj))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_CREATE3resfail(register XDR *xdrs, CREATE3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_CREATE3res(register XDR *xdrs, CREATE3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_CREATE3resok(xdrs, &objp->CREATE3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_CREATE3resfail(xdrs, &objp->CREATE3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_MKDIR3args(register XDR *xdrs, MKDIR3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->where))
+		return (FALSE);
+	if (!xdr_sattr3(xdrs, &objp->attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_MKDIR3resok(register XDR *xdrs, MKDIR3resok *objp)
+{
+	if (!xdr_post_op_fh3(xdrs, &objp->obj))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_MKDIR3resfail(register XDR *xdrs, MKDIR3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_MKDIR3res(register XDR *xdrs, MKDIR3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_MKDIR3resok(xdrs, &objp->MKDIR3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_MKDIR3resfail(xdrs, &objp->MKDIR3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_symlinkdata3(register XDR *xdrs, symlinkdata3 *objp)
+{
+	if (!xdr_sattr3(xdrs, &objp->symlink_attributes))
+		return (FALSE);
+	if (!xdr_nfspath3(xdrs, &objp->symlink_data))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_SYMLINK3args(register XDR *xdrs, SYMLINK3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->where))
+		return (FALSE);
+	if (!xdr_symlinkdata3(xdrs, &objp->symlink))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_SYMLINK3resok(register XDR *xdrs, SYMLINK3resok *objp)
+{
+	if (!xdr_post_op_fh3(xdrs, &objp->obj))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_SYMLINK3resfail(register XDR *xdrs, SYMLINK3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_SYMLINK3res(register XDR *xdrs, SYMLINK3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_SYMLINK3resok(xdrs, &objp->SYMLINK3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_SYMLINK3resfail(xdrs, &objp->SYMLINK3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_devicedata3(register XDR *xdrs, devicedata3 *objp)
+{
+	if (!xdr_sattr3(xdrs, &objp->dev_attributes))
+		return (FALSE);
+	if (!xdr_specdata3(xdrs, &objp->spec))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_mknoddata3(register XDR *xdrs, mknoddata3 *objp)
+{
+	if (!xdr_ftype3(xdrs, &objp->type))
+		return (FALSE);
+	switch (objp->type) {
+	case NFS3CHR:
+	case NFS3BLK:
+		if (!xdr_devicedata3(xdrs, &objp->mknoddata3_u.device))
+			return (FALSE);
+		break;
+	case NFS3SOCK:
+	case NFS3FIFO:
+		if (!xdr_sattr3(xdrs, &objp->mknoddata3_u.pipe_attributes))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_MKNOD3args(register XDR *xdrs, MKNOD3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->where))
+		return (FALSE);
+	if (!xdr_mknoddata3(xdrs, &objp->what))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_MKNOD3resok(register XDR *xdrs, MKNOD3resok *objp)
+{
+	if (!xdr_post_op_fh3(xdrs, &objp->obj))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_MKNOD3resfail(register XDR *xdrs, MKNOD3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_MKNOD3res(register XDR *xdrs, MKNOD3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_MKNOD3resok(xdrs, &objp->MKNOD3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_MKNOD3resfail(xdrs, &objp->MKNOD3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_REMOVE3args(register XDR *xdrs, REMOVE3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->object))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_REMOVE3resok(register XDR *xdrs, REMOVE3resok *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_REMOVE3resfail(register XDR *xdrs, REMOVE3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_REMOVE3res(register XDR *xdrs, REMOVE3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_REMOVE3resok(xdrs, &objp->REMOVE3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_REMOVE3resfail(xdrs, &objp->REMOVE3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_RMDIR3args(register XDR *xdrs, RMDIR3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->object))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_RMDIR3resok(register XDR *xdrs, RMDIR3resok *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_RMDIR3resfail(register XDR *xdrs, RMDIR3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_RMDIR3res(register XDR *xdrs, RMDIR3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_RMDIR3resok(xdrs, &objp->RMDIR3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_RMDIR3resfail(xdrs, &objp->RMDIR3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_RENAME3args(register XDR *xdrs, RENAME3args *objp)
+{
+	if (!xdr_diropargs3(xdrs, &objp->from))
+		return (FALSE);
+	if (!xdr_diropargs3(xdrs, &objp->to))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_RENAME3resok(register XDR *xdrs, RENAME3resok *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->fromdir_wcc))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->todir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_RENAME3resfail(register XDR *xdrs, RENAME3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->fromdir_wcc))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->todir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_RENAME3res(register XDR *xdrs, RENAME3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_RENAME3resok(xdrs, &objp->RENAME3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_RENAME3resfail(xdrs, &objp->RENAME3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_LINK3args(register XDR *xdrs, LINK3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->file))
+		return (FALSE);
+	if (!xdr_diropargs3(xdrs, &objp->link))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_LINK3resok(register XDR *xdrs, LINK3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->linkdir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_LINK3resfail(register XDR *xdrs, LINK3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
+		return (FALSE);
+	if (!xdr_wcc_data(xdrs, &objp->linkdir_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_LINK3res(register XDR *xdrs, LINK3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_LINK3resok(xdrs, &objp->LINK3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_LINK3resfail(xdrs, &objp->LINK3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIR3args(register XDR *xdrs, READDIR3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->dir))
+		return (FALSE);
+	if (!xdr_cookie3(xdrs, &objp->cookie))
+		return (FALSE);
+	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->count))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_entry3(register XDR *xdrs, entry3 *objp)
+{
+	if (!xdr_fileid3(xdrs, &objp->fileid))
+		return (FALSE);
+	if (!xdr_filename3(xdrs, &objp->name))
+		return (FALSE);
+	if (!xdr_cookie3(xdrs, &objp->cookie))
+		return (FALSE);
+	if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof (entry3), (xdrproc_t) xdr_entry3))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_dirlist3(register XDR *xdrs, dirlist3 *objp)
+{
+	if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof (entry3), (xdrproc_t) xdr_entry3))
+		return (FALSE);
+	if (!xdr_bool(xdrs, &objp->eof))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIR3resok(register XDR *xdrs, READDIR3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+		return (FALSE);
+	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
+		return (FALSE);
+	if (!xdr_dirlist3(xdrs, &objp->reply))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIR3resfail(register XDR *xdrs, READDIR3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIR3res(register XDR *xdrs, READDIR3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_READDIR3resok(xdrs, &objp->READDIR3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_READDIR3resfail(xdrs, &objp->READDIR3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIRPLUS3args(register XDR *xdrs, READDIRPLUS3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->dir))
+		return (FALSE);
+	if (!xdr_cookie3(xdrs, &objp->cookie))
+		return (FALSE);
+	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->dircount))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->maxcount))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_entryplus3(register XDR *xdrs, entryplus3 *objp)
+{
+	if (!xdr_fileid3(xdrs, &objp->fileid))
+		return (FALSE);
+	if (!xdr_filename3(xdrs, &objp->name))
+		return (FALSE);
+	if (!xdr_cookie3(xdrs, &objp->cookie))
+		return (FALSE);
+	if (!xdr_post_op_attr(xdrs, &objp->name_attributes))
+		return (FALSE);
+	if (!xdr_post_op_fh3(xdrs, &objp->name_handle))
+		return (FALSE);
+	if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof (entryplus3), (xdrproc_t) xdr_entryplus3))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_dirlistplus3(register XDR *xdrs, dirlistplus3 *objp)
+{
+	if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof (entryplus3), (xdrproc_t) xdr_entryplus3))
+		return (FALSE);
+	if (!xdr_bool(xdrs, &objp->eof))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIRPLUS3resok(register XDR *xdrs, READDIRPLUS3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+		return (FALSE);
+	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
+		return (FALSE);
+	if (!xdr_dirlistplus3(xdrs, &objp->reply))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIRPLUS3resfail(register XDR *xdrs, READDIRPLUS3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_READDIRPLUS3res(register XDR *xdrs, READDIRPLUS3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_READDIRPLUS3resok(xdrs, &objp->READDIRPLUS3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_READDIRPLUS3resfail(xdrs, &objp->READDIRPLUS3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_FSSTAT3args(register XDR *xdrs, FSSTAT3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->fsroot))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_FSSTAT3resok(register XDR *xdrs, FSSTAT3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->tbytes))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->fbytes))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->abytes))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->tfiles))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->ffiles))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->afiles))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->invarsec))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_FSSTAT3resfail(register XDR *xdrs, FSSTAT3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_FSSTAT3res(register XDR *xdrs, FSSTAT3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_FSSTAT3resok(xdrs, &objp->FSSTAT3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_FSSTAT3resfail(xdrs, &objp->FSSTAT3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_FSINFO3args(register XDR *xdrs, FSINFO3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->fsroot))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_FSINFO3resok(register XDR *xdrs, FSINFO3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->rtmax))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->rtpref))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->rtmult))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->wtmax))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->wtpref))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->wtmult))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->dtpref))
+		return (FALSE);
+	if (!xdr_size3(xdrs, &objp->maxfilesize))
+		return (FALSE);
+	if (!xdr_nfstime3(xdrs, &objp->time_delta))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->properties))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_FSINFO3resfail(register XDR *xdrs, FSINFO3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_FSINFO3res(register XDR *xdrs, FSINFO3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_FSINFO3resok(xdrs, &objp->FSINFO3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_FSINFO3resfail(xdrs, &objp->FSINFO3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_PATHCONF3args(register XDR *xdrs, PATHCONF3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->object))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_PATHCONF3resok(register XDR *xdrs, PATHCONF3resok *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->linkmax))
+		return (FALSE);
+	if (!xdr_uint32(xdrs, &objp->name_max))
+		return (FALSE);
+	if (!xdr_bool(xdrs, &objp->no_trunc))
+		return (FALSE);
+	if (!xdr_bool(xdrs, &objp->chown_restricted))
+		return (FALSE);
+	if (!xdr_bool(xdrs, &objp->case_insensitive))
+		return (FALSE);
+	if (!xdr_bool(xdrs, &objp->case_preserving))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_PATHCONF3resfail(register XDR *xdrs, PATHCONF3resfail *objp)
+{
+	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_PATHCONF3res(register XDR *xdrs, PATHCONF3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_PATHCONF3resok(xdrs, &objp->PATHCONF3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_PATHCONF3resfail(xdrs, &objp->PATHCONF3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}
+
+bool_t
+xdr_COMMIT3args(register XDR *xdrs, COMMIT3args *objp)
+{
+	if (!xdr_nfs_fh3(xdrs, &objp->file))
+		return (FALSE);
+	if (!xdr_offset3(xdrs, &objp->offset))
+		return (FALSE);
+	if (!xdr_count3(xdrs, &objp->count))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_COMMIT3resok(register XDR *xdrs, COMMIT3resok *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
+		return (FALSE);
+	if (!xdr_writeverf3(xdrs, objp->verf))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_COMMIT3resfail(register XDR *xdrs, COMMIT3resfail *objp)
+{
+	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
+		return (FALSE);
+	return (TRUE);
+}
+
+bool_t
+xdr_COMMIT3res(register XDR *xdrs, COMMIT3res *objp)
+{
+	if (!xdr_nfsstat3(xdrs, &objp->status))
+		return (FALSE);
+	switch (objp->status) {
+	case NFS3_OK:
+		if (!xdr_COMMIT3resok(xdrs, &objp->COMMIT3res_u.resok))
+			return (FALSE);
+		break;
+	default:
+		if (!xdr_COMMIT3resfail(xdrs, &objp->COMMIT3res_u.resfail))
+			return (FALSE);
+		break;
+	}
+	return (TRUE);
+}

+ 104 - 0
components/dfs/filesystems/nfs/rpc/auth.h

@@ -0,0 +1,104 @@
+#ifndef __AUTH_H__
+#define __AUTH_H__
+
+#include <rpc/xdr.h>
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+	AUTH_OK=0,
+	/*
+	 * failed at remote end
+	 */
+	AUTH_BADCRED=1,			/* bogus credentials (seal broken) */
+	AUTH_REJECTEDCRED=2,		/* client should begin new session */
+	AUTH_BADVERF=3,			/* bogus verifier (seal broken) */
+	AUTH_REJECTEDVERF=4,		/* verifier expired or was replayed */
+	AUTH_TOOWEAK=5,			/* rejected due to security reasons */
+	/*
+	 * failed locally
+	*/
+	AUTH_INVALIDRESP=6,		/* bogus response verifier */
+	AUTH_FAILED=7			/* some unknown reason */
+};
+
+union des_block {
+	struct {
+		uint32_t high;
+		uint32_t low;
+	} key;
+	char c[8];
+};
+typedef union des_block des_block;
+
+/*
+ * Authentication info.  Opaque to client.
+ */
+struct opaque_auth {
+	enum_t	oa_flavor;		/* flavor of auth */
+	char*	oa_base;		/* address of more auth stuff */
+	unsigned int	oa_length;		/* not to exceed MAX_AUTH_BYTES */
+};
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct AUTH AUTH;
+struct AUTH {
+  struct opaque_auth ah_cred;
+  struct opaque_auth ah_verf;
+  union des_block ah_key;
+  struct auth_ops {
+    void (*ah_nextverf) (AUTH *);
+    int  (*ah_marshal) (AUTH *, XDR *);		/* nextverf & serialize */
+    int  (*ah_validate) (AUTH *, struct opaque_auth *);
+						/* validate verifier */
+    int  (*ah_refresh) (AUTH *);		/* refresh credentials */
+    void (*ah_destroy) (AUTH *); 	    	/* destroy this structure */
+  } *ah_ops;
+  char* ah_private;
+};
+
+extern struct opaque_auth _null_auth;
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH	*auth;
+ * XDR	*xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth)		\
+		((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth)		\
+		((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs)	\
+		((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs)	\
+		((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp)	\
+		((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp)	\
+		((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth)		\
+		((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth)		\
+		((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth)		\
+		((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth)		\
+		((*((auth)->ah_ops->ah_destroy))(auth))
+
+#define MAX_AUTH_BYTES	400
+#define MAXNETNAMELEN	255	/* maximum length of network user's name */
+
+AUTH *authnone_create(void);
+
+#endif

+ 128 - 0
components/dfs/filesystems/nfs/rpc/auth_none.c

@@ -0,0 +1,128 @@
+/* @(#)auth_none.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] =
+
+	"@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null" 
+ * credentials and verifiers to remote systems. 
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc. 
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#define MAX_MARSHEL_SIZE 20
+
+static void authnone_verf(AUTH *);
+static bool_t authnone_validate(AUTH *, struct opaque_auth *);
+static bool_t authnone_refresh(AUTH *);
+static void authnone_destroy(AUTH *);
+static bool_t authnone_marshal(AUTH *client, XDR *xdrs);
+
+struct opaque_auth _null_auth;
+
+static struct auth_ops ops = {
+	authnone_verf,
+	authnone_marshal,
+	authnone_validate,
+	authnone_refresh,
+	authnone_destroy
+};
+
+static struct authnone_private {
+	AUTH no_client;
+	char marshalled_client[MAX_MARSHEL_SIZE];
+	unsigned int mcnt;
+} *authnone_private;
+
+AUTH *authnone_create()
+{
+	register struct authnone_private *ap = authnone_private;
+	XDR xdr_stream;
+	register XDR *xdrs;
+
+	if (ap == 0) {
+		ap = (struct authnone_private *) rt_malloc (sizeof(*ap));
+		if (ap == 0) return NULL;
+		memset(ap, 0, sizeof(*ap));
+		authnone_private = ap;
+	}
+	if (!ap->mcnt) {
+		ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+		ap->no_client.ah_ops = &ops;
+		xdrs = &xdr_stream;
+		xdrmem_create(xdrs, ap->marshalled_client,
+					  (unsigned int) MAX_MARSHEL_SIZE, XDR_ENCODE);
+		(void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+		(void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+		ap->mcnt = XDR_GETPOS(xdrs);
+		XDR_DESTROY(xdrs);
+	}
+	return (&ap->no_client);
+}
+
+/*ARGSUSED*/ 
+static bool_t authnone_marshal(client, xdrs)
+AUTH *client;
+XDR *xdrs;
+{
+	register struct authnone_private *ap = authnone_private;
+
+	if (ap == 0)
+		return (0);
+	return ((*xdrs->x_ops->x_putbytes) (xdrs,
+										ap->marshalled_client, ap->mcnt));
+}
+
+static void authnone_verf(AUTH *x)
+{
+}
+
+static bool_t authnone_validate(AUTH *x, struct opaque_auth *x1)
+{
+
+	return (TRUE);
+}
+
+static bool_t authnone_refresh(AUTH *x)
+{
+
+	return (FALSE);
+}
+
+static void authnone_destroy(AUTH *x)
+{
+}

+ 322 - 0
components/dfs/filesystems/nfs/rpc/clnt.h

@@ -0,0 +1,322 @@
+/* @(#)clnt.h	2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_CLNT_H
+#define _RPC_CLNT_H	1
+
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <lwip/sockets.h>
+
+/*
+ * Rpc calls return an enum clnt_stat.  This should be looked at more,
+ * since each implementation is required to live with this (implementation
+ * independent) list of errors.
+ */
+enum clnt_stat {
+	RPC_SUCCESS=0,			/* call succeeded */
+	/*
+	 * local errors
+	 */
+	RPC_CANTENCODEARGS=1,		/* can't encode arguments */
+	RPC_CANTDECODERES=2,		/* can't decode results */
+	RPC_CANTSEND=3,			/* failure in sending call */
+	RPC_CANTRECV=4,			/* failure in receiving result */
+	RPC_TIMEDOUT=5,			/* call timed out */
+	/*
+	 * remote errors
+	 */
+	RPC_VERSMISMATCH=6,		/* rpc versions not compatible */
+	RPC_AUTHERROR=7,		/* authentication error */
+	RPC_PROGUNAVAIL=8,		/* program not available */
+	RPC_PROGVERSMISMATCH=9,		/* program version mismatched */
+	RPC_PROCUNAVAIL=10,		/* procedure unavailable */
+	RPC_CANTDECODEARGS=11,		/* decode arguments error */
+	RPC_SYSTEMERROR=12,		/* generic "other problem" */
+	RPC_NOBROADCAST = 21,		/* Broadcasting not supported */
+	/*
+	 * callrpc & clnt_create errors
+	 */
+	RPC_UNKNOWNHOST=13,		/* unknown host name */
+	RPC_UNKNOWNPROTO=17,		/* unknown protocol */
+	RPC_UNKNOWNADDR = 19,		/* Remote address unknown */
+
+	/*
+	 * rpcbind errors
+	 */
+	RPC_RPCBFAILURE=14,		/* portmapper failed in its call */
+#define RPC_PMAPFAILURE RPC_RPCBFAILURE
+	RPC_PROGNOTREGISTERED=15,	/* remote program is not registered */
+	RPC_N2AXLATEFAILURE = 22,	/* Name to addr translation failed */
+	/*
+	 * unspecified error
+	 */
+	RPC_FAILED=16,
+	RPC_INTR=18,
+	RPC_TLIERROR=20,
+	RPC_UDERROR=23,
+        /*
+         * asynchronous errors
+         */
+        RPC_INPROGRESS = 24,
+        RPC_STALERACHANDLE = 25
+};
+
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+  int re_status;
+  union {
+    int RE_errno;		/* related system error */
+    int RE_why;	/* why the auth error occurred */
+    struct {
+      unsigned long low;		/* lowest verion supported */
+      unsigned long high;		/* highest verion supported */
+    } RE_vers;
+    struct {			/* maybe meaningful if RPC_FAILED */
+      long s1;
+      long s2;
+    } RE_lb;			/* life boot & debugging only */
+  } ru;
+#define	re_errno	ru.RE_errno
+#define	re_why		ru.RE_why
+#define	re_vers		ru.RE_vers
+#define	re_lb		ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations, see e.g. rpc_udp.c.
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct CLIENT CLIENT;
+struct CLIENT {
+  AUTH	*cl_auth;		 /* authenticator */
+  struct clnt_ops {
+    enum clnt_stat (*cl_call) (CLIENT *, unsigned long, xdrproc_t, char*, xdrproc_t,
+			       char*, struct timeval);
+			       	/* call remote procedure */
+    void (*cl_abort) (void);	/* abort a call */
+    void (*cl_geterr) (CLIENT *, struct rpc_err *);
+				/* get specific error code */
+    bool_t (*cl_freeres) (CLIENT *, xdrproc_t, char*);
+				/* frees results */
+    void (*cl_destroy) (CLIENT *); /* destroy this structure */
+    bool_t (*cl_control) (CLIENT *, int, char *);
+				/* the ioctl() of rpc */
+  } *cl_ops;
+  char* cl_private;		/* private stuff */
+};
+
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ * 	CLIENT *rh;
+ *	unsigned long proc;
+ *	xdrproc_t xargs;
+ *	char* argsp;
+ *	xdrproc_t xres;
+ *	char* resp;
+ *	struct timeval timeout;
+ */
+#define	CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)	\
+	((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+#define	clnt_call(rh, proc, xargs, argsp, xres, resp, secs)	\
+	((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ * 	CLIENT *rh;
+ */
+#define	CLNT_ABORT(rh)	((*(rh)->cl_ops->cl_abort)(rh))
+#define	clnt_abort(rh)	((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ * 	CLIENT *rh;
+ */
+#define	CLNT_GETERR(rh,errp)	((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define	clnt_geterr(rh,errp)	((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ * 	CLIENT *rh;
+ *	xdrproc_t xres;
+ *	char* resp;
+ */
+#define	CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+#define	clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ *      CLIENT *cl;
+ *      unsigned int request;
+ *      char *info;
+ */
+#define	CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define	clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to all transports
+ *
+ * Note: options marked XXX are no-ops in this implementation of RPC.
+ * The are present in TI-RPC but can't be implemented here since they
+ * depend on the presence of STREAMS/TLI, which we don't have.
+ */
+#define CLSET_TIMEOUT        1    /* set timeout (timeval) */
+#define CLGET_TIMEOUT        2    /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR    3    /* get server's address (sockaddr) */
+#define CLGET_FD             6    /* get connections file descriptor */
+#define CLGET_SVC_ADDR       7    /* get server's address (netbuf)      XXX */
+#define CLSET_FD_CLOSE       8    /* close fd while clnt_destroy */
+#define CLSET_FD_NCLOSE      9    /* Do not close fd while clnt_destroy*/
+#define CLGET_XID            10   /* Get xid */
+#define CLSET_XID            11   /* Set xid */
+#define CLGET_VERS           12   /* Get version number */
+#define CLSET_VERS           13   /* Set version number */
+#define CLGET_PROG           14   /* Get program number */
+#define CLSET_PROG           15   /* Set program number */
+#define CLSET_SVC_ADDR       16   /* get server's address (netbuf)      XXX */
+#define CLSET_PUSH_TIMOD     17   /* push timod if not already present  XXX */
+#define CLSET_POP_TIMOD      18   /* pop timod                          XXX */
+/*
+ * Connectionless only control operations
+ */
+#define CLSET_RETRY_TIMEOUT	4	/* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT	5	/* get retry timeout (timeval) */
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ * 	CLIENT *rh;
+ */
+#define	CLNT_DESTROY(rh)	((*(rh)->cl_ops->cl_destroy)(rh))
+#define	clnt_destroy(rh)	((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessible on every rpc
+ * transport/port.  It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM		((unsigned long)1)
+#define RPCTEST_VERSION		((unsigned long)1)
+#define RPCTEST_NULL_PROC	((unsigned long)2)
+#define RPCTEST_NULL_BATCH_PROC	((unsigned long)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((unsigned long)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc.  They can return NULL if a
+ * creation failure occurs.
+ */
+
+/*
+ * Generic client creation routine. Supported protocols are "udp", "tcp" and
+ * "unix"
+ * CLIENT *
+ * clnt_create(host, prog, vers, prot)
+ *	char *host; 	-- hostname
+ *	unsigned long prog;	-- program number
+ *	u_ong vers;	-- version number
+ *	char *prot;	-- protocol
+ */
+extern CLIENT *clnt_create (const char *__host, const unsigned long __prog,
+			    const unsigned long __vers, const char *__prot)
+    ;
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ *	struct sockaddr_in *raddr;
+ *	unsigned long program;
+ *	unsigned long version;
+ *	struct timeval wait_resend;
+ *	int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ *	struct sockaddr_in *raddr;
+ *	unsigned long program;
+ *	unsigned long version;
+ *	struct timeval wait_resend;
+ *	int *sockp;
+ *	unsigned int sendsz;
+ *	unsigned int recvsz;
+ */
+extern CLIENT *clntudp_create (struct sockaddr_in *__raddr, unsigned long __program,
+			       unsigned long __version, struct timeval __wait_resend,
+			       int *__sockp);
+extern CLIENT *clntudp_bufcreate (struct sockaddr_in *__raddr,
+				  unsigned long __program, unsigned long __version,
+				  struct timeval __wait_resend, int *__sockp,
+				  unsigned int __sendsz, unsigned int __recvsz);
+
+extern int callrpc (const char *__host, const unsigned long __prognum,
+		    const unsigned long __versnum, const unsigned long __procnum,
+		    const xdrproc_t __inproc, const char *__in,
+		    const xdrproc_t __outproc, char *__out);
+
+#define UDPMSGSIZE	8800	/* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE	400	/* a more reasonable packet size */
+
+void clnt_perror(CLIENT *rpch, const char *s);
+
+#endif /* rpc/clnt.h */

+ 89 - 0
components/dfs/filesystems/nfs/rpc/clnt_generic.c

@@ -0,0 +1,89 @@
+/* @(#)clnt_generic.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";
+#endif
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <rpc/rpc.h>
+#include <string.h>
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *clnt_create (const char *hostname, const unsigned long prog,
+				 const unsigned long vers, const char *proto)
+{
+	int sock;
+	struct hostent *h;
+	struct sockaddr_in sin;
+	struct timeval tv;
+	CLIENT *client;
+
+	h = gethostbyname(hostname);
+	if (h == NULL) {
+		rt_kprintf("unknown host\n");
+		return (NULL);
+	}
+	if (h->h_addrtype != AF_INET) {
+		rt_kprintf("unknow inet\n");
+		return (NULL);
+	}
+	memset((char*)&sin,0,sizeof(sin));
+	sin.sin_family = h->h_addrtype;
+	sin.sin_port = 0;
+	memmove((char *) &sin.sin_addr, h->h_addr, h->h_length);
+
+	sock = -1;
+	if (strcmp(proto, "udp") == 0)
+	{
+		tv.tv_sec = 5;
+		tv.tv_usec = 0;
+		client = clntudp_create(&sin, prog, vers, tv, &sock);
+		if (client == NULL) return NULL;
+		tv.tv_sec = 25;
+		clnt_control(client, CLSET_TIMEOUT, (char*)&tv);
+	}
+	else
+	{
+		rt_kprintf("unknow protocol\n");
+		return NULL;
+	}
+
+	return (client);
+}
+
+void clnt_perror(CLIENT *rpch, const char *s)
+{
+	rt_kprintf("rpc client error:%s\n", s);
+}

+ 394 - 0
components/dfs/filesystems/nfs/rpc/clnt_udp.c

@@ -0,0 +1,394 @@
+/* @(#)clnt_udp.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <rtthread.h>
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat clntudp_call(register CLIENT *cl,         /* client handle */
+	unsigned long proc,          /* procedure number */
+	xdrproc_t xargs,             /* xdr routine for args */
+	char* argsp,                 /* pointer to args */
+	xdrproc_t xresults,          /* xdr routine for results */
+	char* resultsp,              /* pointer to results */
+	struct timeval utimeout);
+
+static void clntudp_abort(void);
+static void clntudp_geterr(CLIENT *, struct rpc_err *);
+static bool_t clntudp_freeres(CLIENT *, xdrproc_t, char*);
+static bool_t clntudp_control(CLIENT *, int, char *);
+static void clntudp_destroy(CLIENT *);
+
+static struct clnt_ops udp_ops =
+{
+	clntudp_call,
+	clntudp_abort,
+	clntudp_geterr,
+	clntudp_freeres,
+	clntudp_destroy,
+	clntudp_control
+};
+
+/*
+ * Private data kept per client handle
+ */
+struct cu_data
+{
+	int cu_sock;
+	bool_t cu_closeit;
+	struct sockaddr_in cu_raddr;
+	int cu_rlen;
+	struct timeval cu_wait;
+	struct timeval cu_total;
+	struct rpc_err cu_error;
+	XDR cu_outxdrs;
+	unsigned int cu_xdrpos;
+	unsigned int cu_sendsz;
+	char *cu_outbuf;
+	unsigned int cu_recvsz;
+	char cu_inbuf[1];
+};
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ *     Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard;  retransmition occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *clntudp_bufcreate(struct sockaddr_in *raddr, 
+	unsigned long program, 
+	unsigned long version,
+	struct timeval wait, 
+	int *sockp, 
+	unsigned int sendsz,
+	unsigned int recvsz)
+{
+	CLIENT *cl;
+	register struct cu_data *cu = NULL;
+	struct rpc_msg call_msg;
+	static int xid_count = 0;
+
+	cl = (CLIENT *) rt_malloc (sizeof(CLIENT));
+	if (cl == NULL)
+	{
+		rt_kprintf("clntudp_create: out of memory\n");
+		goto fooy;
+	}
+	sendsz = ((sendsz + 3) / 4) * 4;
+	recvsz = ((recvsz + 3) / 4) * 4;
+	cu = (struct cu_data *) rt_malloc (sizeof(*cu) + sendsz + recvsz);
+	if (cu == NULL)
+	{
+		rt_kprintf("clntudp_create: out of memory\n");
+		goto fooy;
+	}
+	cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+	if (raddr->sin_port == 0) {
+		unsigned short port;
+
+		if ((port =
+			 pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
+			goto fooy;
+		}
+		raddr->sin_port = htons(port);
+	}
+
+	cl->cl_ops = &udp_ops;
+	cl->cl_private = (char*) cu;
+	cu->cu_raddr = *raddr;
+	cu->cu_rlen = sizeof(cu->cu_raddr);
+	cu->cu_wait = wait;
+	cu->cu_total.tv_sec = -1;
+	cu->cu_total.tv_usec = -1;
+	cu->cu_sendsz = sendsz;
+	cu->cu_recvsz = recvsz;
+	call_msg.rm_xid = ((unsigned long)rt_thread_self()) ^ ((unsigned long)rt_tick_get()) ^ (xid_count++);
+	call_msg.rm_direction = CALL;
+	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	call_msg.rm_call.cb_prog = program;
+	call_msg.rm_call.cb_vers = version;
+	xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
+	if (!xdr_callhdr(&(cu->cu_outxdrs), &call_msg))
+	{
+		goto fooy;
+	}
+	cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+	if (*sockp < 0)
+	{
+		int dontblock = 1;
+
+		*sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+		if (*sockp < 0)
+		{
+			rt_kprintf("create socket error\n");
+			goto fooy;
+		}
+		cu->cu_closeit = TRUE;
+	}
+	else
+	{
+		cu->cu_closeit = FALSE;
+	}
+	cu->cu_sock = *sockp;
+	cl->cl_auth = authnone_create();
+	return (cl);
+
+fooy:
+	if (cu) rt_free(cu);
+	if (cl) rt_free(cl);
+
+	return ((CLIENT *) NULL);
+}
+
+CLIENT *clntudp_create(struct sockaddr_in *raddr, 
+	unsigned long program, 
+	unsigned long version, 
+	struct timeval wait, 
+	int *sockp)
+{
+	return (clntudp_bufcreate(raddr, program, version, wait, sockp,
+							  UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum clnt_stat
+clntudp_call(CLIENT *cl, 
+	unsigned long proc, 
+	xdrproc_t xargs, char* argsp, 
+	xdrproc_t xresults, char* resultsp, 
+	struct timeval utimeout)
+{
+	register struct cu_data *cu = (struct cu_data *) cl->cl_private;
+	register XDR *xdrs;
+	register int outlen;
+	register int inlen;
+	struct timeval singlewait;
+	socklen_t fromlen;
+
+	struct sockaddr_in from;
+	struct rpc_msg reply_msg;
+	XDR reply_xdrs;
+	bool_t ok;
+	int nrefreshes = 2;			/* number of times to refresh cred */
+
+call_again:
+	xdrs = &(cu->cu_outxdrs);
+	xdrs->x_op = XDR_ENCODE;
+	XDR_SETPOS(xdrs, cu->cu_xdrpos);
+	/*
+	 * the transaction is the first thing in the out buffer
+	 */
+	(*(uint32_t *) (cu->cu_outbuf))++;
+	if ((!XDR_PUTLONG(xdrs, (long *) &proc)) ||
+			(!AUTH_MARSHALL(cl->cl_auth, xdrs)) || (!(*xargs) (xdrs, argsp)))
+		return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+	outlen = (int) XDR_GETPOS(xdrs);
+
+send_again:
+	if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+			   (struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)
+			!= outlen)
+	{
+		cu->cu_error.re_errno = errno;
+		return (cu->cu_error.re_status = RPC_CANTSEND);
+	}
+
+	/*
+	 * sub-optimal code appears here because we have
+	 * some clock time to spare while the packets are in flight.
+	 * (We assume that this is actually only executed once.)
+	 */
+	reply_msg.acpted_rply.ar_verf = _null_auth;
+	reply_msg.acpted_rply.ar_results.where = resultsp;
+	reply_msg.acpted_rply.ar_results.proc = xresults;
+
+	/* do recv */
+	do
+	{
+		fromlen = sizeof(struct sockaddr);
+
+		inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
+						 (int) cu->cu_recvsz, 0,
+						 (struct sockaddr *) &from, &fromlen);
+	}while (inlen < 0 && errno == EINTR);
+
+	if (inlen < 4)
+	{
+		rt_kprintf("recv error, len %d\n", inlen);
+		cu->cu_error.re_errno = errno;
+		return (cu->cu_error.re_status = RPC_CANTRECV);
+	}
+
+	/* see if reply transaction id matches sent id */
+	if (*((uint32_t *) (cu->cu_inbuf)) != *((uint32_t *) (cu->cu_outbuf)))
+		goto send_again;
+
+	/* we now assume we have the proper reply */
+
+	/*
+	 * now decode and validate the response
+	 */
+	xdrmem_create(&reply_xdrs, cu->cu_inbuf, (unsigned int) inlen, XDR_DECODE);
+	ok = xdr_replymsg(&reply_xdrs, &reply_msg);
+	/* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
+	if (ok)
+	{
+		_seterr_reply(&reply_msg, &(cu->cu_error));
+		if (cu->cu_error.re_status == RPC_SUCCESS)
+		{
+			if (!AUTH_VALIDATE(cl->cl_auth,
+							   &reply_msg.acpted_rply.ar_verf))
+			{
+				cu->cu_error.re_status = RPC_AUTHERROR;
+				cu->cu_error.re_why = AUTH_INVALIDRESP;
+			}
+			if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
+			{
+				xdrs->x_op = XDR_FREE;
+				(void) xdr_opaque_auth(xdrs,
+									   &(reply_msg.acpted_rply.ar_verf));
+			}
+		} /* end successful completion */
+		else
+		{
+			/* maybe our credentials need to be refreshed ... */
+			if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth))
+			{
+				nrefreshes--;
+				goto call_again;
+			}
+		}						/* end of unsuccessful completion */
+	} /* end of valid reply message */
+	else
+	{
+		cu->cu_error.re_status = RPC_CANTDECODERES;
+	}
+
+	return (cu->cu_error.re_status);
+}
+
+static void clntudp_geterr(cl, errp)
+CLIENT *cl;
+struct rpc_err *errp;
+{
+	register struct cu_data *cu = (struct cu_data *) cl->cl_private;
+
+	*errp = cu->cu_error;
+}
+
+
+static bool_t clntudp_freeres(cl, xdr_res, res_ptr)
+CLIENT *cl;
+xdrproc_t xdr_res;
+char* res_ptr;
+{
+	register struct cu_data *cu = (struct cu_data *) cl->cl_private;
+	register XDR *xdrs = &(cu->cu_outxdrs);
+
+	xdrs->x_op = XDR_FREE;
+	return ((*xdr_res) (xdrs, res_ptr));
+}
+
+static void clntudp_abort( /*h */ )
+/*CLIENT *h; */
+{
+}
+
+static bool_t clntudp_control(cl, request, info)
+CLIENT *cl;
+int request;
+char *info;
+{
+	register struct cu_data *cu = (struct cu_data *) cl->cl_private;
+
+	switch (request)
+	{
+	case CLSET_TIMEOUT:
+		cu->cu_total = *(struct timeval *) info;
+		
+		/* set socket option */
+		setsockopt(cu->cu_sock, SOL_SOCKET, SO_RCVTIMEO, &cu->cu_total, sizeof(cu->cu_total));
+
+		break;
+	case CLGET_TIMEOUT:
+		*(struct timeval *) info = cu->cu_total;
+		break;
+	case CLSET_RETRY_TIMEOUT:
+		cu->cu_wait = *(struct timeval *) info;
+		break;
+	case CLGET_RETRY_TIMEOUT:
+		*(struct timeval *) info = cu->cu_wait;
+		break;
+	case CLGET_SERVER_ADDR:
+		*(struct sockaddr_in *) info = cu->cu_raddr;
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static void clntudp_destroy(cl)
+CLIENT *cl;
+{
+	register struct cu_data *cu = (struct cu_data *) cl->cl_private;
+
+	if (cu->cu_closeit)
+	{
+		lwip_close(cu->cu_sock);
+	}
+
+	XDR_DESTROY(&(cu->cu_outxdrs));
+	rt_free(cu);
+	rt_free(cl);
+}
+

+ 60 - 0
components/dfs/filesystems/nfs/rpc/pmap.c

@@ -0,0 +1,60 @@
+#include "pmap.h"
+#include "clnt.h"
+#include <rpc/rpc.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+
+bool_t xdr_pmap(xdrs, regs)
+XDR *xdrs;
+struct pmap *regs;
+{
+	if (xdr_u_long(xdrs, &regs->pm_prog) &&
+		xdr_u_long(xdrs, &regs->pm_vers) &&
+		xdr_u_long(xdrs, &regs->pm_prot))
+			return (xdr_u_long(xdrs, &regs->pm_port));
+	return (FALSE);
+}
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+unsigned short pmap_getport(address, program, version, protocol)
+struct sockaddr_in *address;
+unsigned long program;
+unsigned long version;
+unsigned int protocol;
+{
+	unsigned short port = 0;
+	int socket = -1;
+	register CLIENT *client;
+	struct pmap parms;
+
+	address->sin_port = htons((unsigned short)PMAPPORT);
+	if (protocol == IPPROTO_UDP)
+	  client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout,
+								  &socket, RPCSMALLMSGSIZE,
+							   RPCSMALLMSGSIZE);
+
+	if (client != (CLIENT *) NULL)
+	{
+		parms.pm_prog = program;
+		parms.pm_vers = version;
+		parms.pm_prot = protocol;
+		parms.pm_port = 0;		/* not needed or used */
+		if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, (char*)&parms,
+					  (xdrproc_t)xdr_u_short, (char*)&port, tottimeout) != RPC_SUCCESS)
+		{
+			rt_kprintf("pmap failure\n");
+		}
+		CLNT_DESTROY(client);
+	}
+
+	(void) lwip_close(socket);
+	address->sin_port = 0;
+
+	return (port);
+}

+ 58 - 0
components/dfs/filesystems/nfs/rpc/pmap.h

@@ -0,0 +1,58 @@
+#ifndef __RPC_PMAP_PROT_H__
+#define __RPC_PMAP_PROT_H__
+
+#include <rpc/xdr.h>
+
+/* The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ * 	takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ * 	TRUE is success, FALSE is failure.  Registers the tuple
+ *	[prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ *	TRUE is success, FALSE is failure.  Un-registers pair
+ *	[prog, vers].  prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ *	0 is failure.  Otherwise returns the port number where the pair
+ *	[prog, vers] is registered.  It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ * 	RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ * 	Calls the procedure on the local machine.  If it is not registered,
+ *	this procedure is quite; ie it does not return error information!!!
+ *	This procedure only is supported on rpc/udp and calls via
+ *	rpc/udp.  This routine only passes null authentication parameters.
+ *	This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#define PMAPPORT		((unsigned short)111)
+#define PMAPPROG		((unsigned long)100000)
+#define PMAPVERS		((unsigned long)2)
+#define PMAPVERS_PROTO		((unsigned long)2)
+#define PMAPVERS_ORIG		((unsigned long)1)
+#define PMAPPROC_NULL		((unsigned long)0)
+#define PMAPPROC_SET		((unsigned long)1)
+#define PMAPPROC_UNSET		((unsigned long)2)
+#define PMAPPROC_GETPORT	((unsigned long)3)
+#define PMAPPROC_DUMP		((unsigned long)4)
+#define PMAPPROC_CALLIT		((unsigned long)5)
+
+struct pmap {
+	long unsigned pm_prog;
+	long unsigned pm_vers;
+	long unsigned pm_prot;
+	long unsigned pm_port;
+};
+
+extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs);
+
+#endif

+ 54 - 0
components/dfs/filesystems/nfs/rpc/rpc.h

@@ -0,0 +1,54 @@
+/* @(#)rpc.h	2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_RPC_H
+#define _RPC_RPC_H 1
+
+#include <rpc/types.h>		/* some typedefs */
+
+/* external data representation interfaces */
+#include <rpc/xdr.h>		/* generic (de)serializer */
+
+#include <rpc/auth.h>
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h>		/* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h>	/* protocol for rpc messages */
+
+#endif

+ 195 - 0
components/dfs/filesystems/nfs/rpc/rpc_msg.h

@@ -0,0 +1,195 @@
+/* @(#)rpc_msg.h	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)rpc_msg.h 1.7 86/07/16 SMI      */
+
+#ifndef _RPC_MSG_H
+#define _RPC_MSG_H 1
+
+#include <rpc/xdr.h>
+#include <rpc/clnt.h>
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#define RPC_MSG_VERSION		((unsigned long) 2)
+#define RPC_SERVICE_PORT	((unsigned short) 2048)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall struct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+	CALL=0,
+	REPLY=1
+};
+
+enum reply_stat {
+	MSG_ACCEPTED=0,
+	MSG_DENIED=1
+};
+
+enum accept_stat {
+	SUCCESS=0,
+	PROG_UNAVAIL=1,
+	PROG_MISMATCH=2,
+	PROC_UNAVAIL=3,
+	GARBAGE_ARGS=4,
+	SYSTEM_ERR=5
+};
+
+enum reject_stat {
+	RPC_MISMATCH=0,
+	AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+	struct opaque_auth	ar_verf;
+	int	                ar_stat;
+	union {
+		struct {
+			unsigned long	low;
+			unsigned long	high;
+		} AR_versions;
+		struct {
+			char*	where;
+			xdrproc_t proc;
+		} AR_results;
+		/* and many other null cases */
+	} ru;
+#define	ar_results	ru.AR_results
+#define	ar_vers		ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+	int rj_stat;
+	union {
+		struct {
+			unsigned long low;
+			unsigned long high;
+		} RJ_versions;
+		int RJ_why;  /* why authentication did not work */
+	} ru;
+#define	rj_vers	ru.RJ_versions
+#define	rj_why	ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+	int rp_stat;
+	union {
+		struct accepted_reply RP_ar;
+		struct rejected_reply RP_dr;
+	} ru;
+#define	rp_acpt	ru.RP_ar
+#define	rp_rjct	ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+	unsigned long cb_rpcvers;	/* must be equal to two */
+	unsigned long cb_prog;
+	unsigned long cb_vers;
+	unsigned long cb_proc;
+	struct opaque_auth cb_cred;
+	struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+	unsigned long	rm_xid;
+	int				rm_direction;
+	union {
+		struct call_body RM_cmb;
+		struct reply_body RM_rmb;
+	} ru;
+#define	rm_call		ru.RM_cmb
+#define	rm_reply	ru.RM_rmb
+};
+#define	acpted_rply	ru.RM_rmb.ru.RP_ar
+#define	rjcted_rply	ru.RM_rmb.ru.RP_dr
+
+
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *cmsg;
+ */
+extern bool_t	xdr_callmsg (XDR *__xdrs, struct rpc_msg *__cmsg);
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *cmsg;
+ */
+extern bool_t	xdr_callhdr (XDR *__xdrs, struct rpc_msg *__cmsg);
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *rmsg;
+ */
+extern bool_t	xdr_replymsg (XDR *__xdrs, struct rpc_msg *__rmsg);
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ * 	struct rpc_msg *msg;
+ * 	struct rpc_err *error;
+ */
+extern void	_seterr_reply (struct rpc_msg *__msg, struct rpc_err *__error);
+
+#endif /* rpc/rpc_msg.h */

+ 277 - 0
components/dfs/filesystems/nfs/rpc/rpc_prot.c

@@ -0,0 +1,277 @@
+/* @(#)rpc_prot.c	2.3 88/08/07 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#include <rpc/rpc.h>
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t xdr_opaque_auth(xdrs, ap)
+register XDR *xdrs;
+register struct opaque_auth *ap;
+{
+
+	if (xdr_enum(xdrs, &(ap->oa_flavor)))
+		return (xdr_bytes(xdrs, &ap->oa_base,
+						  &ap->oa_length, MAX_AUTH_BYTES));
+	return (FALSE);
+}
+
+/*
+ * XDR a DES block
+ */
+bool_t xdr_des_block(xdrs, blkp)
+register XDR *xdrs;
+register des_block *blkp;
+{
+	return (xdr_opaque(xdrs, (char*) blkp, sizeof(des_block)));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+static bool_t xdr_accepted_reply(xdrs, ar)
+register XDR *xdrs;
+register struct accepted_reply *ar;
+{
+
+	/* personalized union, rather than calling xdr_union */
+	if (!xdr_opaque_auth(xdrs, &(ar->ar_verf)))
+		return (FALSE);
+	if (!xdr_enum(xdrs, (enum_t *) & (ar->ar_stat)))
+		return (FALSE);
+	switch (ar->ar_stat) {
+
+	case SUCCESS:
+		return ((*(ar->ar_results.proc)) (xdrs, ar->ar_results.where));
+
+	case PROG_MISMATCH:
+		if (!xdr_u_long(xdrs, &(ar->ar_vers.low)))
+			return (FALSE);
+		return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
+	}
+	return (TRUE);				/* TRUE => open ended set of problems */
+}
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+static bool_t xdr_rejected_reply(xdrs, rr)
+register XDR *xdrs;
+register struct rejected_reply *rr;
+{
+
+	/* personalized union, rather than calling xdr_union */
+	if (!xdr_enum(xdrs, (enum_t *) & (rr->rj_stat)))
+		return (FALSE);
+	switch (rr->rj_stat) {
+
+	case RPC_MISMATCH:
+		if (!xdr_u_long(xdrs, &(rr->rj_vers.low)))
+			return (FALSE);
+		return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
+
+	case AUTH_ERROR:
+		return (xdr_enum(xdrs, (enum_t *) & (rr->rj_why)));
+	}
+	return (FALSE);
+}
+
+static struct xdr_discrim reply_dscrm[3] = {
+	{(int) MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply},
+	{(int) MSG_DENIED, (xdrproc_t)xdr_rejected_reply},
+	{__dontcare__, NULL_xdrproc_t}
+};
+
+/*
+ * XDR a reply message
+ */
+bool_t xdr_replymsg(xdrs, rmsg)
+register XDR *xdrs;
+register struct rpc_msg *rmsg;
+{
+	if (xdr_u_long(xdrs, &(rmsg->rm_xid)) &&
+		xdr_enum(xdrs, (enum_t *) & (rmsg->rm_direction)) &&
+		(rmsg->rm_direction == REPLY))
+		return (xdr_union(xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
+						  (char*) & (rmsg->rm_reply.ru), reply_dscrm,
+						  NULL_xdrproc_t));
+	return (FALSE);
+}
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t xdr_callhdr(xdrs, cmsg)
+register XDR *xdrs;
+register struct rpc_msg *cmsg;
+{
+
+	cmsg->rm_direction = CALL;
+	cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	if (
+		(xdrs->x_op == XDR_ENCODE) &&
+		xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+		xdr_enum(xdrs, (enum_t *) & (cmsg->rm_direction)) &&
+		xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+		xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)))
+			return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
+	return (FALSE);
+}
+
+/* ************************** Client utility routine ************* */
+
+static void accepted(acpt_stat, error)
+register enum accept_stat acpt_stat;
+register struct rpc_err *error;
+{
+
+	switch (acpt_stat) {
+
+	case PROG_UNAVAIL:
+		error->re_status = RPC_PROGUNAVAIL;
+		return;
+
+	case PROG_MISMATCH:
+		error->re_status = RPC_PROGVERSMISMATCH;
+		return;
+
+	case PROC_UNAVAIL:
+		error->re_status = RPC_PROCUNAVAIL;
+		return;
+
+	case GARBAGE_ARGS:
+		error->re_status = RPC_CANTDECODEARGS;
+		return;
+
+	case SYSTEM_ERR:
+		error->re_status = RPC_SYSTEMERROR;
+		return;
+
+	case SUCCESS:
+		error->re_status = RPC_SUCCESS;
+		return;
+	}
+	/* something's wrong, but we don't know what ... */
+	error->re_status = RPC_FAILED;
+	error->re_lb.s1 = (long) MSG_ACCEPTED;
+	error->re_lb.s2 = (long) acpt_stat;
+}
+
+static void rejected(rjct_stat, error)
+register enum reject_stat rjct_stat;
+register struct rpc_err *error;
+{
+
+	switch (rjct_stat) {
+
+	case RPC_VERSMISMATCH:
+		error->re_status = RPC_VERSMISMATCH;
+		return;
+
+	case AUTH_ERROR:
+		error->re_status = RPC_AUTHERROR;
+		return;
+	}
+	/* something's wrong, but we don't know what ... */
+	error->re_status = RPC_FAILED;
+	error->re_lb.s1 = (long) MSG_DENIED;
+	error->re_lb.s2 = (long) rjct_stat;
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void _seterr_reply(msg, error)
+register struct rpc_msg *msg;
+register struct rpc_err *error;
+{
+
+	/* optimized for normal, SUCCESSful case */
+	switch (msg->rm_reply.rp_stat) {
+
+	case MSG_ACCEPTED:
+		if (msg->acpted_rply.ar_stat == SUCCESS) {
+			error->re_status = RPC_SUCCESS;
+			return;
+		};
+		accepted(msg->acpted_rply.ar_stat, error);
+		break;
+
+	case MSG_DENIED:
+		rejected(msg->rjcted_rply.rj_stat, error);
+		break;
+
+	default:
+		error->re_status = RPC_FAILED;
+		error->re_lb.s1 = (long) (msg->rm_reply.rp_stat);
+		break;
+	}
+	switch (error->re_status) {
+
+	case RPC_VERSMISMATCH:
+		error->re_vers.low = msg->rjcted_rply.rj_vers.low;
+		error->re_vers.high = msg->rjcted_rply.rj_vers.high;
+		break;
+
+	case RPC_AUTHERROR:
+		error->re_why = msg->rjcted_rply.rj_why;
+		break;
+
+	case RPC_PROGVERSMISMATCH:
+		error->re_vers.low = msg->acpted_rply.ar_vers.low;
+		error->re_vers.high = msg->acpted_rply.ar_vers.high;
+		break;
+	}
+}

+ 83 - 0
components/dfs/filesystems/nfs/rpc/types.h

@@ -0,0 +1,83 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/* fixincludes should not add extern "C" to this file */
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef _RPC_TYPES_H
+#define _RPC_TYPES_H 1
+
+#include <rtthread.h>
+#include <lwip/netdb.h>
+#include <lwip/sockets.h>
+
+#include <string.h>
+typedef unsigned int u_int;
+typedef unsigned char u_char;
+typedef unsigned long u_long;
+typedef rt_int32_t  ssize_t;
+
+typedef rt_int8_t   int8_t;
+typedef rt_uint8_t  uint8_t;
+typedef rt_int16_t  int16_t;
+typedef rt_uint16_t uint16_t;
+typedef rt_int32_t  int32_t;
+typedef rt_uint32_t uint32_t;
+
+typedef long long   int64_t;
+typedef unsigned long long uint64_t;
+
+typedef int bool_t;
+typedef int enum_t;
+
+typedef unsigned long mode_t;
+typedef unsigned long dev_t;
+
+/* This needs to be changed to uint32_t in the future */
+typedef unsigned long rpcprog_t;
+typedef unsigned long rpcvers_t;
+typedef unsigned long rpcproc_t;
+typedef unsigned long rpcprot_t;
+typedef unsigned long rpcport_t;
+
+#define        __dontcare__    -1
+
+#ifndef FALSE
+# define  FALSE   (0)
+#endif
+
+#ifndef TRUE
+# define  TRUE    (1)
+#endif
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN  64
+#endif
+
+#endif /* rpc/types.h */

+ 808 - 0
components/dfs/filesystems/nfs/rpc/xdr.c

@@ -0,0 +1,808 @@
+/* @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <string.h>
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE	((long) 0)
+#define XDR_TRUE	((long) 1)
+#define LASTUNSIGNED	((unsigned int) 0-1)
+
+/*
+ * for unit alignment
+ */
+static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
+
+/*
+ * Free a data structure using XDR
+ * Not a filter, but a convenient utility nonetheless
+ */
+void xdr_free(xdrproc_t proc, char* objp)
+{
+	XDR x;
+
+	x.x_op = XDR_FREE;
+	(*proc) (&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t xdr_void( /* xdrs, addr */ )
+	/* XDR *xdrs; */
+	/* char* addr; */
+{
+
+	return (TRUE);
+}
+
+/*
+ * XDR integers
+ */
+bool_t xdr_int(XDR* xdrs, int* ip)
+{
+	if (sizeof(int) == sizeof(long)) {
+		return (xdr_long(xdrs, (long *) ip));
+	} else if (sizeof(int) < sizeof(long)) {
+	  long l;
+	  switch (xdrs->x_op) {
+	  case XDR_ENCODE:
+		l = (long) *ip;
+		return XDR_PUTLONG(xdrs, &l);
+	  case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l))
+		  return FALSE;
+		*ip = (int) l;
+	  case XDR_FREE:
+		return TRUE;
+	  }
+	  return FALSE;
+	} else {
+		return (xdr_short(xdrs, (short *) ip));
+	}
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t xdr_u_int(XDR* xdrs, unsigned int* up)
+{
+	if (sizeof(unsigned int) == sizeof(unsigned long)) {
+		return (xdr_u_long(xdrs, (unsigned long *) up));
+	} else if (sizeof(unsigned int) < sizeof(unsigned long)) {
+	  unsigned long l;
+	  switch (xdrs->x_op) {
+	  case XDR_ENCODE:
+		l = (unsigned long) *up;
+		return XDR_PUTLONG(xdrs, (long*)&l);
+	  case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, (long*)&l))
+		  return FALSE;
+		*up = (unsigned int) l;
+	  case XDR_FREE:
+		return TRUE;
+	  }
+	  return FALSE;
+	} else {
+		return (xdr_short(xdrs, (short *) up));
+	}
+}
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t xdr_long(XDR* xdrs, long* lp)
+{
+
+	if (xdrs->x_op == XDR_ENCODE
+		&& (sizeof(int32_t) == sizeof(long)
+			|| (int32_t) *lp == *lp))
+		return (XDR_PUTLONG(xdrs, lp));
+
+	if (xdrs->x_op == XDR_DECODE)
+		return (XDR_GETLONG(xdrs, lp));
+
+	if (xdrs->x_op == XDR_FREE)
+		return (TRUE);
+
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t xdr_u_long(XDR* xdrs, unsigned long* ulp)
+{
+
+  if (xdrs->x_op == XDR_DECODE) {
+	long l;
+	if (XDR_GETLONG(xdrs, &l) == FALSE)
+	  return FALSE;
+	*ulp = (uint32_t) l;
+	return TRUE;
+  }
+
+  if (xdrs->x_op == XDR_ENCODE) {
+	if (sizeof(uint32_t) != sizeof(unsigned long)
+		&& (uint32_t) *ulp != *ulp)
+	  return FALSE;
+
+		return (XDR_PUTLONG(xdrs, (long *) ulp));
+  }
+
+	if (xdrs->x_op == XDR_FREE)
+		return (TRUE);
+
+	return (FALSE);
+}
+
+
+/*
+ * XDR long long integers
+ */
+bool_t xdr_longlong_t (XDR * xdrs, long long* llp)
+{
+  int32_t t1, t2;
+
+  switch (xdrs->x_op)
+    {
+    case XDR_ENCODE:
+      t1 = (int32_t) ((*llp) >> 32);
+      t2 = (int32_t) (*llp);
+      return (XDR_PUTLONG (xdrs, &t1) && XDR_PUTLONG (xdrs, &t2));
+
+    case XDR_DECODE:
+      if (!XDR_GETLONG (xdrs, &t1) || !XDR_GETLONG (xdrs, &t2))
+        return FALSE;
+      *llp = ((int64_t) t1) << 32;
+      *llp |= (uint32_t) t2;
+      return TRUE;
+
+    case XDR_FREE:
+      return TRUE;
+    }
+  return FALSE;
+}
+
+/*
+ * XDR unsigned long long integers
+ */
+bool_t xdr_u_longlong_t (XDR * xdrs, unsigned long long* ullp)
+{
+  uint32_t t1, t2;
+
+  switch (xdrs->x_op)
+    {
+    case XDR_ENCODE:
+      t1 = (uint32_t) ((*ullp) >> 32);
+      t2 = (uint32_t) (*ullp);
+      return (XDR_PUTLONG (xdrs, (int32_t *)&t1) &&
+              XDR_PUTLONG (xdrs, (int32_t *)&t2));
+
+    case XDR_DECODE:
+      if (!XDR_GETLONG (xdrs, (int32_t *)&t1) ||
+          !XDR_GETLONG (xdrs, (int32_t *)&t2))
+        return FALSE;
+      *ullp = ((uint64_t) t1) << 32;
+      *ullp |= t2;
+      return TRUE;
+
+    case XDR_FREE:
+      return TRUE;
+    }
+  return FALSE;
+}
+
+/*
+ * XDR short integers
+ */
+bool_t xdr_short(XDR* xdrs, short* sp)
+{
+	long l;
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (long) *sp;
+		return (XDR_PUTLONG(xdrs, &l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l)) {
+			return (FALSE);
+		}
+		*sp = (short) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t xdr_u_short(XDR* xdrs, unsigned short* usp)
+{
+	unsigned long l;
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (unsigned long) * usp;
+		return (XDR_PUTLONG(xdrs, (long*)&l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, (long*)&l)) {
+			return (FALSE);
+		}
+		*usp = (unsigned short) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t xdr_char(XDR* xdrs, char* cp)
+{
+	int i;
+
+	i = (*cp);
+	if (!xdr_int(xdrs, &i)) {
+		return (FALSE);
+	}
+	*cp = i;
+	return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t xdr_u_char(XDR* xdrs, unsigned char* cp)
+{
+	unsigned int u;
+
+	u = (*cp);
+	if (!xdr_u_int(xdrs, &u)) {
+		return (FALSE);
+	}
+	*cp = u;
+	return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t xdr_bool(xdrs, bp)
+register XDR *xdrs;
+bool_t *bp;
+{
+	long lb;
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		lb = *bp ? XDR_TRUE : XDR_FALSE;
+		return (XDR_PUTLONG(xdrs, &lb));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &lb)) {
+			return (FALSE);
+		}
+		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t xdr_enum(xdrs, ep)
+XDR *xdrs;
+enum_t *ep;
+{
+	long lp;
+
+	lp = *ep;
+
+	/*
+	 * enums are treated as ints
+	 */
+	return (xdr_long(xdrs, (long *) ep));
+}
+
+/*
+ * XDR opaque data
+ * Allows the specification of a fixed size sequence of opaque bytes.
+ * cp points to the opaque object and cnt gives the byte length.
+ */
+bool_t xdr_opaque(xdrs, cp, cnt)
+register XDR *xdrs;
+char* cp;
+register unsigned int cnt;
+{
+	register unsigned int rndup;
+	static char crud[BYTES_PER_XDR_UNIT];
+
+	/*
+	 * if no data we are done
+	 */
+	if (cnt == 0)
+		return (TRUE);
+
+	/*
+	 * round byte count to full xdr units
+	 */
+	rndup = cnt % BYTES_PER_XDR_UNIT;
+	if (rndup > 0)
+		rndup = BYTES_PER_XDR_UNIT - rndup;
+
+	if (xdrs->x_op == XDR_DECODE) {
+		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
+			return (FALSE);
+		}
+		if (rndup == 0)
+			return (TRUE);
+		return (XDR_GETBYTES(xdrs, crud, rndup));
+	}
+
+	if (xdrs->x_op == XDR_ENCODE) {
+		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
+			return (FALSE);
+		}
+		if (rndup == 0)
+			return (TRUE);
+		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
+	}
+
+	if (xdrs->x_op == XDR_FREE) {
+		return (TRUE);
+	}
+
+	return (FALSE);
+}
+
+/*
+ * XDR counted bytes
+ * *cpp is a pointer to the bytes, *sizep is the count.
+ * If *cpp is NULL maxsize bytes are allocated
+ */
+bool_t xdr_bytes(xdrs, cpp, sizep, maxsize)
+register XDR *xdrs;
+char **cpp;
+register unsigned int *sizep;
+unsigned int maxsize;
+{
+	register char *sp = *cpp;	/* sp is the actual string pointer */
+	register unsigned int nodesize;
+
+	/*
+	 * first deal with the length since xdr bytes are counted
+	 */
+	if (!xdr_u_int(xdrs, sizep)) {
+		return (FALSE);
+	}
+	nodesize = *sizep;
+	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
+		return (FALSE);
+	}
+
+	/*
+	 * now deal with the actual bytes
+	 */
+	switch (xdrs->x_op) {
+
+	case XDR_DECODE:
+		if (nodesize == 0) {
+			return (TRUE);
+		}
+		if (sp == NULL) {
+			*cpp = sp = (char *) rt_malloc(nodesize);
+		}
+		if (sp == NULL) {
+			rt_kprintf("xdr_bytes: out of memory\n");
+			return (FALSE);
+		}
+		/* fall into ... */
+
+	case XDR_ENCODE:
+		return (xdr_opaque(xdrs, sp, nodesize));
+
+	case XDR_FREE:
+		if (sp != NULL) {
+			rt_free(sp);
+			*cpp = NULL;
+		}
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t xdr_netobj(xdrs, np)
+XDR *xdrs;
+struct netobj *np;
+{
+
+	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
+}
+
+/*
+ * XDR a descriminated union
+ * Support routine for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer.  The routine gets
+ * the discriminant value and then searches the array of xdrdiscrims
+ * looking for that value.  It calls the procedure given in the xdrdiscrim
+ * to handle the discriminant.  If there is no specific routine a default
+ * routine may be called.
+ * If there is no specific or default routine an error is returned.
+ */
+bool_t xdr_union(XDR* xdrs, enum_t* dscmp, char* unp, const struct xdr_discrim* choices, xdrproc_t dfault)
+{
+	register enum_t dscm;
+
+	/*
+	 * we deal with the discriminator;  it's an enum
+	 */
+	if (!xdr_enum(xdrs, dscmp)) {
+		return (FALSE);
+	}
+	dscm = *dscmp;
+
+	/*
+	 * search choices for a value that matches the discriminator.
+	 * if we find one, execute the xdr routine for that value.
+	 */
+	for (; choices->proc != NULL_xdrproc_t; choices++) {
+		if (choices->value == dscm)
+			return ((*(choices->proc)) (xdrs, unp, LASTUNSIGNED));
+	}
+
+	/*
+	 * no match - execute the default xdr routine if there is one
+	 */
+	return ((dfault == NULL_xdrproc_t) ? FALSE :
+			(*dfault) (xdrs, unp, LASTUNSIGNED));
+}
+
+
+/*
+ * Non-portable xdr primitives.
+ * Care should be taken when moving these routines to new architectures.
+ */
+
+
+/*
+ * XDR null terminated ASCII strings
+ * xdr_string deals with "C strings" - arrays of bytes that are
+ * terminated by a NULL character.  The parameter cpp references a
+ * pointer to storage; If the pointer is null, then the necessary
+ * storage is allocated.  The last parameter is the max allowed length
+ * of the string as specified by a protocol.
+ */
+bool_t xdr_string(xdrs, cpp, maxsize)
+register XDR *xdrs;
+char **cpp;
+unsigned int maxsize;
+{
+	register char *sp = *cpp;	/* sp is the actual string pointer */
+	unsigned int size;
+	unsigned int nodesize;
+
+	/*
+	 * first deal with the length since xdr strings are counted-strings
+	 */
+	switch (xdrs->x_op) {
+	case XDR_FREE:
+		if (sp == NULL) {
+			return (TRUE);		/* already free */
+		}
+		/* fall through... */
+	case XDR_ENCODE:
+		size = strlen(sp);
+		break;
+	}
+	if (!xdr_u_int(xdrs, &size)) {
+		return (FALSE);
+	}
+	if (size > maxsize) {
+		return (FALSE);
+	}
+	nodesize = size + 1;
+
+	/*
+	 * now deal with the actual bytes
+	 */
+	switch (xdrs->x_op) {
+
+	case XDR_DECODE:
+		if (nodesize == 0) {
+			return (TRUE);
+		}
+		if (sp == NULL)
+			*cpp = sp = (char *) rt_malloc(nodesize);
+		if (sp == NULL) {
+			rt_kprintf("xdr_string: out of memory\n");
+			return (FALSE);
+		}
+		sp[size] = 0;
+		/* fall into ... */
+
+	case XDR_ENCODE:
+		return (xdr_opaque(xdrs, sp, size));
+
+	case XDR_FREE:
+		rt_free(sp);
+		*cpp = NULL;
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/* 
+ * Wrapper for xdr_string that can be called directly from 
+ * routines like clnt_call
+ */
+bool_t xdr_wrapstring(xdrs, cpp)
+XDR *xdrs;
+char **cpp;
+{
+	if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * XDR an array of arbitrary elements
+ * *addrp is a pointer to the array, *sizep is the number of elements.
+ * If addrp is NULL (*sizep * elsize) bytes are allocated.
+ * elsize is the size (in bytes) of each element, and elproc is the
+ * xdr procedure to call to handle each element of the array.
+ */
+bool_t xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
+register XDR *xdrs;
+char* *addrp;					/* array pointer */
+unsigned int *sizep;					/* number of elements */
+unsigned int maxsize;					/* max numberof elements */
+unsigned int elsize;					/* size in bytes of each element */
+xdrproc_t elproc;				/* xdr routine to handle each element */
+{
+	register unsigned int i;
+	register char* target = *addrp;
+	register unsigned int c;			/* the actual element count */
+	register bool_t stat = TRUE;
+	register unsigned int nodesize;
+
+	/* like strings, arrays are really counted arrays */
+	if (!xdr_u_int(xdrs, sizep)) {
+		return (FALSE);
+	}
+	c = *sizep;
+	if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+		return (FALSE);
+	}
+	/* duh, look for integer overflow (fefe) */
+	{
+	  unsigned int i;
+	  nodesize = 0;
+	  for (i=c; i; --i) {
+	    unsigned int tmp=nodesize+elsize;
+	    if (tmp<nodesize)	/* overflow */
+	      return FALSE;
+	    nodesize=tmp;
+	  }
+	}
+
+	/*
+	 * if we are deserializing, we may need to allocate an array.
+	 * We also save time by checking for a null array if we are freeing.
+	 */
+	if (target == NULL)
+		switch (xdrs->x_op) {
+		case XDR_DECODE:
+			if (c == 0)
+				return (TRUE);
+			*addrp = target = rt_malloc(nodesize);
+			if (target == NULL) {
+				rt_kprintf("xdr_array: out of memory\n");
+				return (FALSE);
+			}
+			memset(target, 0, nodesize);
+			break;
+
+		case XDR_FREE:
+			return (TRUE);
+		}
+
+	/*
+	 * now we xdr each element of array
+	 */
+	for (i = 0; (i < c) && stat; i++) {
+		stat = (*elproc) (xdrs, target, LASTUNSIGNED);
+		target += elsize;
+	}
+
+	/*
+	 * the array may need freeing
+	 */
+	if (xdrs->x_op == XDR_FREE) {
+		rt_free(*addrp);
+		*addrp = NULL;
+	}
+	return (stat);
+}
+
+/*
+ * xdr_vector():
+ *
+ * XDR a fixed length array. Unlike variable-length arrays,
+ * the storage of fixed length arrays is static and unfreeable.
+ * > basep: base of the array
+ * > size: size of the array
+ * > elemsize: size of each element
+ * > xdr_elem: routine to XDR each element
+ */
+bool_t xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
+register XDR *xdrs;
+register char *basep;
+register unsigned int nelem;
+register unsigned int elemsize;
+register xdrproc_t xdr_elem;
+{
+	register unsigned int i;
+	register char *elptr;
+
+	elptr = basep;
+	for (i = 0; i < nelem; i++) {
+		if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED)) {
+			return (FALSE);
+		}
+		elptr += elemsize;
+	}
+	return (TRUE);
+}
+
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated.  pp references a pointer to storage. If *pp is null
+ * the  necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t xdr_reference(xdrs, pp, size, proc)
+register XDR *xdrs;
+char* *pp;					/* the pointer to work on */
+unsigned int size;						/* size of the object pointed to */
+xdrproc_t proc;					/* xdr routine to handle the object */
+{
+	register char* loc = *pp;
+	register bool_t stat;
+
+	if (loc == NULL)
+		switch (xdrs->x_op) {
+		case XDR_FREE:
+			return (TRUE);
+
+		case XDR_DECODE:
+			*pp = loc = (char*) rt_malloc(size);
+			if (loc == NULL) {
+				rt_kprintf("xdr_reference: out of memory\n");
+				return (FALSE);
+			}
+			memset(loc, 0, (int) size);
+			break;
+		}
+
+	stat = (*proc) (xdrs, loc, LASTUNSIGNED);
+
+	if (xdrs->x_op == XDR_FREE) {
+		rt_free(loc);
+		*pp = NULL;
+	}
+	return (stat);
+}
+
+
+/*
+ * xdr_pointer():
+ *
+ * XDR a pointer to a possibly recursive data structure. This
+ * differs with xdr_reference in that it can serialize/deserialiaze
+ * trees correctly.
+ *
+ *  What's sent is actually a union:
+ *
+ *  union object_pointer switch (boolean b) {
+ *  case TRUE: object_data data;
+ *  case FALSE: void nothing;
+ *  }
+ *
+ * > objpp: Pointer to the pointer to the object.
+ * > obj_size: size of the object.
+ * > xdr_obj: routine to XDR an object.
+ *
+ */
+bool_t xdr_pointer(xdrs, objpp, obj_size, xdr_obj)
+register XDR *xdrs;
+char **objpp;
+unsigned int obj_size;
+xdrproc_t xdr_obj;
+{
+
+	bool_t more_data;
+
+	more_data = (*objpp != NULL);
+	if (!xdr_bool(xdrs, &more_data)) {
+		return (FALSE);
+	}
+	if (!more_data) {
+		*objpp = NULL;
+		return (TRUE);
+	}
+	return (xdr_reference(xdrs, objpp, obj_size, xdr_obj));
+}

+ 361 - 0
components/dfs/filesystems/nfs/rpc/xdr.h

@@ -0,0 +1,361 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_XDR_H
+#define _RPC_XDR_H
+
+#include <rpc/types.h>
+
+/* We need FILE.  */
+#include <stdio.h>
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation.  Library supplied
+ * routines provide for the conversion on built-in C data types.  These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ *      bool_t
+ *      xdrproc(xdrs, argresp)
+ *              XDR *xdrs;
+ *              <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted.  argresp is a pointer to the structure to be
+ * converted.  The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null.  This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
+ * stream.  XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+  XDR_ENCODE = 0,
+  XDR_DECODE = 1,
+  XDR_FREE = 2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT	(4)
+/*
+ * This only works if the above is a power of 2.  But it's defined to be
+ * 4 by the appropriate RFCs.  So it will work.  And it's normally quicker
+ * than the old routine.
+ */
+#define RNDUP(x)  (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1))
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the particular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular implementation.
+ */
+typedef struct XDR XDR;
+struct XDR
+  {
+    enum xdr_op x_op;		/* operation; fast additional param */
+    struct xdr_ops
+      {
+	bool_t (*x_getlong) (XDR *__xdrs, long *__lp);
+	/* get a long from underlying stream */
+	bool_t (*x_putlong) (XDR *__xdrs, const long *__lp);
+	/* put a long to " */
+	bool_t (*x_getbytes) (XDR *__xdrs, char* __addr, unsigned int __len);
+	/* get some bytes from " */
+	bool_t (*x_putbytes) (XDR *__xdrs, const char *__addr, unsigned int __len);
+	/* put some bytes to " */
+	unsigned int (*x_getpostn) (const XDR *__xdrs);
+	/* returns bytes off from beginning */
+	bool_t (*x_setpostn) (XDR *__xdrs, unsigned int __pos);
+	/* lets you reposition the stream */
+	int32_t *(*x_inline) (XDR *__xdrs, unsigned int __len);
+	/* buf quick ptr to buffered data */
+	void (*x_destroy) (XDR *__xdrs);
+	/* free privates of this xdr_stream */
+	bool_t (*x_getint32) (XDR *__xdrs, int32_t *__ip);
+	/* get a int from underlying stream */
+	bool_t (*x_putint32) (XDR *__xdrs, const int32_t *__ip);
+	/* put a int to " */
+      }
+     *x_ops;
+    char* x_public;		/* users' data */
+    char* x_private;		/* pointer to private data */
+    char* x_base;		/* private used for position info */
+    unsigned int x_handy;	/* extra private word */
+  };
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded.  If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ * bool_t       (*xdrproc_t)(XDR *, char* *);
+ */
+typedef bool_t (*xdrproc_t) (XDR *, void *,...);
+
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR          *xdrs;
+ * int32_t      *int32p;
+ * long         *longp;
+ * char*       addr;
+ * unsigned int         len;
+ * unsigned int         pos;
+ */
+#define XDR_GETINT32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
+#define xdr_getint32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
+
+#define XDR_PUTINT32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
+#define xdr_putint32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
+
+#define XDR_GETLONG(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs)				\
+	(*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs)				\
+	(*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos)				\
+	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos)				\
+	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define	XDR_INLINE(xdrs, len)				\
+	(*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define	xdr_inline(xdrs, len)				\
+	(*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define	XDR_DESTROY(xdrs)					\
+	do {							\
+		if ((xdrs)->x_ops->x_destroy)			\
+			(*(xdrs)->x_ops->x_destroy)(xdrs);	\
+	} while (0)
+#define	xdr_destroy(xdrs)					\
+	do {							\
+		if ((xdrs)->x_ops->x_destroy)			\
+			(*(xdrs)->x_ops->x_destroy)(xdrs);	\
+	} while (0)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * a entry with a null procedure pointer.  The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value.  If a match is found the associated xdr routine
+ * is called to handle that part of the union.  If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim
+{
+  int value;
+  xdrproc_t proc;
+};
+
+/*
+ * Inline routines for fast encode/decode of primitive data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned.  The standard way to use these
+ * is to say:
+ *      if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ *              return (FALSE);
+ *      <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+
+#define IXDR_GET_INT32(buf)           ((int32_t)ntohl((uint32_t)*(buf)++))
+#define IXDR_PUT_INT32(buf, v)        (*(buf)++ = (int32_t)htonl((uint32_t)(v)))
+#define IXDR_GET_U_INT32(buf)         ((uint32_t)IXDR_GET_INT32(buf))
+#define IXDR_PUT_U_INT32(buf, v)      IXDR_PUT_INT32(buf, (int32_t)(v))
+
+/* WARNING: The IXDR_*_LONG defines are removed by Sun for new platforms
+ * and shouldn't be used any longer. Code which use this defines or longs
+ * in the RPC code will not work on 64bit Solaris platforms !
+ */
+#define IXDR_GET_LONG(buf)	      ((long)IXDR_GET_U_INT32(buf))
+#define IXDR_PUT_LONG(buf, v)	      ((long)IXDR_PUT_INT32(buf, (long)(v)))
+#define IXDR_GET_U_LONG(buf)	      ((unsigned long)IXDR_GET_LONG(buf))
+#define IXDR_PUT_U_LONG(buf, v)	      IXDR_PUT_LONG(buf, (long)(v))
+
+
+#define IXDR_GET_BOOL(buf)            ((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t)         ((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf)           ((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf)         ((unsigned short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v)         IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_ENUM(buf, v)         IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_SHORT(buf, v)        IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_U_SHORT(buf, v)      IXDR_PUT_LONG(buf, (long)(v))
+
+/*
+ * These are the "generic" xdr routines.
+ * None of these can have const applied because it's not possible to
+ * know whether the call is a read or a write to the passed parameter
+ * also, the XDR structure is always updated by some of these calls.
+ */
+extern bool_t xdr_void (void);
+extern bool_t xdr_short (XDR *__xdrs, short *__sp);
+extern bool_t xdr_u_short (XDR *__xdrs, unsigned short *__usp);
+extern bool_t xdr_int (XDR *__xdrs, int *__ip);
+extern bool_t xdr_u_int (XDR *__xdrs, unsigned int *__up);
+extern bool_t xdr_long (XDR *__xdrs, long *__lp);
+extern bool_t xdr_u_long (XDR *__xdrs, unsigned long *__ulp);
+extern bool_t xdr_hyper (XDR *__xdrs, int64_t *__llp);
+extern bool_t xdr_u_hyper (XDR *__xdrs, uint64_t *__ullp);
+extern bool_t xdr_longlong_t (XDR *__xdrs, int64_t *__llp);
+extern bool_t xdr_u_longlong_t (XDR *__xdrs, uint64_t *__ullp);
+extern bool_t xdr_int8_t (XDR *__xdrs, int8_t *__ip);
+extern bool_t xdr_uint8_t (XDR *__xdrs, uint8_t *__up);
+extern bool_t xdr_int16_t (XDR *__xdrs, int16_t *__ip);
+extern bool_t xdr_uint16_t (XDR *__xdrs, uint16_t *__up);
+extern bool_t xdr_int32_t (XDR *__xdrs, int32_t *__ip);
+extern bool_t xdr_uint32_t (XDR *__xdrs, uint32_t *__up);
+extern bool_t xdr_int64_t (XDR *__xdrs, int64_t *__ip);
+extern bool_t xdr_uint64_t (XDR *__xdrs, uint64_t *__up);
+extern bool_t xdr_bool (XDR *__xdrs, bool_t *__bp);
+extern bool_t xdr_enum (XDR *__xdrs, enum_t *__ep);
+extern bool_t xdr_array (XDR * _xdrs, char* *__addrp, unsigned int *__sizep,
+			 unsigned int __maxsize, unsigned int __elsize, xdrproc_t __elproc);
+extern bool_t xdr_bytes (XDR *xdrs, char **cpp, unsigned int *sizep,
+			 unsigned int maxsize);
+extern bool_t xdr_opaque (XDR *__xdrs, char* __cp, unsigned int __cnt);
+extern bool_t xdr_string (XDR *xdrs, char **cpp, unsigned int maxsize);
+extern bool_t xdr_union (XDR *__xdrs, enum_t *__dscmp, char *__unp,
+			 const struct xdr_discrim *__choices,
+			 xdrproc_t dfault);
+extern bool_t xdr_char (XDR *__xdrs, char *__cp);
+extern bool_t xdr_u_char (XDR *__xdrs, unsigned char *__cp);
+extern bool_t xdr_vector (XDR *__xdrs, char *__basep, unsigned int __nelem,
+			  unsigned int __elemsize, xdrproc_t __xdr_elem);
+extern bool_t xdr_float (XDR *__xdrs, float *__fp);
+extern bool_t xdr_double (XDR *__xdrs, double *__dp);
+extern bool_t xdr_reference (XDR *__xdrs, char* *__xpp, unsigned int __size,
+			     xdrproc_t __proc);
+extern bool_t xdr_pointer (XDR *__xdrs, char **__objpp,
+			   unsigned int __obj_size, xdrproc_t __xdr_obj);
+extern bool_t xdr_wrapstring (XDR *__xdrs, char **cpp);
+extern unsigned long xdr_sizeof (xdrproc_t, void *);
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024
+struct netobj
+{
+  unsigned int n_len;
+  char *n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t xdr_netobj (XDR *__xdrs, struct netobj *__np);
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+
+/* XDR using memory buffers */
+extern void xdrmem_create (XDR *__xdrs, const char* __addr,
+			   unsigned int __size, enum xdr_op __xop);
+
+/* XDR pseudo records for tcp */
+extern void xdrrec_create (XDR *__xdrs, unsigned int __sendsize,
+			   unsigned int __recvsize, char* __tcp_handle,
+			   int (*__readit) (char *, char *, int),
+			   int (*__writeit) (char *, char *, int));
+
+/* make end of xdr record */
+extern bool_t xdrrec_endofrecord (XDR *__xdrs, bool_t __sendnow);
+
+/* move to beginning of next record */
+extern bool_t xdrrec_skiprecord (XDR *__xdrs);
+
+/* true if no more input */
+extern bool_t xdrrec_eof (XDR *__xdrs);
+
+/* free memory buffers for xdr */
+extern void xdr_free (xdrproc_t __proc, char *__objp);
+
+#endif /* rpc/xdr.h */

+ 166 - 0
components/dfs/filesystems/nfs/rpc/xdr_mem.c

@@ -0,0 +1,166 @@
+/* @(#)xdr_mem.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <string.h>
+#include <limits.h>
+
+static bool_t xdrmem_getlong (XDR *, long *);
+static bool_t xdrmem_putlong (XDR *, const long *);
+static bool_t xdrmem_getbytes (XDR *, char *, unsigned int);
+static bool_t xdrmem_putbytes (XDR *, const char *, unsigned int);
+static unsigned int xdrmem_getpos (const XDR *);
+static bool_t xdrmem_setpos (XDR *, unsigned int);
+static int32_t *xdrmem_inline (XDR *, unsigned int);
+static void xdrmem_destroy (XDR *);
+
+static struct xdr_ops xdrmem_ops = {
+	xdrmem_getlong,
+	xdrmem_putlong,
+	xdrmem_getbytes,
+	xdrmem_putbytes,
+	xdrmem_getpos,
+	xdrmem_setpos,
+	xdrmem_inline,
+	xdrmem_destroy,
+	NULL,
+	NULL
+};
+
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.  
+ */
+void
+xdrmem_create (XDR *xdrs, const char* addr, unsigned int size, enum xdr_op op)
+{
+	xdrs->x_op = op;
+	xdrs->x_ops = &xdrmem_ops;
+	xdrs->x_private = xdrs->x_base = (char*)addr;
+	xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy (XDR *xdrs)
+{
+}
+
+static bool_t
+xdrmem_getlong (XDR *xdrs, long *lp)
+{
+  if (xdrs->x_handy < 4) return FALSE;
+  xdrs->x_handy -= 4;
+
+  *lp = (int32_t) ntohl((*((int32_t *) (xdrs->x_private))));
+  xdrs->x_private += 4;
+  return TRUE;
+}
+
+static bool_t
+xdrmem_putlong (XDR *xdrs, const long *lp)
+{
+  if (xdrs->x_handy < 4) return FALSE;
+  xdrs->x_handy -= 4;
+
+  *(int32_t *) xdrs->x_private = htonl(*lp);
+  xdrs->x_private += 4;
+  return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes (XDR *xdrs, char *addr, unsigned int len)
+{
+  if (xdrs->x_handy < len) return FALSE;
+  xdrs->x_handy -= len;
+  memmove(addr, xdrs->x_private, len);
+  xdrs->x_private += len;
+  return TRUE;
+}
+
+static bool_t
+xdrmem_putbytes (XDR *xdrs, const char *addr, unsigned int len)
+{
+  if (xdrs->x_handy < len) return FALSE;
+  xdrs->x_handy -= len;
+  memmove(xdrs->x_private, addr, len);
+  xdrs->x_private += len;
+  return (TRUE);
+}
+
+static unsigned int xdrmem_getpos (const XDR *xdrs)
+{
+	return ((unsigned long) xdrs->x_private - (unsigned long) xdrs->x_base);
+}
+
+static bool_t xdrmem_setpos(xdrs, pos)
+register XDR *xdrs;
+unsigned int pos;
+{
+  register char* newaddr = xdrs->x_base + pos;
+  register char* lastaddr = xdrs->x_private + xdrs->x_handy;
+
+  if ((long) newaddr > (long) lastaddr
+	  || (UINT_MAX < LONG_MAX
+		  && (long) UINT_MAX < (long) lastaddr - (long) newaddr))
+	  return (FALSE);
+  xdrs->x_private = newaddr;
+  xdrs->x_handy = (long) lastaddr - (long) newaddr;
+  return (TRUE);
+}
+
+static int32_t *
+xdrmem_inline (XDR *xdrs, unsigned int len)
+{
+	int32_t *buf = 0;
+
+	if (xdrs->x_handy >= len) {
+		xdrs->x_handy -= len;
+		buf = (int32_t *) xdrs->x_private;
+		xdrs->x_private += len;
+	}
+	return (buf);
+}
+