/*
	$Id: nfs-spec 95 2003-11-02 22:41:17Z ajw $
	$URL: http://svn/NFS/trunk/!Sunfish/nfs-spec $

	XDR Specification for the NFS V3 protocol.
	See RFC 1813 for more details.
	Some structures have been renamed to help integration with NFS2

	StrongEd$Mode=C
*/

#define NFS_RPC_PROGRAM 100003
#define NFS_RPC_VERSION 3

const NFS3_FHSIZE = 64;
/* The maximum size in bytes of the opaque file handle. */

const NFS3_COOKIEVERFSIZE = 8;
/* The size in bytes of the opaque cookie verifier passed by
   READDIR and READDIRPLUS. */

const NFS3_CREATEVERFSIZE = 8;
/* The size in bytes of the opaque verifier used for
   exclusive CREATE. */

/* The size in bytes of the opaque verifier used for
   asynchronous WRITE. */
const NFS3_WRITEVERFSIZE = 8;

typedef uint64_t uint64;
typedef int uint32;

typedef string filename3<>;

typedef string nfspath3<>;

typedef uint64 fileid3;

typedef uint64 cookie3;

typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];


typedef opaque createverf3[NFS3_CREATEVERFSIZE];

typedef opaque writeverf3[NFS3_WRITEVERFSIZE];

typedef uint32 uid3;

typedef uint32 gid3;

typedef uint64 size3;

typedef uint64 offset3;

typedef uint32 mode3;

typedef uint32 count3;

enum nstat {
   NFS_OK             = 0,
   NFSERR_PERM        = 1,
   NFSERR_NOENT       = 2,
   NFSERR_IO          = 5,
   NFSERR_NXIO        = 6,
   NFSERR_ACCES       = 13,
   NFSERR_EXIST       = 17,
   NFSERR_XDEV        = 18,
   NFSERR_NODEV       = 19,
   NFSERR_NOTDIR      = 20,
   NFSERR_ISDIR       = 21,
   NFSERR_INVAL       = 22,
   NFSERR_FBIG        = 27,
   NFSERR_NOSPC       = 28,
   NFSERR_ROFS        = 30,
   NFSERR_MLINK       = 31,
   NFSERR_NAMETOOLONG = 63,
   NFSERR_NOTEMPTY    = 66,
   NFSERR_DQUOT       = 69,
   NFSERR_STALE       = 70,
   NFSERR_REMOTE      = 71,
   NFSERR_BADHANDLE   = 10001,
   NFSERR_NOT_SYNC    = 10002,
   NFSERR_BAD_COOKIE  = 10003,
   NFSERR_NOTSUPP     = 10004,
   NFSERR_TOOSMALL    = 10005,
   NFSERR_SERVERFAULT = 10006,
   NFSERR_BADTYPE     = 10007,
   NFSERR_JUKEBOX     = 10008
};

enum ftype {
   NFREG    = 1,
   NFDIR    = 2,
   NFBLK    = 3,
   NFCHR    = 4,
   NFLNK    = 5,
   NFSOCK   = 6,
   NFFIFO   = 7
};

struct specdata3 {
     uint32     specdata1;
     uint32     specdata2;
};

#ifndef NFS_FH
#define NFS_FH
struct nfs_fh {
   opaque       data<NFS3_FHSIZE>;
};
#endif


struct ntimeval {
   uint32   seconds;
   uint32   nseconds;
};

struct fattr {
   ftype      type;
   mode3      mode;
   uint32     nlink;
   uid3       uid;
   gid3       gid;
   size3      size;
   size3      used;
   specdata3  rdev;
   uint64     fsid;
   fileid3    fileid;
   ntimeval   atime;
   ntimeval   mtime;
   ntimeval   ctime;
};

union post_op_attr switch (bool attributes_follow) {
case TRUE:
   fattr   attributes;
case FALSE:
   void;
};

struct wcc_attr {
   size3       size;
   ntimeval    mtime;
   ntimeval    ctime;
};

union pre_op_attr switch (bool attributes_follow) {
case TRUE:
     wcc_attr  attributes;
case FALSE:
     void;
};

struct wcc_data {
   pre_op_attr    before;
   post_op_attr   after;
};

union post_op_fh3 switch (bool handle_follows) {
case TRUE:
     nfs_fh  handle;
case FALSE:
     void;
};

enum time_how {
   DONT_CHANGE        = 0,
   SET_TO_SERVER_TIME = 1,
   SET_TO_CLIENT_TIME = 2
};

union set_mode3 switch (bool set_it) {
case TRUE:
   mode3    mode;
default:
   void;
};

union set_uid3 switch (bool set_it) {
case TRUE:
   uid3     uid;
default:
   void;
};

union set_gid3 switch (bool set_it) {
case TRUE:
   gid3     gid;
default:
   void;
};

union set_size3 switch (bool set_it) {
case TRUE:
   size3    size;
default:
   void;
};

union set_atime switch (time_how set_it) {
case SET_TO_CLIENT_TIME:
   ntimeval  atime;
default:
   void;
};

union set_mtime switch (time_how set_it) {
case SET_TO_CLIENT_TIME:
   ntimeval  mtime;
default:
   void;
};

struct sattr3 {
   set_mode3   mode;
   set_uid3    uid;
   set_gid3    gid;
   set_size3   size;
   set_atime   atime;
   set_mtime   mtime;
};

struct diropargs {
   nfs_fh     dir;
   filename3   name;
};



void NFSPROC3_NULL(void) = 0;


struct GETATTR3args {
   nfs_fh  object;
};

struct GETATTR3resok {
   fattr   obj_attributes;
};

union GETATTR3res switch (nstat status) {
case NFS_OK:
   GETATTR3resok  resok;
default:
   void;
};

GETATTR3res NFSPROC3_GETATTR(GETATTR3args) = 1;


union sattrguard3 switch (bool check) {
case TRUE:
   ntimeval  obj_ctime;
case FALSE:
   void;
};

struct sattrargs {
   nfs_fh      file;
   sattr3       attributes;
   sattrguard3  guard;
};

struct SETATTR3resok {
   wcc_data  obj_wcc;
};

struct SETATTR3resfail {
   wcc_data  obj_wcc;
};

union sattrres switch (nstat status) {
case NFS_OK:
   SETATTR3resok   resok;
default:
   SETATTR3resfail resfail;
};

sattrres NFSPROC3_SETATTR(sattrargs) = 2;


struct diropok {
     nfs_fh      file;
     post_op_attr obj_attributes;
     post_op_attr dir_attributes;
};

struct LOOKUP3resfail {
     post_op_attr dir_attributes;
};

union diropres switch (nstat status) {
case NFS_OK:
     diropok    diropok;
default:
     LOOKUP3resfail  resfail;
};

diropres NFSPROC3_LOOKUP(diropargs) = 3;

/*
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_fh  object;
     uint32   access;
};

struct ACCESS3resok {
     post_op_attr   obj_attributes;
     uint32         access;
};

struct ACCESS3resfail {
     post_op_attr   obj_attributes;
};

union ACCESS3res switch (nstat status) {
case NFS_OK:
     ACCESS3resok   resok;
default:
     ACCESS3resfail resfail;
};


ACCESS3res NFSPROC3_ACCESS(ACCESS3args) = 4;
*/

struct readlinkargs {
     nfs_fh  fhandle;
};

struct READLINK3resok {
     post_op_attr   symlink_attributes;
     nfspath3       data;
};

struct READLINK3resfail {
     post_op_attr   symlink_attributes;
};

union readlinkres switch (nstat status) {
case NFS_OK:
     READLINK3resok   resok;
default:
     READLINK3resfail resfail;
};

readlinkres NFSPROC3_READLINK(readlinkargs) = 5;


struct readargs {
     nfs_fh  file;
     offset3  offset;
     count3   count;
};

struct READ3resok {
     post_op_attr   file_attributes;
     count3         count;
     bool           eof;
     opaque         data<>;
};

struct READ3resfail {
     post_op_attr   file_attributes;
};

union readres switch (nstat status) {
case NFS_OK:
     READ3resok   resok;
default:
     READ3resfail resfail;
};


readres NFSPROC3_READ(readargs) = 6;


enum stable_how {
     UNSTABLE  = 0,
     DATA_SYNC = 1,
     FILE_SYNC = 2
};

struct writeargs {
     nfs_fh     file;
     offset3     offset;
     count3      count;
     stable_how  stable;
     opaque      data<>;
};

struct WRITE3resok {
     wcc_data    file_wcc;
     count3      count;
     stable_how  committed;
     writeverf3  verf;
};

struct WRITE3resfail {
     wcc_data    file_wcc;
};

union writeres switch (nstat status) {
case NFS_OK:
     WRITE3resok    resok;
default:
     WRITE3resfail  resfail;
};

writeres NFSPROC3_WRITE(writeargs) = 7;


enum createmode3 {
     UNCHECKED = 0,
     GUARDED   = 1,
     EXCLUSIVE = 2
};

union createhow3 switch (createmode3 mode) {
case UNCHECKED:
     sattr3       obj_attributes;
case GUARDED:
     sattr3       obj_attributes2;
case EXCLUSIVE:
     createverf3  verf;
};

struct createargs {
     diropargs   where;
     createhow3   how;
};

struct CREATE3resok {
     post_op_fh3   obj;
     post_op_attr  obj_attributes;
     wcc_data      dir_wcc;
};

struct CREATE3resfail {
     wcc_data      dir_wcc;
};

union createres switch (nstat status) {
case NFS_OK:
     CREATE3resok    diropok;
default:
     CREATE3resfail  resfail;
};

createres NFSPROC3_CREATE(createargs) = 8;


struct mkdirargs {
     diropargs   where;
     sattr3       attributes;
};

createres NFSPROC3_MKDIR(mkdirargs) = 9;

/*

struct symlinkdata3 {
     sattr3    symlink_attributes;
     nfspath3  symlink_data;
};

struct SYMLINK3args {
     diropargs    where;
     symlinkdata3  symlink;
};

struct SYMLINK3resok {
     post_op_fh3   obj;
     post_op_attr  obj_attributes;
     wcc_data      dir_wcc;
};

struct SYMLINK3resfail {
     wcc_data      dir_wcc;
};

union SYMLINK3res switch (nstat status) {
case NFS_OK:
     SYMLINK3resok   resok;
default:
     SYMLINK3resfail resfail;
};


SYMLINK3res NFSPROC3_SYMLINK(SYMLINK3args) = 10;


struct devicedata3 {
     sattr3     dev_attributes;
     specdata3  spec;
};

union mknoddata3 switch (ftype type) {
case NF3CHR:
case NF3BLK:
     devicedata3  device;
case NF3SOCK:
case NF3FIFO:
     sattr3       pipe_attributes;
default:
     void;
};

struct MKNOD3args {
     diropargs   where;
     mknoddata3   what;
};



struct MKNOD3resok {
     post_op_fh3   obj;
     post_op_attr  obj_attributes;
     wcc_data      dir_wcc;
};

struct MKNOD3resfail {
     wcc_data      dir_wcc;
};

union MKNOD3res switch (nstat status) {
case NFS_OK:
     MKNOD3resok   resok;
default:
     MKNOD3resfail resfail;
};

MKNOD3res NFSPROC3_MKNOD(MKNOD3args) = 11;

*/


struct REMOVE3resok {
     wcc_data    dir_wcc;
};

struct REMOVE3resfail {
     wcc_data    dir_wcc;
};

union removeres switch (nstat status) {
case NFS_OK:
     REMOVE3resok   resok;
default:
     REMOVE3resfail resfail;
};


removeres NFSPROC3_REMOVE(diropargs) = 12;


removeres NFSPROC3_RMDIR(diropargs) = 13;


struct renameargs {
     diropargs   from;
     diropargs   to;
};

struct RENAME3resok {
     wcc_data     fromdir_wcc;
     wcc_data     todir_wcc;
};

struct RENAME3resfail {
     wcc_data     fromdir_wcc;
     wcc_data     todir_wcc;
};

union renameres switch (nstat status) {
case NFS_OK:
     RENAME3resok   resok;
default:
     RENAME3resfail resfail;
};


renameres NFSPROC3_RENAME(renameargs) = 14;

/*
struct LINK3args {
     nfs_fh     file;
     diropargs  link;
};

struct LINK3resok {
     post_op_attr   file_attributes;
     wcc_data       linkdir_wcc;
};

struct LINK3resfail {
     post_op_attr   file_attributes;
     wcc_data       linkdir_wcc;
};

union LINK3res switch (nstat status) {
case NFS_OK:
     LINK3resok    resok;
default:
     LINK3resfail  resfail;
};


LINK3res NFSPROC3_LINK(LINK3args) = 15;

*/
struct readdirargs {
     nfs_fh      dir;
     cookie3      cookie;
     cookieverf3  cookieverf;
     count3       count;
};


struct *entry {
     fileid3      fileid;
     filename3    name;
     cookie3      cookie;
     entry       *next;
};

struct READDIR3resok {
     post_op_attr dir_attributes;
     cookieverf3  cookieverf;
     entry       *entries;
     bool         eof;
};

struct READDIR3resfail {
     post_op_attr dir_attributes;
};

union readdirres switch (nstat status) {
case NFS_OK:
     READDIR3resok   readdirok;
default:
     READDIR3resfail resfail;
};


readdirres NFSPROC3_READDIR(readdirargs) = 16;


struct readdirplusargs {
     nfs_fh      dir;
     cookie3      cookie;
     cookieverf3  cookieverf;
     count3       count;
     count3       maxcount;
};

struct *entryplus3 {
     fileid3      fileid;
     filename3    name;
     cookie3      cookie;
     post_op_attr name_attributes;
     post_op_fh3  name_handle;
     entryplus3   *next;
};


struct READDIRPLUS3resok {
     post_op_attr dir_attributes;
     cookieverf3  cookieverf;
     entryplus3   *entries;
     bool         eof;
};


struct READDIRPLUS3resfail {
     post_op_attr dir_attributes;
};

union readdirplusres switch (nstat status) {
case NFS_OK:
     READDIRPLUS3resok   readdirok;
default:
     READDIRPLUS3resfail resfail;
};

readdirplusres NFSPROC3_READDIRPLUS(readdirplusargs) = 17;


/*
struct FSSTAT3args {
     nfs_fh   fsroot;
};

struct FSSTAT3resok {
     post_op_attr obj_attributes;
     size3        tbytes;
     size3        fbytes;
     size3        abytes;
     size3        tfiles;
     size3        ffiles;
     size3        afiles;
     uint32       invarsec;
};

struct FSSTAT3resfail {
     post_op_attr obj_attributes;
};

union FSSTAT3res switch (nstat status) {
case NFS_OK:
     FSSTAT3resok   resok;
default:
     FSSTAT3resfail resfail;
};

FSSTAT3res NFSPROC3_FSSTAT(FSSTAT3args) = 18;
*/

const FSF3_LINK        = 0x0001;
const FSF3_SYMLINK     = 0x0002;
const FSF3_HOMOGENEOUS = 0x0008;
const FSF3_CANSETTIME  = 0x0010;

struct fsinfoargs {
     nfs_fh   fsroot;
};

struct FSINFO3resok {
     post_op_attr obj_attributes;
     uint32       rtmax;
     uint32       rtpref;
     uint32       rtmult;
     uint32       wtmax;
     uint32       wtpref;
     uint32       wtmult;
     uint32       dtpref;
     size3        maxfilesize;
     ntimeval     time_delta;
     uint32       properties;
};

struct FSINFO3resfail {
     post_op_attr obj_attributes;
};

union fsinfores switch (nstat status) {
case NFS_OK:
     FSINFO3resok   resok;
default:
     FSINFO3resfail resfail;
};

fsinfores NFSPROC3_FSINFO(fsinfoargs) = 19;

/*
struct PATHCONF3args {
     nfs_fh   object;
};

struct PATHCONF3resok {
     post_op_attr obj_attributes;
     uint32       linkmax;
     uint32       name_max;
     bool         no_trunc;
     bool         chown_restricted;
     bool         case_insensitive;
     bool         case_preserving;
};

struct PATHCONF3resfail {
     post_op_attr obj_attributes;
};

union PATHCONF3res switch (nstat status) {
case NFS_OK:
     PATHCONF3resok   resok;
default:
     PATHCONF3resfail resfail;
};

PATHCONF3res NFSPROC3_PATHCONF(PATHCONF3args) = 20;

struct COMMIT3args {
     nfs_fh    file;
     offset3    offset;
     count3     count;
};

struct COMMIT3resok {
     wcc_data   file_wcc;
     writeverf3 verf;
};

struct COMMIT3resfail {
     wcc_data   file_wcc;
};

union COMMIT3res switch (nstat status) {
case NFS_OK:
     COMMIT3resok   resok;
default:
     COMMIT3resfail resfail;
};

COMMIT3res NFSPROC3_COMMIT(COMMIT3args) = 21;

*/
