Initial start on a user-level NFS server.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Thu, 20 Aug 2009 22:07:18 +0000 (15:07 -0700)
committerMichael Vrable <mvrable@turin.ucsd.edu>
Thu, 20 Aug 2009 22:07:18 +0000 (15:07 -0700)
15 files changed:
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
inode.c [new file with mode: 0644]
inode.h [new file with mode: 0644]
nfs3/Makefile [new file with mode: 0644]
nfs3/mount.c [new file with mode: 0644]
nfs3/mount_prot.h [new file with mode: 0644]
nfs3/mount_prot.x [new file with mode: 0644]
nfs3/mount_prot_xdr.c [new file with mode: 0644]
nfs3/nfs3.c [new file with mode: 0644]
nfs3/nfs3_prot.h [new file with mode: 0644]
nfs3/nfs3_prot.x [new file with mode: 0644]
nfs3/nfs3_prot_xdr.c [new file with mode: 0644]
nfs3/nfsd.c [new file with mode: 0644]
nfs3/rpc.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..5761abc
--- /dev/null
@@ -0,0 +1 @@
+*.o
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..593f4d4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+PACKAGES=glib-2.0
+DEBUG=-g
+CFLAGS=-O -Wall -D_FILE_OFFSET_BITS=64 $(DEBUG) \
+       $(shell pkg-config --cflags $(PACKAGES))
+LDFLAGS=$(DEBUG) $(shell pkg-config --libs $(PACKAGES))
+
+SRCS=nfsd.c rpc.c mount.c mount_prot_xdr.c
+OBJS=$(SRCS:.c=.o)
+
+nfsproxy : $(OBJS)
+       $(CC) $(LDFLAGS) -o $@ $^
+
+clean :
+       rm -f $(OBJS) nfsproxy
+
+dep :
+       touch Makefile.dep
+       makedepend -fMakefile.dep $(SRCS)
+
+.PHONY : clean dep
+
+-include *.dep
diff --git a/inode.c b/inode.c
new file mode 100644 (file)
index 0000000..5f31326
--- /dev/null
+++ b/inode.c
@@ -0,0 +1,112 @@
+/* Blue Sky: File Systems in the Cloud
+ *
+ * Copyright (C) 2009  The Regents of the University of California
+ * Written by Michael Vrable <mvrable@cs.ucsd.edu>
+ *
+ * TODO: Licensing
+ */
+
+#include <stdint.h>
+#include <glib.h>
+
+#include "inode.h"
+
+/* Core filesystem.  Different proxies, such as the NFSv3 one, interface to
+ * this, but the core actually tracks the data which is stored.  So far we just
+ * implement an in-memory filesystem, but eventually this will be state which
+ * is persisted to the cloud. */
+
+
+/* Hash a filename for a directory lookup.  The string is hashed to a 64-bit
+ * value. */
+uint64_t bluesky_directory_hash(gchar *name)
+{
+    GChecksum *csum = g_checksum_new(G_CHECKSUM_MD5);
+    g_checksum_update(csum, (guchar *)name, -1);
+
+    guint64 hashbytes[2];
+    gsize hashsize = sizeof(hashbytes);
+    g_checksum_get_digest(csum, (guint8 *)hashbytes, &hashsize);
+    return GUINT64_FROM_LE(hashbytes[0]);
+}
+
+/* Return the current time, in microseconds since the epoch. */
+int64_t bluesky_get_current_time()
+{
+    GTimeVal t;
+    g_get_current_time(&t);
+    return t.tv_sec * 1000000 + t.tv_usec;
+}
+
+/* Allocate a fresh inode number which has not been used before within a
+ * filesystem. */
+uint64_t bluesky_fs_alloc_inode(BlueSkyFS *fs)
+{
+    uint64_t inum;
+
+    g_mutex_lock(fs->lock);
+    inum = fs->next_inum;
+    fs->next_inum++;
+    g_mutex_unlock(fs->lock);
+
+    return inum;
+}
+
+BlueSkyInode *bluesky_new_inode(uint64_t inum)
+{
+    BlueSkyInode *i = g_new0(BlueSkyInode, 1);
+
+    i->lock = g_mutex_new();
+    i->inum = inum;
+
+    return i;
+}
+
+void bluesky_dirent_destroy(BlueSkyDirent *dirent)
+{
+    g_free(dirent->name);
+    g_free(dirent);
+}
+
+gint bluesky_dirent_compare(gconstpointer a, gconstpointer b,
+                            gpointer unused)
+{
+    /* We can't simply subtract the hash values, since they are 64-bit and the
+     * result could overflow when converted to a gint. */
+    uint64_t hash1 = ((const BlueSkyDirent *)a)->hash;
+    uint64_t hash2 = ((const BlueSkyDirent *)b)->hash;
+
+    if (hash1 < hash2)
+        return -1;
+    else if (hash1 > hash2)
+        return 1;
+    else
+        return 0;
+}
+
+/* Perform a lookup for a file name within a directory.  Returns the inode
+ * number if found, or 0 if not (0 is never a valid inode number).  Should be
+ * called with the inode lock already held. */
+uint64_t bluesky_directory_lookup(BlueSkyInode *inode, gchar *name)
+{
+    g_return_val_if_fail(inode->type != BLUESKY_DIRECTORY, 0);
+    g_return_val_if_fail(inode->dirents != NULL, 0);
+
+    /* First, construct a hash of the file name.  Search the directory for a
+     * match, then check to see if it does really match. */
+    uint64_t hash = bluesky_directory_hash(name);
+
+    BlueSkyDirent d = {name, hash, 0};
+    GSequenceIter *i = g_sequence_search(inode->dirents, &d,
+                                         bluesky_dirent_compare, NULL);
+
+    if (g_sequence_iter_is_end(i))
+        return 0;
+    BlueSkyDirent *dirent = g_sequence_get(i);
+    if (dirent->hash != hash)
+        return 0;
+    if (g_strcmp0(name, dirent->name) != 0)
+        return 0;
+
+    return dirent->inum;
+}
diff --git a/inode.h b/inode.h
new file mode 100644 (file)
index 0000000..23361c5
--- /dev/null
+++ b/inode.h
@@ -0,0 +1,75 @@
+#ifndef _BLUESKY_INODE_H
+#define _BLUESKY_INODE_H
+
+#include <stdint.h>
+#include <glib.h>
+
+/* File types.  The numeric values are chosen to match with those used in
+ * NFSv3. */
+enum BlueSkyFileType {
+    BLUESKY_INVALID = 0,
+    BLUESKY_REGULAR = 1,
+    BLUESKY_DIRECTORY = 2,
+    BLUESKY_BLOCK = 3,
+    BLUESKY_CHARACTER = 4,
+    BLUESKY_SYMLINK = 5,
+    BLUESKY_SOCKET = 6,
+    BLUESKY_FIFO = 7,
+};
+
+/* Filesystem state.  Each filesystem which is exported is represented by a
+ * single bluesky_fs structure in memory. */
+typedef struct {
+    GMutex *lock;
+
+    gchar *name;                /* Descriptive name for the filesystem */
+    GHashTable *inodes;         /* Cached inodes */
+    uint64_t next_inum;         /* Next available inode for allocation */
+} BlueSkyFS;
+
+/* Timestamp, measured in microseconds since the Unix epoch. */
+typedef int64_t bluesky_time;
+
+/* In-memory representation of an inode within a Blue Sky server.  This
+ * corresponds roughly with information that is committed to persistent
+ * storage. */
+typedef struct {
+    gint refcnt;                /* May be accessed atomically without lock */
+    GMutex *lock;
+
+    int type;
+    uint32_t mode;
+    uint32_t uid, gid;
+    uint32_t nlink;
+
+    /* Rather than track an inode number and generation number, we will simply
+     * never re-use a fileid after a file is deleted.  64 bits should be enough
+     * that we don't exhaust the identifier space. */
+    uint64_t inum;
+
+    uint64_t change_count;      /* Incremented each with each change made */
+    int64_t atime;              /* Microseconds since the Unix epoch */
+    int64_t ctime;
+    int64_t mtime;
+    int64_t ntime;              /* "new time": time object was created */
+
+    /* File-specific fields */
+    uint64_t size;
+
+    /* Directory-specific fields */
+    GSequence *dirents;
+} BlueSkyInode;
+
+/* A directory entry.  The name is UTF-8 and is a freshly-allocated string.
+ * The name is hashed to a 64-bit value, and the directory entries are sorted
+ * by hash value (the hash value can then be used as a cookie for resuming a
+ * READDIR call). */
+typedef struct {
+    gchar *name;
+    uint64_t hash;
+    uint64_t inum;
+} BlueSkyDirent ;
+
+uint64_t bluesky_directory_hash(gchar *name);
+
+#endif
diff --git a/nfs3/Makefile b/nfs3/Makefile
new file mode 100644 (file)
index 0000000..87b2c04
--- /dev/null
@@ -0,0 +1,22 @@
+PACKAGES=glib-2.0
+DEBUG=-g
+CFLAGS=-O -Wall -D_FILE_OFFSET_BITS=64 $(DEBUG) \
+       $(shell pkg-config --cflags $(PACKAGES))
+LDFLAGS=$(DEBUG) $(shell pkg-config --libs $(PACKAGES))
+
+SRCS=nfsd.c rpc.c mount.c nfs3.c mount_prot_xdr.c nfs3_prot_xdr.c
+OBJS=$(SRCS:.c=.o)
+
+nfsproxy : $(OBJS)
+       $(CC) $(LDFLAGS) -o $@ $^
+
+clean :
+       rm -f $(OBJS) nfsproxy
+
+dep :
+       touch Makefile.dep
+       makedepend -fMakefile.dep $(SRCS)
+
+.PHONY : clean dep
+
+-include *.dep
diff --git a/nfs3/mount.c b/nfs3/mount.c
new file mode 100644 (file)
index 0000000..e4eb3a1
--- /dev/null
@@ -0,0 +1,57 @@
+#include "mount_prot.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <rpc/pmap_clnt.h>
+#include <string.h>
+#include <memory.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+static int null_int;
+static void *null_result = (void *)&null_int;
+
+void *
+mountproc3_null_3_svc(void *argp, struct svc_req *rqstp)
+{
+    return null_result;
+}
+
+mountres3 *
+mountproc3_mnt_3_svc(dirpath *argp, struct svc_req *rqstp)
+{
+    static char fhbytes[] = {0, 0, 0, 1};
+    static fhandle3 fh = {4, fhbytes};
+    static mountres3 result;
+    static int auth_flavors = AUTH_UNIX;
+
+    result.fhs_status = MNT3_OK;
+    result.mountres3_u.mountinfo.fhandle = fh;
+    result.mountres3_u.mountinfo.auth_flavors.auth_flavors_len = 1;
+    result.mountres3_u.mountinfo.auth_flavors.auth_flavors_val = &auth_flavors;
+
+    return &result;
+}
+
+mountlist *
+mountproc3_dump_3_svc(void *argp, struct svc_req *rqstp)
+{
+    return null_result;
+}
+
+void *
+mountproc3_umnt_3_svc(dirpath *argp, struct svc_req *rqstp)
+{
+    return null_result;
+}
+
+void *
+mountproc3_umntall_3_svc(void *argp, struct svc_req *rqstp)
+{
+    return null_result;
+}
+
+exports *
+mountproc3_export_3_svc(void *argp, struct svc_req *rqstp)
+{
+    return null_result;
+}
diff --git a/nfs3/mount_prot.h b/nfs3/mount_prot.h
new file mode 100644 (file)
index 0000000..74c15fb
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _MOUNT_PROT_H_RPCGEN
+#define _MOUNT_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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;
+
+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;
+
+typedef struct mountbody *mountlist;
+
+struct mountbody {
+       name ml_hostname;
+       dirpath ml_directory;
+       mountlist ml_next;
+};
+typedef struct mountbody mountbody;
+
+typedef struct groupnode *groups;
+
+struct groupnode {
+       name gr_name;
+       groups gr_next;
+};
+typedef struct groupnode groupnode;
+
+typedef struct exportnode *exports;
+
+struct exportnode {
+       dirpath ex_dir;
+       groups ex_groups;
+       exports ex_next;
+};
+typedef struct exportnode exportnode;
+
+#define MOUNT_PROGRAM 100005
+#define MOUNT_V3 3
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC3_NULL 0
+extern  void * mountproc3_null_3(void *, CLIENT *);
+extern  void * mountproc3_null_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_MNT 1
+extern  mountres3 * mountproc3_mnt_3(dirpath *, CLIENT *);
+extern  mountres3 * mountproc3_mnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_DUMP 2
+extern  mountlist * mountproc3_dump_3(void *, CLIENT *);
+extern  mountlist * mountproc3_dump_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_UMNT 3
+extern  void * mountproc3_umnt_3(dirpath *, CLIENT *);
+extern  void * mountproc3_umnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_UMNTALL 4
+extern  void * mountproc3_umntall_3(void *, CLIENT *);
+extern  void * mountproc3_umntall_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_EXPORT 5
+extern  exports * mountproc3_export_3(void *, CLIENT *);
+extern  exports * mountproc3_export_3_svc(void *, struct svc_req *);
+extern int mount_program_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define MOUNTPROC3_NULL 0
+extern  void * mountproc3_null_3();
+extern  void * mountproc3_null_3_svc();
+#define MOUNTPROC3_MNT 1
+extern  mountres3 * mountproc3_mnt_3();
+extern  mountres3 * mountproc3_mnt_3_svc();
+#define MOUNTPROC3_DUMP 2
+extern  mountlist * mountproc3_dump_3();
+extern  mountlist * mountproc3_dump_3_svc();
+#define MOUNTPROC3_UMNT 3
+extern  void * mountproc3_umnt_3();
+extern  void * mountproc3_umnt_3_svc();
+#define MOUNTPROC3_UMNTALL 4
+extern  void * mountproc3_umntall_3();
+extern  void * mountproc3_umntall_3_svc();
+#define MOUNTPROC3_EXPORT 5
+extern  exports * mountproc3_export_3();
+extern  exports * mountproc3_export_3_svc();
+extern int mount_program_3_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+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_mountstat3 (XDR *, mountstat3*);
+extern  bool_t xdr_mountres3_ok (XDR *, mountres3_ok*);
+extern  bool_t xdr_mountres3 (XDR *, mountres3*);
+extern  bool_t xdr_mountlist (XDR *, mountlist*);
+extern  bool_t xdr_mountbody (XDR *, mountbody*);
+extern  bool_t xdr_groups (XDR *, groups*);
+extern  bool_t xdr_groupnode (XDR *, groupnode*);
+extern  bool_t xdr_exports (XDR *, exports*);
+extern  bool_t xdr_exportnode (XDR *, exportnode*);
+
+#else /* K&R C */
+extern bool_t xdr_fhandle3 ();
+extern bool_t xdr_dirpath ();
+extern bool_t xdr_name ();
+extern bool_t xdr_mountstat3 ();
+extern bool_t xdr_mountres3_ok ();
+extern bool_t xdr_mountres3 ();
+extern bool_t xdr_mountlist ();
+extern bool_t xdr_mountbody ();
+extern bool_t xdr_groups ();
+extern bool_t xdr_groupnode ();
+extern bool_t xdr_exports ();
+extern bool_t xdr_exportnode ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_MOUNT_PROT_H_RPCGEN */
diff --git a/nfs3/mount_prot.x b/nfs3/mount_prot.x
new file mode 100644 (file)
index 0000000..c5ff613
--- /dev/null
@@ -0,0 +1,66 @@
+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>;
+
+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;
+};
+
+typedef struct mountbody *mountlist;
+
+struct mountbody {
+    name ml_hostname;
+    dirpath ml_directory;
+    mountlist ml_next;
+};
+
+typedef struct groupnode *groups;
+
+struct groupnode {
+    name gr_name;
+    groups gr_next;
+};
+
+typedef struct exportnode *exports;
+
+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;
diff --git a/nfs3/mount_prot_xdr.c b/nfs3/mount_prot_xdr.c
new file mode 100644 (file)
index 0000000..8182c75
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "mount_prot.h"
+
+bool_t
+xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_dirpath (XDR *xdrs, dirpath *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_string (xdrs, objp, MNTPATHLEN))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_name (XDR *xdrs, name *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_string (xdrs, objp, MNTNAMLEN))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, mountres3 *objp)
+{
+       register int32_t *buf;
+
+        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;
+       default:
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_mountlist (XDR *xdrs, mountlist *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountbody (XDR *xdrs, mountbody *objp)
+{
+       register int32_t *buf;
+
+        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_groups (XDR *xdrs, groups *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_groupnode (XDR *xdrs, groupnode *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_name (xdrs, &objp->gr_name))
+                return FALSE;
+        if (!xdr_groups (xdrs, &objp->gr_next))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_exports (XDR *xdrs, exports *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_exportnode (XDR *xdrs, exportnode *objp)
+{
+       register int32_t *buf;
+
+        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;
+}
diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c
new file mode 100644 (file)
index 0000000..cbf5650
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * This is sample code generated by rpcgen.
+ * These are only templates and you can use them
+ * as a guideline for developing your own functions.
+ */
+
+#include "nfs3_prot.h"
+
+static int null_int;
+static void *null_result = (void *)&null_int;
+
+void encode_fattr3(struct fattr3 *result, uint64_t inum)
+{
+    result->type = NF3DIR;
+    result->mode = 0755;
+    result->nlink = 1;
+    result->uid = 0;
+    result->gid = 0;
+    result->size = 0;
+    result->used = 0;
+    result->rdev.major = 0;
+    result->rdev.minor = 0;
+    result->fsid = 0;
+    result->fileid = inum;
+    result->atime.seconds = 0;
+    result->atime.nseconds = 0;
+    result->mtime.seconds = 0;
+    result->mtime.nseconds = 0;
+    result->ctime.seconds = 0;
+    result->ctime.nseconds = 0;
+}
+
+void *
+nfsproc3_null_3_svc(void *argp, struct svc_req *rqstp)
+{
+    return null_result;
+}
+
+getattr3res *
+nfsproc3_getattr_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
+{
+    static getattr3res result;
+
+    result.status = NFS3_OK;
+    encode_fattr3(&result.getattr3res_u.attributes, 1);
+
+    return &result;
+}
+
+wccstat3 *
+nfsproc3_setattr_3_svc(setattr3args *argp, struct svc_req *rqstp)
+{
+    static wccstat3 result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+lookup3res *
+nfsproc3_lookup_3_svc(diropargs3 *argp, struct svc_req *rqstp)
+{
+    static lookup3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+access3res *
+nfsproc3_access_3_svc(access3args *argp, struct svc_req *rqstp)
+{
+    static access3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+readlink3res *
+nfsproc3_readlink_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
+{
+    static readlink3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+read3res *
+nfsproc3_read_3_svc(read3args *argp, struct svc_req *rqstp)
+{
+    static read3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+write3res *
+nfsproc3_write_3_svc(write3args *argp, struct svc_req *rqstp)
+{
+    static write3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+diropres3 *
+nfsproc3_create_3_svc(create3args *argp, struct svc_req *rqstp)
+{
+    static diropres3 result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+diropres3 *
+nfsproc3_mkdir_3_svc(mkdir3args *argp, struct svc_req *rqstp)
+{
+    static diropres3 result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+diropres3 *
+nfsproc3_symlink_3_svc(symlink3args *argp, struct svc_req *rqstp)
+{
+    static diropres3 result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+diropres3 *
+nfsproc3_mknod_3_svc(mknod3args *argp, struct svc_req *rqstp)
+{
+    static diropres3 result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+wccstat3 *
+nfsproc3_remove_3_svc(diropargs3 *argp, struct svc_req *rqstp)
+{
+    static wccstat3 result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+wccstat3 *
+nfsproc3_rmdir_3_svc(diropargs3 *argp, struct svc_req *rqstp)
+{
+    static wccstat3 result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+rename3res *
+nfsproc3_rename_3_svc(rename3args *argp, struct svc_req *rqstp)
+{
+    static rename3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+link3res *
+nfsproc3_link_3_svc(link3args *argp, struct svc_req *rqstp)
+{
+    static link3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+readdir3res *
+nfsproc3_readdir_3_svc(readdir3args *argp, struct svc_req *rqstp)
+{
+    static readdir3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+readdirplus3res *
+nfsproc3_readdirplus_3_svc(readdirplus3args *argp, struct svc_req *rqstp)
+{
+    static readdirplus3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+fsstat3res *
+nfsproc3_fsstat_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
+{
+    static fsstat3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
+
+fsinfo3res *
+nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
+{
+    static fsinfo3res result;
+
+    result.status = NFS3_OK;
+    result.fsinfo3res_u.resok.obj_attributes.present = TRUE;
+    encode_fattr3(&result.fsinfo3res_u.resok.obj_attributes.post_op_attr_u.attributes, 1);
+    result.fsinfo3res_u.resok.rtmax = 32768;
+    result.fsinfo3res_u.resok.rtpref = 32768;
+    result.fsinfo3res_u.resok.rtmult = 4096;
+    result.fsinfo3res_u.resok.wtmax = 32768;
+    result.fsinfo3res_u.resok.wtpref = 32768;
+    result.fsinfo3res_u.resok.wtmult = 4096;
+    result.fsinfo3res_u.resok.dtpref = 4096;
+    result.fsinfo3res_u.resok.maxfilesize = 0x7fffffffffffffffULL;
+    result.fsinfo3res_u.resok.time_delta.seconds = 0;
+    result.fsinfo3res_u.resok.time_delta.nseconds = 1000;
+    result.fsinfo3res_u.resok.properties
+        = FSF3_LINK | FSF3_SYMLINK | FSF3_HOMOGENEOUS | FSF3_CANSETTIME;
+
+    return &result;
+}
+
+pathconf3res *
+nfsproc3_pathconf_3_svc(nfs_fh3 *argp, struct svc_req *rqstp)
+{
+    static pathconf3res result;
+
+    result.status = NFS3_OK;
+    result.pathconf3res_u.resok.obj_attributes.present = TRUE;
+    encode_fattr3(&result.pathconf3res_u.resok.obj_attributes.post_op_attr_u.attributes, 1);
+    result.pathconf3res_u.resok.linkmax = 0xffffffff;
+    result.pathconf3res_u.resok.name_max = 255;
+    result.pathconf3res_u.resok.no_trunc = TRUE;
+    result.pathconf3res_u.resok.chown_restricted = TRUE;
+    result.pathconf3res_u.resok.case_insensitive = FALSE;
+    result.pathconf3res_u.resok.case_preserving = TRUE;
+
+    return &result;
+}
+
+commit3res *
+nfsproc3_commit_3_svc(commit3args *argp, struct svc_req *rqstp)
+{
+    static commit3res result;
+
+    result.status = NFS3ERR_NOTSUPP;
+
+    return &result;
+}
diff --git a/nfs3/nfs3_prot.h b/nfs3/nfs3_prot.h
new file mode 100644 (file)
index 0000000..5839996
--- /dev/null
@@ -0,0 +1,959 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NFS3_PROT_H_RPCGEN
+#define _NFS3_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef u_quad_t uint64;
+
+typedef quad_t int64;
+
+typedef u_int uint32;
+
+typedef int int32;
+#define NFS3_FHSIZE 64
+#define NFS3_COOKIEVERFSIZE 8
+#define NFS3_CREATEVERFSIZE 8
+#define NFS3_WRITEVERFSIZE 8
+
+typedef char *filename3;
+
+typedef char *nfspath3;
+
+typedef char cookieverf3[NFS3_COOKIEVERFSIZE];
+
+typedef char createverf3[NFS3_CREATEVERFSIZE];
+
+typedef char writeverf3[NFS3_WRITEVERFSIZE];
+
+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,
+       NFS3ERR_FPRINTNOTFOUND = 10009,
+       NFS3ERR_ABORTED = 10010,
+};
+typedef enum nfsstat3 nfsstat3;
+
+enum ftype3 {
+       NF3REG = 1,
+       NF3DIR = 2,
+       NF3BLK = 3,
+       NF3CHR = 4,
+       NF3LNK = 5,
+       NF3SOCK = 6,
+       NF3FIFO = 7,
+};
+typedef enum ftype3 ftype3;
+
+struct specdata3 {
+       uint32 major;
+       uint32 minor;
+};
+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;
+       uint32 mode;
+       uint32 nlink;
+       uint32 uid;
+       uint32 gid;
+       uint64 size;
+       uint64 used;
+       specdata3 rdev;
+       uint64 fsid;
+       uint64 fileid;
+       nfstime3 atime;
+       nfstime3 mtime;
+       nfstime3 ctime;
+};
+typedef struct fattr3 fattr3;
+
+struct post_op_attr {
+       bool_t present;
+       union {
+               fattr3 attributes;
+       } post_op_attr_u;
+};
+typedef struct post_op_attr post_op_attr;
+
+struct wcc_attr {
+       uint64 size;
+       nfstime3 mtime;
+       nfstime3 ctime;
+};
+typedef struct wcc_attr wcc_attr;
+
+struct pre_op_attr {
+       bool_t present;
+       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 present;
+       union {
+               nfs_fh3 handle;
+       } post_op_fh3_u;
+};
+typedef struct post_op_fh3 post_op_fh3;
+
+struct set_uint32 {
+       bool_t set;
+       union {
+               uint32 val;
+       } set_uint32_u;
+};
+typedef struct set_uint32 set_uint32;
+
+struct set_uint64 {
+       bool_t set;
+       union {
+               uint64 val;
+       } set_uint64_u;
+};
+typedef struct set_uint64 set_uint64;
+
+enum time_how {
+       DONT_CHANGE = 0,
+       SET_TO_SERVER_TIME = 1,
+       SET_TO_CLIENT_TIME = 2,
+};
+typedef enum time_how time_how;
+
+struct set_time {
+       time_how set;
+       union {
+               nfstime3 time;
+       } set_time_u;
+};
+typedef struct set_time set_time;
+
+struct sattr3 {
+       set_uint32 mode;
+       set_uint32 uid;
+       set_uint32 gid;
+       set_uint64 size;
+       set_time atime;
+       set_time mtime;
+};
+typedef struct sattr3 sattr3;
+
+struct diropargs3 {
+       nfs_fh3 dir;
+       filename3 name;
+};
+typedef struct diropargs3 diropargs3;
+
+struct diropres3ok {
+       post_op_fh3 obj;
+       post_op_attr obj_attributes;
+       wcc_data dir_wcc;
+};
+typedef struct diropres3ok diropres3ok;
+
+struct diropres3 {
+       nfsstat3 status;
+       union {
+               diropres3ok resok;
+               wcc_data resfail;
+       } diropres3_u;
+};
+typedef struct diropres3 diropres3;
+
+struct wccstat3 {
+       nfsstat3 status;
+       union {
+               wcc_data wcc;
+       } wccstat3_u;
+};
+typedef struct wccstat3 wccstat3;
+
+struct getattr3res {
+       nfsstat3 status;
+       union {
+               fattr3 attributes;
+       } getattr3res_u;
+};
+typedef struct getattr3res getattr3res;
+
+struct sattrguard3 {
+       bool_t check;
+       union {
+               nfstime3 ctime;
+       } sattrguard3_u;
+};
+typedef struct sattrguard3 sattrguard3;
+
+struct setattr3args {
+       nfs_fh3 object;
+       sattr3 new_attributes;
+       sattrguard3 guard;
+};
+typedef struct setattr3args setattr3args;
+
+struct lookup3resok {
+       nfs_fh3 object;
+       post_op_attr obj_attributes;
+       post_op_attr dir_attributes;
+};
+typedef struct lookup3resok lookup3resok;
+
+struct lookup3res {
+       nfsstat3 status;
+       union {
+               lookup3resok resok;
+               post_op_attr resfail;
+       } lookup3res_u;
+};
+typedef struct lookup3res lookup3res;
+#define ACCESS3_READ 0x0001
+#define ACCESS3_LOOKUP 0x0002
+#define ACCESS3_MODIFY 0x0004
+#define ACCESS3_EXTEND 0x0008
+#define ACCESS3_DELETE 0x0010
+#define ACCESS3_EXECUTE 0x0020
+
+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 access3res {
+       nfsstat3 status;
+       union {
+               access3resok resok;
+               post_op_attr resfail;
+       } access3res_u;
+};
+typedef struct access3res access3res;
+
+struct readlink3resok {
+       post_op_attr symlink_attributes;
+       nfspath3 data;
+};
+typedef struct readlink3resok readlink3resok;
+
+struct readlink3res {
+       nfsstat3 status;
+       union {
+               readlink3resok resok;
+               post_op_attr resfail;
+       } readlink3res_u;
+};
+typedef struct readlink3res readlink3res;
+
+struct read3args {
+       nfs_fh3 file;
+       uint64 offset;
+       uint32 count;
+};
+typedef struct read3args read3args;
+
+struct read3resok {
+       post_op_attr file_attributes;
+       uint32 count;
+       bool_t eof;
+       struct {
+               u_int data_len;
+               char *data_val;
+       } data;
+};
+typedef struct read3resok read3resok;
+
+struct read3res {
+       nfsstat3 status;
+       union {
+               read3resok resok;
+               post_op_attr resfail;
+       } read3res_u;
+};
+typedef struct read3res read3res;
+
+enum stable_how {
+       UNSTABLE = 0,
+       DATA_SYNC = 1,
+       FILE_SYNC = 2,
+};
+typedef enum stable_how stable_how;
+
+struct write3args {
+       nfs_fh3 file;
+       uint64 offset;
+       uint32 count;
+       stable_how stable;
+       struct {
+               u_int data_len;
+               char *data_val;
+       } data;
+};
+typedef struct write3args write3args;
+
+struct write3resok {
+       wcc_data file_wcc;
+       uint32 count;
+       stable_how committed;
+       writeverf3 verf;
+};
+typedef struct write3resok write3resok;
+
+struct write3res {
+       nfsstat3 status;
+       union {
+               write3resok resok;
+               wcc_data resfail;
+       } write3res_u;
+};
+typedef struct write3res write3res;
+
+enum createmode3 {
+       UNCHECKED = 0,
+       GUARDED = 1,
+       EXCLUSIVE = 2,
+};
+typedef enum createmode3 createmode3;
+
+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 mkdir3args {
+       diropargs3 where;
+       sattr3 attributes;
+};
+typedef struct mkdir3args mkdir3args;
+
+struct symlinkdata3 {
+       sattr3 symlink_attributes;
+       nfspath3 symlink_data;
+};
+typedef struct symlinkdata3 symlinkdata3;
+
+struct symlink3args {
+       diropargs3 where;
+       symlinkdata3 symlink;
+};
+typedef struct symlink3args symlink3args;
+
+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 rename3args {
+       diropargs3 from;
+       diropargs3 to;
+};
+typedef struct rename3args rename3args;
+
+struct rename3wcc {
+       wcc_data fromdir_wcc;
+       wcc_data todir_wcc;
+};
+typedef struct rename3wcc rename3wcc;
+
+struct rename3res {
+       nfsstat3 status;
+       union {
+               rename3wcc res;
+       } rename3res_u;
+};
+typedef struct rename3res rename3res;
+
+struct link3args {
+       nfs_fh3 file;
+       diropargs3 link;
+};
+typedef struct link3args link3args;
+
+struct link3wcc {
+       post_op_attr file_attributes;
+       wcc_data linkdir_wcc;
+};
+typedef struct link3wcc link3wcc;
+
+struct link3res {
+       nfsstat3 status;
+       union {
+               link3wcc res;
+       } link3res_u;
+};
+typedef struct link3res link3res;
+
+struct readdir3args {
+       nfs_fh3 dir;
+       uint64 cookie;
+       cookieverf3 cookieverf;
+       uint32 count;
+};
+typedef struct readdir3args readdir3args;
+
+struct entry3 {
+       uint64 fileid;
+       filename3 name;
+       uint64 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 readdir3res {
+       nfsstat3 status;
+       union {
+               readdir3resok resok;
+               post_op_attr resfail;
+       } readdir3res_u;
+};
+typedef struct readdir3res readdir3res;
+
+struct readdirplus3args {
+       nfs_fh3 dir;
+       uint64 cookie;
+       cookieverf3 cookieverf;
+       uint32 dircount;
+       uint32 maxcount;
+};
+typedef struct readdirplus3args readdirplus3args;
+
+struct entryplus3 {
+       uint64 fileid;
+       filename3 name;
+       uint64 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 readdirplus3res {
+       nfsstat3 status;
+       union {
+               readdirplus3resok resok;
+               post_op_attr resfail;
+       } readdirplus3res_u;
+};
+typedef struct readdirplus3res readdirplus3res;
+
+struct fsstat3resok {
+       post_op_attr obj_attributes;
+       uint64 tbytes;
+       uint64 fbytes;
+       uint64 abytes;
+       uint64 tfiles;
+       uint64 ffiles;
+       uint64 afiles;
+       uint32 invarsec;
+};
+typedef struct fsstat3resok fsstat3resok;
+
+struct fsstat3res {
+       nfsstat3 status;
+       union {
+               fsstat3resok resok;
+               post_op_attr resfail;
+       } fsstat3res_u;
+};
+typedef struct fsstat3res fsstat3res;
+#define FSF3_LINK 0x0001
+#define FSF3_SYMLINK 0x0002
+#define FSF3_HOMOGENEOUS 0x0008
+#define FSF3_CANSETTIME 0x0010
+
+struct fsinfo3resok {
+       post_op_attr obj_attributes;
+       uint32 rtmax;
+       uint32 rtpref;
+       uint32 rtmult;
+       uint32 wtmax;
+       uint32 wtpref;
+       uint32 wtmult;
+       uint32 dtpref;
+       uint64 maxfilesize;
+       nfstime3 time_delta;
+       uint32 properties;
+};
+typedef struct fsinfo3resok fsinfo3resok;
+
+struct fsinfo3res {
+       nfsstat3 status;
+       union {
+               fsinfo3resok resok;
+               post_op_attr resfail;
+       } fsinfo3res_u;
+};
+typedef struct fsinfo3res fsinfo3res;
+
+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 pathconf3res {
+       nfsstat3 status;
+       union {
+               pathconf3resok resok;
+               post_op_attr resfail;
+       } pathconf3res_u;
+};
+typedef struct pathconf3res pathconf3res;
+
+struct commit3args {
+       nfs_fh3 file;
+       uint64 offset;
+       uint32 count;
+};
+typedef struct commit3args commit3args;
+
+struct commit3resok {
+       wcc_data file_wcc;
+       writeverf3 verf;
+};
+typedef struct commit3resok commit3resok;
+
+struct commit3res {
+       nfsstat3 status;
+       union {
+               commit3resok resok;
+               wcc_data resfail;
+       } commit3res_u;
+};
+typedef struct commit3res commit3res;
+
+#define NFS_PROGRAM 100003
+#define NFS_V3 3
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define NFSPROC3_NULL 0
+extern  void * nfsproc3_null_3(void *, CLIENT *);
+extern  void * nfsproc3_null_3_svc(void *, struct svc_req *);
+#define NFSPROC3_GETATTR 1
+extern  getattr3res * nfsproc3_getattr_3(nfs_fh3 *, CLIENT *);
+extern  getattr3res * nfsproc3_getattr_3_svc(nfs_fh3 *, struct svc_req *);
+#define NFSPROC3_SETATTR 2
+extern  wccstat3 * nfsproc3_setattr_3(setattr3args *, CLIENT *);
+extern  wccstat3 * nfsproc3_setattr_3_svc(setattr3args *, struct svc_req *);
+#define NFSPROC3_LOOKUP 3
+extern  lookup3res * nfsproc3_lookup_3(diropargs3 *, CLIENT *);
+extern  lookup3res * nfsproc3_lookup_3_svc(diropargs3 *, struct svc_req *);
+#define NFSPROC3_ACCESS 4
+extern  access3res * nfsproc3_access_3(access3args *, CLIENT *);
+extern  access3res * nfsproc3_access_3_svc(access3args *, struct svc_req *);
+#define NFSPROC3_READLINK 5
+extern  readlink3res * nfsproc3_readlink_3(nfs_fh3 *, CLIENT *);
+extern  readlink3res * nfsproc3_readlink_3_svc(nfs_fh3 *, struct svc_req *);
+#define NFSPROC3_READ 6
+extern  read3res * nfsproc3_read_3(read3args *, CLIENT *);
+extern  read3res * nfsproc3_read_3_svc(read3args *, struct svc_req *);
+#define NFSPROC3_WRITE 7
+extern  write3res * nfsproc3_write_3(write3args *, CLIENT *);
+extern  write3res * nfsproc3_write_3_svc(write3args *, struct svc_req *);
+#define NFSPROC3_CREATE 8
+extern  diropres3 * nfsproc3_create_3(create3args *, CLIENT *);
+extern  diropres3 * nfsproc3_create_3_svc(create3args *, struct svc_req *);
+#define NFSPROC3_MKDIR 9
+extern  diropres3 * nfsproc3_mkdir_3(mkdir3args *, CLIENT *);
+extern  diropres3 * nfsproc3_mkdir_3_svc(mkdir3args *, struct svc_req *);
+#define NFSPROC3_SYMLINK 10
+extern  diropres3 * nfsproc3_symlink_3(symlink3args *, CLIENT *);
+extern  diropres3 * nfsproc3_symlink_3_svc(symlink3args *, struct svc_req *);
+#define NFSPROC3_MKNOD 11
+extern  diropres3 * nfsproc3_mknod_3(mknod3args *, CLIENT *);
+extern  diropres3 * nfsproc3_mknod_3_svc(mknod3args *, struct svc_req *);
+#define NFSPROC3_REMOVE 12
+extern  wccstat3 * nfsproc3_remove_3(diropargs3 *, CLIENT *);
+extern  wccstat3 * nfsproc3_remove_3_svc(diropargs3 *, struct svc_req *);
+#define NFSPROC3_RMDIR 13
+extern  wccstat3 * nfsproc3_rmdir_3(diropargs3 *, CLIENT *);
+extern  wccstat3 * nfsproc3_rmdir_3_svc(diropargs3 *, struct svc_req *);
+#define NFSPROC3_RENAME 14
+extern  rename3res * nfsproc3_rename_3(rename3args *, CLIENT *);
+extern  rename3res * nfsproc3_rename_3_svc(rename3args *, struct svc_req *);
+#define NFSPROC3_LINK 15
+extern  link3res * nfsproc3_link_3(link3args *, CLIENT *);
+extern  link3res * nfsproc3_link_3_svc(link3args *, struct svc_req *);
+#define NFSPROC3_READDIR 16
+extern  readdir3res * nfsproc3_readdir_3(readdir3args *, CLIENT *);
+extern  readdir3res * nfsproc3_readdir_3_svc(readdir3args *, struct svc_req *);
+#define NFSPROC3_READDIRPLUS 17
+extern  readdirplus3res * nfsproc3_readdirplus_3(readdirplus3args *, CLIENT *);
+extern  readdirplus3res * nfsproc3_readdirplus_3_svc(readdirplus3args *, struct svc_req *);
+#define NFSPROC3_FSSTAT 18
+extern  fsstat3res * nfsproc3_fsstat_3(nfs_fh3 *, CLIENT *);
+extern  fsstat3res * nfsproc3_fsstat_3_svc(nfs_fh3 *, struct svc_req *);
+#define NFSPROC3_FSINFO 19
+extern  fsinfo3res * nfsproc3_fsinfo_3(nfs_fh3 *, CLIENT *);
+extern  fsinfo3res * nfsproc3_fsinfo_3_svc(nfs_fh3 *, struct svc_req *);
+#define NFSPROC3_PATHCONF 20
+extern  pathconf3res * nfsproc3_pathconf_3(nfs_fh3 *, CLIENT *);
+extern  pathconf3res * nfsproc3_pathconf_3_svc(nfs_fh3 *, struct svc_req *);
+#define NFSPROC3_COMMIT 21
+extern  commit3res * nfsproc3_commit_3(commit3args *, CLIENT *);
+extern  commit3res * nfsproc3_commit_3_svc(commit3args *, struct svc_req *);
+extern int nfs_program_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define NFSPROC3_NULL 0
+extern  void * nfsproc3_null_3();
+extern  void * nfsproc3_null_3_svc();
+#define NFSPROC3_GETATTR 1
+extern  getattr3res * nfsproc3_getattr_3();
+extern  getattr3res * nfsproc3_getattr_3_svc();
+#define NFSPROC3_SETATTR 2
+extern  wccstat3 * nfsproc3_setattr_3();
+extern  wccstat3 * nfsproc3_setattr_3_svc();
+#define NFSPROC3_LOOKUP 3
+extern  lookup3res * nfsproc3_lookup_3();
+extern  lookup3res * nfsproc3_lookup_3_svc();
+#define NFSPROC3_ACCESS 4
+extern  access3res * nfsproc3_access_3();
+extern  access3res * nfsproc3_access_3_svc();
+#define NFSPROC3_READLINK 5
+extern  readlink3res * nfsproc3_readlink_3();
+extern  readlink3res * nfsproc3_readlink_3_svc();
+#define NFSPROC3_READ 6
+extern  read3res * nfsproc3_read_3();
+extern  read3res * nfsproc3_read_3_svc();
+#define NFSPROC3_WRITE 7
+extern  write3res * nfsproc3_write_3();
+extern  write3res * nfsproc3_write_3_svc();
+#define NFSPROC3_CREATE 8
+extern  diropres3 * nfsproc3_create_3();
+extern  diropres3 * nfsproc3_create_3_svc();
+#define NFSPROC3_MKDIR 9
+extern  diropres3 * nfsproc3_mkdir_3();
+extern  diropres3 * nfsproc3_mkdir_3_svc();
+#define NFSPROC3_SYMLINK 10
+extern  diropres3 * nfsproc3_symlink_3();
+extern  diropres3 * nfsproc3_symlink_3_svc();
+#define NFSPROC3_MKNOD 11
+extern  diropres3 * nfsproc3_mknod_3();
+extern  diropres3 * nfsproc3_mknod_3_svc();
+#define NFSPROC3_REMOVE 12
+extern  wccstat3 * nfsproc3_remove_3();
+extern  wccstat3 * nfsproc3_remove_3_svc();
+#define NFSPROC3_RMDIR 13
+extern  wccstat3 * nfsproc3_rmdir_3();
+extern  wccstat3 * nfsproc3_rmdir_3_svc();
+#define NFSPROC3_RENAME 14
+extern  rename3res * nfsproc3_rename_3();
+extern  rename3res * nfsproc3_rename_3_svc();
+#define NFSPROC3_LINK 15
+extern  link3res * nfsproc3_link_3();
+extern  link3res * nfsproc3_link_3_svc();
+#define NFSPROC3_READDIR 16
+extern  readdir3res * nfsproc3_readdir_3();
+extern  readdir3res * nfsproc3_readdir_3_svc();
+#define NFSPROC3_READDIRPLUS 17
+extern  readdirplus3res * nfsproc3_readdirplus_3();
+extern  readdirplus3res * nfsproc3_readdirplus_3_svc();
+#define NFSPROC3_FSSTAT 18
+extern  fsstat3res * nfsproc3_fsstat_3();
+extern  fsstat3res * nfsproc3_fsstat_3_svc();
+#define NFSPROC3_FSINFO 19
+extern  fsinfo3res * nfsproc3_fsinfo_3();
+extern  fsinfo3res * nfsproc3_fsinfo_3_svc();
+#define NFSPROC3_PATHCONF 20
+extern  pathconf3res * nfsproc3_pathconf_3();
+extern  pathconf3res * nfsproc3_pathconf_3_svc();
+#define NFSPROC3_COMMIT 21
+extern  commit3res * nfsproc3_commit_3();
+extern  commit3res * nfsproc3_commit_3_svc();
+extern int nfs_program_3_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+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_cookieverf3 (XDR *, cookieverf3);
+extern  bool_t xdr_createverf3 (XDR *, createverf3);
+extern  bool_t xdr_writeverf3 (XDR *, writeverf3);
+extern  bool_t xdr_nfsstat3 (XDR *, nfsstat3*);
+extern  bool_t xdr_ftype3 (XDR *, ftype3*);
+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_set_uint32 (XDR *, set_uint32*);
+extern  bool_t xdr_set_uint64 (XDR *, set_uint64*);
+extern  bool_t xdr_time_how (XDR *, time_how*);
+extern  bool_t xdr_set_time (XDR *, set_time*);
+extern  bool_t xdr_sattr3 (XDR *, sattr3*);
+extern  bool_t xdr_diropargs3 (XDR *, diropargs3*);
+extern  bool_t xdr_diropres3ok (XDR *, diropres3ok*);
+extern  bool_t xdr_diropres3 (XDR *, diropres3*);
+extern  bool_t xdr_wccstat3 (XDR *, wccstat3*);
+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_lookup3resok (XDR *, lookup3resok*);
+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_access3res (XDR *, access3res*);
+extern  bool_t xdr_readlink3resok (XDR *, readlink3resok*);
+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_read3res (XDR *, read3res*);
+extern  bool_t xdr_stable_how (XDR *, stable_how*);
+extern  bool_t xdr_write3args (XDR *, write3args*);
+extern  bool_t xdr_write3resok (XDR *, write3resok*);
+extern  bool_t xdr_write3res (XDR *, write3res*);
+extern  bool_t xdr_createmode3 (XDR *, createmode3*);
+extern  bool_t xdr_createhow3 (XDR *, createhow3*);
+extern  bool_t xdr_create3args (XDR *, create3args*);
+extern  bool_t xdr_mkdir3args (XDR *, mkdir3args*);
+extern  bool_t xdr_symlinkdata3 (XDR *, symlinkdata3*);
+extern  bool_t xdr_symlink3args (XDR *, symlink3args*);
+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_rename3args (XDR *, rename3args*);
+extern  bool_t xdr_rename3wcc (XDR *, rename3wcc*);
+extern  bool_t xdr_rename3res (XDR *, rename3res*);
+extern  bool_t xdr_link3args (XDR *, link3args*);
+extern  bool_t xdr_link3wcc (XDR *, link3wcc*);
+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_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_readdirplus3res (XDR *, readdirplus3res*);
+extern  bool_t xdr_fsstat3resok (XDR *, fsstat3resok*);
+extern  bool_t xdr_fsstat3res (XDR *, fsstat3res*);
+extern  bool_t xdr_fsinfo3resok (XDR *, fsinfo3resok*);
+extern  bool_t xdr_fsinfo3res (XDR *, fsinfo3res*);
+extern  bool_t xdr_pathconf3resok (XDR *, pathconf3resok*);
+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_commit3res (XDR *, commit3res*);
+
+#else /* K&R C */
+extern bool_t xdr_uint64 ();
+extern bool_t xdr_int64 ();
+extern bool_t xdr_uint32 ();
+extern bool_t xdr_int32 ();
+extern bool_t xdr_filename3 ();
+extern bool_t xdr_nfspath3 ();
+extern bool_t xdr_cookieverf3 ();
+extern bool_t xdr_createverf3 ();
+extern bool_t xdr_writeverf3 ();
+extern bool_t xdr_nfsstat3 ();
+extern bool_t xdr_ftype3 ();
+extern bool_t xdr_specdata3 ();
+extern bool_t xdr_nfs_fh3 ();
+extern bool_t xdr_nfstime3 ();
+extern bool_t xdr_fattr3 ();
+extern bool_t xdr_post_op_attr ();
+extern bool_t xdr_wcc_attr ();
+extern bool_t xdr_pre_op_attr ();
+extern bool_t xdr_wcc_data ();
+extern bool_t xdr_post_op_fh3 ();
+extern bool_t xdr_set_uint32 ();
+extern bool_t xdr_set_uint64 ();
+extern bool_t xdr_time_how ();
+extern bool_t xdr_set_time ();
+extern bool_t xdr_sattr3 ();
+extern bool_t xdr_diropargs3 ();
+extern bool_t xdr_diropres3ok ();
+extern bool_t xdr_diropres3 ();
+extern bool_t xdr_wccstat3 ();
+extern bool_t xdr_getattr3res ();
+extern bool_t xdr_sattrguard3 ();
+extern bool_t xdr_setattr3args ();
+extern bool_t xdr_lookup3resok ();
+extern bool_t xdr_lookup3res ();
+extern bool_t xdr_access3args ();
+extern bool_t xdr_access3resok ();
+extern bool_t xdr_access3res ();
+extern bool_t xdr_readlink3resok ();
+extern bool_t xdr_readlink3res ();
+extern bool_t xdr_read3args ();
+extern bool_t xdr_read3resok ();
+extern bool_t xdr_read3res ();
+extern bool_t xdr_stable_how ();
+extern bool_t xdr_write3args ();
+extern bool_t xdr_write3resok ();
+extern bool_t xdr_write3res ();
+extern bool_t xdr_createmode3 ();
+extern bool_t xdr_createhow3 ();
+extern bool_t xdr_create3args ();
+extern bool_t xdr_mkdir3args ();
+extern bool_t xdr_symlinkdata3 ();
+extern bool_t xdr_symlink3args ();
+extern bool_t xdr_devicedata3 ();
+extern bool_t xdr_mknoddata3 ();
+extern bool_t xdr_mknod3args ();
+extern bool_t xdr_rename3args ();
+extern bool_t xdr_rename3wcc ();
+extern bool_t xdr_rename3res ();
+extern bool_t xdr_link3args ();
+extern bool_t xdr_link3wcc ();
+extern bool_t xdr_link3res ();
+extern bool_t xdr_readdir3args ();
+extern bool_t xdr_entry3 ();
+extern bool_t xdr_dirlist3 ();
+extern bool_t xdr_readdir3resok ();
+extern bool_t xdr_readdir3res ();
+extern bool_t xdr_readdirplus3args ();
+extern bool_t xdr_entryplus3 ();
+extern bool_t xdr_dirlistplus3 ();
+extern bool_t xdr_readdirplus3resok ();
+extern bool_t xdr_readdirplus3res ();
+extern bool_t xdr_fsstat3resok ();
+extern bool_t xdr_fsstat3res ();
+extern bool_t xdr_fsinfo3resok ();
+extern bool_t xdr_fsinfo3res ();
+extern bool_t xdr_pathconf3resok ();
+extern bool_t xdr_pathconf3res ();
+extern bool_t xdr_commit3args ();
+extern bool_t xdr_commit3resok ();
+extern bool_t xdr_commit3res ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_NFS3_PROT_H_RPCGEN */
diff --git a/nfs3/nfs3_prot.x b/nfs3/nfs3_prot.x
new file mode 100644 (file)
index 0000000..1060431
--- /dev/null
@@ -0,0 +1,612 @@
+/* $Id: nfs3_prot.x,v 1.17 2002/10/11 19:13:00 kaminsky Exp $ */
+
+typedef unsigned hyper uint64;
+typedef hyper int64;
+typedef unsigned int uint32;
+typedef int int32;
+
+const NFS3_FHSIZE = 64;
+const NFS3_COOKIEVERFSIZE = 8;
+const NFS3_CREATEVERFSIZE = 8;
+const NFS3_WRITEVERFSIZE = 8;
+
+typedef string filename3<>;
+typedef string nfspath3<>;
+typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
+typedef opaque createverf3[NFS3_CREATEVERFSIZE];
+typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
+
+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,
+    NFS3ERR_FPRINTNOTFOUND = 10009,
+    NFS3ERR_ABORTED = 10010
+};
+
+enum ftype3 {
+    NF3REG = 1,
+    NF3DIR = 2,
+    NF3BLK = 3,
+    NF3CHR = 4,
+    NF3LNK = 5,
+    NF3SOCK = 6,
+    NF3FIFO = 7
+};
+
+struct specdata3 {
+    uint32 major;
+    uint32 minor;
+};
+
+struct nfs_fh3 {
+    opaque data<NFS3_FHSIZE>;
+};
+
+struct nfstime3 {
+    uint32 seconds;
+    uint32 nseconds;
+};
+
+struct fattr3 {
+    ftype3 type;
+    uint32 mode;
+    uint32 nlink;
+    uint32 uid;
+    uint32 gid;
+    uint64 size;
+    uint64 used;
+    specdata3 rdev;
+    uint64 fsid;
+    uint64 fileid;
+    nfstime3 atime;
+    nfstime3 mtime;
+    nfstime3 ctime;
+};
+
+union post_op_attr switch (bool present) {
+case TRUE:
+    fattr3 attributes;
+case FALSE:
+    void;
+};
+
+struct wcc_attr {
+    uint64 size;
+    nfstime3 mtime;
+    nfstime3 ctime;
+};
+
+union pre_op_attr switch (bool present) {
+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 present) {
+case TRUE:
+    nfs_fh3 handle;
+case FALSE:
+    void;
+};
+
+union set_uint32 switch (bool set) {
+case TRUE:
+    uint32 val;
+default:
+    void;
+};
+
+union set_uint64 switch (bool set) {
+case TRUE:
+    uint64 val;
+default:
+    void;
+};
+
+enum time_how {
+    DONT_CHANGE = 0,
+    SET_TO_SERVER_TIME = 1,
+    SET_TO_CLIENT_TIME = 2
+};
+
+union set_time switch (time_how set) {
+case SET_TO_CLIENT_TIME:
+    nfstime3 time;
+default:
+    void;
+};
+
+struct sattr3 {
+    set_uint32 mode;
+    set_uint32 uid;
+    set_uint32 gid;
+    set_uint64 size;
+    set_time atime;
+    set_time mtime;
+};
+
+struct diropargs3 {
+    nfs_fh3 dir;
+    filename3 name;
+};
+
+struct diropres3ok {
+    post_op_fh3 obj;
+    post_op_attr obj_attributes;
+    wcc_data dir_wcc;
+};
+
+union diropres3 switch (nfsstat3 status) {
+case NFS3_OK:
+    diropres3ok resok;
+default:
+    wcc_data resfail;   /* Directory attributes  */
+};
+
+union wccstat3 switch (nfsstat3 status) {
+#ifndef UNION_ONLY_DEFAULT
+case -1:
+    void;
+#endif /* !UNION_ONLY_DEFAULT */
+default:
+    wcc_data wcc;
+};
+
+union getattr3res switch (nfsstat3 status) {
+case NFS3_OK:
+    fattr3 attributes;
+default:
+    void;
+};
+
+union sattrguard3 switch (bool check) {
+case TRUE:
+    nfstime3 ctime;
+case FALSE:
+    void;
+};
+
+struct setattr3args {
+    nfs_fh3 object;
+    sattr3 new_attributes;
+    sattrguard3 guard;
+};
+
+struct lookup3resok {
+    nfs_fh3 object;
+    post_op_attr obj_attributes;
+    post_op_attr dir_attributes;
+};
+
+union lookup3res switch (nfsstat3 status) {
+case NFS3_OK:
+    lookup3resok resok;
+default:
+    post_op_attr resfail;   /* Directory attributes */
+};
+
+const ACCESS3_READ    = 0x0001;
+const ACCESS3_LOOKUP  = 0x0002;
+const ACCESS3_MODIFY  = 0x0004;
+const ACCESS3_EXTEND  = 0x0008;
+const ACCESS3_DELETE  = 0x0010;
+const ACCESS3_EXECUTE = 0x0020;
+
+struct access3args {
+    nfs_fh3 object;
+    uint32 access;
+};
+
+struct access3resok {
+    post_op_attr obj_attributes;
+    uint32 access;
+};
+
+union access3res switch (nfsstat3 status) {
+case NFS3_OK:
+    access3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+struct readlink3resok {
+    post_op_attr symlink_attributes;
+    nfspath3 data;
+};
+
+union readlink3res switch (nfsstat3 status) {
+case NFS3_OK:
+    readlink3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+struct read3args {
+    nfs_fh3 file;
+    uint64 offset;
+    uint32 count;
+};
+
+struct read3resok {
+    post_op_attr file_attributes;
+    uint32 count;
+    bool eof;
+    opaque data<>;
+};
+
+union read3res switch (nfsstat3 status) {
+case NFS3_OK:
+    read3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+enum stable_how {
+    UNSTABLE = 0,
+    DATA_SYNC = 1,
+    FILE_SYNC = 2
+};
+
+struct write3args {
+    nfs_fh3 file;
+    uint64 offset;
+    uint32 count;
+    stable_how stable;
+    opaque data<>;
+};
+
+struct write3resok {
+    wcc_data file_wcc;
+    uint32 count;
+    stable_how committed;
+    writeverf3 verf;
+};
+
+union write3res switch (nfsstat3 status) {
+case NFS3_OK:
+    write3resok resok;
+default:
+    wcc_data resfail;
+};
+
+enum createmode3 {
+    UNCHECKED = 0,
+    GUARDED = 1,
+    EXCLUSIVE = 2
+};
+
+union createhow3 switch (createmode3 mode) {
+case UNCHECKED:
+case GUARDED:
+    sattr3 obj_attributes;
+case EXCLUSIVE:
+    createverf3 verf;
+};
+
+struct create3args {
+    diropargs3 where;
+    createhow3 how;
+};
+
+struct mkdir3args {
+    diropargs3 where;
+    sattr3 attributes;
+};
+
+struct symlinkdata3 {
+    sattr3 symlink_attributes;
+    nfspath3 symlink_data;
+};
+
+struct symlink3args {
+    diropargs3 where;
+    symlinkdata3 symlink;
+};
+
+struct devicedata3 {
+    sattr3 dev_attributes;
+    specdata3 spec;
+};
+
+union mknoddata3 switch (ftype3 type) {
+case NF3CHR:
+case NF3BLK:
+    devicedata3 device;
+case NF3SOCK:
+case NF3FIFO:
+    sattr3 pipe_attributes;
+default:
+    void;
+};
+
+struct mknod3args {
+    diropargs3 where;
+    mknoddata3 what;
+};
+
+struct rename3args {
+    diropargs3 from;
+    diropargs3 to;
+};
+
+struct rename3wcc {
+    wcc_data fromdir_wcc;
+    wcc_data todir_wcc;
+};
+
+union rename3res switch (nfsstat3 status) {
+#ifndef UNION_ONLY_DEFAULT
+case -1:
+    void;
+#endif /* !UNION_ONLY_DEFAULT */
+default:
+    rename3wcc res;
+};
+
+struct link3args {
+    nfs_fh3 file;
+    diropargs3 link;
+};
+
+struct link3wcc {
+    post_op_attr file_attributes;
+    wcc_data linkdir_wcc;
+};
+
+union link3res switch (nfsstat3 status) {
+#ifndef UNION_ONLY_DEFAULT
+case -1:
+    void;
+#endif /* !UNION_ONLY_DEFAULT */
+default:
+    link3wcc res;
+};
+
+struct readdir3args {
+    nfs_fh3 dir;
+    uint64 cookie;
+    cookieverf3 cookieverf;
+    uint32 count;
+};
+
+struct entry3 {
+    uint64 fileid;
+    filename3 name;
+    uint64 cookie;
+    entry3 *nextentry;
+};
+
+struct dirlist3 {
+    entry3 *entries;
+    bool eof;
+};
+
+struct readdir3resok {
+    post_op_attr dir_attributes;
+    cookieverf3 cookieverf;
+    dirlist3 reply;
+};
+
+union readdir3res switch (nfsstat3 status) {
+case NFS3_OK:
+    readdir3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+struct readdirplus3args {
+    nfs_fh3 dir;
+    uint64 cookie;
+    cookieverf3 cookieverf;
+    uint32 dircount;
+    uint32 maxcount;
+};
+
+struct entryplus3 {
+    uint64 fileid;
+    filename3 name;
+    uint64 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;
+};
+
+union readdirplus3res switch (nfsstat3 status) {
+case NFS3_OK:
+    readdirplus3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+struct fsstat3resok {
+    post_op_attr obj_attributes;
+    uint64 tbytes;
+    uint64 fbytes;
+    uint64 abytes;
+    uint64 tfiles;
+    uint64 ffiles;
+    uint64 afiles;
+    uint32 invarsec;
+};
+
+union fsstat3res switch (nfsstat3 status) {
+case NFS3_OK:
+    fsstat3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+const FSF3_LINK        = 0x0001;
+const FSF3_SYMLINK     = 0x0002;
+const FSF3_HOMOGENEOUS = 0x0008;
+const FSF3_CANSETTIME  = 0x0010;
+
+struct fsinfo3resok {
+    post_op_attr obj_attributes;
+    uint32 rtmax;
+    uint32 rtpref;
+    uint32 rtmult;
+    uint32 wtmax;
+    uint32 wtpref;
+    uint32 wtmult;
+    uint32 dtpref;
+    uint64 maxfilesize;
+    nfstime3 time_delta;
+    uint32 properties;
+};
+
+union fsinfo3res switch (nfsstat3 status) {
+case NFS3_OK:
+    fsinfo3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+struct pathconf3resok {
+    post_op_attr obj_attributes;
+    uint32 linkmax;
+    uint32 name_max;
+    bool no_trunc;
+    bool chown_restricted;
+    bool case_insensitive;
+    bool case_preserving;
+};
+
+union pathconf3res switch (nfsstat3 status) {
+case NFS3_OK:
+    pathconf3resok resok;
+default:
+    post_op_attr resfail;
+};
+
+struct commit3args {
+    nfs_fh3 file;
+    uint64 offset;
+    uint32 count;
+};
+
+struct commit3resok {
+    wcc_data file_wcc;
+    writeverf3 verf;
+};
+
+union commit3res switch (nfsstat3 status) {
+case NFS3_OK:
+    commit3resok resok;
+default:
+    wcc_data resfail;
+};
+
+program NFS_PROGRAM {
+    version NFS_V3 {
+        void
+        NFSPROC3_NULL (void) = 0;
+
+        getattr3res
+        NFSPROC3_GETATTR (nfs_fh3) = 1;
+
+        wccstat3
+        NFSPROC3_SETATTR (setattr3args) = 2;
+
+        lookup3res
+        NFSPROC3_LOOKUP (diropargs3) = 3;
+
+        access3res
+        NFSPROC3_ACCESS (access3args) = 4;
+
+        readlink3res
+        NFSPROC3_READLINK (nfs_fh3) = 5;
+
+        read3res
+        NFSPROC3_READ (read3args) = 6;
+
+        write3res
+        NFSPROC3_WRITE (write3args) = 7;
+
+        diropres3
+        NFSPROC3_CREATE (create3args) = 8;
+
+        diropres3
+        NFSPROC3_MKDIR (mkdir3args) = 9;
+
+        diropres3
+        NFSPROC3_SYMLINK (symlink3args) = 10;
+
+        diropres3
+        NFSPROC3_MKNOD (mknod3args) = 11;
+
+        wccstat3
+        NFSPROC3_REMOVE (diropargs3) = 12;
+
+        wccstat3
+        NFSPROC3_RMDIR (diropargs3) = 13;
+
+        rename3res
+        NFSPROC3_RENAME (rename3args) = 14;
+
+        link3res
+        NFSPROC3_LINK (link3args) = 15;
+
+        readdir3res
+        NFSPROC3_READDIR (readdir3args) = 16;
+
+        readdirplus3res
+        NFSPROC3_READDIRPLUS (readdirplus3args) = 17;
+
+        fsstat3res
+        NFSPROC3_FSSTAT (nfs_fh3) = 18;
+
+        fsinfo3res
+        NFSPROC3_FSINFO (nfs_fh3) = 19;
+
+        pathconf3res
+        NFSPROC3_PATHCONF (nfs_fh3) = 20;
+
+        commit3res
+        NFSPROC3_COMMIT (commit3args) = 21;
+    } = 3;
+} = 100003;
diff --git a/nfs3/nfs3_prot_xdr.c b/nfs3/nfs3_prot_xdr.c
new file mode 100644 (file)
index 0000000..ac22e70
--- /dev/null
@@ -0,0 +1,1302 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "nfs3_prot.h"
+
+bool_t
+xdr_uint64 (XDR *xdrs, uint64 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_u_quad_t (xdrs, objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_int64 (XDR *xdrs, int64 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_quad_t (xdrs, objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_uint32 (XDR *xdrs, uint32 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_u_int (xdrs, objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_int32 (XDR *xdrs, int32 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_int (xdrs, objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_filename3 (XDR *xdrs, filename3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_string (xdrs, objp, ~0))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_nfspath3 (XDR *xdrs, nfspath3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_string (xdrs, objp, ~0))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_cookieverf3 (XDR *xdrs, cookieverf3 objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_opaque (xdrs, objp, NFS3_COOKIEVERFSIZE))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_createverf3 (XDR *xdrs, createverf3 objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_opaque (xdrs, objp, NFS3_CREATEVERFSIZE))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_writeverf3 (XDR *xdrs, writeverf3 objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_opaque (xdrs, objp, NFS3_WRITEVERFSIZE))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_nfsstat3 (XDR *xdrs, nfsstat3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_ftype3 (XDR *xdrs, ftype3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_specdata3 (XDR *xdrs, specdata3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_uint32 (xdrs, &objp->major))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->minor))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_nfs_fh3 (XDR *xdrs, nfs_fh3 *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, nfstime3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_uint32 (xdrs, &objp->seconds))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->nseconds))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_fattr3 (XDR *xdrs, fattr3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_ftype3 (xdrs, &objp->type))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->mode))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->nlink))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->uid))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->gid))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->size))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->used))
+                return FALSE;
+        if (!xdr_specdata3 (xdrs, &objp->rdev))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->fsid))
+                return FALSE;
+        if (!xdr_uint64 (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 (XDR *xdrs, post_op_attr *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_bool (xdrs, &objp->present))
+                return FALSE;
+       switch (objp->present) {
+       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 (XDR *xdrs, wcc_attr *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_uint64 (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 (XDR *xdrs, pre_op_attr *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_bool (xdrs, &objp->present))
+                return FALSE;
+       switch (objp->present) {
+       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 (XDR *xdrs, wcc_data *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, post_op_fh3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_bool (xdrs, &objp->present))
+                return FALSE;
+       switch (objp->present) {
+       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_set_uint32 (XDR *xdrs, set_uint32 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_bool (xdrs, &objp->set))
+                return FALSE;
+       switch (objp->set) {
+       case TRUE:
+                if (!xdr_uint32 (xdrs, &objp->set_uint32_u.val))
+                        return FALSE;
+               break;
+       default:
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_set_uint64 (XDR *xdrs, set_uint64 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_bool (xdrs, &objp->set))
+                return FALSE;
+       switch (objp->set) {
+       case TRUE:
+                if (!xdr_uint64 (xdrs, &objp->set_uint64_u.val))
+                        return FALSE;
+               break;
+       default:
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_time_how (XDR *xdrs, time_how *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_set_time (XDR *xdrs, set_time *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_time_how (xdrs, &objp->set))
+                return FALSE;
+       switch (objp->set) {
+       case SET_TO_CLIENT_TIME:
+                if (!xdr_nfstime3 (xdrs, &objp->set_time_u.time))
+                        return FALSE;
+               break;
+       default:
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_sattr3 (XDR *xdrs, sattr3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_set_uint32 (xdrs, &objp->mode))
+                return FALSE;
+        if (!xdr_set_uint32 (xdrs, &objp->uid))
+                return FALSE;
+        if (!xdr_set_uint32 (xdrs, &objp->gid))
+                return FALSE;
+        if (!xdr_set_uint64 (xdrs, &objp->size))
+                return FALSE;
+        if (!xdr_set_time (xdrs, &objp->atime))
+                return FALSE;
+        if (!xdr_set_time (xdrs, &objp->mtime))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_diropargs3 (XDR *xdrs, diropargs3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+                return FALSE;
+        if (!xdr_filename3 (xdrs, &objp->name))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_diropres3ok (XDR *xdrs, diropres3ok *objp)
+{
+       register int32_t *buf;
+
+        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_diropres3 (XDR *xdrs, diropres3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfsstat3 (xdrs, &objp->status))
+                return FALSE;
+       switch (objp->status) {
+       case NFS3_OK:
+                if (!xdr_diropres3ok (xdrs, &objp->diropres3_u.resok))
+                        return FALSE;
+               break;
+       default:
+                if (!xdr_wcc_data (xdrs, &objp->diropres3_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_wccstat3 (XDR *xdrs, wccstat3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfsstat3 (xdrs, &objp->status))
+                return FALSE;
+       switch (objp->status) {
+       case -1:
+               break;
+       default:
+                if (!xdr_wcc_data (xdrs, &objp->wccstat3_u.wcc))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_getattr3res (XDR *xdrs, getattr3res *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfsstat3 (xdrs, &objp->status))
+                return FALSE;
+       switch (objp->status) {
+       case NFS3_OK:
+                if (!xdr_fattr3 (xdrs, &objp->getattr3res_u.attributes))
+                        return FALSE;
+               break;
+       default:
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_sattrguard3 (XDR *xdrs, sattrguard3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_bool (xdrs, &objp->check))
+                return FALSE;
+       switch (objp->check) {
+       case TRUE:
+                if (!xdr_nfstime3 (xdrs, &objp->sattrguard3_u.ctime))
+                        return FALSE;
+               break;
+       case FALSE:
+               break;
+       default:
+               return FALSE;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_setattr3args (XDR *xdrs, setattr3args *objp)
+{
+       register int32_t *buf;
+
+        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_lookup3resok (XDR *xdrs, lookup3resok *objp)
+{
+       register int32_t *buf;
+
+        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_lookup3res (XDR *xdrs, lookup3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->lookup3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_access3args (XDR *xdrs, access3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->object))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->access))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_access3resok (XDR *xdrs, access3resok *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->access))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_access3res (XDR *xdrs, access3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->access3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_readlink3resok (XDR *xdrs, readlink3resok *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_post_op_attr (xdrs, &objp->symlink_attributes))
+                return FALSE;
+        if (!xdr_nfspath3 (xdrs, &objp->data))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_readlink3res (XDR *xdrs, readlink3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->readlink3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_read3args (XDR *xdrs, read3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->file))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->offset))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->count))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_read3resok (XDR *xdrs, read3resok *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+                return FALSE;
+        if (!xdr_uint32 (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_read3res (XDR *xdrs, read3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->read3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_stable_how (XDR *xdrs, stable_how *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_write3args (XDR *xdrs, write3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->file))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->offset))
+                return FALSE;
+        if (!xdr_uint32 (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 (XDR *xdrs, write3resok *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+                return FALSE;
+        if (!xdr_uint32 (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_write3res (XDR *xdrs, write3res *objp)
+{
+       register int32_t *buf;
+
+        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_wcc_data (xdrs, &objp->write3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_createmode3 (XDR *xdrs, createmode3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_createhow3 (XDR *xdrs, createhow3 *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, create3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_diropargs3 (xdrs, &objp->where))
+                return FALSE;
+        if (!xdr_createhow3 (xdrs, &objp->how))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mkdir3args (XDR *xdrs, mkdir3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_diropargs3 (xdrs, &objp->where))
+                return FALSE;
+        if (!xdr_sattr3 (xdrs, &objp->attributes))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_symlinkdata3 (XDR *xdrs, symlinkdata3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_sattr3 (xdrs, &objp->symlink_attributes))
+                return FALSE;
+        if (!xdr_nfspath3 (xdrs, &objp->symlink_data))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_symlink3args (XDR *xdrs, symlink3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_diropargs3 (xdrs, &objp->where))
+                return FALSE;
+        if (!xdr_symlinkdata3 (xdrs, &objp->symlink))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_devicedata3 (XDR *xdrs, devicedata3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_sattr3 (xdrs, &objp->dev_attributes))
+                return FALSE;
+        if (!xdr_specdata3 (xdrs, &objp->spec))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mknoddata3 (XDR *xdrs, mknoddata3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_ftype3 (xdrs, &objp->type))
+                return FALSE;
+       switch (objp->type) {
+       case NF3CHR:
+       case NF3BLK:
+                if (!xdr_devicedata3 (xdrs, &objp->mknoddata3_u.device))
+                        return FALSE;
+               break;
+       case NF3SOCK:
+       case NF3FIFO:
+                if (!xdr_sattr3 (xdrs, &objp->mknoddata3_u.pipe_attributes))
+                        return FALSE;
+               break;
+       default:
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_mknod3args (XDR *xdrs, mknod3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_diropargs3 (xdrs, &objp->where))
+                return FALSE;
+        if (!xdr_mknoddata3 (xdrs, &objp->what))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_rename3args (XDR *xdrs, rename3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_diropargs3 (xdrs, &objp->from))
+                return FALSE;
+        if (!xdr_diropargs3 (xdrs, &objp->to))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_rename3wcc (XDR *xdrs, rename3wcc *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, rename3res *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfsstat3 (xdrs, &objp->status))
+                return FALSE;
+       switch (objp->status) {
+       case -1:
+               break;
+       default:
+                if (!xdr_rename3wcc (xdrs, &objp->rename3res_u.res))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_link3args (XDR *xdrs, link3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->file))
+                return FALSE;
+        if (!xdr_diropargs3 (xdrs, &objp->link))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_link3wcc (XDR *xdrs, link3wcc *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, link3res *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfsstat3 (xdrs, &objp->status))
+                return FALSE;
+       switch (objp->status) {
+       case -1:
+               break;
+       default:
+                if (!xdr_link3wcc (xdrs, &objp->link3res_u.res))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_readdir3args (XDR *xdrs, readdir3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->cookie))
+                return FALSE;
+        if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->count))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_entry3 (XDR *xdrs, entry3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_uint64 (xdrs, &objp->fileid))
+                return FALSE;
+        if (!xdr_filename3 (xdrs, &objp->name))
+                return FALSE;
+        if (!xdr_uint64 (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 (XDR *xdrs, dirlist3 *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, readdir3resok *objp)
+{
+       register int32_t *buf;
+
+        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_readdir3res (XDR *xdrs, readdir3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->readdir3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_readdirplus3args (XDR *xdrs, readdirplus3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->cookie))
+                return FALSE;
+        if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->dircount))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->maxcount))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_entryplus3 (XDR *xdrs, entryplus3 *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_uint64 (xdrs, &objp->fileid))
+                return FALSE;
+        if (!xdr_filename3 (xdrs, &objp->name))
+                return FALSE;
+        if (!xdr_uint64 (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 (XDR *xdrs, dirlistplus3 *objp)
+{
+       register int32_t *buf;
+
+        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 (XDR *xdrs, readdirplus3resok *objp)
+{
+       register int32_t *buf;
+
+        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_readdirplus3res (XDR *xdrs, readdirplus3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->readdirplus3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_fsstat3resok (XDR *xdrs, fsstat3resok *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->tbytes))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->fbytes))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->abytes))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->tfiles))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->ffiles))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->afiles))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->invarsec))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_fsstat3res (XDR *xdrs, fsstat3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->fsstat3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_fsinfo3resok (XDR *xdrs, fsinfo3resok *objp)
+{
+       register int32_t *buf;
+
+        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_uint64 (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_fsinfo3res (XDR *xdrs, fsinfo3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->fsinfo3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_pathconf3resok (XDR *xdrs, pathconf3resok *objp)
+{
+       register int32_t *buf;
+
+
+       if (xdrs->x_op == XDR_ENCODE) {
+                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;
+               buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+               if (buf == NULL) {
+                        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;
+               } else {
+                       IXDR_PUT_BOOL(buf, objp->no_trunc);
+                       IXDR_PUT_BOOL(buf, objp->chown_restricted);
+                       IXDR_PUT_BOOL(buf, objp->case_insensitive);
+                       IXDR_PUT_BOOL(buf, objp->case_preserving);
+               }
+               return TRUE;
+       } else if (xdrs->x_op == XDR_DECODE) {
+                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;
+               buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+               if (buf == NULL) {
+                        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;
+               } else {
+                       objp->no_trunc = IXDR_GET_BOOL(buf);
+                       objp->chown_restricted = IXDR_GET_BOOL(buf);
+                       objp->case_insensitive = IXDR_GET_BOOL(buf);
+                       objp->case_preserving = IXDR_GET_BOOL(buf);
+               }
+        return TRUE;
+       }
+
+        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_pathconf3res (XDR *xdrs, pathconf3res *objp)
+{
+       register int32_t *buf;
+
+        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_post_op_attr (xdrs, &objp->pathconf3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_commit3args (XDR *xdrs, commit3args *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_nfs_fh3 (xdrs, &objp->file))
+                return FALSE;
+        if (!xdr_uint64 (xdrs, &objp->offset))
+                return FALSE;
+        if (!xdr_uint32 (xdrs, &objp->count))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_commit3resok (XDR *xdrs, commit3resok *objp)
+{
+       register int32_t *buf;
+
+        if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+                return FALSE;
+        if (!xdr_writeverf3 (xdrs, objp->verf))
+                return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_commit3res (XDR *xdrs, commit3res *objp)
+{
+       register int32_t *buf;
+
+        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_wcc_data (xdrs, &objp->commit3res_u.resfail))
+                        return FALSE;
+               break;
+       }
+       return TRUE;
+}
diff --git a/nfs3/nfsd.c b/nfs3/nfsd.c
new file mode 100644 (file)
index 0000000..7a0338d
--- /dev/null
@@ -0,0 +1,31 @@
+/* Blue Sky: File Systems in the Cloud
+ *
+ * Copyright (C) 2009  The Regents of the University of California
+ * Written by Michael Vrable <mvrable@cs.ucsd.edu>
+ *
+ * TODO: Licensing
+ */
+
+/* Main entry point for an NFSv3 server which will proxy requests to a cloud
+ * filesystem. */
+
+#include "mount_prot.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <rpc/pmap_clnt.h>
+#include <string.h>
+#include <memory.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+void register_rpc();
+
+int main(int argc, char *argv[])
+{
+    register_rpc();
+
+    svc_run ();
+    fprintf (stderr, "%s", "svc_run returned");
+    exit (1);
+    /* NOTREACHED */
+}
diff --git a/nfs3/rpc.c b/nfs3/rpc.c
new file mode 100644 (file)
index 0000000..38a3c22
--- /dev/null
@@ -0,0 +1,325 @@
+/* Blue Sky: File Systems in the Cloud
+ *
+ * Copyright (C) 2009  The Regents of the University of California
+ * Written by Michael Vrable <mvrable@cs.ucsd.edu>
+ *
+ * TODO: Licensing
+ */
+
+/* RPC handling: registration, marshalling and unmarshalling of messages.  For
+ * now this uses the standard Sun RPC mechanisms in the standard C library.
+ * Later, it might be changed to use something better.  Much of this code was
+ * generated with rpcgen from the XDR specifications, but has been hand-edited
+ * slightly. */
+
+#include "mount_prot.h"
+#include "nfs3_prot.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <rpc/pmap_clnt.h>
+#include <string.h>
+#include <memory.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+static void
+mount_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
+{
+    union {
+        dirpath mountproc3_mnt_3_arg;
+        dirpath mountproc3_umnt_3_arg;
+    } argument;
+    char *result;
+    xdrproc_t _xdr_argument, _xdr_result;
+    char *(*local)(char *, struct svc_req *);
+
+    switch (rqstp->rq_proc) {
+    case MOUNTPROC3_NULL:
+        _xdr_argument = (xdrproc_t) xdr_void;
+        _xdr_result = (xdrproc_t) xdr_void;
+        local = (char *(*)(char *, struct svc_req *)) mountproc3_null_3_svc;
+        break;
+
+    case MOUNTPROC3_MNT:
+        _xdr_argument = (xdrproc_t) xdr_dirpath;
+        _xdr_result = (xdrproc_t) xdr_mountres3;
+        local = (char *(*)(char *, struct svc_req *)) mountproc3_mnt_3_svc;
+        break;
+
+    case MOUNTPROC3_DUMP:
+        _xdr_argument = (xdrproc_t) xdr_void;
+        _xdr_result = (xdrproc_t) xdr_mountlist;
+        local = (char *(*)(char *, struct svc_req *)) mountproc3_dump_3_svc;
+        break;
+
+    case MOUNTPROC3_UMNT:
+        _xdr_argument = (xdrproc_t) xdr_dirpath;
+        _xdr_result = (xdrproc_t) xdr_void;
+        local = (char *(*)(char *, struct svc_req *)) mountproc3_umnt_3_svc;
+        break;
+
+    case MOUNTPROC3_UMNTALL:
+        _xdr_argument = (xdrproc_t) xdr_void;
+        _xdr_result = (xdrproc_t) xdr_void;
+        local = (char *(*)(char *, struct svc_req *)) mountproc3_umntall_3_svc;
+        break;
+
+    case MOUNTPROC3_EXPORT:
+        _xdr_argument = (xdrproc_t) xdr_void;
+        _xdr_result = (xdrproc_t) xdr_exports;
+        local = (char *(*)(char *, struct svc_req *)) mountproc3_export_3_svc;
+        break;
+
+    default:
+        svcerr_noproc (transp);
+        return;
+    }
+    memset ((char *)&argument, 0, sizeof (argument));
+    if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+        svcerr_decode (transp);
+        return;
+    }
+    result = (*local)((char *)&argument, rqstp);
+    if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
+        svcerr_systemerr (transp);
+    }
+    if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+        fprintf (stderr, "%s", "unable to free arguments");
+        exit (1);
+    }
+    return;
+}
+
+static void
+nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
+{
+    union {
+        nfs_fh3 nfsproc3_getattr_3_arg;
+        setattr3args nfsproc3_setattr_3_arg;
+        diropargs3 nfsproc3_lookup_3_arg;
+        access3args nfsproc3_access_3_arg;
+        nfs_fh3 nfsproc3_readlink_3_arg;
+        read3args nfsproc3_read_3_arg;
+        write3args nfsproc3_write_3_arg;
+        create3args nfsproc3_create_3_arg;
+        mkdir3args nfsproc3_mkdir_3_arg;
+        symlink3args nfsproc3_symlink_3_arg;
+        mknod3args nfsproc3_mknod_3_arg;
+        diropargs3 nfsproc3_remove_3_arg;
+        diropargs3 nfsproc3_rmdir_3_arg;
+        rename3args nfsproc3_rename_3_arg;
+        link3args nfsproc3_link_3_arg;
+        readdir3args nfsproc3_readdir_3_arg;
+        readdirplus3args nfsproc3_readdirplus_3_arg;
+        nfs_fh3 nfsproc3_fsstat_3_arg;
+        nfs_fh3 nfsproc3_fsinfo_3_arg;
+        nfs_fh3 nfsproc3_pathconf_3_arg;
+        commit3args nfsproc3_commit_3_arg;
+    } argument;
+    char *result;
+    xdrproc_t _xdr_argument, _xdr_result;
+    char *(*local)(char *, struct svc_req *);
+
+    switch (rqstp->rq_proc) {
+    case NFSPROC3_NULL:
+        _xdr_argument = (xdrproc_t) xdr_void;
+        _xdr_result = (xdrproc_t) xdr_void;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_null_3_svc;
+        break;
+
+    case NFSPROC3_GETATTR:
+        _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
+        _xdr_result = (xdrproc_t) xdr_getattr3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_getattr_3_svc;
+        break;
+
+    case NFSPROC3_SETATTR:
+        _xdr_argument = (xdrproc_t) xdr_setattr3args;
+        _xdr_result = (xdrproc_t) xdr_wccstat3;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_setattr_3_svc;
+        break;
+
+    case NFSPROC3_LOOKUP:
+        _xdr_argument = (xdrproc_t) xdr_diropargs3;
+        _xdr_result = (xdrproc_t) xdr_lookup3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_lookup_3_svc;
+        break;
+
+    case NFSPROC3_ACCESS:
+        _xdr_argument = (xdrproc_t) xdr_access3args;
+        _xdr_result = (xdrproc_t) xdr_access3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_access_3_svc;
+        break;
+
+    case NFSPROC3_READLINK:
+        _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
+        _xdr_result = (xdrproc_t) xdr_readlink3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_readlink_3_svc;
+        break;
+
+    case NFSPROC3_READ:
+        _xdr_argument = (xdrproc_t) xdr_read3args;
+        _xdr_result = (xdrproc_t) xdr_read3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_read_3_svc;
+        break;
+
+    case NFSPROC3_WRITE:
+        _xdr_argument = (xdrproc_t) xdr_write3args;
+        _xdr_result = (xdrproc_t) xdr_write3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_write_3_svc;
+        break;
+
+    case NFSPROC3_CREATE:
+        _xdr_argument = (xdrproc_t) xdr_create3args;
+        _xdr_result = (xdrproc_t) xdr_diropres3;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_create_3_svc;
+        break;
+
+    case NFSPROC3_MKDIR:
+        _xdr_argument = (xdrproc_t) xdr_mkdir3args;
+        _xdr_result = (xdrproc_t) xdr_diropres3;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_mkdir_3_svc;
+        break;
+
+    case NFSPROC3_SYMLINK:
+        _xdr_argument = (xdrproc_t) xdr_symlink3args;
+        _xdr_result = (xdrproc_t) xdr_diropres3;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_symlink_3_svc;
+        break;
+
+    case NFSPROC3_MKNOD:
+        _xdr_argument = (xdrproc_t) xdr_mknod3args;
+        _xdr_result = (xdrproc_t) xdr_diropres3;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_mknod_3_svc;
+        break;
+
+    case NFSPROC3_REMOVE:
+        _xdr_argument = (xdrproc_t) xdr_diropargs3;
+        _xdr_result = (xdrproc_t) xdr_wccstat3;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_remove_3_svc;
+        break;
+
+    case NFSPROC3_RMDIR:
+        _xdr_argument = (xdrproc_t) xdr_diropargs3;
+        _xdr_result = (xdrproc_t) xdr_wccstat3;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_rmdir_3_svc;
+        break;
+
+    case NFSPROC3_RENAME:
+        _xdr_argument = (xdrproc_t) xdr_rename3args;
+        _xdr_result = (xdrproc_t) xdr_rename3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_rename_3_svc;
+        break;
+
+    case NFSPROC3_LINK:
+        _xdr_argument = (xdrproc_t) xdr_link3args;
+        _xdr_result = (xdrproc_t) xdr_link3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_link_3_svc;
+        break;
+
+    case NFSPROC3_READDIR:
+        _xdr_argument = (xdrproc_t) xdr_readdir3args;
+        _xdr_result = (xdrproc_t) xdr_readdir3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_readdir_3_svc;
+        break;
+
+    case NFSPROC3_READDIRPLUS:
+        _xdr_argument = (xdrproc_t) xdr_readdirplus3args;
+        _xdr_result = (xdrproc_t) xdr_readdirplus3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_readdirplus_3_svc;
+        break;
+
+    case NFSPROC3_FSSTAT:
+        _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
+        _xdr_result = (xdrproc_t) xdr_fsstat3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_fsstat_3_svc;
+        break;
+
+    case NFSPROC3_FSINFO:
+        _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
+        _xdr_result = (xdrproc_t) xdr_fsinfo3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_fsinfo_3_svc;
+        break;
+
+    case NFSPROC3_PATHCONF:
+        _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
+        _xdr_result = (xdrproc_t) xdr_pathconf3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_pathconf_3_svc;
+        break;
+
+    case NFSPROC3_COMMIT:
+        _xdr_argument = (xdrproc_t) xdr_commit3args;
+        _xdr_result = (xdrproc_t) xdr_commit3res;
+        local = (char *(*)(char *, struct svc_req *)) nfsproc3_commit_3_svc;
+        break;
+
+    default:
+        svcerr_noproc (transp);
+        return;
+    }
+    memset ((char *)&argument, 0, sizeof (argument));
+    if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+        svcerr_decode (transp);
+        return;
+    }
+    result = (*local)((char *)&argument, rqstp);
+    if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
+        svcerr_systemerr (transp);
+    }
+    if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+        fprintf (stderr, "%s", "unable to free arguments");
+        exit (1);
+    }
+    return;
+}
+
+void register_rpc()
+{
+    SVCXPRT *transp;
+
+    /* MOUNT protocol */
+    pmap_unset (MOUNT_PROGRAM, MOUNT_V3);
+
+    transp = svcudp_create(RPC_ANYSOCK);
+    if (transp == NULL) {
+        fprintf(stderr, "%s", "cannot create udp service.");
+        exit(1);
+    }
+    if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3, mount_program_3, IPPROTO_UDP)) {
+        fprintf(stderr, "%s", "unable to register (MOUNT_PROGRAM, MOUNT_V3, udp).");
+        exit(1);
+    }
+
+    transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+    if (transp == NULL) {
+        fprintf(stderr, "%s", "cannot create tcp service.");
+        exit(1);
+    }
+    if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3, mount_program_3, IPPROTO_TCP)) {
+        fprintf(stderr, "%s", "unable to register (MOUNT_PROGRAM, MOUNT_V3, tcp).");
+        exit(1);
+    }
+
+    /* NFS protocol (version 3) */
+    pmap_unset (NFS_PROGRAM, NFS_V3);
+
+    transp = svcudp_create(RPC_ANYSOCK);
+    if (transp == NULL) {
+        fprintf (stderr, "%s", "cannot create udp service.");
+        exit(1);
+    }
+    if (!svc_register(transp, NFS_PROGRAM, NFS_V3, nfs_program_3, IPPROTO_UDP)) {
+        fprintf (stderr, "%s", "unable to register (NFS_PROGRAM, NFS_V3, udp).");
+        exit(1);
+    }
+
+    transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+    if (transp == NULL) {
+        fprintf (stderr, "%s", "cannot create tcp service.");
+        exit(1);
+    }
+    if (!svc_register(transp, NFS_PROGRAM, NFS_V3, nfs_program_3, IPPROTO_TCP)) {
+        fprintf (stderr, "%s", "unable to register (NFS_PROGRAM, NFS_V3, tcp).");
+        exit(1);
+    }
+}