summaryrefslogtreecommitdiff
path: root/sys/src/libsunrpc
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libsunrpc
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libsunrpc')
-rwxr-xr-xsys/src/libsunrpc/COPYING29
-rwxr-xr-xsys/src/libsunrpc/authunix.c60
-rwxr-xr-xsys/src/libsunrpc/client.c482
-rwxr-xr-xsys/src/libsunrpc/emalloc.c34
-rwxr-xr-xsys/src/libsunrpc/error.c37
-rwxr-xr-xsys/src/libsunrpc/fd.c107
-rwxr-xr-xsys/src/libsunrpc/fmt.c64
-rwxr-xr-xsys/src/libsunrpc/mkfile30
-rwxr-xr-xsys/src/libsunrpc/mount3.c727
-rwxr-xr-xsys/src/libsunrpc/net.c57
-rwxr-xr-xsys/src/libsunrpc/nfs3.c4045
-rwxr-xr-xsys/src/libsunrpc/portmap.c498
-rwxr-xr-xsys/src/libsunrpc/prog.c74
-rwxr-xr-xsys/src/libsunrpc/rpc.c528
-rwxr-xr-xsys/src/libsunrpc/server.c277
-rwxr-xr-xsys/src/libsunrpc/suncall.c14
-rwxr-xr-xsys/src/libsunrpc/udp.c113
17 files changed, 7176 insertions, 0 deletions
diff --git a/sys/src/libsunrpc/COPYING b/sys/src/libsunrpc/COPYING
new file mode 100755
index 000000000..e57f239fb
--- /dev/null
+++ b/sys/src/libsunrpc/COPYING
@@ -0,0 +1,29 @@
+
+This software was developed as part of a project at MIT:
+ /sys/src/libsunrpc/*
+ /sys/src/cmd/nfs.c
+ /sys/src/cmd/aux/nfsmount.c
+ /sys/src/cmd/aux/portmap.c
+
+Copyright (c) 2003 Russ Cox,
+ Massachusetts Institute of Technology
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/sys/src/libsunrpc/authunix.c b/sys/src/libsunrpc/authunix.c
new file mode 100755
index 000000000..2b59c07d5
--- /dev/null
+++ b/sys/src/libsunrpc/authunix.c
@@ -0,0 +1,60 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+uint
+sunAuthUnixSize(SunAuthUnix *x)
+{
+ return 4 + sunStringSize(x->sysname) + 4 + 4 + 4 + 4*x->ng;
+}
+int
+sunAuthUnixUnpack(uchar *a, uchar *ea, uchar **pa, SunAuthUnix *x)
+{
+ int i;
+
+ if(sunUint32Unpack(a, ea, &a, &x->stamp) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->sysname, 256) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->uid) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->gid) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->ng) < 0 || x->ng > nelem(x->g)) goto Err;
+ for(i=0; i<x->ng; i++)
+ if(sunUint32Unpack(a, ea, &a, &x->g[i]) < 0) goto Err;
+
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+sunAuthUnixPack(uchar *a, uchar *ea, uchar **pa, SunAuthUnix *x)
+{
+ int i;
+
+ if(sunUint32Pack(a, ea, &a, &x->stamp) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->sysname, 256) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->uid) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->gid) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->ng) < 0 || x->ng > nelem(x->g)) goto Err;
+ for(i=0; i<x->ng; i++)
+ if(sunUint32Pack(a, ea, &a, &x->g[i]) < 0) goto Err;
+
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+sunAuthUnixPrint(Fmt *fmt, SunAuthUnix *x)
+{
+ int i;
+ fmtprint(fmt, "unix %.8lux %s %lud %lud (", (ulong)x->stamp,
+ x->sysname, (ulong)x->uid, (ulong)x->gid);
+ for(i=0; i<x->ng; i++)
+ fmtprint(fmt, "%s%lud", i ? " ":"", (ulong)x->g[i]);
+ fmtprint(fmt, ")");
+}
diff --git a/sys/src/libsunrpc/client.c b/sys/src/libsunrpc/client.c
new file mode 100755
index 000000000..94859486c
--- /dev/null
+++ b/sys/src/libsunrpc/client.c
@@ -0,0 +1,482 @@
+/*
+ * Sun RPC client.
+ */
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+typedef struct Out Out;
+struct Out
+{
+ char err[ERRMAX]; /* error string */
+ Channel *creply; /* send to finish rpc */
+ uchar *p; /* pending request packet */
+ int n; /* size of request */
+ ulong tag; /* flush tag of pending request */
+ ulong xid; /* xid of pending request */
+ ulong st; /* first send time */
+ ulong t; /* resend time */
+ int nresend; /* number of resends */
+ SunRpc rpc; /* response rpc */
+};
+
+static void
+udpThread(void *v)
+{
+ uchar *p, *buf;
+ Ioproc *io;
+ int n;
+ SunClient *cli;
+ enum { BufSize = 65536 };
+
+ cli = v;
+ buf = emalloc(BufSize);
+ io = ioproc();
+ p = nil;
+ for(;;){
+ n = ioread(io, cli->fd, buf, BufSize);
+ if(n <= 0)
+ break;
+ p = emalloc(4+n);
+ memmove(p+4, buf, n);
+ p[0] = n>>24;
+ p[1] = n>>16;
+ p[2] = n>>8;
+ p[3] = n;
+ if(sendp(cli->readchan, p) == 0)
+ break;
+ p = nil;
+ }
+ free(p);
+ closeioproc(io);
+ while(send(cli->dying, nil) == -1)
+ ;
+}
+
+static void
+netThread(void *v)
+{
+ uchar *p, buf[4];
+ Ioproc *io;
+ uint n, tot;
+ int done;
+ SunClient *cli;
+
+ cli = v;
+ io = ioproc();
+ tot = 0;
+ p = nil;
+ for(;;){
+ n = ioreadn(io, cli->fd, buf, 4);
+ if(n != 4)
+ break;
+ n = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];
+ if(cli->chatty)
+ fprint(2, "%.8ux...", n);
+ done = n&0x80000000;
+ n &= ~0x80000000;
+ if(tot == 0){
+ p = emalloc(4+n);
+ tot = 4;
+ }else
+ p = erealloc(p, tot+n);
+ if(ioreadn(io, cli->fd, p+tot, n) != n)
+ break;
+ tot += n;
+ if(done){
+ p[0] = tot>>24;
+ p[1] = tot>>16;
+ p[2] = tot>>8;
+ p[3] = tot;
+ if(sendp(cli->readchan, p) == 0)
+ break;
+ p = nil;
+ tot = 0;
+ }
+ }
+ free(p);
+ closeioproc(io);
+ while(send(cli->dying, 0) == -1)
+ ;
+}
+
+static void
+timerThread(void *v)
+{
+ Ioproc *io;
+ SunClient *cli;
+
+ cli = v;
+ io = ioproc();
+ for(;;){
+ if(iosleep(io, 200) < 0)
+ break;
+ if(sendul(cli->timerchan, 0) == 0)
+ break;
+ }
+ closeioproc(io);
+ while(send(cli->dying, 0) == -1)
+ ;
+}
+
+static ulong
+msec(void)
+{
+ return nsec()/1000000;
+}
+
+static ulong
+twait(ulong rtt, int nresend)
+{
+ ulong t;
+
+ t = rtt;
+ if(nresend <= 1)
+ {}
+ else if(nresend <= 3)
+ t *= 2;
+ else if(nresend <= 18)
+ t <<= nresend-2;
+ else
+ t = 60*1000;
+ if(t > 60*1000)
+ t = 60*1000;
+
+ return t;
+}
+
+static void
+rpcMuxThread(void *v)
+{
+ uchar *buf, *p, *ep;
+ int i, n, nout, mout;
+ ulong t, xidgen, tag;
+ Alt a[5];
+ Out *o, **out;
+ SunRpc rpc;
+ SunClient *cli;
+
+ cli = v;
+ mout = 16;
+ nout = 0;
+ out = emalloc(mout*sizeof(out[0]));
+ xidgen = truerand();
+
+ a[0].op = CHANRCV;
+ a[0].c = cli->rpcchan;
+ a[0].v = &o;
+ a[1].op = CHANNOP;
+ a[1].c = cli->timerchan;
+ a[1].v = nil;
+ a[2].op = CHANRCV;
+ a[2].c = cli->flushchan;
+ a[2].v = &tag;
+ a[3].op = CHANRCV;
+ a[3].c = cli->readchan;
+ a[3].v = &buf;
+ a[4].op = CHANEND;
+
+ for(;;){
+ switch(alt(a)){
+ case 0: /* o = <-rpcchan */
+ if(o == nil)
+ goto Done;
+ cli->nsend++;
+ /* set xid */
+ o->xid = ++xidgen;
+ if(cli->needcount)
+ p = o->p+4;
+ else
+ p = o->p;
+ p[0] = xidgen>>24;
+ p[1] = xidgen>>16;
+ p[2] = xidgen>>8;
+ p[3] = xidgen;
+ if(write(cli->fd, o->p, o->n) != o->n){
+ free(o->p);
+ o->p = nil;
+ snprint(o->err, sizeof o->err, "write: %r");
+ sendp(o->creply, 0);
+ break;
+ }
+ if(nout >= mout){
+ mout *= 2;
+ out = erealloc(out, mout*sizeof(out[0]));
+ }
+ o->st = msec();
+ o->nresend = 0;
+ o->t = o->st + twait(cli->rtt.avg, 0);
+if(cli->chatty) fprint(2, "send %lux %lud %lud\n", o->xid, o->st, o->t);
+ out[nout++] = o;
+ a[1].op = CHANRCV;
+ break;
+
+ case 1: /* <-timerchan */
+ t = msec();
+ for(i=0; i<nout; i++){
+ o = out[i];
+ if((int)(t - o->t) > 0){
+if(cli->chatty) fprint(2, "resend %lux %lud %lud\n", o->xid, t, o->t);
+ if(cli->maxwait && t - o->st >= cli->maxwait){
+ free(o->p);
+ o->p = nil;
+ strcpy(o->err, "timeout");
+ sendp(o->creply, 0);
+ out[i--] = out[--nout];
+ continue;
+ }
+ cli->nresend++;
+ o->nresend++;
+ o->t = t + twait(cli->rtt.avg, o->nresend);
+ if(write(cli->fd, o->p, o->n) != o->n){
+ free(o->p);
+ o->p = nil;
+ snprint(o->err, sizeof o->err, "rewrite: %r");
+ sendp(o->creply, 0);
+ out[i--] = out[--nout];
+ continue;
+ }
+ }
+ }
+ /* stop ticking if no work; rpcchan will turn it back on */
+ if(nout == 0)
+ a[1].op = CHANNOP;
+ break;
+
+ case 2: /* tag = <-flushchan */
+ for(i=0; i<nout; i++){
+ o = out[i];
+ if(o->tag == tag){
+ out[i--] = out[--nout];
+ strcpy(o->err, "flushed");
+ free(o->p);
+ o->p = nil;
+ sendp(o->creply, 0);
+ }
+ }
+ break;
+
+ case 3: /* buf = <-readchan */
+ p = buf;
+ n = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
+ p += 4;
+ ep = p+n;
+ if(sunRpcUnpack(p, ep, &p, &rpc) < 0){
+ fprint(2, "in: %.*H unpack failed\n", n, buf+4);
+ free(buf);
+ break;
+ }
+ if(cli->chatty)
+ fprint(2, "in: %B\n", &rpc);
+ if(rpc.iscall){
+ fprint(2, "did not get reply\n");
+ free(buf);
+ break;
+ }
+ o = nil;
+ for(i=0; i<nout; i++){
+ o = out[i];
+ if(o->xid == rpc.xid)
+ break;
+ }
+ if(i==nout){
+ if(cli->chatty) fprint(2, "did not find waiting request\n");
+ free(buf);
+ break;
+ }
+ out[i] = out[--nout];
+ free(o->p);
+ o->p = nil;
+ if(rpc.status == SunSuccess){
+ o->p = buf;
+ o->rpc = rpc;
+ }else{
+ o->p = nil;
+ free(buf);
+ sunErrstr(rpc.status);
+ rerrstr(o->err, sizeof o->err);
+ }
+ sendp(o->creply, 0);
+ break;
+ }
+ }
+Done:
+ free(out);
+ sendp(cli->dying, 0);
+}
+
+SunClient*
+sunDial(char *address)
+{
+ int fd;
+ SunClient *cli;
+
+ if((fd = dial(address, 0, 0, 0)) < 0)
+ return nil;
+
+ cli = emalloc(sizeof(SunClient));
+ cli->fd = fd;
+ cli->maxwait = 15000;
+ cli->rtt.avg = 1000;
+ cli->dying = chancreate(sizeof(void*), 0);
+ cli->rpcchan = chancreate(sizeof(Out*), 0);
+ cli->timerchan = chancreate(sizeof(ulong), 0);
+ cli->flushchan = chancreate(sizeof(ulong), 0);
+ cli->readchan = chancreate(sizeof(uchar*), 0);
+ if(strstr(address, "udp!")){
+ cli->needcount = 0;
+ cli->nettid = threadcreate(udpThread, cli, SunStackSize);
+ cli->timertid = threadcreate(timerThread, cli, SunStackSize);
+ }else{
+ cli->needcount = 1;
+ cli->nettid = threadcreate(netThread, cli, SunStackSize);
+ /* assume reliable: don't need timer */
+ /* BUG: netThread should know how to redial */
+ }
+ threadcreate(rpcMuxThread, cli, SunStackSize);
+
+ return cli;
+}
+
+void
+sunClientClose(SunClient *cli)
+{
+ int n;
+
+ /*
+ * Threadints get you out of any stuck system calls
+ * or thread rendezvouses, but do nothing if the thread
+ * is in the ready state. Keep interrupting until it takes.
+ */
+ n = 0;
+ if(!cli->timertid)
+ n++;
+ while(n < 2){
+ threadint(cli->nettid);
+ if(cli->timertid)
+ threadint(cli->timertid);
+ yield();
+ while(nbrecv(cli->dying, nil) == 1)
+ n++;
+ }
+
+ sendp(cli->rpcchan, 0);
+ recvp(cli->dying);
+
+ /* everyone's gone: clean up */
+ close(cli->fd);
+ chanfree(cli->flushchan);
+ chanfree(cli->readchan);
+ chanfree(cli->timerchan);
+ free(cli);
+}
+
+void
+sunClientFlushRpc(SunClient *cli, ulong tag)
+{
+ sendul(cli->flushchan, tag);
+}
+
+void
+sunClientProg(SunClient *cli, SunProg *p)
+{
+ if(cli->nprog%16 == 0)
+ cli->prog = erealloc(cli->prog, (cli->nprog+16)*sizeof(cli->prog[0]));
+ cli->prog[cli->nprog++] = p;
+}
+
+int
+sunClientRpc(SunClient *cli, ulong tag, SunCall *tx, SunCall *rx, uchar **tofree)
+{
+ uchar *bp, *p, *ep;
+ int i, n1, n2, n, nn;
+ Out o;
+ SunProg *prog;
+ SunStatus ok;
+
+ for(i=0; i<cli->nprog; i++)
+ if(cli->prog[i]->prog == tx->rpc.prog && cli->prog[i]->vers == tx->rpc.vers)
+ break;
+ if(i==cli->nprog){
+ werrstr("unknown sun rpc program %d version %d", tx->rpc.prog, tx->rpc.vers);
+ return -1;
+ }
+ prog = cli->prog[i];
+
+ if(cli->chatty){
+ fprint(2, "out: %B\n", &tx->rpc);
+ fprint(2, "\t%C\n", tx);
+ }
+
+ n1 = sunRpcSize(&tx->rpc);
+ n2 = sunCallSize(prog, tx);
+
+ n = n1+n2;
+ if(cli->needcount)
+ n += 4;
+
+ bp = emalloc(n);
+ ep = bp+n;
+ p = bp;
+ if(cli->needcount){
+ nn = n-4;
+ p[0] = (nn>>24)|0x80;
+ p[1] = nn>>16;
+ p[2] = nn>>8;
+ p[3] = nn;
+ p += 4;
+ }
+ if((ok = sunRpcPack(p, ep, &p, &tx->rpc)) != SunSuccess
+ || (ok = sunCallPack(prog, p, ep, &p, tx)) != SunSuccess){
+ sunErrstr(ok);
+ free(bp);
+ return -1;
+ }
+ if(p != ep){
+ werrstr("rpc: packet size mismatch");
+ free(bp);
+ return -1;
+ }
+
+ memset(&o, 0, sizeof o);
+ o.creply = chancreate(sizeof(void*), 0);
+ o.tag = tag;
+ o.p = bp;
+ o.n = n;
+
+ sendp(cli->rpcchan, &o);
+ recvp(o.creply);
+ chanfree(o.creply);
+
+ if(o.p == nil){
+ werrstr("%s", o.err);
+ return -1;
+ }
+
+ p = o.rpc.data;
+ ep = p+o.rpc.ndata;
+ rx->rpc = o.rpc;
+ rx->rpc.proc = tx->rpc.proc;
+ rx->rpc.prog = tx->rpc.prog;
+ rx->rpc.vers = tx->rpc.vers;
+ rx->type = (rx->rpc.proc<<1)|1;
+ if((ok = sunCallUnpack(prog, p, ep, &p, rx)) != SunSuccess){
+ sunErrstr(ok);
+ werrstr("unpack: %r");
+ free(o.p);
+ return -1;
+ }
+
+ if(cli->chatty){
+ fprint(2, "in: %B\n", &rx->rpc);
+ fprint(2, "in:\t%C\n", rx);
+ }
+
+ if(tofree)
+ *tofree = o.p;
+ else
+ free(o.p);
+
+ return 0;
+}
diff --git a/sys/src/libsunrpc/emalloc.c b/sys/src/libsunrpc/emalloc.c
new file mode 100755
index 000000000..8a09eda78
--- /dev/null
+++ b/sys/src/libsunrpc/emalloc.c
@@ -0,0 +1,34 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+void*
+emalloc(ulong n)
+{
+ void *v;
+
+ v = mallocz(n, 1);
+ if(v == nil)
+{
+abort();
+ sysfatal("out of memory");
+}
+ setmalloctag(v, getcallerpc(&n));
+ return v;
+}
+
+void*
+erealloc(void *v, ulong n)
+{
+ v = realloc(v, n);
+ if(v == nil)
+{
+abort();
+ sysfatal("out of memory");
+}
+ setrealloctag(v, getcallerpc(&n));
+ return v;
+}
+
+
diff --git a/sys/src/libsunrpc/error.c b/sys/src/libsunrpc/error.c
new file mode 100755
index 000000000..51d36ee8c
--- /dev/null
+++ b/sys/src/libsunrpc/error.c
@@ -0,0 +1,37 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+static struct {
+ SunStatus status;
+ char *msg;
+} tab[] = {
+ SunProgUnavail, "program unavailable",
+ SunProgMismatch, "program mismatch",
+ SunProcUnavail, "procedure unavailable",
+ SunGarbageArgs, "garbage args",
+ SunSystemErr, "system error",
+ SunRpcMismatch, "rpc mismatch",
+ SunAuthBadCred, "bad auth cred",
+ SunAuthRejectedCred, "rejected auth cred",
+ SunAuthBadVerf, "bad auth verf",
+ SunAuthRejectedVerf, "rejected auth verf",
+ SunAuthTooWeak, "auth too weak",
+ SunAuthInvalidResp, "invalid auth response",
+ SunAuthFailed, "auth failed",
+};
+
+void
+sunErrstr(SunStatus status)
+{
+ int i;
+
+ for(i=0; i<nelem(tab); i++){
+ if(tab[i].status == status){
+ werrstr(tab[i].msg);
+ return;
+ }
+ }
+ werrstr("unknown sun error %d", (int)status);
+}
diff --git a/sys/src/libsunrpc/fd.c b/sys/src/libsunrpc/fd.c
new file mode 100755
index 000000000..e20b9ae47
--- /dev/null
+++ b/sys/src/libsunrpc/fd.c
@@ -0,0 +1,107 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+enum
+{
+ MaxRead = 17000,
+};
+
+typedef struct SunMsgFd SunMsgFd;
+struct SunMsgFd
+{
+ SunMsg msg;
+ int fd;
+};
+
+typedef struct Arg Arg;
+struct Arg
+{
+ SunSrv *srv;
+ Channel *creply;
+ Channel *csync;
+ int fd;
+};
+
+static void
+sunFdRead(void *v)
+{
+ uint n, tot;
+ int done;
+ uchar buf[4], *p;
+ Arg arg = *(Arg*)v;
+ SunMsgFd *msg;
+
+ sendp(arg.csync, 0);
+
+ p = nil;
+ tot = 0;
+ for(;;){
+ n = readn(arg.fd, buf, 4);
+ if(n != 4)
+ break;
+ n = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];
+if(arg.srv->chatty) fprint(2, "%.8ux...", n);
+ done = n&0x80000000;
+ n &= ~0x80000000;
+ p = erealloc(p, tot+n);
+ if(readn(arg.fd, p+tot, n) != n)
+ break;
+ tot += n;
+ if(done){
+ msg = emalloc(sizeof(SunMsgFd));
+ msg->msg.data = p;
+ msg->msg.count = tot;
+ msg->msg.creply = arg.creply;
+ sendp(arg.srv->crequest, msg);
+ p = nil;
+ tot = 0;
+ }
+ }
+}
+
+static void
+sunFdWrite(void *v)
+{
+ uchar buf[4];
+ u32int n;
+ Arg arg = *(Arg*)v;
+ SunMsgFd *msg;
+
+ sendp(arg.csync, 0);
+
+ while((msg = recvp(arg.creply)) != nil){
+ n = msg->msg.count;
+ buf[0] = (n>>24)|0x80;
+ buf[1] = n>>16;
+ buf[2] = n>>8;
+ buf[3] = n;
+ if(write(arg.fd, buf, 4) != 4
+ || write(arg.fd, msg->msg.data, msg->msg.count) != msg->msg.count)
+ fprint(2, "sunFdWrite: %r\n");
+ free(msg->msg.data);
+ free(msg);
+ }
+}
+
+int
+sunSrvFd(SunSrv *srv, int fd)
+{
+ Arg *arg;
+
+ arg = emalloc(sizeof(Arg));
+ arg->fd = fd;
+ arg->srv = srv;
+ arg->csync = chancreate(sizeof(void*), 0);
+ arg->creply = chancreate(sizeof(SunMsg*), 10);
+
+ proccreate(sunFdRead, arg, SunStackSize);
+ proccreate(sunFdWrite, arg, SunStackSize);
+ recvp(arg->csync);
+ recvp(arg->csync);
+
+ chanfree(arg->csync);
+ free(arg);
+ return 0;
+}
diff --git a/sys/src/libsunrpc/fmt.c b/sys/src/libsunrpc/fmt.c
new file mode 100755
index 000000000..e1bd24492
--- /dev/null
+++ b/sys/src/libsunrpc/fmt.c
@@ -0,0 +1,64 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+/*
+ * print formatters
+ */
+int
+sunRpcFmt(Fmt *f)
+{
+ SunRpc *rpc;
+
+ rpc = va_arg(f->args, SunRpc*);
+ sunRpcPrint(f, rpc);
+ return 0;
+}
+
+static SunProg **fmtProg;
+static int nfmtProg;
+static RWLock fmtLock;
+
+void
+sunFmtInstall(SunProg *p)
+{
+ int i;
+
+ wlock(&fmtLock);
+ for(i=0; i<nfmtProg; i++){
+ if(fmtProg[i] == p){
+ wunlock(&fmtLock);
+ return;
+ }
+ }
+ if(nfmtProg%16 == 0)
+ fmtProg = erealloc(fmtProg, sizeof(fmtProg[0])*(nfmtProg+16));
+ fmtProg[nfmtProg++] = p;
+ wunlock(&fmtLock);
+}
+
+int
+sunCallFmt(Fmt *f)
+{
+ int i;
+ void (*fmt)(Fmt*, SunCall*);
+ SunCall *c;
+ SunProg *p;
+
+ c = va_arg(f->args, SunCall*);
+ rlock(&fmtLock);
+ for(i=0; i<nfmtProg; i++){
+ p = fmtProg[i];
+ if(p->prog == c->rpc.prog && p->vers == c->rpc.vers){
+ runlock(&fmtLock);
+ if(c->type < 0 || c->type >= p->nproc || (fmt=p->proc[c->type].fmt) == nil)
+ return fmtprint(f, "unknown proc %c%d", "TR"[c->type&1], c->type>>1);
+ (*fmt)(f, c);
+ return 0;
+ }
+ }
+ runlock(&fmtLock);
+ fmtprint(f, "<sunrpc %d %d %c%d>", c->rpc.prog, c->rpc.vers, "TR"[c->type&1], c->type>>1);
+ return 0;
+}
diff --git a/sys/src/libsunrpc/mkfile b/sys/src/libsunrpc/mkfile
new file mode 100755
index 000000000..b067983a9
--- /dev/null
+++ b/sys/src/libsunrpc/mkfile
@@ -0,0 +1,30 @@
+</$objtype/mkfile
+
+PROTO=\
+ mount3.$O\
+ nfs3.$O\
+ portmap.$O\
+
+OFILES=\
+ authunix.$O\
+ client.$O\
+ emalloc.$O\
+ error.$O\
+ fd.$O\
+ fmt.$O\
+ net.$O\
+ prog.$O\
+ rpc.$O\
+ server.$O\
+ suncall.$O\
+ udp.$O\
+ $PROTO\
+
+HFILES=\
+ /sys/include/sunrpc.h\
+
+LIB=/$objtype/lib/libsunrpc.a
+
+</sys/src/cmd/mksyslib
+
+mount3.$O: /sys/include/nfs3.h
diff --git a/sys/src/libsunrpc/mount3.c b/sys/src/libsunrpc/mount3.c
new file mode 100755
index 000000000..3f11f1fe3
--- /dev/null
+++ b/sys/src/libsunrpc/mount3.c
@@ -0,0 +1,727 @@
+/*
+ * SUN NFSv3 Mounter. See RFC 1813
+ */
+
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+#include <nfs3.h>
+
+void
+nfsMount3TNullPrint(Fmt *fmt, NfsMount3TNull *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3TNull");
+}
+uint
+nfsMount3TNullSize(NfsMount3TNull *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfsMount3TNullPack(uchar *a, uchar *ea, uchar **pa, NfsMount3TNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfsMount3TNullUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3TNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfsMount3RNullPrint(Fmt *fmt, NfsMount3RNull *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3RNull");
+}
+uint
+nfsMount3RNullSize(NfsMount3RNull *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfsMount3RNullPack(uchar *a, uchar *ea, uchar **pa, NfsMount3RNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfsMount3RNullUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3RNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfsMount3TMntPrint(Fmt *fmt, NfsMount3TMnt *x)
+{
+ fmtprint(fmt, "%s\n", "NfsMount3TMnt");
+ fmtprint(fmt, "\t%s=", "path");
+ fmtprint(fmt, "\"%s\"", x->path);
+ fmtprint(fmt, "\n");
+}
+uint
+nfsMount3TMntSize(NfsMount3TMnt *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + sunStringSize(x->path);
+ return a;
+}
+int
+nfsMount3TMntPack(uchar *a, uchar *ea, uchar **pa, NfsMount3TMnt *x)
+{
+ if(sunStringPack(a, ea, &a, &x->path, 1024) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfsMount3TMntUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3TMnt *x)
+{
+ if(sunStringUnpack(a, ea, &a, &x->path, 1024) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfsMount3RMntPrint(Fmt *fmt, NfsMount3RMnt *x)
+{
+ fmtprint(fmt, "%s\n", "NfsMount3RMnt");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%ud", x->status);
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case 0:
+ fmtprint(fmt, "\t%s=", "handle");
+ fmtprint(fmt, "%.*H", x->len, x->handle);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfsMount3RMntSize(NfsMount3RMnt *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case 0:
+ a = a + sunVarOpaqueSize(x->len);
+ a = a + 4 + 4 * x->nauth;
+ break;
+ }
+ a = a;
+ return a;
+}
+uint
+nfsMount1RMntSize(NfsMount3RMnt *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case 0:
+ a = a + NfsMount1HandleSize;
+ break;
+ }
+ return a;
+}
+
+int
+nfsMount3RMntPack(uchar *a, uchar *ea, uchar **pa, NfsMount3RMnt *x)
+{
+ int i;
+ if(sunUint32Pack(a, ea, &a, &x->status) < 0) goto Err;
+ switch(x->status){
+ case 0:
+ if(sunVarOpaquePack(a, ea, &a, &x->handle, &x->len, NfsMount3MaxHandleSize) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->nauth) < 0) goto Err;
+ for(i=0; i<x->nauth; i++)
+ if(sunUint32Pack(a, ea, &a, &x->auth[i]) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfsMount1RMntPack(uchar *a, uchar *ea, uchar **pa, NfsMount3RMnt *x)
+{
+ if(sunUint32Pack(a, ea, &a, &x->status) < 0) goto Err;
+ switch(x->status){
+ case 0:
+ if(x->len != NfsMount1HandleSize)
+ goto Err;
+ if(sunFixedOpaquePack(a, ea, &a, x->handle, NfsMount1HandleSize) < 0) goto Err;
+ if(x->nauth != 0)
+ goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfsMount1RMntUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3RMnt *x)
+{
+ if(sunUint32Unpack(a, ea, &a, &x->status) < 0) goto Err;
+ switch(x->status){
+ case 0:
+ x->len = NfsMount1HandleSize;
+ x->nauth = 0;
+ x->auth = 0;
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->handle, NfsMount1HandleSize) < 0) goto Err;
+ if(x->nauth != 0)
+ goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+nfsMount3RMntUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3RMnt *x)
+{
+ int i;
+
+ if(sunUint32Unpack(a, ea, &a, &x->status) < 0) goto Err;
+ switch(x->status){
+ case 0:
+ if(sunVarOpaqueUnpack(a, ea, &a, &x->handle, &x->len, NfsMount3MaxHandleSize) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->nauth) < 0) goto Err;
+ x->auth = (u32int*)a;
+ for(i=0; i<x->nauth; i++)
+ if(sunUint32Unpack(a, ea, &a, &x->auth[i]) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfsMount3TDumpPrint(Fmt *fmt, NfsMount3TDump *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3TDump");
+}
+uint
+nfsMount3TDumpSize(NfsMount3TDump *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfsMount3TDumpPack(uchar *a, uchar *ea, uchar **pa, NfsMount3TDump *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfsMount3TDumpUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3TDump *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfsMount3EntryPrint(Fmt *fmt, NfsMount3Entry *x)
+{
+ fmtprint(fmt, "%s\n", "NfsMount3Entry");
+ fmtprint(fmt, "\t%s=", "host");
+ fmtprint(fmt, "\"%s\"", x->host);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "path");
+ fmtprint(fmt, "\"%s\"", x->path);
+ fmtprint(fmt, "\n");
+}
+uint
+nfsMount3EntrySize(NfsMount3Entry *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + sunStringSize(x->host) + sunStringSize(x->path);
+ return a;
+}
+int
+nfsMount3EntryPack(uchar *a, uchar *ea, uchar **pa, NfsMount3Entry *x)
+{
+ u1int one;
+
+ one = 1;
+ if(sunUint1Pack(a, ea, &a, &one) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->host, 255) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->path, 1024) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfsMount3EntryUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3Entry *x)
+{
+ u1int one;
+
+ if(sunUint1Unpack(a, ea, &a, &one) < 0 || one != 1) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->host, NfsMount3MaxNameSize) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->path, NfsMount3MaxPathSize) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfsMount3RDumpPrint(Fmt *fmt, NfsMount3RDump *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3RDump");
+}
+uint
+nfsMount3RDumpSize(NfsMount3RDump *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ a += x->count;
+ a += 4;
+ return a;
+}
+int
+nfsMount3RDumpPack(uchar *a, uchar *ea, uchar **pa, NfsMount3RDump *x)
+{
+ u1int zero;
+
+ zero = 0;
+ if(a+x->count > ea) goto Err;
+ memmove(a, x->data, x->count);
+ a += x->count;
+ if(sunUint1Pack(a, ea, &a, &zero) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfsMount3RDumpUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3RDump *x)
+{
+ int i;
+ uchar *oa;
+ u1int u1;
+ u32int u32;
+
+ oa = a;
+ for(i=0;; i++){
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0)
+ goto Err;
+ if(u1 == 0)
+ break;
+ if(sunUint32Unpack(a, ea, &a, &u32) < 0
+ || u32 > NfsMount3MaxNameSize
+ || (a+=u32) >= ea
+ || sunUint32Unpack(a, ea, &a, &u32) < 0
+ || u32 > NfsMount3MaxPathSize
+ || (a+=u32) >= ea)
+ goto Err;
+ }
+ x->count = (a-4) - oa;
+ x->data = oa;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfsMount3TUmntPrint(Fmt *fmt, NfsMount3TUmnt *x)
+{
+ fmtprint(fmt, "%s\n", "NfsMount3TUmnt");
+ fmtprint(fmt, "\t%s=", "path");
+ fmtprint(fmt, "\"%s\"", x->path);
+ fmtprint(fmt, "\n");
+}
+uint
+nfsMount3TUmntSize(NfsMount3TUmnt *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + sunStringSize(x->path);
+ return a;
+}
+int
+nfsMount3TUmntPack(uchar *a, uchar *ea, uchar **pa, NfsMount3TUmnt *x)
+{
+ if(sunStringPack(a, ea, &a, &x->path, 1024) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfsMount3TUmntUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3TUmnt *x)
+{
+ if(sunStringUnpack(a, ea, &a, &x->path, 1024) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfsMount3RUmntPrint(Fmt *fmt, NfsMount3RUmnt *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3RUmnt");
+}
+uint
+nfsMount3RUmntSize(NfsMount3RUmnt *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfsMount3RUmntPack(uchar *a, uchar *ea, uchar **pa, NfsMount3RUmnt *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfsMount3RUmntUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3RUmnt *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfsMount3TUmntallPrint(Fmt *fmt, NfsMount3TUmntall *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3TUmntall");
+}
+uint
+nfsMount3TUmntallSize(NfsMount3TUmntall *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfsMount3TUmntallPack(uchar *a, uchar *ea, uchar **pa, NfsMount3TUmntall *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfsMount3TUmntallUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3TUmntall *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfsMount3RUmntallPrint(Fmt *fmt, NfsMount3RUmntall *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3RUmntall");
+}
+uint
+nfsMount3RUmntallSize(NfsMount3RUmntall *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfsMount3RUmntallPack(uchar *a, uchar *ea, uchar **pa, NfsMount3RUmntall *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfsMount3RUmntallUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3RUmntall *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfsMount3TExportPrint(Fmt *fmt, NfsMount3TExport *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3TExport");
+}
+uint
+nfsMount3TExportSize(NfsMount3TExport *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfsMount3TExportPack(uchar *a, uchar *ea, uchar **pa, NfsMount3TExport *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfsMount3TExportUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3TExport *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfsMount3RExportPrint(Fmt *fmt, NfsMount3RExport *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "NfsMount3RExport");
+ fmtprint(fmt, "\n");
+}
+uint
+nfsMount3RExportSize(NfsMount3RExport *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ a += x->count;
+ a += 4; /* end of export list */
+ return a;
+}
+int
+nfsMount3RExportPack(uchar *a, uchar *ea, uchar **pa, NfsMount3RExport *x)
+{
+ u1int zero;
+
+ zero = 0;
+ if(a+x->count > ea) goto Err;
+ memmove(a, x->data, x->count);
+ a += x->count;
+ if(sunUint1Pack(a, ea, &a, &zero) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfsMount3RExportUnpack(uchar *a, uchar *ea, uchar **pa, NfsMount3RExport *x)
+{
+ int ng, ne;
+ uchar *oa;
+ u1int u1;
+ u32int u32;
+
+ oa = a;
+ ng = 0;
+ for(ne=0;; ne++){
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0)
+ goto Err;
+ if(u1 == 0)
+ break;
+ if(sunUint32Unpack(a, ea, &a, &u32) < 0
+ || (a += (u32+3)&~3) >= ea)
+ goto Err;
+ for(;; ng++){
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0)
+ goto Err;
+ if(u1 == 0)
+ break;
+ if(sunUint32Unpack(a, ea, &a, &u32) < 0
+ || (a += (u32+3)&~3) >= ea)
+ goto Err;
+ }
+ }
+ x->data = oa;
+ x->count = (a-4) - oa;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+uint
+nfsMount3ExportGroupSize(uchar *a)
+{
+ int ng;
+ u1int have;
+ u32int n;
+
+ a += 4;
+ sunUint32Unpack(a, a+4, &a, &n);
+ a += (n+3)&~3;
+ ng = 0;
+ for(;;){
+ sunUint1Unpack(a, a+4, &a, &have);
+ if(have == 0)
+ break;
+ ng++;
+ sunUint32Unpack(a, a+4, &a, &n);
+ a += (n+3)&~3;
+ }
+ return ng;
+}
+int
+nfsMount3ExportUnpack(uchar *a, uchar *ea, uchar **pa, char **gp, char ***pgp, NfsMount3Export *x)
+{
+ int ng;
+ u1int u1;
+
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0 || u1 != 1) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->path, NfsMount3MaxPathSize) < 0) goto Err;
+ x->g = gp;
+ ng = 0;
+ for(;;){
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0) goto Err;
+ if(u1 == 0)
+ break;
+ if(sunStringUnpack(a, ea, &a, &gp[ng++], NfsMount3MaxNameSize) < 0) goto Err;
+ }
+ x->ng = ng;
+ *pgp = gp+ng;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+uint
+nfsMount3ExportSize(NfsMount3Export *x)
+{
+ int i;
+ uint a;
+
+ a = 4 + sunStringSize(x->path);
+ for(i=0; i<x->ng; i++)
+ a += 4 + sunStringSize(x->g[i]);
+ a += 4;
+ return a;
+}
+int
+nfsMount3ExportPack(uchar *a, uchar *ea, uchar **pa, NfsMount3Export *x)
+{
+ int i;
+ u1int u1;
+
+ u1 = 1;
+ if(sunUint1Pack(a, ea, &a, &u1) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->path, NfsMount3MaxPathSize) < 0) goto Err;
+ for(i=0; i<x->ng; i++){
+ if(sunUint1Pack(a, ea, &a, &u1) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->g[i], NfsMount3MaxNameSize) < 0) goto Err;
+ }
+ u1 = 0;
+ if(sunUint1Pack(a, ea, &a, &u1) < 0) goto Err;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+typedef int (*P)(uchar*, uchar*, uchar**, SunCall*);
+typedef void (*F)(Fmt*, SunCall*);
+typedef uint (*S)(SunCall*);
+
+static SunProc proc3[] = {
+ (P)nfsMount3TNullPack, (P)nfsMount3TNullUnpack, (S)nfsMount3TNullSize, (F)nfsMount3TNullPrint, sizeof(NfsMount3TNull),
+ (P)nfsMount3RNullPack, (P)nfsMount3RNullUnpack, (S)nfsMount3RNullSize, (F)nfsMount3RNullPrint, sizeof(NfsMount3RNull),
+ (P)nfsMount3TMntPack, (P)nfsMount3TMntUnpack, (S)nfsMount3TMntSize, (F)nfsMount3TMntPrint, sizeof(NfsMount3TMnt),
+ (P)nfsMount3RMntPack, (P)nfsMount3RMntUnpack, (S)nfsMount3RMntSize, (F)nfsMount3RMntPrint, sizeof(NfsMount3RMnt),
+ (P)nfsMount3TDumpPack, (P)nfsMount3TDumpUnpack, (S)nfsMount3TDumpSize, (F)nfsMount3TDumpPrint, sizeof(NfsMount3TDump),
+ (P)nfsMount3RDumpPack, (P)nfsMount3RDumpUnpack, (S)nfsMount3RDumpSize, (F)nfsMount3RDumpPrint, sizeof(NfsMount3RDump),
+ (P)nfsMount3TUmntPack, (P)nfsMount3TUmntUnpack, (S)nfsMount3TUmntSize, (F)nfsMount3TUmntPrint, sizeof(NfsMount3TUmnt),
+ (P)nfsMount3RUmntPack, (P)nfsMount3RUmntUnpack, (S)nfsMount3RUmntSize, (F)nfsMount3RUmntPrint, sizeof(NfsMount3RUmnt),
+ (P)nfsMount3TUmntallPack, (P)nfsMount3TUmntallUnpack, (S)nfsMount3TUmntallSize, (F)nfsMount3TUmntallPrint, sizeof(NfsMount3TUmntall),
+ (P)nfsMount3RUmntallPack, (P)nfsMount3RUmntallUnpack, (S)nfsMount3RUmntallSize, (F)nfsMount3RUmntallPrint, sizeof(NfsMount3RUmntall),
+ (P)nfsMount3TExportPack, (P)nfsMount3TExportUnpack, (S)nfsMount3TExportSize, (F)nfsMount3TExportPrint, sizeof(NfsMount3TExport),
+ (P)nfsMount3RExportPack, (P)nfsMount3RExportUnpack, (S)nfsMount3RExportSize, (F)nfsMount3RExportPrint, sizeof(NfsMount3RExport),
+};
+
+static SunProc proc1[] = {
+ (P)nfsMount3TNullPack, (P)nfsMount3TNullUnpack, (S)nfsMount3TNullSize, (F)nfsMount3TNullPrint, sizeof(NfsMount3TNull),
+ (P)nfsMount3RNullPack, (P)nfsMount3RNullUnpack, (S)nfsMount3RNullSize, (F)nfsMount3RNullPrint, sizeof(NfsMount3RNull),
+ (P)nfsMount3TMntPack, (P)nfsMount3TMntUnpack, (S)nfsMount3TMntSize, (F)nfsMount3TMntPrint, sizeof(NfsMount3TMnt),
+ (P)nfsMount1RMntPack, (P)nfsMount1RMntUnpack, (S)nfsMount1RMntSize, (F)nfsMount3RMntPrint, sizeof(NfsMount3RMnt),
+ (P)nfsMount3TDumpPack, (P)nfsMount3TDumpUnpack, (S)nfsMount3TDumpSize, (F)nfsMount3TDumpPrint, sizeof(NfsMount3TDump),
+ (P)nfsMount3RDumpPack, (P)nfsMount3RDumpUnpack, (S)nfsMount3RDumpSize, (F)nfsMount3RDumpPrint, sizeof(NfsMount3RDump),
+ (P)nfsMount3TUmntPack, (P)nfsMount3TUmntUnpack, (S)nfsMount3TUmntSize, (F)nfsMount3TUmntPrint, sizeof(NfsMount3TUmnt),
+ (P)nfsMount3RUmntPack, (P)nfsMount3RUmntUnpack, (S)nfsMount3RUmntSize, (F)nfsMount3RUmntPrint, sizeof(NfsMount3RUmnt),
+ (P)nfsMount3TUmntallPack, (P)nfsMount3TUmntallUnpack, (S)nfsMount3TUmntallSize, (F)nfsMount3TUmntallPrint, sizeof(NfsMount3TUmntall),
+ (P)nfsMount3RUmntallPack, (P)nfsMount3RUmntallUnpack, (S)nfsMount3RUmntallSize, (F)nfsMount3RUmntallPrint, sizeof(NfsMount3RUmntall),
+ (P)nfsMount3TExportPack, (P)nfsMount3TExportUnpack, (S)nfsMount3TExportSize, (F)nfsMount3TExportPrint, sizeof(NfsMount3TExport),
+ (P)nfsMount3RExportPack, (P)nfsMount3RExportUnpack, (S)nfsMount3RExportSize, (F)nfsMount3RExportPrint, sizeof(NfsMount3RExport),
+};
+
+SunProg nfsMount3Prog =
+{
+ NfsMount3Program,
+ NfsMount3Version,
+ proc3,
+ nelem(proc3),
+};
+
+SunProg nfsMount1Prog =
+{
+ NfsMount1Program,
+ NfsMount1Version,
+ proc1,
+ nelem(proc1),
+};
diff --git a/sys/src/libsunrpc/net.c b/sys/src/libsunrpc/net.c
new file mode 100755
index 000000000..3060e2125
--- /dev/null
+++ b/sys/src/libsunrpc/net.c
@@ -0,0 +1,57 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+typedef struct Arg Arg;
+struct Arg
+{
+ int fd;
+ char adir[40];
+ SunSrv *srv;
+};
+
+static void
+sunNetListen(void *v)
+{
+ int fd, lcfd;
+ char ldir[40];
+ Arg *a = v;
+
+ for(;;){
+ lcfd = listen(a->adir, ldir);
+ if(lcfd < 0)
+ break;
+ fd = accept(lcfd, ldir);
+ close(lcfd);
+ if(fd < 0)
+ continue;
+ if(!sunSrvFd(a->srv, fd))
+ close(fd);
+ }
+ free(a);
+ close(a->fd);
+}
+
+int
+sunSrvNet(SunSrv *srv, char *addr)
+{
+ Arg *a;
+
+ a = emalloc(sizeof(Arg));
+ if((a->fd = announce(addr, a->adir)) < 0)
+ return -1;
+ a->srv = srv;
+
+ proccreate(sunNetListen, a, SunStackSize);
+ return 0;
+}
+
+int
+sunSrvAnnounce(SunSrv *srv, char *addr)
+{
+ if(strstr(addr, "udp!"))
+ return sunSrvUdp(srv, addr);
+ else
+ return sunSrvNet(srv, addr);
+}
diff --git a/sys/src/libsunrpc/nfs3.c b/sys/src/libsunrpc/nfs3.c
new file mode 100755
index 000000000..eb722f1ff
--- /dev/null
+++ b/sys/src/libsunrpc/nfs3.c
@@ -0,0 +1,4045 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+#include <nfs3.h>
+
+char*
+nfs3StatusStr(Nfs3Status x)
+{
+ switch(x){
+ case Nfs3Ok:
+ return "Nfs3Ok";
+ case Nfs3ErrNotOwner:
+ return "Nfs3ErrNotOwner";
+ case Nfs3ErrNoEnt:
+ return "Nfs3ErrNoEnt";
+ case Nfs3ErrNoMem:
+ return "Nfs3ErrNoMem";
+ case Nfs3ErrIo:
+ return "Nfs3ErrIo";
+ case Nfs3ErrNxio:
+ return "Nfs3ErrNxio";
+ case Nfs3ErrAcces:
+ return "Nfs3ErrAcces";
+ case Nfs3ErrExist:
+ return "Nfs3ErrExist";
+ case Nfs3ErrXDev:
+ return "Nfs3ErrXDev";
+ case Nfs3ErrNoDev:
+ return "Nfs3ErrNoDev";
+ case Nfs3ErrNotDir:
+ return "Nfs3ErrNotDir";
+ case Nfs3ErrIsDir:
+ return "Nfs3ErrIsDir";
+ case Nfs3ErrInval:
+ return "Nfs3ErrInval";
+ case Nfs3ErrFbig:
+ return "Nfs3ErrFbig";
+ case Nfs3ErrNoSpc:
+ return "Nfs3ErrNoSpc";
+ case Nfs3ErrRoFs:
+ return "Nfs3ErrRoFs";
+ case Nfs3ErrMLink:
+ return "Nfs3ErrMLink";
+ case Nfs3ErrNameTooLong:
+ return "Nfs3ErrNameTooLong";
+ case Nfs3ErrNotEmpty:
+ return "Nfs3ErrNotEmpty";
+ case Nfs3ErrDQuot:
+ return "Nfs3ErrDQuot";
+ case Nfs3ErrStale:
+ return "Nfs3ErrStale";
+ case Nfs3ErrRemote:
+ return "Nfs3ErrRemote";
+ case Nfs3ErrBadHandle:
+ return "Nfs3ErrBadHandle";
+ case Nfs3ErrNotSync:
+ return "Nfs3ErrNotSync";
+ case Nfs3ErrBadCookie:
+ return "Nfs3ErrBadCookie";
+ case Nfs3ErrNotSupp:
+ return "Nfs3ErrNotSupp";
+ case Nfs3ErrTooSmall:
+ return "Nfs3ErrTooSmall";
+ case Nfs3ErrServerFault:
+ return "Nfs3ErrServerFault";
+ case Nfs3ErrBadType:
+ return "Nfs3ErrBadType";
+ case Nfs3ErrJukebox:
+ return "Nfs3ErrJukebox";
+ case Nfs3ErrFprintNotFound:
+ return "Nfs3ErrFprintNotFound";
+ case Nfs3ErrAborted:
+ return "Nfs3ErrAborted";
+ default:
+ return "unknown";
+ }
+}
+
+static struct {
+ SunStatus status;
+ char *msg;
+} etab[] = {
+ Nfs3ErrNotOwner, "not owner",
+ Nfs3ErrNoEnt, "directory entry not found",
+ Nfs3ErrIo, "i/o error",
+ Nfs3ErrNxio, "no such device",
+ Nfs3ErrNoMem, "out of memory",
+ Nfs3ErrAcces, "access denied",
+ Nfs3ErrExist, "file or directory exists",
+ Nfs3ErrXDev, "cross-device operation",
+ Nfs3ErrNoDev, "no such device",
+ Nfs3ErrNotDir, "not a directory",
+ Nfs3ErrIsDir, "is a directory",
+ Nfs3ErrInval, "invalid arguments",
+ Nfs3ErrFbig, "file too big",
+ Nfs3ErrNoSpc, "no space left on device",
+ Nfs3ErrRoFs, "read-only file system",
+ Nfs3ErrMLink, "too many links",
+ Nfs3ErrNameTooLong, "name too long",
+ Nfs3ErrNotEmpty, "directory not empty",
+ Nfs3ErrDQuot, "dquot",
+ Nfs3ErrStale, "stale handle",
+ Nfs3ErrRemote, "remote error",
+ Nfs3ErrBadHandle, "bad handle",
+ Nfs3ErrNotSync, "out of sync with server",
+ Nfs3ErrBadCookie, "bad cookie",
+ Nfs3ErrNotSupp, "not supported",
+ Nfs3ErrTooSmall, "too small",
+ Nfs3ErrServerFault, "server fault",
+ Nfs3ErrBadType, "bad type",
+ Nfs3ErrJukebox, "jukebox -- try again later",
+ Nfs3ErrFprintNotFound, "fprint not found",
+ Nfs3ErrAborted, "aborted",
+};
+
+void
+nfs3Errstr(SunStatus status)
+{
+ int i;
+
+ for(i=0; i<nelem(etab); i++){
+ if(etab[i].status == status){
+ werrstr(etab[i].msg);
+ return;
+ }
+ }
+ werrstr("unknown nfs3 error %d", (int)status);
+}
+
+char*
+nfs3FileTypeStr(Nfs3FileType x)
+{
+ switch(x){
+ case Nfs3FileReg:
+ return "Nfs3FileReg";
+ case Nfs3FileDir:
+ return "Nfs3FileDir";
+ case Nfs3FileBlock:
+ return "Nfs3FileBlock";
+ case Nfs3FileChar:
+ return "Nfs3FileChar";
+ case Nfs3FileSymlink:
+ return "Nfs3FileSymlink";
+ case Nfs3FileSocket:
+ return "Nfs3FileSocket";
+ case Nfs3FileFifo:
+ return "Nfs3FileFifo";
+ default:
+ return "unknown";
+ }
+}
+
+void
+nfs3HandlePrint(Fmt *fmt, Nfs3Handle *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3Handle");
+ fmtprint(fmt, "\t%s=", "handle");
+ if(x->len > 64)
+ fmtprint(fmt, "%.*H... (%d)", 64, x->h, x->len);
+ else
+ fmtprint(fmt, "%.*H", x->len, x->h);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3HandleSize(Nfs3Handle *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + sunVarOpaqueSize(x->len);
+ return a;
+}
+int
+nfs3HandlePack(uchar *a, uchar *ea, uchar **pa, Nfs3Handle *x)
+{
+ if(x->len > Nfs3MaxHandleSize || sunUint32Pack(a, ea, &a, &x->len) < 0
+ || sunFixedOpaquePack(a, ea, &a, x->h, x->len) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3HandleUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3Handle *x)
+{
+ uchar *ha;
+ u32int n;
+
+ if(sunUint32Unpack(a, ea, &a, &n) < 0 || n > Nfs3MaxHandleSize)
+ goto Err;
+ ha = a;
+ a += (n+3)&~3;
+ if(a > ea)
+ goto Err;
+ memmove(x->h, ha, n);
+ x->len = n;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TimePrint(Fmt *fmt, Nfs3Time *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3Time");
+ fmtprint(fmt, "\t%s=", "sec");
+ fmtprint(fmt, "%ud", x->sec);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "nsec");
+ fmtprint(fmt, "%ud", x->nsec);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TimeSize(Nfs3Time *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ return a;
+}
+int
+nfs3TimePack(uchar *a, uchar *ea, uchar **pa, Nfs3Time *x)
+{
+ if(sunUint32Pack(a, ea, &a, &x->sec) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->nsec) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TimeUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3Time *x)
+{
+ if(sunUint32Unpack(a, ea, &a, &x->sec) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->nsec) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3AttrPrint(Fmt *fmt, Nfs3Attr *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3Attr");
+ fmtprint(fmt, "\t%s=", "type");
+ fmtprint(fmt, "%s", nfs3FileTypeStr(x->type));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "mode");
+ fmtprint(fmt, "%ud", x->mode);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "nlink");
+ fmtprint(fmt, "%ud", x->nlink);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "uid");
+ fmtprint(fmt, "%ud", x->uid);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "gid");
+ fmtprint(fmt, "%ud", x->gid);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "size");
+ fmtprint(fmt, "%llud", x->size);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "used");
+ fmtprint(fmt, "%llud", x->used);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "major");
+ fmtprint(fmt, "%ud", x->major);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "minor");
+ fmtprint(fmt, "%ud", x->minor);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "fsid");
+ fmtprint(fmt, "%llud", x->fsid);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "fileid");
+ fmtprint(fmt, "%llud", x->fileid);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "atime");
+ nfs3TimePrint(fmt, &x->atime);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "mtime");
+ nfs3TimePrint(fmt, &x->mtime);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "ctime");
+ nfs3TimePrint(fmt, &x->ctime);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3AttrSize(Nfs3Attr *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4 + 4 + 4 + 4 + 8 + 8 + 4 + 4 + 8 + 8 + nfs3TimeSize(&x->atime) + nfs3TimeSize(&x->mtime) + nfs3TimeSize(&x->ctime);
+ return a;
+}
+int
+nfs3AttrPack(uchar *a, uchar *ea, uchar **pa, Nfs3Attr *x)
+{
+ int i;
+
+ if(i=x->type, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->mode) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->nlink) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->uid) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->gid) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->size) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->used) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->major) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->minor) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->fsid) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->fileid) < 0) goto Err;
+ if(nfs3TimePack(a, ea, &a, &x->atime) < 0) goto Err;
+ if(nfs3TimePack(a, ea, &a, &x->mtime) < 0) goto Err;
+ if(nfs3TimePack(a, ea, &a, &x->ctime) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3AttrUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3Attr *x)
+{
+ int i;
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->type = i;
+ if(sunUint32Unpack(a, ea, &a, &x->mode) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->nlink) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->uid) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->gid) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->size) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->used) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->major) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->minor) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->fsid) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->fileid) < 0) goto Err;
+ if(nfs3TimeUnpack(a, ea, &a, &x->atime) < 0) goto Err;
+ if(nfs3TimeUnpack(a, ea, &a, &x->mtime) < 0) goto Err;
+ if(nfs3TimeUnpack(a, ea, &a, &x->ctime) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3WccAttrPrint(Fmt *fmt, Nfs3WccAttr *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3WccAttr");
+ fmtprint(fmt, "\t%s=", "size");
+ fmtprint(fmt, "%llud", x->size);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "mtime");
+ nfs3TimePrint(fmt, &x->mtime);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "ctime");
+ nfs3TimePrint(fmt, &x->ctime);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3WccAttrSize(Nfs3WccAttr *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 8 + nfs3TimeSize(&x->mtime) + nfs3TimeSize(&x->ctime);
+ return a;
+}
+int
+nfs3WccAttrPack(uchar *a, uchar *ea, uchar **pa, Nfs3WccAttr *x)
+{
+ if(sunUint64Pack(a, ea, &a, &x->size) < 0) goto Err;
+ if(nfs3TimePack(a, ea, &a, &x->mtime) < 0) goto Err;
+ if(nfs3TimePack(a, ea, &a, &x->ctime) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3WccAttrUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3WccAttr *x)
+{
+ if(sunUint64Unpack(a, ea, &a, &x->size) < 0) goto Err;
+ if(nfs3TimeUnpack(a, ea, &a, &x->mtime) < 0) goto Err;
+ if(nfs3TimeUnpack(a, ea, &a, &x->ctime) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3WccPrint(Fmt *fmt, Nfs3Wcc *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3Wcc");
+ fmtprint(fmt, "\t%s=", "haveWccAttr");
+ fmtprint(fmt, "%d", x->haveWccAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveWccAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "wccAttr");
+ nfs3WccAttrPrint(fmt, &x->wccAttr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3WccSize(Nfs3Wcc *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->haveWccAttr){
+ case 1:
+ a = a + nfs3WccAttrSize(&x->wccAttr);
+ break;
+ }
+ a = a + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ return a;
+}
+int
+nfs3WccPack(uchar *a, uchar *ea, uchar **pa, Nfs3Wcc *x)
+{
+ if(sunUint1Pack(a, ea, &a, &x->haveWccAttr) < 0) goto Err;
+ switch(x->haveWccAttr){
+ case 1:
+ if(nfs3WccAttrPack(a, ea, &a, &x->wccAttr) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3WccUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3Wcc *x)
+{
+ if(sunUint1Unpack(a, ea, &a, &x->haveWccAttr) < 0) goto Err;
+ switch(x->haveWccAttr){
+ case 1:
+ if(nfs3WccAttrUnpack(a, ea, &a, &x->wccAttr) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+char*
+nfs3SetTimeStr(Nfs3SetTime x)
+{
+ switch(x){
+ case Nfs3SetTimeDont:
+ return "Nfs3SetTimeDont";
+ case Nfs3SetTimeServer:
+ return "Nfs3SetTimeServer";
+ case Nfs3SetTimeClient:
+ return "Nfs3SetTimeClient";
+ default:
+ return "unknown";
+ }
+}
+
+void
+nfs3SetAttrPrint(Fmt *fmt, Nfs3SetAttr *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3SetAttr");
+ fmtprint(fmt, "\t%s=", "setMode");
+ fmtprint(fmt, "%d", x->setMode);
+ fmtprint(fmt, "\n");
+ switch(x->setMode){
+ case 1:
+ fmtprint(fmt, "\t%s=", "mode");
+ fmtprint(fmt, "%ud", x->mode);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "setUid");
+ fmtprint(fmt, "%d", x->setUid);
+ fmtprint(fmt, "\n");
+ switch(x->setUid){
+ case 1:
+ fmtprint(fmt, "\t%s=", "uid");
+ fmtprint(fmt, "%ud", x->uid);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "setGid");
+ fmtprint(fmt, "%d", x->setGid);
+ fmtprint(fmt, "\n");
+ switch(x->setGid){
+ case 1:
+ fmtprint(fmt, "\t%s=", "gid");
+ fmtprint(fmt, "%ud", x->gid);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "setSize");
+ fmtprint(fmt, "%d", x->setSize);
+ fmtprint(fmt, "\n");
+ switch(x->setSize){
+ case 1:
+ fmtprint(fmt, "\t%s=", "size");
+ fmtprint(fmt, "%llud", x->size);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "setAtime");
+ fmtprint(fmt, "%s", nfs3SetTimeStr(x->setAtime));
+ fmtprint(fmt, "\n");
+ switch(x->setAtime){
+ case Nfs3SetTimeClient:
+ fmtprint(fmt, "\t%s=", "atime");
+ nfs3TimePrint(fmt, &x->atime);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "setMtime");
+ fmtprint(fmt, "%s", nfs3SetTimeStr(x->setMtime));
+ fmtprint(fmt, "\n");
+ switch(x->setMtime){
+ case Nfs3SetTimeClient:
+ fmtprint(fmt, "\t%s=", "mtime");
+ nfs3TimePrint(fmt, &x->mtime);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3SetAttrSize(Nfs3SetAttr *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->setMode){
+ case 1:
+ a = a + 4;
+ break;
+ }
+ a = a + 4;
+ switch(x->setUid){
+ case 1:
+ a = a + 4;
+ break;
+ }
+ a = a + 4;
+ switch(x->setGid){
+ case 1:
+ a = a + 4;
+ break;
+ }
+ a = a + 4;
+ switch(x->setSize){
+ case 1:
+ a = a + 8;
+ break;
+ }
+ a = a + 4;
+ switch(x->setAtime){
+ case Nfs3SetTimeClient:
+ a = a + nfs3TimeSize(&x->atime);
+ break;
+ }
+ a = a + 4;
+ switch(x->setMtime){
+ case Nfs3SetTimeClient:
+ a = a + nfs3TimeSize(&x->mtime);
+ break;
+ }
+ return a;
+}
+int
+nfs3SetAttrPack(uchar *a, uchar *ea, uchar **pa, Nfs3SetAttr *x)
+{
+ int i;
+
+ if(sunUint1Pack(a, ea, &a, &x->setMode) < 0) goto Err;
+ switch(x->setMode){
+ case 1:
+ if(sunUint32Pack(a, ea, &a, &x->mode) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->setUid) < 0) goto Err;
+ switch(x->setUid){
+ case 1:
+ if(sunUint32Pack(a, ea, &a, &x->uid) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->setGid) < 0) goto Err;
+ switch(x->setGid){
+ case 1:
+ if(sunUint32Pack(a, ea, &a, &x->gid) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->setSize) < 0) goto Err;
+ switch(x->setSize){
+ case 1:
+ if(sunUint64Pack(a, ea, &a, &x->size) < 0) goto Err;
+ break;
+ }
+ if(i=x->setAtime, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->setAtime){
+ case Nfs3SetTimeClient:
+ if(nfs3TimePack(a, ea, &a, &x->atime) < 0) goto Err;
+ break;
+ }
+ if(i=x->setMtime, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->setMtime){
+ case Nfs3SetTimeClient:
+ if(nfs3TimePack(a, ea, &a, &x->mtime) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3SetAttrUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3SetAttr *x)
+{
+ int i;
+
+ if(sunUint1Unpack(a, ea, &a, &x->setMode) < 0) goto Err;
+ switch(x->setMode){
+ case 1:
+ if(sunUint32Unpack(a, ea, &a, &x->mode) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->setUid) < 0) goto Err;
+ switch(x->setUid){
+ case 1:
+ if(sunUint32Unpack(a, ea, &a, &x->uid) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->setGid) < 0) goto Err;
+ switch(x->setGid){
+ case 1:
+ if(sunUint32Unpack(a, ea, &a, &x->gid) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->setSize) < 0) goto Err;
+ switch(x->setSize){
+ case 1:
+ if(sunUint64Unpack(a, ea, &a, &x->size) < 0) goto Err;
+ break;
+ }
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->setAtime = i;
+ switch(x->setAtime){
+ case Nfs3SetTimeClient:
+ if(nfs3TimeUnpack(a, ea, &a, &x->atime) < 0) goto Err;
+ break;
+ }
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->setMtime = i;
+ switch(x->setMtime){
+ case Nfs3SetTimeClient:
+ if(nfs3TimeUnpack(a, ea, &a, &x->mtime) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TNullPrint(Fmt *fmt, Nfs3TNull *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "Nfs3TNull");
+}
+uint
+nfs3TNullSize(Nfs3TNull *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfs3TNullPack(uchar *a, uchar *ea, uchar **pa, Nfs3TNull *x)
+{
+ USED(x);
+ USED(ea);
+ *pa = a;
+ return 0;
+}
+int
+nfs3TNullUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TNull *x)
+{
+ USED(x);
+ USED(ea);
+ *pa = a;
+ return 0;
+}
+void
+nfs3RNullPrint(Fmt *fmt, Nfs3RNull *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s\n", "Nfs3RNull");
+}
+uint
+nfs3RNullSize(Nfs3RNull *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+int
+nfs3RNullPack(uchar *a, uchar *ea, uchar **pa, Nfs3RNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+int
+nfs3RNullUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+void
+nfs3TGetattrPrint(Fmt *fmt, Nfs3TGetattr *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TGetattr");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TGetattrSize(Nfs3TGetattr *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle);
+ return a;
+}
+int
+nfs3TGetattrPack(uchar *a, uchar *ea, uchar **pa, Nfs3TGetattr *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TGetattrUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TGetattr *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RGetattrPrint(Fmt *fmt, Nfs3RGetattr *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RGetattr");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RGetattrSize(Nfs3RGetattr *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ return a;
+}
+int
+nfs3RGetattrPack(uchar *a, uchar *ea, uchar **pa, Nfs3RGetattr *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RGetattrUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RGetattr *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ switch(x->status){
+ case Nfs3Ok:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TSetattrPrint(Fmt *fmt, Nfs3TSetattr *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TSetattr");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3SetAttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "checkCtime");
+ fmtprint(fmt, "%d", x->checkCtime);
+ fmtprint(fmt, "\n");
+ switch(x->checkCtime){
+ case 1:
+ fmtprint(fmt, "\t%s=", "ctime");
+ nfs3TimePrint(fmt, &x->ctime);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3TSetattrSize(Nfs3TSetattr *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + nfs3SetAttrSize(&x->attr) + 4;
+ switch(x->checkCtime){
+ case 1:
+ a = a + nfs3TimeSize(&x->ctime);
+ break;
+ }
+ return a;
+}
+int
+nfs3TSetattrPack(uchar *a, uchar *ea, uchar **pa, Nfs3TSetattr *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(nfs3SetAttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->checkCtime) < 0) goto Err;
+ switch(x->checkCtime){
+ case 1:
+ if(nfs3TimePack(a, ea, &a, &x->ctime) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TSetattrUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TSetattr *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(nfs3SetAttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->checkCtime) < 0) goto Err;
+ switch(x->checkCtime){
+ case 1:
+ if(nfs3TimeUnpack(a, ea, &a, &x->ctime) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RSetattrPrint(Fmt *fmt, Nfs3RSetattr *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RSetattr");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "wcc");
+ nfs3WccPrint(fmt, &x->wcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RSetattrSize(Nfs3RSetattr *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + nfs3WccSize(&x->wcc);
+ return a;
+}
+int
+nfs3RSetattrPack(uchar *a, uchar *ea, uchar **pa, Nfs3RSetattr *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(nfs3WccPack(a, ea, &a, &x->wcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RSetattrUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RSetattr *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(nfs3WccUnpack(a, ea, &a, &x->wcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TLookupPrint(Fmt *fmt, Nfs3TLookup *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TLookup");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TLookupSize(Nfs3TLookup *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + sunStringSize(x->name);
+ return a;
+}
+int
+nfs3TLookupPack(uchar *a, uchar *ea, uchar **pa, Nfs3TLookup *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TLookupUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TLookup *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RLookupPrint(Fmt *fmt, Nfs3RLookup *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RLookup");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "haveDirAttr");
+ fmtprint(fmt, "%d", x->haveDirAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveDirAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "dirAttr");
+ nfs3AttrPrint(fmt, &x->dirAttr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RLookupSize(Nfs3RLookup *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + nfs3HandleSize(&x->handle) + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ break;
+ }
+ a = a + 4;
+ switch(x->haveDirAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->dirAttr);
+ break;
+ }
+ return a;
+}
+int
+nfs3RLookupPack(uchar *a, uchar *ea, uchar **pa, Nfs3RLookup *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->haveDirAttr) < 0) goto Err;
+ switch(x->haveDirAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->dirAttr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RLookupUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RLookup *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ switch(x->status){
+ case Nfs3Ok:
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->haveDirAttr) < 0) goto Err;
+ switch(x->haveDirAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->dirAttr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TAccessPrint(Fmt *fmt, Nfs3TAccess *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TAccess");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "access");
+ fmtprint(fmt, "%ud", x->access);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TAccessSize(Nfs3TAccess *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + 4;
+ return a;
+}
+int
+nfs3TAccessPack(uchar *a, uchar *ea, uchar **pa, Nfs3TAccess *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->access) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TAccessUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TAccess *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->access) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RAccessPrint(Fmt *fmt, Nfs3RAccess *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RAccess");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "access");
+ fmtprint(fmt, "%ud", x->access);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RAccessSize(Nfs3RAccess *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4;
+ break;
+ }
+ return a;
+}
+int
+nfs3RAccessPack(uchar *a, uchar *ea, uchar **pa, Nfs3RAccess *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Pack(a, ea, &a, &x->access) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RAccessUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RAccess *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Unpack(a, ea, &a, &x->access) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TReadlinkPrint(Fmt *fmt, Nfs3TReadlink *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TReadlink");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TReadlinkSize(Nfs3TReadlink *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle);
+ return a;
+}
+int
+nfs3TReadlinkPack(uchar *a, uchar *ea, uchar **pa, Nfs3TReadlink *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TReadlinkUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TReadlink *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RReadlinkPrint(Fmt *fmt, Nfs3RReadlink *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RReadlink");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "data");
+ fmtprint(fmt, "\"%s\"", x->data);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RReadlinkSize(Nfs3RReadlink *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + sunStringSize(x->data);
+ break;
+ }
+ return a;
+}
+int
+nfs3RReadlinkPack(uchar *a, uchar *ea, uchar **pa, Nfs3RReadlink *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunStringPack(a, ea, &a, &x->data, -1) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RReadlinkUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RReadlink *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunStringUnpack(a, ea, &a, &x->data, -1) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TReadPrint(Fmt *fmt, Nfs3TRead *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TRead");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "offset");
+ fmtprint(fmt, "%llud", x->offset);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "count");
+ fmtprint(fmt, "%ud", x->count);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TReadSize(Nfs3TRead *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + 8 + 4;
+ return a;
+}
+int
+nfs3TReadPack(uchar *a, uchar *ea, uchar **pa, Nfs3TRead *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->offset) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TReadUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TRead *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->offset) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RReadPrint(Fmt *fmt, Nfs3RRead *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RRead");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "count");
+ fmtprint(fmt, "%ud", x->count);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "eof");
+ fmtprint(fmt, "%d", x->eof);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "data");
+ if(x->ndata <= 32)
+ fmtprint(fmt, "%.*H", x->ndata, x->data);
+ else
+ fmtprint(fmt, "%.32H...", x->data);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RReadSize(Nfs3RRead *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4 + 4 + sunVarOpaqueSize(x->ndata);
+ break;
+ }
+ return a;
+}
+int
+nfs3RReadPack(uchar *a, uchar *ea, uchar **pa, Nfs3RRead *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Pack(a, ea, &a, &x->count) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->eof) < 0) goto Err;
+ if(sunVarOpaquePack(a, ea, &a, &x->data, &x->ndata, x->count) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RReadUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RRead *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Unpack(a, ea, &a, &x->count) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->eof) < 0) goto Err;
+ if(sunVarOpaqueUnpack(a, ea, &a, &x->data, &x->ndata, x->count) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+char*
+nfs3SyncStr(Nfs3Sync x)
+{
+ switch(x){
+ case Nfs3SyncNone:
+ return "Nfs3SyncNone";
+ case Nfs3SyncData:
+ return "Nfs3SyncData";
+ case Nfs3SyncFile:
+ return "Nfs3SyncFile";
+ default:
+ return "unknown";
+ }
+}
+
+void
+nfs3TWritePrint(Fmt *fmt, Nfs3TWrite *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TWrite");
+ fmtprint(fmt, "\t%s=", "file");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "offset");
+ fmtprint(fmt, "%llud", x->offset);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "count");
+ fmtprint(fmt, "%ud", x->count);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "stable");
+ fmtprint(fmt, "%s", nfs3SyncStr(x->stable));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "data");
+ if(x->ndata > 32)
+ fmtprint(fmt, "%.32H... (%d)", x->data, x->ndata);
+ else
+ fmtprint(fmt, "%.*H", x->ndata, x->data);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TWriteSize(Nfs3TWrite *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + 8 + 4 + 4 + sunVarOpaqueSize(x->ndata);
+ return a;
+}
+int
+nfs3TWritePack(uchar *a, uchar *ea, uchar **pa, Nfs3TWrite *x)
+{
+ int i;
+
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->offset) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->count) < 0) goto Err;
+ if(i=x->stable, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunVarOpaquePack(a, ea, &a, &x->data, &x->ndata, x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TWriteUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TWrite *x)
+{
+ int i;
+
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->offset) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->count) < 0) goto Err;
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->stable = i;
+ if(sunVarOpaqueUnpack(a, ea, &a, &x->data, &x->ndata, x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RWritePrint(Fmt *fmt, Nfs3RWrite *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RWrite");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "wcc");
+ nfs3WccPrint(fmt, &x->wcc);
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "count");
+ fmtprint(fmt, "%ud", x->count);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "committed");
+ fmtprint(fmt, "%s", nfs3SyncStr(x->committed));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "verf");
+ fmtprint(fmt, "%.*H", Nfs3WriteVerfSize, x->verf);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RWriteSize(Nfs3RWrite *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + nfs3WccSize(&x->wcc);
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4 + 4 + Nfs3WriteVerfSize;
+ break;
+ }
+ return a;
+}
+int
+nfs3RWritePack(uchar *a, uchar *ea, uchar **pa, Nfs3RWrite *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(nfs3WccPack(a, ea, &a, &x->wcc) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Pack(a, ea, &a, &x->count) < 0) goto Err;
+ if(i=x->committed, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunFixedOpaquePack(a, ea, &a, x->verf, Nfs3WriteVerfSize) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RWriteUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RWrite *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(nfs3WccUnpack(a, ea, &a, &x->wcc) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Unpack(a, ea, &a, &x->count) < 0) goto Err;
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->committed = i;
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->verf, Nfs3WriteVerfSize) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+char*
+nfs3CreateStr(Nfs3Create x)
+{
+ switch(x){
+ case Nfs3CreateUnchecked:
+ return "Nfs3CreateUnchecked";
+ case Nfs3CreateGuarded:
+ return "Nfs3CreateGuarded";
+ case Nfs3CreateExclusive:
+ return "Nfs3CreateExclusive";
+ default:
+ return "unknown";
+ }
+}
+
+void
+nfs3TCreatePrint(Fmt *fmt, Nfs3TCreate *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TCreate");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "mode");
+ fmtprint(fmt, "%s", nfs3CreateStr(x->mode));
+ fmtprint(fmt, "\n");
+ switch(x->mode){
+ case Nfs3CreateUnchecked:
+ case Nfs3CreateGuarded:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3SetAttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ case Nfs3CreateExclusive:
+ fmtprint(fmt, "\t%s=", "verf");
+ fmtprint(fmt, "%.*H", Nfs3CreateVerfSize, x->verf);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3TCreateSize(Nfs3TCreate *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + sunStringSize(x->name) + 4;
+ switch(x->mode){
+ case Nfs3CreateUnchecked:
+ case Nfs3CreateGuarded:
+ a = a + nfs3SetAttrSize(&x->attr);
+ break;
+ case Nfs3CreateExclusive:
+ a = a + Nfs3CreateVerfSize;
+ break;
+ }
+ return a;
+}
+int
+nfs3TCreatePack(uchar *a, uchar *ea, uchar **pa, Nfs3TCreate *x)
+{
+ int i;
+
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(i=x->mode, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->mode){
+ case Nfs3CreateUnchecked:
+ case Nfs3CreateGuarded:
+ if(nfs3SetAttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ case Nfs3CreateExclusive:
+ if(sunFixedOpaquePack(a, ea, &a, x->verf, Nfs3CreateVerfSize) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TCreateUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TCreate *x)
+{
+ int i;
+
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->mode = i;
+ switch(x->mode){
+ case Nfs3CreateUnchecked:
+ case Nfs3CreateGuarded:
+ if(nfs3SetAttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ case Nfs3CreateExclusive:
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->verf, Nfs3CreateVerfSize) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RCreatePrint(Fmt *fmt, Nfs3RCreate *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RCreate");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "haveHandle");
+ fmtprint(fmt, "%d", x->haveHandle);
+ fmtprint(fmt, "\n");
+ switch(x->haveHandle){
+ case 1:
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "dirWcc");
+ nfs3WccPrint(fmt, &x->dirWcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RCreateSize(Nfs3RCreate *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4;
+ switch(x->haveHandle){
+ case 1:
+ a = a + nfs3HandleSize(&x->handle);
+ break;
+ }
+ a = a + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ break;
+ }
+ a = a + nfs3WccSize(&x->dirWcc);
+ return a;
+}
+int
+nfs3RCreatePack(uchar *a, uchar *ea, uchar **pa, Nfs3RCreate *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Pack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccPack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RCreateUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RCreate *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Unpack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccUnpack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TMkdirPrint(Fmt *fmt, Nfs3TMkdir *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TMkdir");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3SetAttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TMkdirSize(Nfs3TMkdir *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + sunStringSize(x->name) + nfs3SetAttrSize(&x->attr);
+ return a;
+}
+int
+nfs3TMkdirPack(uchar *a, uchar *ea, uchar **pa, Nfs3TMkdir *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(nfs3SetAttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TMkdirUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TMkdir *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(nfs3SetAttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RMkdirPrint(Fmt *fmt, Nfs3RMkdir *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RMkdir");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "haveHandle");
+ fmtprint(fmt, "%d", x->haveHandle);
+ fmtprint(fmt, "\n");
+ switch(x->haveHandle){
+ case 1:
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "dirWcc");
+ nfs3WccPrint(fmt, &x->dirWcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RMkdirSize(Nfs3RMkdir *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4;
+ switch(x->haveHandle){
+ case 1:
+ a = a + nfs3HandleSize(&x->handle);
+ break;
+ }
+ a = a + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ break;
+ }
+ a = a + nfs3WccSize(&x->dirWcc);
+ return a;
+}
+int
+nfs3RMkdirPack(uchar *a, uchar *ea, uchar **pa, Nfs3RMkdir *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Pack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccPack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RMkdirUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RMkdir *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Unpack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccUnpack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TSymlinkPrint(Fmt *fmt, Nfs3TSymlink *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TSymlink");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3SetAttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "data");
+ fmtprint(fmt, "\"%s\"", x->data);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TSymlinkSize(Nfs3TSymlink *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + sunStringSize(x->name) + nfs3SetAttrSize(&x->attr) + sunStringSize(x->data);
+ return a;
+}
+int
+nfs3TSymlinkPack(uchar *a, uchar *ea, uchar **pa, Nfs3TSymlink *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(nfs3SetAttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->data, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TSymlinkUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TSymlink *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(nfs3SetAttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->data, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RSymlinkPrint(Fmt *fmt, Nfs3RSymlink *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RSymlink");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "haveHandle");
+ fmtprint(fmt, "%d", x->haveHandle);
+ fmtprint(fmt, "\n");
+ switch(x->haveHandle){
+ case 1:
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "dirWcc");
+ nfs3WccPrint(fmt, &x->dirWcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RSymlinkSize(Nfs3RSymlink *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4;
+ switch(x->haveHandle){
+ case 1:
+ a = a + nfs3HandleSize(&x->handle);
+ break;
+ }
+ a = a + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ break;
+ }
+ a = a + nfs3WccSize(&x->dirWcc);
+ return a;
+}
+int
+nfs3RSymlinkPack(uchar *a, uchar *ea, uchar **pa, Nfs3RSymlink *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Pack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccPack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RSymlinkUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RSymlink *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Unpack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccUnpack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TMknodPrint(Fmt *fmt, Nfs3TMknod *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TMknod");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "type");
+ fmtprint(fmt, "%s", nfs3FileTypeStr(x->type));
+ fmtprint(fmt, "\n");
+ switch(x->type){
+ case Nfs3FileChar:
+ case Nfs3FileBlock:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3SetAttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "major");
+ fmtprint(fmt, "%ud", x->major);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "minor");
+ fmtprint(fmt, "%ud", x->minor);
+ fmtprint(fmt, "\n");
+ break;
+ case Nfs3FileSocket:
+ case Nfs3FileFifo:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3SetAttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3TMknodSize(Nfs3TMknod *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + sunStringSize(x->name) + 4;
+ switch(x->type){
+ case Nfs3FileChar:
+ case Nfs3FileBlock:
+ a = a + nfs3SetAttrSize(&x->attr) + 4 + 4;
+ break;
+ case Nfs3FileSocket:
+ case Nfs3FileFifo:
+ a = a + nfs3SetAttrSize(&x->attr);
+ break;
+ }
+ return a;
+}
+int
+nfs3TMknodPack(uchar *a, uchar *ea, uchar **pa, Nfs3TMknod *x)
+{
+ int i;
+
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(i=x->type, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->type){
+ case Nfs3FileChar:
+ case Nfs3FileBlock:
+ if(nfs3SetAttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->major) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->minor) < 0) goto Err;
+ break;
+ case Nfs3FileSocket:
+ case Nfs3FileFifo:
+ if(nfs3SetAttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TMknodUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TMknod *x)
+{
+ int i;
+
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->type = i;
+ switch(x->type){
+ case Nfs3FileChar:
+ case Nfs3FileBlock:
+ if(nfs3SetAttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->major) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->minor) < 0) goto Err;
+ break;
+ case Nfs3FileSocket:
+ case Nfs3FileFifo:
+ if(nfs3SetAttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RMknodPrint(Fmt *fmt, Nfs3RMknod *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RMknod");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "haveHandle");
+ fmtprint(fmt, "%d", x->haveHandle);
+ fmtprint(fmt, "\n");
+ switch(x->haveHandle){
+ case 1:
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "dirWcc");
+ nfs3WccPrint(fmt, &x->dirWcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RMknodSize(Nfs3RMknod *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4;
+ switch(x->haveHandle){
+ case 1:
+ a = a + nfs3HandleSize(&x->handle);
+ break;
+ }
+ a = a + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ break;
+ }
+ a = a + nfs3WccSize(&x->dirWcc);
+ return a;
+}
+int
+nfs3RMknodPack(uchar *a, uchar *ea, uchar **pa, Nfs3RMknod *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Pack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccPack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RMknodUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RMknod *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint1Unpack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ break;
+ }
+ if(nfs3WccUnpack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TRemovePrint(Fmt *fmt, Nfs3TRemove *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TRemove");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TRemoveSize(Nfs3TRemove *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + sunStringSize(x->name);
+ return a;
+}
+int
+nfs3TRemovePack(uchar *a, uchar *ea, uchar **pa, Nfs3TRemove *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TRemoveUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TRemove *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RRemovePrint(Fmt *fmt, Nfs3RRemove *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RRemove");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "wcc");
+ nfs3WccPrint(fmt, &x->wcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RRemoveSize(Nfs3RRemove *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + nfs3WccSize(&x->wcc);
+ return a;
+}
+int
+nfs3RRemovePack(uchar *a, uchar *ea, uchar **pa, Nfs3RRemove *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(nfs3WccPack(a, ea, &a, &x->wcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RRemoveUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RRemove *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(nfs3WccUnpack(a, ea, &a, &x->wcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TRmdirPrint(Fmt *fmt, Nfs3TRmdir *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TRmdir");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TRmdirSize(Nfs3TRmdir *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + sunStringSize(x->name);
+ return a;
+}
+int
+nfs3TRmdirPack(uchar *a, uchar *ea, uchar **pa, Nfs3TRmdir *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TRmdirUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TRmdir *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RRmdirPrint(Fmt *fmt, Nfs3RRmdir *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RRmdir");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "wcc");
+ nfs3WccPrint(fmt, &x->wcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RRmdirSize(Nfs3RRmdir *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + nfs3WccSize(&x->wcc);
+ return a;
+}
+int
+nfs3RRmdirPack(uchar *a, uchar *ea, uchar **pa, Nfs3RRmdir *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(nfs3WccPack(a, ea, &a, &x->wcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RRmdirUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RRmdir *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(nfs3WccUnpack(a, ea, &a, &x->wcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TRenamePrint(Fmt *fmt, Nfs3TRename *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TRename");
+ fmtprint(fmt, "\t%s=", "from");
+ fmtprint(fmt, "{\n");
+ fmtprint(fmt, "\t\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->from.handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->from.name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t}");
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "to");
+ fmtprint(fmt, "{\n");
+ fmtprint(fmt, "\t\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->to.handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->to.name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t}");
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TRenameSize(Nfs3TRename *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->from.handle) + sunStringSize(x->from.name) + nfs3HandleSize(&x->to.handle) + sunStringSize(x->to.name);
+ return a;
+}
+int
+nfs3TRenamePack(uchar *a, uchar *ea, uchar **pa, Nfs3TRename *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->from.handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->from.name, -1) < 0) goto Err;
+ if(nfs3HandlePack(a, ea, &a, &x->to.handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->to.name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TRenameUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TRename *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->from.handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->from.name, -1) < 0) goto Err;
+ if(nfs3HandleUnpack(a, ea, &a, &x->to.handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->to.name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RRenamePrint(Fmt *fmt, Nfs3RRename *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RRename");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "fromWcc");
+ nfs3WccPrint(fmt, &x->fromWcc);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "toWcc");
+ nfs3WccPrint(fmt, &x->toWcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RRenameSize(Nfs3RRename *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + nfs3WccSize(&x->fromWcc) + nfs3WccSize(&x->toWcc);
+ return a;
+}
+int
+nfs3RRenamePack(uchar *a, uchar *ea, uchar **pa, Nfs3RRename *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(nfs3WccPack(a, ea, &a, &x->fromWcc) < 0) goto Err;
+ if(nfs3WccPack(a, ea, &a, &x->toWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RRenameUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RRename *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(nfs3WccUnpack(a, ea, &a, &x->fromWcc) < 0) goto Err;
+ if(nfs3WccUnpack(a, ea, &a, &x->toWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TLinkPrint(Fmt *fmt, Nfs3TLink *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TLink");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "link");
+ fmtprint(fmt, "{\n");
+ fmtprint(fmt, "\t\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->link.handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->link.name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t}");
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TLinkSize(Nfs3TLink *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + nfs3HandleSize(&x->link.handle) + sunStringSize(x->link.name);
+ return a;
+}
+int
+nfs3TLinkPack(uchar *a, uchar *ea, uchar **pa, Nfs3TLink *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(nfs3HandlePack(a, ea, &a, &x->link.handle) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->link.name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TLinkUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TLink *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(nfs3HandleUnpack(a, ea, &a, &x->link.handle) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->link.name, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RLinkPrint(Fmt *fmt, Nfs3RLink *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RLink");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "dirWcc");
+ nfs3WccPrint(fmt, &x->dirWcc);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3RLinkSize(Nfs3RLink *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ a = a + nfs3WccSize(&x->dirWcc);
+ return a;
+}
+int
+nfs3RLinkPack(uchar *a, uchar *ea, uchar **pa, Nfs3RLink *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ if(nfs3WccPack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RLinkUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RLink *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ if(nfs3WccUnpack(a, ea, &a, &x->dirWcc) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TReadDirPrint(Fmt *fmt, Nfs3TReadDir *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TReadDir");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "cookie");
+ fmtprint(fmt, "%llud", x->cookie);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "verf");
+ fmtprint(fmt, "%.*H", Nfs3CookieVerfSize, x->verf);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "count");
+ fmtprint(fmt, "%ud", x->count);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TReadDirSize(Nfs3TReadDir *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + 8 + Nfs3CookieVerfSize + 4;
+ return a;
+}
+int
+nfs3TReadDirPack(uchar *a, uchar *ea, uchar **pa, Nfs3TReadDir *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->cookie) < 0) goto Err;
+ if(sunFixedOpaquePack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TReadDirUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TReadDir *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->cookie) < 0) goto Err;
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3EntryPrint(Fmt *fmt, Nfs3Entry *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3Entry");
+ fmtprint(fmt, "\t%s=", "fileid");
+ fmtprint(fmt, "%llud", x->fileid);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "cookie");
+ fmtprint(fmt, "%llud", x->cookie);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3EntrySize(Nfs3Entry *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 8 + sunStringSize(x->name) + 8;
+ return a;
+}
+int
+nfs3EntryPack(uchar *a, uchar *ea, uchar **pa, Nfs3Entry *x)
+{
+ u1int one;
+
+ one = 1;
+ if(sunUint1Pack(a, ea, &a, &one) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->fileid) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->cookie) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3EntryUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3Entry *x)
+{
+ u1int one;
+
+ memset(x, 0, sizeof *x);
+ if(sunUint1Unpack(a, ea, &a, &one) < 0 || one != 1) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->fileid) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->cookie) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RReadDirPrint(Fmt *fmt, Nfs3RReadDir *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RReadDir");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "verf");
+ fmtprint(fmt, "%.*H", Nfs3CookieVerfSize, x->verf);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=%ud\n", "count", x->count);
+ fmtprint(fmt, "\t%s=", "eof");
+ fmtprint(fmt, "%d", x->eof);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RReadDirSize(Nfs3RReadDir *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + Nfs3CookieVerfSize;
+ a += x->count;
+ a += 4 + 4;
+ break;
+ }
+ return a;
+}
+int
+nfs3RReadDirPack(uchar *a, uchar *ea, uchar **pa, Nfs3RReadDir *x)
+{
+ int i;
+ u1int zero;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunFixedOpaquePack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ if(sunFixedOpaquePack(a, ea, &a, x->data, x->count) < 0) goto Err;
+ zero = 0;
+ if(sunUint1Pack(a, ea, &a, &zero) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->eof) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+countEntry(uchar *a, uchar *ea, uchar **pa, u32int *n)
+{
+ uchar *oa;
+ u64int u64;
+ u32int u32;
+ u1int u1;
+
+ oa = a;
+ for(;;){
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0)
+ return -1;
+ if(u1 == 0)
+ break;
+ if(sunUint64Unpack(a, ea, &a, &u64) < 0
+ || sunUint32Unpack(a, ea, &a, &u32) < 0)
+ return -1;
+ a += (u32+3)&~3;
+ if(a >= ea)
+ return -1;
+ if(sunUint64Unpack(a, ea, &a, &u64) < 0)
+ return -1;
+ }
+ *n = (a-4) - oa;
+ *pa = a;
+ return 0;
+}
+int
+nfs3RReadDirUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RReadDir *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ if(x->status == Nfs3Ok){
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ x->data = a;
+ if(countEntry(a, ea, &a, &x->count) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->eof) < 0) goto Err;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TReadDirPlusPrint(Fmt *fmt, Nfs3TReadDirPlus *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TReadDirPlus");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "cookie");
+ fmtprint(fmt, "%llud", x->cookie);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "verf");
+ fmtprint(fmt, "%.*H", Nfs3CookieVerfSize, x->verf);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "dirCount");
+ fmtprint(fmt, "%ud", x->dirCount);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "maxCount");
+ fmtprint(fmt, "%ud", x->maxCount);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TReadDirPlusSize(Nfs3TReadDirPlus *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + 8 + Nfs3CookieVerfSize + 4 + 4;
+ return a;
+}
+int
+nfs3TReadDirPlusPack(uchar *a, uchar *ea, uchar **pa, Nfs3TReadDirPlus *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->cookie) < 0) goto Err;
+ if(sunFixedOpaquePack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->dirCount) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->maxCount) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TReadDirPlusUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TReadDirPlus *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->cookie) < 0) goto Err;
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->dirCount) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->maxCount) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3EntryPlusPrint(Fmt *fmt, Nfs3Entry *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3EntryPlus");
+ fmtprint(fmt, "\t%s=", "fileid");
+ fmtprint(fmt, "%llud", x->fileid);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "name");
+ fmtprint(fmt, "\"%s\"", x->name);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "cookie");
+ fmtprint(fmt, "%llud", x->cookie);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ fmtprint(fmt, "\t%s=", "haveHandle");
+ fmtprint(fmt, "%d", x->haveHandle);
+ fmtprint(fmt, "\n");
+ switch(x->haveHandle){
+ case 1:
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3EntryPlusSize(Nfs3Entry *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 8 + sunStringSize(x->name) + 8 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ a = a + 4;
+ switch(x->haveHandle){
+ case 1:
+ a = a + nfs3HandleSize(&x->handle);
+ break;
+ }
+ return a;
+}
+int
+nfs3EntryPlusPack(uchar *a, uchar *ea, uchar **pa, Nfs3Entry *x)
+{
+ u1int u1;
+
+ if(sunUint1Pack(a, ea, &a, &u1) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->fileid) < 0) goto Err;
+ if(sunStringPack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->cookie) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Pack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3EntryPlusUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3Entry *x)
+{
+ u1int u1;
+
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0 || u1 != 1) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->fileid) < 0) goto Err;
+ if(sunStringUnpack(a, ea, &a, &x->name, -1) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->cookie) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ if(sunUint1Unpack(a, ea, &a, &x->haveHandle) < 0) goto Err;
+ switch(x->haveHandle){
+ case 1:
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RReadDirPlusPrint(Fmt *fmt, Nfs3RReadDirPlus *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RReadDirPlus");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "verf");
+ fmtprint(fmt, "%.*H", Nfs3CookieVerfSize, x->verf);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\tcount=%ud\n", x->count);
+ fmtprint(fmt, "\t%s=", "eof");
+ fmtprint(fmt, "%d", x->eof);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RReadDirPlusSize(Nfs3RReadDirPlus *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + Nfs3CookieVerfSize;
+ a += x->count;
+ a += 4 + 4;
+ break;
+ }
+ return a;
+}
+int
+nfs3RReadDirPlusPack(uchar *a, uchar *ea, uchar **pa, Nfs3RReadDirPlus *x)
+{
+ int i;
+ u1int zero;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunFixedOpaquePack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ if(sunFixedOpaquePack(a, ea, &a, x->data, x->count) < 0) goto Err;
+ zero = 0;
+ if(sunUint1Pack(a, ea, &a, &zero) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->eof) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+countEntryPlus(uchar *a, uchar *ea, uchar **pa, u32int *n)
+{
+ uchar *oa;
+ u64int u64;
+ u32int u32;
+ u1int u1;
+ Nfs3Handle h;
+ Nfs3Attr attr;
+
+ oa = a;
+ for(;;){
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0)
+ return -1;
+ if(u1 == 0)
+ break;
+ if(sunUint64Unpack(a, ea, &a, &u64) < 0
+ || sunUint32Unpack(a, ea, &a, &u32) < 0)
+ return -1;
+ a += (u32+3)&~3;
+ if(a >= ea)
+ return -1;
+ if(sunUint64Unpack(a, ea, &a, &u64) < 0
+ || sunUint1Unpack(a, ea, &a, &u1) < 0
+ || (u1 && nfs3AttrUnpack(a, ea, &a, &attr) < 0)
+ || sunUint1Unpack(a, ea, &a, &u1) < 0
+ || (u1 && nfs3HandleUnpack(a, ea, &a, &h) < 0))
+ return -1;
+ }
+ *n = (a-4) - oa;
+ *pa = a;
+ return 0;
+}
+
+int
+nfs3RReadDirPlusUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RReadDirPlus *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ if(x->status == Nfs3Ok){
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->verf, Nfs3CookieVerfSize) < 0) goto Err;
+ x->data = a;
+ if(countEntryPlus(a, ea, &a, &x->count) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->eof) < 0) goto Err;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TFsStatPrint(Fmt *fmt, Nfs3TFsStat *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TFsStat");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TFsStatSize(Nfs3TFsStat *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle);
+ return a;
+}
+int
+nfs3TFsStatPack(uchar *a, uchar *ea, uchar **pa, Nfs3TFsStat *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TFsStatUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TFsStat *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RFsStatPrint(Fmt *fmt, Nfs3RFsStat *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RFsStat");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "totalBytes");
+ fmtprint(fmt, "%llud", x->totalBytes);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "freeBytes");
+ fmtprint(fmt, "%llud", x->freeBytes);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "availBytes");
+ fmtprint(fmt, "%llud", x->availBytes);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "totalFiles");
+ fmtprint(fmt, "%llud", x->totalFiles);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "freeFiles");
+ fmtprint(fmt, "%llud", x->freeFiles);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "availFiles");
+ fmtprint(fmt, "%llud", x->availFiles);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "invarSec");
+ fmtprint(fmt, "%ud", x->invarSec);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RFsStatSize(Nfs3RFsStat *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 8 + 8 + 8 + 8 + 8 + 8 + 4;
+ break;
+ }
+ return a;
+}
+int
+nfs3RFsStatPack(uchar *a, uchar *ea, uchar **pa, Nfs3RFsStat *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint64Pack(a, ea, &a, &x->totalBytes) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->freeBytes) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->availBytes) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->totalFiles) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->freeFiles) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->availFiles) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->invarSec) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RFsStatUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RFsStat *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint64Unpack(a, ea, &a, &x->totalBytes) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->freeBytes) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->availBytes) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->totalFiles) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->freeFiles) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->availFiles) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->invarSec) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TFsInfoPrint(Fmt *fmt, Nfs3TFsInfo *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TFsInfo");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TFsInfoSize(Nfs3TFsInfo *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle);
+ return a;
+}
+int
+nfs3TFsInfoPack(uchar *a, uchar *ea, uchar **pa, Nfs3TFsInfo *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TFsInfoUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TFsInfo *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RFsInfoPrint(Fmt *fmt, Nfs3RFsInfo *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RFsInfo");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "readMax");
+ fmtprint(fmt, "%ud", x->readMax);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "readPref");
+ fmtprint(fmt, "%ud", x->readPref);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "readMult");
+ fmtprint(fmt, "%ud", x->readMult);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "writeMax");
+ fmtprint(fmt, "%ud", x->writeMax);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "writePref");
+ fmtprint(fmt, "%ud", x->writePref);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "writeMult");
+ fmtprint(fmt, "%ud", x->writeMult);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "readDirPref");
+ fmtprint(fmt, "%ud", x->readDirPref);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "maxFileSize");
+ fmtprint(fmt, "%llud", x->maxFileSize);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "timePrec");
+ nfs3TimePrint(fmt, &x->timePrec);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "flags");
+ fmtprint(fmt, "%ud", x->flags);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RFsInfoSize(Nfs3RFsInfo *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 8 + nfs3TimeSize(&x->timePrec) + 4;
+ break;
+ }
+ return a;
+}
+int
+nfs3RFsInfoPack(uchar *a, uchar *ea, uchar **pa, Nfs3RFsInfo *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Pack(a, ea, &a, &x->readMax) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->readPref) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->readMult) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->writeMax) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->writePref) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->writeMult) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->readDirPref) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->maxFileSize) < 0) goto Err;
+ if(nfs3TimePack(a, ea, &a, &x->timePrec) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->flags) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RFsInfoUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RFsInfo *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Unpack(a, ea, &a, &x->readMax) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->readPref) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->readMult) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->writeMax) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->writePref) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->writeMult) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->readDirPref) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->maxFileSize) < 0) goto Err;
+ if(nfs3TimeUnpack(a, ea, &a, &x->timePrec) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->flags) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TPathconfPrint(Fmt *fmt, Nfs3TPathconf *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TPathconf");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TPathconfSize(Nfs3TPathconf *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle);
+ return a;
+}
+int
+nfs3TPathconfPack(uchar *a, uchar *ea, uchar **pa, Nfs3TPathconf *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TPathconfUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TPathconf *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RPathconfPrint(Fmt *fmt, Nfs3RPathconf *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RPathconf");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "haveAttr");
+ fmtprint(fmt, "%d", x->haveAttr);
+ fmtprint(fmt, "\n");
+ switch(x->haveAttr){
+ case 1:
+ fmtprint(fmt, "\t%s=", "attr");
+ nfs3AttrPrint(fmt, &x->attr);
+ fmtprint(fmt, "\n");
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "maxLink");
+ fmtprint(fmt, "%ud", x->maxLink);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "maxName");
+ fmtprint(fmt, "%ud", x->maxName);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "noTrunc");
+ fmtprint(fmt, "%d", x->noTrunc);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "chownRestricted");
+ fmtprint(fmt, "%d", x->chownRestricted);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "caseInsensitive");
+ fmtprint(fmt, "%d", x->caseInsensitive);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "casePreserving");
+ fmtprint(fmt, "%d", x->casePreserving);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RPathconfSize(Nfs3RPathconf *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4;
+ switch(x->haveAttr){
+ case 1:
+ a = a + nfs3AttrSize(&x->attr);
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + 4 + 4 + 4 + 4 + 4 + 4;
+ break;
+ }
+ return a;
+}
+int
+nfs3RPathconfPack(uchar *a, uchar *ea, uchar **pa, Nfs3RPathconf *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrPack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Pack(a, ea, &a, &x->maxLink) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->maxName) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->noTrunc) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->chownRestricted) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->caseInsensitive) < 0) goto Err;
+ if(sunUint1Pack(a, ea, &a, &x->casePreserving) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RPathconfUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RPathconf *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(sunUint1Unpack(a, ea, &a, &x->haveAttr) < 0) goto Err;
+ switch(x->haveAttr){
+ case 1:
+ if(nfs3AttrUnpack(a, ea, &a, &x->attr) < 0) goto Err;
+ break;
+ }
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunUint32Unpack(a, ea, &a, &x->maxLink) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->maxName) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->noTrunc) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->chownRestricted) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->caseInsensitive) < 0) goto Err;
+ if(sunUint1Unpack(a, ea, &a, &x->casePreserving) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3TCommitPrint(Fmt *fmt, Nfs3TCommit *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3TCommit");
+ fmtprint(fmt, "\t%s=", "handle");
+ nfs3HandlePrint(fmt, &x->handle);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "offset");
+ fmtprint(fmt, "%llud", x->offset);
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "count");
+ fmtprint(fmt, "%ud", x->count);
+ fmtprint(fmt, "\n");
+}
+uint
+nfs3TCommitSize(Nfs3TCommit *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + nfs3HandleSize(&x->handle) + 8 + 4;
+ return a;
+}
+int
+nfs3TCommitPack(uchar *a, uchar *ea, uchar **pa, Nfs3TCommit *x)
+{
+ if(nfs3HandlePack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Pack(a, ea, &a, &x->offset) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3TCommitUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3TCommit *x)
+{
+ if(nfs3HandleUnpack(a, ea, &a, &x->handle) < 0) goto Err;
+ if(sunUint64Unpack(a, ea, &a, &x->offset) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->count) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+void
+nfs3RCommitPrint(Fmt *fmt, Nfs3RCommit *x)
+{
+ fmtprint(fmt, "%s\n", "Nfs3RCommit");
+ fmtprint(fmt, "\t%s=", "status");
+ fmtprint(fmt, "%s", nfs3StatusStr(x->status));
+ fmtprint(fmt, "\n");
+ fmtprint(fmt, "\t%s=", "wcc");
+ nfs3WccPrint(fmt, &x->wcc);
+ fmtprint(fmt, "\n");
+ switch(x->status){
+ case Nfs3Ok:
+ fmtprint(fmt, "\t%s=", "verf");
+ fmtprint(fmt, "%.*H", Nfs3WriteVerfSize, x->verf);
+ fmtprint(fmt, "\n");
+ break;
+ }
+}
+uint
+nfs3RCommitSize(Nfs3RCommit *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + nfs3WccSize(&x->wcc);
+ switch(x->status){
+ case Nfs3Ok:
+ a = a + Nfs3WriteVerfSize;
+ break;
+ }
+ return a;
+}
+int
+nfs3RCommitPack(uchar *a, uchar *ea, uchar **pa, Nfs3RCommit *x)
+{
+ int i;
+
+ if(i=x->status, sunEnumPack(a, ea, &a, &i) < 0) goto Err;
+ if(nfs3WccPack(a, ea, &a, &x->wcc) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunFixedOpaquePack(a, ea, &a, x->verf, Nfs3WriteVerfSize) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+int
+nfs3RCommitUnpack(uchar *a, uchar *ea, uchar **pa, Nfs3RCommit *x)
+{
+ int i;
+
+ if(sunEnumUnpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
+ if(nfs3WccUnpack(a, ea, &a, &x->wcc) < 0) goto Err;
+ switch(x->status){
+ case Nfs3Ok:
+ if(sunFixedOpaqueUnpack(a, ea, &a, x->verf, Nfs3WriteVerfSize) < 0) goto Err;
+ break;
+ }
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+
+typedef int (*P)(uchar*, uchar*, uchar**, SunCall*);
+typedef void (*F)(Fmt*, SunCall*);
+typedef uint (*S)(SunCall*);
+
+static SunProc proc[] = {
+ (P)nfs3TNullPack, (P)nfs3TNullUnpack, (S)nfs3TNullSize, (F)nfs3TNullPrint, sizeof(Nfs3TNull),
+ (P)nfs3RNullPack, (P)nfs3RNullUnpack, (S)nfs3RNullSize, (F)nfs3RNullPrint, sizeof(Nfs3RNull),
+ (P)nfs3TGetattrPack, (P)nfs3TGetattrUnpack, (S)nfs3TGetattrSize, (F)nfs3TGetattrPrint, sizeof(Nfs3TGetattr),
+ (P)nfs3RGetattrPack, (P)nfs3RGetattrUnpack, (S)nfs3RGetattrSize, (F)nfs3RGetattrPrint, sizeof(Nfs3RGetattr),
+ (P)nfs3TSetattrPack, (P)nfs3TSetattrUnpack, (S)nfs3TSetattrSize, (F)nfs3TSetattrPrint, sizeof(Nfs3TSetattr),
+ (P)nfs3RSetattrPack, (P)nfs3RSetattrUnpack, (S)nfs3RSetattrSize, (F)nfs3RSetattrPrint, sizeof(Nfs3RSetattr),
+ (P)nfs3TLookupPack, (P)nfs3TLookupUnpack, (S)nfs3TLookupSize, (F)nfs3TLookupPrint, sizeof(Nfs3TLookup),
+ (P)nfs3RLookupPack, (P)nfs3RLookupUnpack, (S)nfs3RLookupSize, (F)nfs3RLookupPrint, sizeof(Nfs3RLookup),
+ (P)nfs3TAccessPack, (P)nfs3TAccessUnpack, (S)nfs3TAccessSize, (F)nfs3TAccessPrint, sizeof(Nfs3TAccess),
+ (P)nfs3RAccessPack, (P)nfs3RAccessUnpack, (S)nfs3RAccessSize, (F)nfs3RAccessPrint, sizeof(Nfs3RAccess),
+ (P)nfs3TReadlinkPack, (P)nfs3TReadlinkUnpack, (S)nfs3TReadlinkSize, (F)nfs3TReadlinkPrint, sizeof(Nfs3TReadlink),
+ (P)nfs3RReadlinkPack, (P)nfs3RReadlinkUnpack, (S)nfs3RReadlinkSize, (F)nfs3RReadlinkPrint, sizeof(Nfs3RReadlink),
+ (P)nfs3TReadPack, (P)nfs3TReadUnpack, (S)nfs3TReadSize, (F)nfs3TReadPrint, sizeof(Nfs3TRead),
+ (P)nfs3RReadPack, (P)nfs3RReadUnpack, (S)nfs3RReadSize, (F)nfs3RReadPrint, sizeof(Nfs3RRead),
+ (P)nfs3TWritePack, (P)nfs3TWriteUnpack, (S)nfs3TWriteSize, (F)nfs3TWritePrint, sizeof(Nfs3TWrite),
+ (P)nfs3RWritePack, (P)nfs3RWriteUnpack, (S)nfs3RWriteSize, (F)nfs3RWritePrint, sizeof(Nfs3RWrite),
+ (P)nfs3TCreatePack, (P)nfs3TCreateUnpack, (S)nfs3TCreateSize, (F)nfs3TCreatePrint, sizeof(Nfs3TCreate),
+ (P)nfs3RCreatePack, (P)nfs3RCreateUnpack, (S)nfs3RCreateSize, (F)nfs3RCreatePrint, sizeof(Nfs3RCreate),
+ (P)nfs3TMkdirPack, (P)nfs3TMkdirUnpack, (S)nfs3TMkdirSize, (F)nfs3TMkdirPrint, sizeof(Nfs3TMkdir),
+ (P)nfs3RMkdirPack, (P)nfs3RMkdirUnpack, (S)nfs3RMkdirSize, (F)nfs3RMkdirPrint, sizeof(Nfs3RMkdir),
+ (P)nfs3TSymlinkPack, (P)nfs3TSymlinkUnpack, (S)nfs3TSymlinkSize, (F)nfs3TSymlinkPrint, sizeof(Nfs3TSymlink),
+ (P)nfs3RSymlinkPack, (P)nfs3RSymlinkUnpack, (S)nfs3RSymlinkSize, (F)nfs3RSymlinkPrint, sizeof(Nfs3RSymlink),
+ (P)nfs3TMknodPack, (P)nfs3TMknodUnpack, (S)nfs3TMknodSize, (F)nfs3TMknodPrint, sizeof(Nfs3TMknod),
+ (P)nfs3RMknodPack, (P)nfs3RMknodUnpack, (S)nfs3RMknodSize, (F)nfs3RMknodPrint, sizeof(Nfs3RMknod),
+ (P)nfs3TRemovePack, (P)nfs3TRemoveUnpack, (S)nfs3TRemoveSize, (F)nfs3TRemovePrint, sizeof(Nfs3TRemove),
+ (P)nfs3RRemovePack, (P)nfs3RRemoveUnpack, (S)nfs3RRemoveSize, (F)nfs3RRemovePrint, sizeof(Nfs3RRemove),
+ (P)nfs3TRmdirPack, (P)nfs3TRmdirUnpack, (S)nfs3TRmdirSize, (F)nfs3TRmdirPrint, sizeof(Nfs3TRmdir),
+ (P)nfs3RRmdirPack, (P)nfs3RRmdirUnpack, (S)nfs3RRmdirSize, (F)nfs3RRmdirPrint, sizeof(Nfs3RRmdir),
+ (P)nfs3TRenamePack, (P)nfs3TRenameUnpack, (S)nfs3TRenameSize, (F)nfs3TRenamePrint, sizeof(Nfs3TRename),
+ (P)nfs3RRenamePack, (P)nfs3RRenameUnpack, (S)nfs3RRenameSize, (F)nfs3RRenamePrint, sizeof(Nfs3RRename),
+ (P)nfs3TLinkPack, (P)nfs3TLinkUnpack, (S)nfs3TLinkSize, (F)nfs3TLinkPrint, sizeof(Nfs3TLink),
+ (P)nfs3RLinkPack, (P)nfs3RLinkUnpack, (S)nfs3RLinkSize, (F)nfs3RLinkPrint, sizeof(Nfs3RLink),
+ (P)nfs3TReadDirPack, (P)nfs3TReadDirUnpack, (S)nfs3TReadDirSize, (F)nfs3TReadDirPrint, sizeof(Nfs3TReadDir),
+ (P)nfs3RReadDirPack, (P)nfs3RReadDirUnpack, (S)nfs3RReadDirSize, (F)nfs3RReadDirPrint, sizeof(Nfs3RReadDir),
+ (P)nfs3TReadDirPlusPack, (P)nfs3TReadDirPlusUnpack, (S)nfs3TReadDirPlusSize, (F)nfs3TReadDirPlusPrint, sizeof(Nfs3TReadDirPlus),
+ (P)nfs3RReadDirPlusPack, (P)nfs3RReadDirPlusUnpack, (S)nfs3RReadDirPlusSize, (F)nfs3RReadDirPlusPrint, sizeof(Nfs3RReadDirPlus),
+ (P)nfs3TFsStatPack, (P)nfs3TFsStatUnpack, (S)nfs3TFsStatSize, (F)nfs3TFsStatPrint, sizeof(Nfs3TFsStat),
+ (P)nfs3RFsStatPack, (P)nfs3RFsStatUnpack, (S)nfs3RFsStatSize, (F)nfs3RFsStatPrint, sizeof(Nfs3RFsStat),
+ (P)nfs3TFsInfoPack, (P)nfs3TFsInfoUnpack, (S)nfs3TFsInfoSize, (F)nfs3TFsInfoPrint, sizeof(Nfs3TFsInfo),
+ (P)nfs3RFsInfoPack, (P)nfs3RFsInfoUnpack, (S)nfs3RFsInfoSize, (F)nfs3RFsInfoPrint, sizeof(Nfs3RFsInfo),
+ (P)nfs3TPathconfPack, (P)nfs3TPathconfUnpack, (S)nfs3TPathconfSize, (F)nfs3TPathconfPrint, sizeof(Nfs3TPathconf),
+ (P)nfs3RPathconfPack, (P)nfs3RPathconfUnpack, (S)nfs3RPathconfSize, (F)nfs3RPathconfPrint, sizeof(Nfs3RPathconf),
+ (P)nfs3TCommitPack, (P)nfs3TCommitUnpack, (S)nfs3TCommitSize, (F)nfs3TCommitPrint, sizeof(Nfs3TCommit),
+ (P)nfs3RCommitPack, (P)nfs3RCommitUnpack, (S)nfs3RCommitSize, (F)nfs3RCommitPrint, sizeof(Nfs3RCommit)
+};
+
+SunProg nfs3Prog =
+{
+ Nfs3Program,
+ Nfs3Version,
+ proc,
+ nelem(proc),
+};
diff --git a/sys/src/libsunrpc/portmap.c b/sys/src/libsunrpc/portmap.c
new file mode 100755
index 000000000..27efce209
--- /dev/null
+++ b/sys/src/libsunrpc/portmap.c
@@ -0,0 +1,498 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+static void
+portMapPrint(Fmt *fmt, PortMap *x)
+{
+ fmtprint(fmt, "[%ud %ud %ud %ud]", x->prog, x->vers, x->prot, x->port);
+}
+static uint
+portMapSize(PortMap *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4 + 4 + 4;
+ return a;
+}
+static int
+portMapPack(uchar *a, uchar *ea, uchar **pa, PortMap *x)
+{
+ if(sunUint32Pack(a, ea, &a, &x->prog) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->vers) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->prot) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->port) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portMapUnpack(uchar *a, uchar *ea, uchar **pa, PortMap *x)
+{
+ if(sunUint32Unpack(a, ea, &a, &x->prog) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->vers) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->prot) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->port) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portTNullPrint(Fmt *fmt, PortTNull *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s", "PortTNull");
+}
+static uint
+portTNullSize(PortTNull *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+static int
+portTNullPack(uchar *a, uchar *ea, uchar **pa, PortTNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+static int
+portTNullUnpack(uchar *a, uchar *ea, uchar **pa, PortTNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+static void
+portRNullPrint(Fmt *fmt, PortRNull *x)
+{
+ USED(x);
+ fmtprint(fmt, "%s", "PortRNull");
+}
+static uint
+portRNullSize(PortRNull *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+static int
+portRNullPack(uchar *a, uchar *ea, uchar **pa, PortRNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+static int
+portRNullUnpack(uchar *a, uchar *ea, uchar **pa, PortRNull *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+static void
+portTSetPrint(Fmt *fmt, PortTSet *x)
+{
+ fmtprint(fmt, "PortTSet ");
+ portMapPrint(fmt, &x->map);
+}
+static uint
+portTSetSize(PortTSet *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + portMapSize(&x->map);
+ return a;
+}
+static int
+portTSetPack(uchar *a, uchar *ea, uchar **pa, PortTSet *x)
+{
+ if(portMapPack(a, ea, &a, &x->map) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portTSetUnpack(uchar *a, uchar *ea, uchar **pa, PortTSet *x)
+{
+ if(portMapUnpack(a, ea, &a, &x->map) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portRSetPrint(Fmt *fmt, PortRSet *x)
+{
+ fmtprint(fmt, "PortRSet %ud", x->b);
+}
+static uint
+portRSetSize(PortRSet *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ return a;
+}
+static int
+portRSetPack(uchar *a, uchar *ea, uchar **pa, PortRSet *x)
+{
+ if(sunUint1Pack(a, ea, &a, &x->b) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portRSetUnpack(uchar *a, uchar *ea, uchar **pa, PortRSet *x)
+{
+ if(sunUint1Unpack(a, ea, &a, &x->b) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portTUnsetPrint(Fmt *fmt, PortTUnset *x)
+{
+ fmtprint(fmt, "PortTUnset ");
+ portMapPrint(fmt, &x->map);
+}
+static uint
+portTUnsetSize(PortTUnset *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + portMapSize(&x->map);
+ return a;
+}
+static int
+portTUnsetPack(uchar *a, uchar *ea, uchar **pa, PortTUnset *x)
+{
+ if(portMapPack(a, ea, &a, &x->map) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portTUnsetUnpack(uchar *a, uchar *ea, uchar **pa, PortTUnset *x)
+{
+ if(portMapUnpack(a, ea, &a, &x->map) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portRUnsetPrint(Fmt *fmt, PortRUnset *x)
+{
+ fmtprint(fmt, "PortRUnset %ud", x->b);
+}
+static uint
+portRUnsetSize(PortRUnset *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ return a;
+}
+static int
+portRUnsetPack(uchar *a, uchar *ea, uchar **pa, PortRUnset *x)
+{
+ if(sunUint1Pack(a, ea, &a, &x->b) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portRUnsetUnpack(uchar *a, uchar *ea, uchar **pa, PortRUnset *x)
+{
+ if(sunUint1Unpack(a, ea, &a, &x->b) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portTGetportPrint(Fmt *fmt, PortTGetport *x)
+{
+ fmtprint(fmt, "PortTGetport ");
+ portMapPrint(fmt, &x->map);
+}
+static uint
+portTGetportSize(PortTGetport *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + portMapSize(&x->map);
+ return a;
+}
+static int
+portTGetportPack(uchar *a, uchar *ea, uchar **pa, PortTGetport *x)
+{
+ if(portMapPack(a, ea, &a, &x->map) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portTGetportUnpack(uchar *a, uchar *ea, uchar **pa, PortTGetport *x)
+{
+ if(portMapUnpack(a, ea, &a, &x->map) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portRGetportPrint(Fmt *fmt, PortRGetport *x)
+{
+ fmtprint(fmt, "PortRGetport %ud", x->port);
+}
+static uint
+portRGetportSize(PortRGetport *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4;
+ return a;
+}
+static int
+portRGetportPack(uchar *a, uchar *ea, uchar **pa, PortRGetport *x)
+{
+ if(sunUint32Pack(a, ea, &a, &x->port) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portRGetportUnpack(uchar *a, uchar *ea, uchar **pa, PortRGetport *x)
+{
+ if(sunUint32Unpack(a, ea, &a, &x->port) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portTDumpPrint(Fmt *fmt, PortTDump *x)
+{
+ USED(x);
+ fmtprint(fmt, "PortTDump");
+}
+static uint
+portTDumpSize(PortTDump *x)
+{
+ uint a;
+ USED(x);
+ a = 0;
+ return a;
+}
+static int
+portTDumpPack(uchar *a, uchar *ea, uchar **pa, PortTDump *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+static int
+portTDumpUnpack(uchar *a, uchar *ea, uchar **pa, PortTDump *x)
+{
+ USED(ea);
+ USED(x);
+ *pa = a;
+ return 0;
+}
+static void
+portRDumpPrint(Fmt *fmt, PortRDump *x)
+{
+ int i;
+
+ fmtprint(fmt, "PortRDump");
+ for(i=0; i<x->nmap; i++){
+ fmtprint(fmt, " ");
+ portMapPrint(fmt, &x->map[i]);
+ }
+}
+static uint
+portRDumpSize(PortRDump *x)
+{
+ return (5*4*x->nmap) + 4;
+}
+static int
+portRDumpPack(uchar *a, uchar *ea, uchar **pa, PortRDump *x)
+{
+ int i;
+ u32int zero, one;
+
+ zero = 0;
+ one = 1;
+ for(i=0; i<x->nmap; i++){
+ if(sunUint32Pack(a, ea, &a, &one) < 0
+ || portMapPack(a, ea, &a, &x->map[i]) < 0)
+ goto Err;
+ }
+ if(sunUint32Pack(a, ea, &a, &zero) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portRDumpUnpack(uchar *a, uchar *ea, uchar **pa, PortRDump *x)
+{
+ int i;
+ u1int u1;
+ PortMap *m;
+
+ m = (PortMap*)a;
+ for(i=0;; i++){
+ if(sunUint1Unpack(a, ea, &a, &u1) < 0)
+ goto Err;
+ if(u1 == 0)
+ break;
+ if(portMapUnpack(a, ea, &a, &m[i]) < 0)
+ goto Err;
+ }
+ x->nmap = i;
+ x->map = m;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portTCallitPrint(Fmt *fmt, PortTCallit *x)
+{
+ fmtprint(fmt, "PortTCallit [%ud,%ud,%ud] %ud", x->prog, x->vers, x->proc, x->count);
+}
+static uint
+portTCallitSize(PortTCallit *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + 4 + 4 + sunVarOpaqueSize(x->count);
+ return a;
+}
+static int
+portTCallitPack(uchar *a, uchar *ea, uchar **pa, PortTCallit *x)
+{
+ if(sunUint32Pack(a, ea, &a, &x->prog) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->vers) < 0) goto Err;
+ if(sunUint32Pack(a, ea, &a, &x->proc) < 0) goto Err;
+ if(sunVarOpaquePack(a, ea, &a, &x->data, &x->count, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portTCallitUnpack(uchar *a, uchar *ea, uchar **pa, PortTCallit *x)
+{
+ if(sunUint32Unpack(a, ea, &a, &x->prog) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->vers) < 0) goto Err;
+ if(sunUint32Unpack(a, ea, &a, &x->proc) < 0) goto Err;
+ if(sunVarOpaqueUnpack(a, ea, &a, &x->data, &x->count, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static void
+portRCallitPrint(Fmt *fmt, PortRCallit *x)
+{
+ fmtprint(fmt, "PortRCallit %ud %ud", x->port, x->count);
+}
+static uint
+portRCallitSize(PortRCallit *x)
+{
+ uint a;
+ USED(x);
+ a = 0 + 4 + sunVarOpaqueSize(x->count);
+ return a;
+}
+static int
+portRCallitPack(uchar *a, uchar *ea, uchar **pa, PortRCallit *x)
+{
+ if(sunUint32Pack(a, ea, &a, &x->port) < 0) goto Err;
+ if(sunVarOpaquePack(a, ea, &a, &x->data, &x->count, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+static int
+portRCallitUnpack(uchar *a, uchar *ea, uchar **pa, PortRCallit *x)
+{
+ if(sunUint32Unpack(a, ea, &a, &x->port) < 0) goto Err;
+ if(sunVarOpaqueUnpack(a, ea, &a, &x->data, &x->count, -1) < 0) goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+
+typedef int (*P)(uchar*, uchar*, uchar**, SunCall*);
+typedef void (*F)(Fmt*, SunCall*);
+typedef uint (*S)(SunCall*);
+
+static SunProc proc[] = {
+ (P)portTNullPack, (P)portTNullUnpack, (S)portTNullSize, (F)portTNullPrint, sizeof(PortTNull),
+ (P)portRNullPack, (P)portRNullUnpack, (S)portRNullSize, (F)portRNullPrint, sizeof(PortRNull),
+ (P)portTSetPack, (P)portTSetUnpack, (S)portTSetSize, (F)portTSetPrint, sizeof(PortTSet),
+ (P)portRSetPack, (P)portRSetUnpack, (S)portRSetSize, (F)portRSetPrint, sizeof(PortRSet),
+ (P)portTUnsetPack, (P)portTUnsetUnpack, (S)portTUnsetSize, (F)portTUnsetPrint, sizeof(PortTUnset),
+ (P)portRUnsetPack, (P)portRUnsetUnpack, (S)portRUnsetSize, (F)portRUnsetPrint, sizeof(PortRUnset),
+ (P)portTGetportPack, (P)portTGetportUnpack, (S)portTGetportSize, (F)portTGetportPrint, sizeof(PortTGetport),
+ (P)portRGetportPack, (P)portRGetportUnpack, (S)portRGetportSize, (F)portRGetportPrint, sizeof(PortRGetport),
+ (P)portTDumpPack, (P)portTDumpUnpack, (S)portTDumpSize, (F)portTDumpPrint, sizeof(PortTDump),
+ (P)portRDumpPack, (P)portRDumpUnpack, (S)portRDumpSize, (F)portRDumpPrint, sizeof(PortRDump),
+ (P)portTCallitPack, (P)portTCallitUnpack, (S)portTCallitSize, (F)portTCallitPrint, sizeof(PortTCallit),
+ (P)portRCallitPack, (P)portRCallitUnpack, (S)portRCallitSize, (F)portRCallitPrint, sizeof(PortRCallit),
+};
+
+SunProg portProg =
+{
+ PortProgram,
+ PortVersion,
+ proc,
+ nelem(proc),
+};
diff --git a/sys/src/libsunrpc/prog.c b/sys/src/libsunrpc/prog.c
new file mode 100755
index 000000000..b6c46f6f0
--- /dev/null
+++ b/sys/src/libsunrpc/prog.c
@@ -0,0 +1,74 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+SunStatus
+sunCallPack(SunProg *prog, uchar *a, uchar *ea, uchar **pa, SunCall *c)
+{
+ uchar *x;
+ int (*pack)(uchar*, uchar*, uchar**, SunCall*);
+
+ if(pa == nil)
+ pa = &x;
+ if(c->type < 0 || c->type >= prog->nproc || (pack=prog->proc[c->type].pack) == nil)
+ return SunProcUnavail;
+ if((*pack)(a, ea, pa, c) < 0)
+ return SunGarbageArgs;
+ return SunSuccess;
+}
+
+SunStatus
+sunCallUnpack(SunProg *prog, uchar *a, uchar *ea, uchar **pa, SunCall *c)
+{
+ uchar *x;
+ int (*unpack)(uchar*, uchar*, uchar**, SunCall*);
+
+ if(pa == nil)
+ pa = &x;
+ if(c->type < 0 || c->type >= prog->nproc || (unpack=prog->proc[c->type].unpack) == nil)
+ return SunProcUnavail;
+ if((*unpack)(a, ea, pa, c) < 0){
+ fprint(2, "in: %.*H unpack failed\n", (int)(ea-a), a);
+ return SunGarbageArgs;
+ }
+ return SunSuccess;
+}
+
+SunStatus
+sunCallUnpackAlloc(SunProg *prog, SunCallType type, uchar *a, uchar *ea, uchar **pa, SunCall **pc)
+{
+ uchar *x;
+ uint size;
+ int (*unpack)(uchar*, uchar*, uchar**, SunCall*);
+ SunCall *c;
+
+ if(pa == nil)
+ pa = &x;
+ if(type < 0 || type >= prog->nproc || (unpack=prog->proc[type].unpack) == nil)
+ return SunProcUnavail;
+ size = prog->proc[type].sizeoftype;
+ if(size == 0)
+ return SunProcUnavail;
+ c = mallocz(size, 1);
+ if(c == nil)
+ return SunSystemErr;
+ c->type = type;
+ if((*unpack)(a, ea, pa, c) < 0){
+ fprint(2, "in: %.*H unpack failed\n", (int)(ea-a), a);
+ free(c);
+ return SunGarbageArgs;
+ }
+ *pc = c;
+ return SunSuccess;
+}
+
+uint
+sunCallSize(SunProg *prog, SunCall *c)
+{
+ uint (*size)(SunCall*);
+
+ if(c->type < 0 || c->type >= prog->nproc || (size=prog->proc[c->type].size) == nil)
+ return ~0;
+ return (*size)(c);
+}
diff --git a/sys/src/libsunrpc/rpc.c b/sys/src/libsunrpc/rpc.c
new file mode 100755
index 000000000..657e04233
--- /dev/null
+++ b/sys/src/libsunrpc/rpc.c
@@ -0,0 +1,528 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+/*
+ * RPC protocol constants
+ */
+enum
+{
+ RpcVersion = 2,
+
+ /* msg type */
+ MsgCall = 0,
+ MsgReply = 1,
+
+ /* reply stat */
+ MsgAccepted = 0,
+ MsgDenied = 1,
+
+ /* accept stat */
+ MsgSuccess = 0,
+ MsgProgUnavail = 1,
+ MsgProgMismatch = 2,
+ MsgProcUnavail = 3,
+ MsgGarbageArgs = 4,
+ MsgSystemErr = 5,
+
+ /* reject stat */
+ MsgRpcMismatch = 0,
+ MsgAuthError = 1,
+
+ /* msg auth xxx */
+ MsgAuthOk = 0,
+ MsgAuthBadCred = 1,
+ MsgAuthRejectedCred = 2,
+ MsgAuthBadVerf = 3,
+ MsgAuthRejectedVerf = 4,
+ MsgAuthTooWeak = 5,
+ MsgAuthInvalidResp = 6,
+ MsgAuthFailed = 7,
+};
+
+SunStatus
+sunRpcPack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
+{
+ u32int x;
+
+ if(sunUint32Pack(a, ea, &a, &rpc->xid) < 0)
+ goto Err;
+ if(rpc->iscall){
+ if(sunUint32Pack(a, ea, &a, (x=MsgCall, &x)) < 0
+ || sunUint32Pack(a, ea, &a, (x=RpcVersion, &x)) < 0
+ || sunUint32Pack(a, ea, &a, &rpc->prog) < 0
+ || sunUint32Pack(a, ea, &a, &rpc->vers) < 0
+ || sunUint32Pack(a, ea, &a, &rpc->proc) < 0
+ || sunAuthInfoPack(a, ea, &a, &rpc->cred) < 0
+ || sunAuthInfoPack(a, ea, &a, &rpc->verf) < 0
+ || sunFixedOpaquePack(a, ea, &a, rpc->data, rpc->ndata) < 0)
+ goto Err;
+ }else{
+ if(sunUint32Pack(a, ea, &a, (x=MsgReply, &x)) < 0)
+ goto Err;
+ switch(rpc->status&0xF0000){
+ case 0:
+ case SunAcceptError:
+ if(sunUint32Pack(a, ea, &a, (x=MsgAccepted, &x)) < 0
+ || sunAuthInfoPack(a, ea, &a, &rpc->verf) < 0)
+ goto Err;
+ break;
+ default:
+ if(sunUint32Pack(a, ea, &a, (x=MsgDenied, &x)) < 0)
+ goto Err;
+ break;
+ }
+
+ switch(rpc->status){
+ case SunSuccess:
+ if(sunUint32Pack(a, ea, &a, (x=MsgSuccess, &x)) < 0
+ || sunFixedOpaquePack(a, ea, &a, rpc->data, rpc->ndata) < 0)
+ goto Err;
+ break;
+ case SunRpcMismatch:
+ case SunProgMismatch:
+ if(sunUint32Pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0
+ || sunUint32Pack(a, ea, &a, &rpc->low) < 0
+ || sunUint32Pack(a, ea, &a, &rpc->high) < 0)
+ goto Err;
+ break;
+ default:
+ if(sunUint32Pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0)
+ goto Err;
+ break;
+ }
+ }
+ *pa = a;
+ return SunSuccess;
+
+Err:
+ *pa = ea;
+ return SunGarbageArgs;
+}
+
+uint
+sunRpcSize(SunRpc *rpc)
+{
+ uint a;
+
+ a = 4;
+ if(rpc->iscall){
+ a += 5*4;
+ a += sunAuthInfoSize(&rpc->cred);
+ a += sunAuthInfoSize(&rpc->verf);
+ a += sunFixedOpaqueSize(rpc->ndata);
+ }else{
+ a += 4;
+ switch(rpc->status&0xF0000){
+ case 0:
+ case SunAcceptError:
+ a += 4+sunAuthInfoSize(&rpc->verf);
+ break;
+ default:
+ a += 4;
+ break;
+ }
+
+ switch(rpc->status){
+ case SunSuccess:
+ a += 4+sunFixedOpaqueSize(rpc->ndata);
+ break;
+ case SunRpcMismatch:
+ case SunProgMismatch:
+ a += 3*4;
+ default:
+ a += 4;
+ }
+ }
+ return a;
+}
+
+SunStatus
+sunRpcUnpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
+{
+ u32int x;
+
+ memset(rpc, 0, sizeof *rpc);
+ if(sunUint32Unpack(a, ea, &a, &rpc->xid) < 0
+ || sunUint32Unpack(a, ea, &a, &x) < 0)
+ goto Err;
+
+ switch(x){
+ default:
+ goto Err;
+ case MsgCall:
+ rpc->iscall = 1;
+ if(sunUint32Unpack(a, ea, &a, &x) < 0 || x != RpcVersion
+ || sunUint32Unpack(a, ea, &a, &rpc->prog) < 0
+ || sunUint32Unpack(a, ea, &a, &rpc->vers) < 0
+ || sunUint32Unpack(a, ea, &a, &rpc->proc) < 0
+ || sunAuthInfoUnpack(a, ea, &a, &rpc->cred) < 0
+ || sunAuthInfoUnpack(a, ea, &a, &rpc->verf) < 0)
+ goto Err;
+ rpc->ndata = ea-a;
+ rpc->data = a;
+ a = ea;
+ break;
+
+ case MsgReply:
+ rpc->iscall = 0;
+ if(sunUint32Unpack(a, ea, &a, &x) < 0)
+ goto Err;
+ switch(x){
+ default:
+ goto Err;
+ case MsgAccepted:
+ if(sunAuthInfoUnpack(a, ea, &a, &rpc->verf) < 0
+ || sunUint32Unpack(a, ea, &a, &x) < 0)
+ goto Err;
+ switch(x){
+ case MsgSuccess:
+ rpc->status = SunSuccess;
+ rpc->ndata = ea-a;
+ rpc->data = a;
+ a = ea;
+ break;
+ case MsgProgUnavail:
+ case MsgProcUnavail:
+ case MsgGarbageArgs:
+ case MsgSystemErr:
+ rpc->status = SunAcceptError | x;
+ break;
+ case MsgProgMismatch:
+ rpc->status = SunAcceptError | x;
+ if(sunUint32Unpack(a, ea, &a, &rpc->low) < 0
+ || sunUint32Unpack(a, ea, &a, &rpc->high) < 0)
+ goto Err;
+ break;
+ }
+ break;
+ case MsgDenied:
+ if(sunUint32Unpack(a, ea, &a, &x) < 0)
+ goto Err;
+ switch(x){
+ default:
+ goto Err;
+ case MsgAuthError:
+ if(sunUint32Unpack(a, ea, &a, &x) < 0)
+ goto Err;
+ rpc->status = SunAuthError | x;
+ break;
+ case MsgRpcMismatch:
+ rpc->status = SunRejectError | x;
+ if(sunUint32Unpack(a, ea, &a, &rpc->low) < 0
+ || sunUint32Unpack(a, ea, &a, &rpc->high) < 0)
+ goto Err;
+ break;
+ }
+ break;
+ }
+ }
+ *pa = a;
+ return SunSuccess;
+
+Err:
+ *pa = ea;
+ return SunGarbageArgs;
+}
+
+void
+sunRpcPrint(Fmt *fmt, SunRpc *rpc)
+{
+ fmtprint(fmt, "xid=%#ux", rpc->xid);
+ if(rpc->iscall){
+ fmtprint(fmt, " prog %#ux vers %#ux proc %#ux [", rpc->prog, rpc->vers, rpc->proc);
+ sunAuthInfoPrint(fmt, &rpc->cred);
+ fmtprint(fmt, "] [");
+ sunAuthInfoPrint(fmt, &rpc->verf);
+ fmtprint(fmt, "]");
+ }else{
+ fmtprint(fmt, " status %#ux [", rpc->status);
+ sunAuthInfoPrint(fmt, &rpc->verf);
+ fmtprint(fmt, "] low %#ux high %#ux", rpc->low, rpc->high);
+ }
+}
+
+void
+sunAuthInfoPrint(Fmt *fmt, SunAuthInfo *ai)
+{
+ switch(ai->flavor){
+ case SunAuthNone:
+ fmtprint(fmt, "none");
+ break;
+ case SunAuthShort:
+ fmtprint(fmt, "short");
+ break;
+ case SunAuthSys:
+ fmtprint(fmt, "sys");
+ break;
+ default:
+ fmtprint(fmt, "%#ux", ai->flavor);
+ break;
+ }
+// if(ai->ndata)
+// fmtprint(fmt, " %.*H", ai->ndata, ai->data);
+}
+
+uint
+sunAuthInfoSize(SunAuthInfo *ai)
+{
+ return 4 + sunVarOpaqueSize(ai->ndata);
+}
+
+int
+sunAuthInfoPack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
+{
+ if(sunUint32Pack(a, ea, &a, &ai->flavor) < 0
+ || sunVarOpaquePack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+sunAuthInfoUnpack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
+{
+ if(sunUint32Unpack(a, ea, &a, &ai->flavor) < 0
+ || sunVarOpaqueUnpack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+sunEnumPack(uchar *a, uchar *ea, uchar **pa, int *e)
+{
+ u32int x;
+
+ x = *e;
+ return sunUint32Pack(a, ea, pa, &x);
+}
+
+int
+sunUint1Pack(uchar *a, uchar *ea, uchar **pa, u1int *u)
+{
+ u32int x;
+
+ x = *u;
+ return sunUint32Pack(a, ea, pa, &x);
+}
+
+int
+sunUint32Pack(uchar *a, uchar *ea, uchar **pa, u32int *u)
+{
+ u32int x;
+
+ if(ea-a < 4)
+ goto Err;
+
+ x = *u;
+ *a++ = x>>24;
+ *a++ = x>>16;
+ *a++ = x>>8;
+ *a++ = x;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+sunEnumUnpack(uchar *a, uchar *ea, uchar **pa, int *e)
+{
+ u32int x;
+ if(sunUint32Unpack(a, ea, pa, &x) < 0)
+ return -1;
+ *e = x;
+ return 0;
+}
+
+int
+sunUint1Unpack(uchar *a, uchar *ea, uchar **pa, u1int *u)
+{
+ u32int x;
+ if(sunUint32Unpack(a, ea, pa, &x) < 0 || (x!=0 && x!=1)){
+ *pa = ea;
+ return -1;
+ }
+ *u = x;
+ return 0;
+}
+
+int
+sunUint32Unpack(uchar *a, uchar *ea, uchar **pa, u32int *u)
+{
+ u32int x;
+
+ if(ea-a < 4)
+ goto Err;
+ x = *a++ << 24;
+ x |= *a++ << 16;
+ x |= *a++ << 8;
+ x |= *a++;
+ *pa = a;
+ *u = x;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+sunUint64Unpack(uchar *a, uchar *ea, uchar **pa, u64int *u)
+{
+ u32int x, y;
+
+ if(sunUint32Unpack(a, ea, &a, &x) < 0
+ || sunUint32Unpack(a, ea, &a, &y) < 0)
+ goto Err;
+ *u = ((uvlong)x<<32) | y;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+sunUint64Pack(uchar *a, uchar *ea, uchar **pa, u64int *u)
+{
+ u32int x, y;
+
+ x = *u >> 32;
+ y = *u;
+ if(sunUint32Pack(a, ea, &a, &x) < 0
+ || sunUint32Pack(a, ea, &a, &y) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+Err:
+ *pa = ea;
+ return -1;
+}
+
+uint
+sunStringSize(char *s)
+{
+ return (4+strlen(s)+3) & ~3;
+}
+
+int
+sunStringUnpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
+{
+ uchar *dat;
+ u32int n;
+
+ if(sunVarOpaqueUnpack(a, ea, pa, &dat, &n, max) < 0)
+ goto Err;
+ /* slide string down over length to make room for NUL */
+ memmove(dat-1, dat, n);
+ dat[-1+n] = 0;
+ *s = (char*)(dat-1);
+ return 0;
+Err:
+ return -1;
+}
+
+int
+sunStringPack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
+{
+ u32int n;
+
+ n = strlen(*s);
+ return sunVarOpaquePack(a, ea, pa, (uchar**)s, &n, max);
+}
+
+uint
+sunVarOpaqueSize(u32int n)
+{
+ return (4+n+3) & ~3;
+}
+
+int
+sunVarOpaquePack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
+{
+ if(*ndat > max || sunUint32Pack(a, ea, &a, ndat) < 0
+ || sunFixedOpaquePack(a, ea, &a, *dat, *ndat) < 0)
+ goto Err;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+sunVarOpaqueUnpack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
+{
+ if(sunUint32Unpack(a, ea, &a, ndat) < 0
+ || *ndat > max)
+ goto Err;
+ *dat = a;
+ a += (*ndat+3)&~3;
+ if(a > ea)
+ goto Err;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+uint
+sunFixedOpaqueSize(u32int n)
+{
+ return (n+3) & ~3;
+}
+
+int
+sunFixedOpaquePack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
+{
+ uint nn;
+
+ nn = (n+3)&~3;
+ if(a+nn > ea)
+ goto Err;
+ memmove(a, dat, n);
+ if(nn > n)
+ memset(a+n, 0, nn-n);
+ a += nn;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
+int
+sunFixedOpaqueUnpack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
+{
+ uint nn;
+
+ nn = (n+3)&~3;
+ if(a+nn > ea)
+ goto Err;
+ memmove(dat, a, n);
+ a += nn;
+ *pa = a;
+ return 0;
+
+Err:
+ *pa = ea;
+ return -1;
+}
+
diff --git a/sys/src/libsunrpc/server.c b/sys/src/libsunrpc/server.c
new file mode 100755
index 000000000..a8cbbf1c7
--- /dev/null
+++ b/sys/src/libsunrpc/server.c
@@ -0,0 +1,277 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+/*
+ * Sun RPC server; for now, no reply cache
+ */
+
+static void sunRpcProc(void*);
+static void sunRpcRequestThread(void*);
+static void sunRpcReplyThread(void*);
+static void sunRpcForkThread(void*);
+static SunProg *sunFindProg(SunSrv*, SunMsg*, SunRpc*, Channel**);
+
+typedef struct Targ Targ;
+struct Targ
+{
+ void (*fn)(void*);
+ void *arg;
+};
+
+SunSrv*
+sunSrv(void)
+{
+ SunSrv *srv;
+
+ srv = emalloc(sizeof(SunSrv));
+ srv->chatty = 0;
+ srv->crequest = chancreate(sizeof(SunMsg*), 16);
+ srv->creply = chancreate(sizeof(SunMsg*), 16);
+ srv->cthread = chancreate(sizeof(Targ), 4);
+
+ proccreate(sunRpcProc, srv, SunStackSize);
+ return srv;
+}
+
+void
+sunSrvProg(SunSrv *srv, SunProg *prog, Channel *c)
+{
+ if(srv->nprog%16 == 0){
+ srv->prog = erealloc(srv->prog, (srv->nprog+16)*sizeof(srv->prog[0]));
+ srv->cdispatch = erealloc(srv->cdispatch, (srv->nprog+16)*sizeof(srv->cdispatch[0]));
+ }
+ srv->prog[srv->nprog] = prog;
+ srv->cdispatch[srv->nprog] = c;
+ srv->nprog++;
+}
+
+static void
+sunRpcProc(void *v)
+{
+ threadcreate(sunRpcReplyThread, v, SunStackSize);
+ threadcreate(sunRpcRequestThread, v, SunStackSize);
+ threadcreate(sunRpcForkThread, v, SunStackSize);
+
+}
+
+static void
+sunRpcForkThread(void *v)
+{
+ SunSrv *srv = v;
+ Targ t;
+
+ while(recv(srv->cthread, &t) == 1)
+ threadcreate(t.fn, t.arg, SunStackSize);
+}
+
+void
+sunSrvThreadCreate(SunSrv *srv, void (*fn)(void*), void *arg)
+{
+ Targ t;
+
+ t.fn = fn;
+ t.arg = arg;
+ send(srv->cthread, &t);
+}
+
+static void
+sunRpcRequestThread(void *v)
+{
+ uchar *p, *ep;
+ Channel *c;
+ SunSrv *srv = v;
+ SunMsg *m;
+ SunProg *pg;
+ SunStatus ok;
+
+ while((m = recvp(srv->crequest)) != nil){
+ /* could look up in cache here? */
+
+if(srv->chatty) fprint(2, "sun msg %p count %d\n", m, m->count);
+ m->srv = srv;
+ p = m->data;
+ ep = p+m->count;
+ if(sunRpcUnpack(p, ep, &p, &m->rpc) != SunSuccess){
+ fprint(2, "in: %.*H unpack failed\n", m->count, m->data);
+ sunMsgDrop(m);
+ continue;
+ }
+ if(srv->chatty)
+ fprint(2, "in: %B\n", &m->rpc);
+
+ if(srv->alwaysReject){
+ if(srv->chatty)
+ fprint(2, "\trejecting\n");
+ sunMsgReplyError(m, SunAuthTooWeak);
+ continue;
+ }
+
+ if(!m->rpc.iscall){
+ sunMsgReplyError(m, SunGarbageArgs);
+ continue;
+ }
+
+ if((pg = sunFindProg(srv, m, &m->rpc, &c)) == nil){
+ /* sunFindProg sent error */
+ continue;
+ }
+
+ p = m->rpc.data;
+ ep = p+m->rpc.ndata;
+ m->call = nil;
+ if((ok = sunCallUnpackAlloc(pg, m->rpc.proc<<1, p, ep, &p, &m->call)) != SunSuccess){
+ sunMsgReplyError(m, ok);
+ continue;
+ }
+ m->call->rpc = m->rpc;
+
+ if(srv->chatty)
+ fprint(2, "\t%C\n", m->call);
+
+ m->pg = pg;
+ sendp(c, m);
+ }
+}
+
+static SunProg*
+sunFindProg(SunSrv *srv, SunMsg *m, SunRpc *rpc, Channel **pc)
+{
+ int i, vlo, vhi;
+ SunProg *pg;
+
+ vlo = 0x7fffffff;
+ vhi = -1;
+
+ for(i=0; i<srv->nprog; i++){
+ pg = srv->prog[i];
+ if(pg->prog != rpc->prog)
+ continue;
+ if(pg->vers == rpc->vers){
+ *pc = srv->cdispatch[i];
+ return pg;
+ }
+ /* right program, wrong version: record range */
+ if(pg->vers < vlo)
+ vlo = pg->vers;
+ if(pg->vers > vhi)
+ vhi = pg->vers;
+ }
+ if(vhi == -1){
+ if(srv->chatty)
+ fprint(2, "\tprogram %ud unavailable\n", rpc->prog);
+ sunMsgReplyError(m, SunProgUnavail);
+ }else{
+ /* putting these in rpc is a botch */
+ rpc->low = vlo;
+ rpc->high = vhi;
+ if(srv->chatty)
+ fprint(2, "\tversion %ud unavailable; have %d-%d\n", rpc->vers, vlo, vhi);
+ sunMsgReplyError(m, SunProgMismatch);
+ }
+ return nil;
+}
+
+static void
+sunRpcReplyThread(void *v)
+{
+ SunMsg *m;
+ SunSrv *srv = v;
+
+ while((m = recvp(srv->creply)) != nil){
+ /* could record in cache here? */
+ sendp(m->creply, m);
+ }
+}
+
+int
+sunMsgReplyError(SunMsg *m, SunStatus error)
+{
+ uchar *p, *bp, *ep;
+ int n;
+
+ m->rpc.status = error;
+ m->rpc.iscall = 0;
+ m->rpc.verf.flavor = SunAuthNone;
+ m->rpc.data = nil;
+ m->rpc.ndata = 0;
+
+ if(m->srv->chatty)
+ fprint(2, "out: %B\n", &m->rpc);
+
+ n = sunRpcSize(&m->rpc);
+ bp = emalloc(n);
+ ep = bp+n;
+ p = bp;
+ if(sunRpcPack(p, ep, &p, &m->rpc) < 0){
+ fprint(2, "sunRpcPack failed\n");
+ sunMsgDrop(m);
+ return 0;
+ }
+ if(p != ep){
+ fprint(2, "sunMsgReplyError: rpc sizes didn't work out\n");
+ sunMsgDrop(m);
+ return 0;
+ }
+ free(m->data);
+ m->data = bp;
+ m->count = n;
+ sendp(m->srv->creply, m);
+ return 0;
+}
+
+int
+sunMsgReply(SunMsg *m, SunCall *c)
+{
+ int n1, n2;
+ uchar *bp, *p, *ep;
+
+ c->type = m->call->type+1;
+ c->rpc.iscall = 0;
+ c->rpc.prog = m->rpc.prog;
+ c->rpc.vers = m->rpc.vers;
+ c->rpc.proc = m->rpc.proc;
+ c->rpc.xid = m->rpc.xid;
+
+ if(m->srv->chatty){
+ fprint(2, "out: %B\n", &c->rpc);
+ fprint(2, "\t%C\n", c);
+ }
+
+ n1 = sunRpcSize(&c->rpc);
+ n2 = sunCallSize(m->pg, c);
+
+ bp = emalloc(n1+n2);
+ ep = bp+n1+n2;
+ p = bp;
+ if(sunRpcPack(p, ep, &p, &c->rpc) != SunSuccess){
+ fprint(2, "sunRpcPack failed\n");
+ return sunMsgDrop(m);
+ }
+ if(sunCallPack(m->pg, p, ep, &p, c) != SunSuccess){
+ fprint(2, "pg->pack failed\n");
+ return sunMsgDrop(m);
+ }
+ if(p != ep){
+ fprint(2, "sunMsgReply: sizes didn't work out\n");
+ return sunMsgDrop(m);
+ }
+ free(m->data);
+ m->data = bp;
+ m->count = n1+n2;
+
+ sendp(m->srv->creply, m);
+ return 0;
+}
+
+int
+sunMsgDrop(SunMsg *m)
+{
+ free(m->data);
+ free(m->call);
+ memset(m, 0xFB, sizeof *m);
+ free(m);
+ return 0;
+}
+
diff --git a/sys/src/libsunrpc/suncall.c b/sys/src/libsunrpc/suncall.c
new file mode 100755
index 000000000..fc6e3d382
--- /dev/null
+++ b/sys/src/libsunrpc/suncall.c
@@ -0,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+void
+sunCallSetup(SunCall *c, SunProg *prog, uint proc)
+{
+ c->rpc.prog = prog->prog;
+ c->rpc.vers = prog->vers;
+ c->rpc.proc = proc>>1;
+ c->rpc.iscall = !(proc&1);
+ c->type = proc;
+}
diff --git a/sys/src/libsunrpc/udp.c b/sys/src/libsunrpc/udp.c
new file mode 100755
index 000000000..8e0697c91
--- /dev/null
+++ b/sys/src/libsunrpc/udp.c
@@ -0,0 +1,113 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+typedef struct SunMsgUdp SunMsgUdp;
+struct SunMsgUdp
+{
+ SunMsg msg;
+ Udphdr udp;
+};
+
+typedef struct Arg Arg;
+struct Arg
+{
+ SunSrv *srv;
+ Channel *creply;
+ Channel *csync;
+ int fd;
+};
+
+enum
+{
+ UdpMaxRead = 65536+Udphdrsize
+};
+
+static void
+sunUdpRead(void *v)
+{
+ int n;
+ uchar *buf;
+ Arg arg = *(Arg*)v;
+ SunMsgUdp *msg;
+
+ sendp(arg.csync, 0);
+
+ buf = emalloc(UdpMaxRead);
+ while((n = read(arg.fd, buf, UdpMaxRead)) > 0){
+ if(arg.srv->chatty)
+ fprint(2, "udp got %d (%d)\n", n, Udphdrsize);
+ msg = emalloc(sizeof(SunMsgUdp));
+ memmove(&msg->udp, buf, Udphdrsize);
+ msg->msg.data = emalloc(n);
+ msg->msg.count = n-Udphdrsize;
+ memmove(msg->msg.data, buf+Udphdrsize, n-Udphdrsize);
+ memmove(&msg->udp, buf, Udphdrsize);
+ msg->msg.creply = arg.creply;
+ if(arg.srv->chatty)
+ fprint(2, "message %p count %d\n", msg, msg->msg.count);
+ sendp(arg.srv->crequest, msg);
+ }
+}
+
+static void
+sunUdpWrite(void *v)
+{
+ uchar *buf;
+ Arg arg = *(Arg*)v;
+ SunMsgUdp *msg;
+
+ sendp(arg.csync, 0);
+
+ buf = emalloc(UdpMaxRead);
+ while((msg = recvp(arg.creply)) != nil){
+ memmove(buf+Udphdrsize, msg->msg.data, msg->msg.count);
+ memmove(buf, &msg->udp, Udphdrsize);
+ msg->msg.count += Udphdrsize;
+ if(write(arg.fd, buf, msg->msg.count) != msg->msg.count)
+ fprint(2, "udpWrite: %r\n");
+ free(msg->msg.data);
+ free(msg);
+ }
+}
+
+int
+sunSrvUdp(SunSrv *srv, char *address)
+{
+ int acfd, fd;
+ char adir[40], data[60];
+ Arg *arg;
+
+ acfd = announce(address, adir);
+ if(acfd < 0)
+ return -1;
+ if(write(acfd, "headers", 7) < 0){
+ werrstr("setting headers: %r");
+ close(acfd);
+ return -1;
+ }
+ snprint(data, sizeof data, "%s/data", adir);
+ if((fd = open(data, ORDWR)) < 0){
+ werrstr("open %s: %r", data);
+ close(acfd);
+ return -1;
+ }
+ close(acfd);
+
+ arg = emalloc(sizeof(Arg));
+ arg->fd = fd;
+ arg->srv = srv;
+ arg->creply = chancreate(sizeof(SunMsg*), 10);
+ arg->csync = chancreate(sizeof(void*), 10);
+
+ proccreate(sunUdpRead, arg, SunStackSize);
+ proccreate(sunUdpWrite, arg, SunStackSize);
+ recvp(arg->csync);
+ recvp(arg->csync);
+ chanfree(arg->csync);
+ free(arg);
+
+ return 0;
+}