aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-03-21 04:33:13 +0000
committerrsc <devnull@localhost>2004-03-21 04:33:13 +0000
commit2277c5d7bbe1f9595fad512d8f790708473a9bf1 (patch)
tree4d653e13906f1971d3170dba6dbe0fbf92eb48d6 /include
parenta770daa795754cb600ad3fab2fdd2961147006c4 (diff)
downloadplan9port-2277c5d7bbe1f9595fad512d8f790708473a9bf1.tar.gz
plan9port-2277c5d7bbe1f9595fad512d8f790708473a9bf1.tar.bz2
plan9port-2277c5d7bbe1f9595fad512d8f790708473a9bf1.zip
Small tweaks
Lots of new code imported.
Diffstat (limited to 'include')
-rw-r--r--include/9p.h244
-rw-r--r--include/auth.h159
-rw-r--r--include/authsrv.h177
-rw-r--r--include/mp.h153
-rw-r--r--include/nfs3.h801
-rw-r--r--include/sunrpc.h400
6 files changed, 1934 insertions, 0 deletions
diff --git a/include/9p.h b/include/9p.h
new file mode 100644
index 00000000..6703d607
--- /dev/null
+++ b/include/9p.h
@@ -0,0 +1,244 @@
+#ifndef __9P_H__
+#define __9P_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+#pragma src "/sys/src/lib9p"
+#pragma lib "lib9p.a"
+*/
+
+/*
+ * Maps from ulongs to void*s.
+ */
+typedef struct Intmap Intmap;
+
+Intmap* allocmap(void (*inc)(void*));
+void freemap(Intmap*, void (*destroy)(void*));
+void* lookupkey(Intmap*, ulong);
+void* insertkey(Intmap*, ulong, void*);
+int caninsertkey(Intmap*, ulong, void*);
+void* deletekey(Intmap*, ulong);
+
+/*
+ * Fid and Request structures.
+ */
+typedef struct Fid Fid;
+typedef struct Req Req;
+typedef struct Fidpool Fidpool;
+typedef struct Reqpool Reqpool;
+typedef struct File File;
+typedef struct Filelist Filelist;
+typedef struct Tree Tree;
+typedef struct Readdir Readdir;
+typedef struct Srv Srv;
+
+struct Fid
+{
+ ulong fid;
+ char omode; /* -1 = not open */
+ File* file;
+ char* uid;
+ Qid qid;
+ void* aux;
+
+/* below is implementation-specific; don't use */
+ Readdir* rdir;
+ Ref ref;
+ Fidpool* pool;
+ vlong diroffset;
+ long dirindex;
+};
+
+struct Req
+{
+ ulong tag;
+ void* aux;
+ Fcall ifcall;
+ Fcall ofcall;
+ Dir d;
+ Req* oldreq;
+ Fid* fid;
+ Fid* afid;
+ Fid* newfid;
+ Srv* srv;
+
+/* below is implementation-specific; don't use */
+ QLock lk;
+ Ref ref;
+ Reqpool* pool;
+ uchar* buf;
+ uchar type;
+ uchar responded;
+ char* error;
+ void* rbuf;
+ Req** flush;
+ int nflush;
+};
+
+/*
+ * Pools to maintain Fid <-> fid and Req <-> tag maps.
+ */
+
+struct Fidpool {
+ Intmap *map;
+ void (*destroy)(Fid*);
+ Srv *srv;
+};
+
+struct Reqpool {
+ Intmap *map;
+ void (*destroy)(Req*);
+ Srv *srv;
+};
+
+Fidpool* allocfidpool(void (*destroy)(Fid*));
+void freefidpool(Fidpool*);
+Fid* allocfid(Fidpool*, ulong);
+Fid* lookupfid(Fidpool*, ulong);
+void closefid(Fid*);
+Fid* removefid(Fidpool*, ulong);
+
+Reqpool* allocreqpool(void (*destroy)(Req*));
+void freereqpool(Reqpool*);
+Req* allocreq(Reqpool*, ulong);
+Req* lookupreq(Reqpool*, ulong);
+void closereq(Req*);
+Req* removereq(Reqpool*, ulong);
+
+typedef int Dirgen(int, Dir*, void*);
+void dirread9p(Req*, Dirgen*, void*);
+
+/*
+ * File trees.
+ */
+struct File {
+ Ref ref;
+ Dir dir;
+ File *parent;
+ void *aux;
+
+/* below is implementation-specific; don't use */
+ RWLock rwlock;
+ Filelist *filelist;
+ Tree *tree;
+ int nchild;
+ int allocd;
+};
+
+struct Tree {
+ File *root;
+ void (*destroy)(File *file);
+
+/* below is implementation-specific; don't use */
+ Lock genlock;
+ ulong qidgen;
+ ulong dirqidgen;
+};
+
+Tree* alloctree(char*, char*, ulong, void(*destroy)(File*));
+void freetree(Tree*);
+File* createfile(File*, char*, char*, ulong, void*);
+int removefile(File*);
+void closefile(File*);
+File* walkfile(File*, char*);
+Readdir* opendirfile(File*);
+long readdirfile(Readdir*, uchar*, long);
+void closedirfile(Readdir*);
+
+/*
+ * Kernel-style command parser
+ */
+typedef struct Cmdbuf Cmdbuf;
+typedef struct Cmdtab Cmdtab;
+Cmdbuf* parsecmd(char *a, int n);
+void respondcmderror(Req*, Cmdbuf*, char*, ...);
+Cmdtab* lookupcmd(Cmdbuf*, Cmdtab*, int);
+/*
+#pragma varargck argpos respondcmderr 3
+*/
+struct Cmdbuf
+{
+ char *buf;
+ char **f;
+ int nf;
+};
+
+struct Cmdtab
+{
+ int index; /* used by client to switch on result */
+ char *cmd; /* command name */
+ int narg; /* expected #args; 0 ==> variadic */
+};
+
+/*
+ * File service loop.
+ */
+struct Srv {
+ Tree* tree;
+ void (*destroyfid)(Fid*);
+ void (*destroyreq)(Req*);
+ void (*end)(Srv*);
+ void* aux;
+
+ void (*attach)(Req*);
+ void (*auth)(Req*);
+ void (*open)(Req*);
+ void (*create)(Req*);
+ void (*read)(Req*);
+ void (*write)(Req*);
+ void (*remove)(Req*);
+ void (*flush)(Req*);
+ void (*stat)(Req*);
+ void (*wstat)(Req*);
+ void (*walk)(Req*);
+ char* (*clone)(Fid*, Fid*);
+ char* (*walk1)(Fid*, char*, Qid*);
+
+ int infd;
+ int outfd;
+ int nopipe;
+ int srvfd;
+ int leavefdsopen; /* magic for acme win */
+
+/* below is implementation-specific; don't use */
+ Fidpool* fpool;
+ Reqpool* rpool;
+ uint msize;
+
+ uchar* rbuf;
+ QLock rlock;
+ uchar* wbuf;
+ QLock wlock;
+};
+
+void srv(Srv*);
+void postmountsrv(Srv*, char*, char*, int);
+int postfd(char*, int);
+int chatty9p;
+void respond(Req*, char*);
+void threadpostmountsrv(Srv*, char*, char*, int);
+
+/*
+ * Helper. Assumes user is same as group.
+ */
+int hasperm(File*, char*, int);
+
+void* emalloc9p(ulong);
+void* erealloc9p(void*, ulong);
+char* estrdup9p(char*);
+
+enum {
+ OMASK = 3
+};
+
+void readstr(Req*, char*);
+void readbuf(Req*, void*, long);
+void walkandclone(Req*, char*(*walk1)(Fid*,char*,void*), char*(*clone)(Fid*,Fid*,void*), void*);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/auth.h b/include/auth.h
new file mode 100644
index 00000000..f0ecdeaf
--- /dev/null
+++ b/include/auth.h
@@ -0,0 +1,159 @@
+#ifndef __AUTH_H__
+#define __AUTH_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+#pragma src "/sys/src/libauth"
+#pragma lib "libauth.a"
+*/
+
+/*
+ * Interface for typical callers.
+ */
+
+typedef struct AuthInfo AuthInfo;
+typedef struct Chalstate Chalstate;
+typedef struct Chapreply Chapreply;
+typedef struct MSchapreply MSchapreply;
+typedef struct UserPasswd UserPasswd;
+typedef struct AuthRpc AuthRpc;
+
+enum
+{
+ MAXCHLEN= 256, /* max challenge length */
+ MAXNAMELEN= 256, /* maximum name length */
+ MD5LEN= 16,
+
+ ARok = 0, /* rpc return values */
+ ARdone,
+ ARerror,
+ ARneedkey,
+ ARbadkey,
+ ARwritenext,
+ ARtoosmall,
+ ARtoobig,
+ ARrpcfailure,
+ ARphase,
+
+ AuthRpcMax = 4096,
+};
+
+struct AuthRpc
+{
+ int afd;
+ char ibuf[AuthRpcMax];
+ char obuf[AuthRpcMax];
+ char *arg;
+ uint narg;
+};
+
+struct AuthInfo
+{
+ char *cuid; /* caller id */
+ char *suid; /* server id */
+ char *cap; /* capability (only valid on server side) */
+ int nsecret; /* length of secret */
+ uchar *secret; /* secret */
+};
+
+struct Chalstate
+{
+ char *user;
+ char chal[MAXCHLEN];
+ int nchal;
+ void *resp;
+ int nresp;
+
+/* for implementation only */
+ int afd; /* to factotum */
+ AuthRpc *rpc; /* to factotum */
+ char userbuf[MAXNAMELEN]; /* temp space if needed */
+ int userinchal; /* user was sent to obtain challenge */
+};
+
+struct Chapreply /* for protocol "chap" */
+{
+ uchar id;
+ char resp[MD5LEN];
+};
+
+struct MSchapreply /* for protocol "mschap" */
+{
+ char LMresp[24]; /* Lan Manager response */
+ char NTresp[24]; /* NT response */
+};
+
+struct UserPasswd
+{
+ char *user;
+ char *passwd;
+};
+
+extern int newns(char*, char*);
+extern int addns(char*, char*);
+
+extern int noworld(char*);
+extern int amount(int, char*, int, char*);
+
+/* these two may get generalized away -rsc */
+extern int login(char*, char*, char*);
+extern int httpauth(char*, char*);
+
+typedef struct Attr Attr;
+enum {
+ AttrNameval, /* name=val -- when matching, must have name=val */
+ AttrQuery, /* name? -- when matching, must be present */
+ AttrDefault, /* name:=val -- when matching, if present must match INTERNAL */
+};
+struct Attr
+{
+ int type;
+ Attr *next;
+ char *name;
+ char *val;
+};
+
+typedef int AuthGetkey(char*);
+
+int _attrfmt(Fmt*);
+Attr *_copyattr(Attr*);
+Attr *_delattr(Attr*, char*);
+Attr *_findattr(Attr*, char*);
+void _freeattr(Attr*);
+Attr *_mkattr(int, char*, char*, Attr*);
+Attr *_parseattr(char*);
+char *_strfindattr(Attr*, char*);
+/*
+#pragma varargck type "A" Attr*
+*/
+
+extern AuthInfo* fauth_proxy(int, AuthRpc *rpc, AuthGetkey *getkey, char *params);
+extern AuthInfo* auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...);
+extern int auth_getkey(char*);
+extern int (*amount_getkey)(char*);
+extern void auth_freeAI(AuthInfo *ai);
+extern int auth_chuid(AuthInfo *ai, char *ns);
+extern Chalstate *auth_challenge(char*, ...);
+extern AuthInfo* auth_response(Chalstate*);
+extern int auth_respond(void*, uint, char*, uint, void*, uint, AuthGetkey *getkey, char*, ...);
+extern void auth_freechal(Chalstate*);
+extern AuthInfo* auth_userpasswd(char *user, char *passwd);
+extern UserPasswd* auth_getuserpasswd(AuthGetkey *getkey, char*, ...);
+extern AuthInfo* auth_getinfo(AuthRpc *rpc);
+extern AuthRpc* auth_allocrpc(int afd);
+extern Attr* auth_attr(AuthRpc *rpc);
+extern void auth_freerpc(AuthRpc *rpc);
+extern uint auth_rpc(AuthRpc *rpc, char *verb, void *a, int n);
+extern int auth_wep(char*, char*, ...);
+/*
+#pragma varargck argpos auth_proxy 3
+#pragma varargck argpos auth_challenge 1
+#pragma varargck argpos auth_respond 3
+#pragma varargck argpos auth_getuserpasswd 2
+*/
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/authsrv.h b/include/authsrv.h
new file mode 100644
index 00000000..1149a212
--- /dev/null
+++ b/include/authsrv.h
@@ -0,0 +1,177 @@
+#ifndef __AUTHSRV_H__
+#define __AUTHSRV_H__ 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+#pragma src "/sys/src/libauthsrv"
+#pragma lib "libauthsrv.a"
+*/
+
+/*
+ * Interface for talking to authentication server.
+ */
+typedef struct Ticket Ticket;
+typedef struct Ticketreq Ticketreq;
+typedef struct Authenticator Authenticator;
+typedef struct Nvrsafe Nvrsafe;
+typedef struct Passwordreq Passwordreq;
+typedef struct OChapreply OChapreply;
+typedef struct OMSchapreply OMSchapreply;
+
+enum
+{
+ ANAMELEN= 28, /* maximum size of name in previous proto */
+ AERRLEN= 64, /* maximum size of errstr in previous proto */
+ DOMLEN= 48, /* length of an authentication domain name */
+ DESKEYLEN= 7, /* length of a des key for encrypt/decrypt */
+ CHALLEN= 8, /* length of a plan9 sk1 challenge */
+ NETCHLEN= 16, /* max network challenge length (used in AS protocol) */
+ CONFIGLEN= 14,
+ SECRETLEN= 32, /* max length of a secret */
+
+ KEYDBOFF= 8, /* length of random data at the start of key file */
+ OKEYDBLEN= ANAMELEN+DESKEYLEN+4+2, /* length of an entry in old key file */
+ KEYDBLEN= OKEYDBLEN+SECRETLEN, /* length of an entry in key file */
+ OMD5LEN= 16,
+};
+
+/* encryption numberings (anti-replay) */
+enum
+{
+ AuthTreq=1, /* ticket request */
+ AuthChal=2, /* challenge box request */
+ AuthPass=3, /* change password */
+ AuthOK=4, /* fixed length reply follows */
+ AuthErr=5, /* error follows */
+ AuthMod=6, /* modify user */
+ AuthApop=7, /* apop authentication for pop3 */
+ AuthOKvar=9, /* variable length reply follows */
+ AuthChap=10, /* chap authentication for ppp */
+ AuthMSchap=11, /* MS chap authentication for ppp */
+ AuthCram=12, /* CRAM verification for IMAP (RFC2195 & rfc2104) */
+ AuthHttp=13, /* http domain login */
+ AuthVNC=14, /* VNC server login (deprecated) */
+
+
+ AuthTs=64, /* ticket encrypted with server's key */
+ AuthTc, /* ticket encrypted with client's key */
+ AuthAs, /* server generated authenticator */
+ AuthAc, /* client generated authenticator */
+ AuthTp, /* ticket encrypted with client's key for password change */
+ AuthHr, /* http reply */
+};
+
+struct Ticketreq
+{
+ char type;
+ char authid[ANAMELEN]; /* server's encryption id */
+ char authdom[DOMLEN]; /* server's authentication domain */
+ char chal[CHALLEN]; /* challenge from server */
+ char hostid[ANAMELEN]; /* host's encryption id */
+ char uid[ANAMELEN]; /* uid of requesting user on host */
+};
+#define TICKREQLEN (3*ANAMELEN+CHALLEN+DOMLEN+1)
+
+struct Ticket
+{
+ char num; /* replay protection */
+ char chal[CHALLEN]; /* server challenge */
+ char cuid[ANAMELEN]; /* uid on client */
+ char suid[ANAMELEN]; /* uid on server */
+ char key[DESKEYLEN]; /* nonce DES key */
+};
+#define TICKETLEN (CHALLEN+2*ANAMELEN+DESKEYLEN+1)
+
+struct Authenticator
+{
+ char num; /* replay protection */
+ char chal[CHALLEN];
+ ulong id; /* authenticator id, ++'d with each auth */
+};
+#define AUTHENTLEN (CHALLEN+4+1)
+
+struct Passwordreq
+{
+ char num;
+ char old[ANAMELEN];
+ char new[ANAMELEN];
+ char changesecret;
+ char secret[SECRETLEN]; /* new secret */
+};
+#define PASSREQLEN (2*ANAMELEN+1+1+SECRETLEN)
+
+struct OChapreply
+{
+ uchar id;
+ char uid[ANAMELEN];
+ char resp[OMD5LEN];
+};
+
+struct OMSchapreply
+{
+ char uid[ANAMELEN];
+ char LMresp[24]; /* Lan Manager response */
+ char NTresp[24]; /* NT response */
+};
+
+/*
+ * convert to/from wire format
+ */
+extern int convT2M(Ticket*, char*, char*);
+extern void convM2T(char*, Ticket*, char*);
+extern void convM2Tnoenc(char*, Ticket*);
+extern int convA2M(Authenticator*, char*, char*);
+extern void convM2A(char*, Authenticator*, char*);
+extern int convTR2M(Ticketreq*, char*);
+extern void convM2TR(char*, Ticketreq*);
+extern int convPR2M(Passwordreq*, char*, char*);
+extern void convM2PR(char*, Passwordreq*, char*);
+
+/*
+ * convert ascii password to DES key
+ */
+extern int opasstokey(char*, char*);
+extern int passtokey(char*, char*);
+
+/*
+ * Nvram interface
+ */
+enum {
+ NVwrite = 1<<0, /* always prompt and rewrite nvram */
+ NVwriteonerr = 1<<1, /* prompt and rewrite nvram when corrupt */
+};
+
+struct Nvrsafe
+{
+ char machkey[DESKEYLEN];
+ uchar machsum;
+ char authkey[DESKEYLEN];
+ uchar authsum;
+ char config[CONFIGLEN];
+ uchar configsum;
+ char authid[ANAMELEN];
+ uchar authidsum;
+ char authdom[DOMLEN];
+ uchar authdomsum;
+};
+
+extern uchar nvcsum(void*, int);
+extern int readnvram(Nvrsafe*, int);
+
+/*
+ * call up auth server
+ */
+extern int authdial(char *netroot, char *authdom);
+
+/*
+ * exchange messages with auth server
+ */
+extern int _asgetticket(int, char*, char*);
+extern int _asrdresp(int, char*, int);
+extern int sslnegotiate(int, Ticket*, char**, char**);
+extern int srvsslnegotiate(int, Ticket*, char**, char**);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/mp.h b/include/mp.h
new file mode 100644
index 00000000..876c0c73
--- /dev/null
+++ b/include/mp.h
@@ -0,0 +1,153 @@
+#ifndef __MP_H__
+#define __MP_H__ 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+#pragma src "/sys/src/libmp"
+#pragma lib "libmp.a"
+*/
+
+#define _MPINT 1
+
+typedef long mpdigit;
+
+// the code assumes mpdigit to be at least an int
+// mpdigit must be an atomic type. mpdigit is defined
+// in the architecture specific u.h
+
+typedef struct mpint mpint;
+
+struct mpint
+{
+ int sign; // +1 or -1
+ int size; // allocated digits
+ int top; // significant digits
+ mpdigit *p;
+ char flags;
+};
+
+enum
+{
+ MPstatic= 0x01,
+ Dbytes= sizeof(mpdigit), // bytes per digit
+ Dbits= Dbytes*8 // bits per digit
+};
+
+// allocation
+void mpsetminbits(int n); // newly created mpint's get at least n bits
+mpint* mpnew(int n); // create a new mpint with at least n bits
+void mpfree(mpint *b);
+void mpbits(mpint *b, int n); // ensure that b has at least n bits
+void mpnorm(mpint *b); // dump leading zeros
+mpint* mpcopy(mpint *b);
+void mpassign(mpint *old, mpint *new);
+
+// random bits
+mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b);
+
+// conversion
+mpint* strtomp(char*, char**, int, mpint*); // ascii
+int mpfmt(Fmt*);
+char* mptoa(mpint*, int, char*, int);
+mpint* letomp(uchar*, uint, mpint*); // byte array, little-endian
+int mptole(mpint*, uchar*, uint, uchar**);
+mpint* betomp(uchar*, uint, mpint*); // byte array, little-endian
+int mptobe(mpint*, uchar*, uint, uchar**);
+uint mptoui(mpint*); // unsigned int
+mpint* uitomp(uint, mpint*);
+int mptoi(mpint*); // int
+mpint* itomp(int, mpint*);
+uvlong mptouv(mpint*); // unsigned vlong
+mpint* uvtomp(uvlong, mpint*);
+vlong mptov(mpint*); // vlong
+mpint* vtomp(vlong, mpint*);
+
+// divide 2 digits by one
+void mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
+
+// in the following, the result mpint may be
+// the same as one of the inputs.
+void mpadd(mpint *b1, mpint *b2, mpint *sum); // sum = b1+b2
+void mpsub(mpint *b1, mpint *b2, mpint *diff); // diff = b1-b2
+void mpleft(mpint *b, int shift, mpint *res); // res = b<<shift
+void mpright(mpint *b, int shift, mpint *res); // res = b>>shift
+void mpmul(mpint *b1, mpint *b2, mpint *prod); // prod = b1*b2
+void mpexp(mpint *b, mpint *e, mpint *m, mpint *res); // res = b**e mod m
+void mpmod(mpint *b, mpint *m, mpint *remainder); // remainder = b mod m
+
+// quotient = dividend/divisor, remainder = dividend % divisor
+void mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder);
+
+// return neg, 0, pos as b1-b2 is neg, 0, pos
+int mpcmp(mpint *b1, mpint *b2);
+
+// extended gcd return d, x, and y, s.t. d = gcd(a,b) and ax+by = d
+void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y);
+
+// res = b**-1 mod m
+void mpinvert(mpint *b, mpint *m, mpint *res);
+
+// bit counting
+int mpsignif(mpint*); // number of sigificant bits in mantissa
+int mplowbits0(mpint*); // k, where n = 2**k * q for odd q
+
+// well known constants
+extern mpint *mpzero, *mpone, *mptwo;
+
+// sum[0:alen] = a[0:alen-1] + b[0:blen-1]
+// prereq: alen >= blen, sum has room for alen+1 digits
+void mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum);
+
+// diff[0:alen-1] = a[0:alen-1] - b[0:blen-1]
+// prereq: alen >= blen, diff has room for alen digits
+void mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *diff);
+
+// p[0:n] += m * b[0:n-1]
+// prereq: p has room for n+1 digits
+void mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p);
+
+// p[0:n] -= m * b[0:n-1]
+// prereq: p has room for n+1 digits
+int mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p);
+
+// p[0:alen*blen-1] = a[0:alen-1] * b[0:blen-1]
+// prereq: alen >= blen, p has room for m*n digits
+void mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p);
+
+// sign of a - b or zero if the same
+int mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen);
+
+// divide the 2 digit dividend by the one digit divisor and stick in quotient
+// we assume that the result is one digit - overflow is all 1's
+void mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
+
+// playing with magnitudes
+int mpmagcmp(mpint *b1, mpint *b2);
+void mpmagadd(mpint *b1, mpint *b2, mpint *sum); // sum = b1+b2
+void mpmagsub(mpint *b1, mpint *b2, mpint *sum); // sum = b1+b2
+
+// chinese remainder theorem
+typedef struct CRTpre CRTpre; // precomputed values for converting
+ // twixt residues and mpint
+typedef struct CRTres CRTres; // residue form of an mpint
+
+struct CRTres
+{
+ int n; // number of residues
+ mpint *r[1]; // residues
+};
+
+CRTpre* crtpre(int, mpint**); // precompute conversion values
+CRTres* crtin(CRTpre*, mpint*); // convert mpint to residues
+void crtout(CRTpre*, CRTres*, mpint*); // convert residues to mpint
+void crtprefree(CRTpre*);
+void crtresfree(CRTres*);
+
+
+/* #pragma varargck type "B" mpint* */
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/nfs3.h b/include/nfs3.h
new file mode 100644
index 00000000..0da51b51
--- /dev/null
+++ b/include/nfs3.h
@@ -0,0 +1,801 @@
+/*
+ * NFS mounter V3; see RFC 1813
+ */
+/*
+#pragma lib "libsunrpc.a"
+#pragma src "/sys/src/libsunrpc"
+*/
+#define _NFS3H_ /* sorry */
+
+enum {
+ NfsMount1HandleSize = 32,
+ NfsMount3MaxPathSize = 1024,
+ NfsMount3MaxNameSize = 255,
+ NfsMount3MaxHandleSize = 64,
+ NfsMount3Program = 100005,
+ NfsMount3Version = 3,
+ NfsMount1Program = 100005,
+ NfsMount1Version = 1
+};
+typedef struct NfsMount3TNull NfsMount3TNull;
+typedef struct NfsMount3RNull NfsMount3RNull;
+typedef struct NfsMount3TMnt NfsMount3TMnt;
+typedef struct NfsMount3RMnt NfsMount3RMnt;
+typedef struct NfsMount3TDump NfsMount3TDump;
+typedef struct NfsMount3Entry NfsMount3Entry;
+typedef struct NfsMount3RDump NfsMount3RDump;
+typedef struct NfsMount3TUmnt NfsMount3TUmnt;
+typedef struct NfsMount3RUmnt NfsMount3RUmnt;
+typedef struct NfsMount3Export NfsMount3Export;
+typedef struct NfsMount3TUmntall NfsMount3TUmntall;
+typedef struct NfsMount3RUmntall NfsMount3RUmntall;
+typedef struct NfsMount3TExport NfsMount3TExport;
+typedef struct NfsMount3RExport NfsMount3RExport;
+
+typedef enum
+{
+ NfsMount3CallTNull,
+ NfsMount3CallRNull,
+ NfsMount3CallTMnt,
+ NfsMount3CallRMnt,
+ NfsMount3CallTDump,
+ NfsMount3CallRDump,
+ NfsMount3CallTUmnt,
+ NfsMount3CallRUmnt,
+ NfsMount3CallTUmntall,
+ NfsMount3CallRUmntall,
+ NfsMount3CallTExport,
+ NfsMount3CallRExport
+} NfsMount3CallType;
+
+struct NfsMount3TNull {
+ SunCall call;
+};
+
+struct NfsMount3RNull {
+ SunCall call;
+};
+
+struct NfsMount3TMnt {
+ SunCall call;
+ char *path;
+};
+
+struct NfsMount3RMnt {
+ SunCall call;
+ uint status;
+ uchar *handle;
+ uint len;
+ u32int *auth;
+ u32int nauth;
+};
+
+struct NfsMount3TDump {
+ SunCall call;
+};
+
+struct NfsMount3Entry {
+ char *host;
+ char *path;
+};
+
+struct NfsMount3RDump {
+ SunCall call;
+ uchar *data;
+ u32int count;
+};
+
+struct NfsMount3TUmnt {
+ SunCall call;
+ char *path;
+};
+
+struct NfsMount3RUmnt {
+ SunCall call;
+};
+
+struct NfsMount3Export {
+ char *path;
+ char **g;
+ u32int ng;
+};
+
+struct NfsMount3TUmntall {
+ SunCall call;
+};
+
+struct NfsMount3RUmntall {
+ SunCall call;
+};
+
+struct NfsMount3TExport {
+ SunCall call;
+};
+
+struct NfsMount3RExport {
+ SunCall call;
+ uchar *data;
+ u32int count;
+};
+
+uint nfsmount3exportgroupsize(uchar*);
+uint nfsmount3exportsize(NfsMount3Export*);
+int nfsmount3exportpack(uchar*, uchar*, uchar**, NfsMount3Export*);
+int nfsmount3exportunpack(uchar*, uchar*, uchar**, char**, char***, NfsMount3Export*);
+int nfsmount3entrypack(uchar*, uchar*, uchar**, NfsMount3Entry*);
+int nfsmount3entryunpack(uchar*, uchar*, uchar**, NfsMount3Entry*);
+uint nfsmount3entrysize(NfsMount3Entry*);
+
+extern SunProg nfsmount3prog;
+
+/*
+ * NFS V3; see RFC 1813
+ */
+enum {
+ Nfs3MaxHandleSize = 64,
+ Nfs3CookieVerfSize = 8,
+ Nfs3CreateVerfSize = 8,
+ Nfs3WriteVerfSize = 8,
+ Nfs3AccessRead = 1,
+ Nfs3AccessLookup = 2,
+ Nfs3AccessModify = 4,
+ Nfs3AccessExtend = 8,
+ Nfs3AccessDelete = 16,
+ Nfs3AccessExecute = 32,
+ Nfs3FsHasLinks = 1,
+ Nfs3FsHasSymlinks = 2,
+ Nfs3FsHomogeneous = 8,
+ Nfs3FsCanSetTime = 16,
+
+ Nfs3Version = 3,
+ Nfs3Program = 100003,
+};
+typedef enum
+{
+ Nfs3Ok = 0,
+ Nfs3ErrNotOwner = 1,
+ Nfs3ErrNoEnt = 2,
+ Nfs3ErrIo = 5,
+ Nfs3ErrNxio = 6,
+ Nfs3ErrNoMem = 12,
+ Nfs3ErrAcces = 13,
+ Nfs3ErrExist = 17,
+ Nfs3ErrXDev = 18,
+ Nfs3ErrNoDev = 19,
+ Nfs3ErrNotDir = 20,
+ Nfs3ErrIsDir = 21,
+ Nfs3ErrInval = 22,
+ Nfs3ErrFbig = 27,
+ Nfs3ErrNoSpc = 28,
+ Nfs3ErrRoFs = 30,
+ Nfs3ErrMLink = 31,
+ Nfs3ErrNameTooLong = 63,
+ Nfs3ErrNotEmpty = 66,
+ Nfs3ErrDQuot = 69,
+ Nfs3ErrStale = 70,
+ Nfs3ErrRemote = 71,
+ Nfs3ErrBadHandle = 10001,
+ Nfs3ErrNotSync = 10002,
+ Nfs3ErrBadCookie = 10003,
+ Nfs3ErrNotSupp = 10004,
+ Nfs3ErrTooSmall = 10005,
+ Nfs3ErrServerFault = 10006,
+ Nfs3ErrBadType = 10007,
+ Nfs3ErrJukebox = 10008,
+ Nfs3ErrFprintNotFound = 10009,
+ Nfs3ErrAborted = 10010,
+} Nfs3Status;
+
+void nfs3Errstr(Nfs3Status);
+
+typedef enum
+{
+ Nfs3FileReg = 1,
+ Nfs3FileDir = 2,
+ Nfs3FileBlock = 3,
+ Nfs3FileChar = 4,
+ Nfs3FileSymlink = 5,
+ Nfs3FileSocket = 6,
+ Nfs3FileFifo = 7,
+} Nfs3FileType;
+
+enum
+{
+ Nfs3ModeSetUid = 0x800,
+ Nfs3ModeSetGid = 0x400,
+ Nfs3ModeSticky = 0x200,
+};
+
+typedef enum
+{
+ Nfs3CallTNull,
+ Nfs3CallRNull,
+ Nfs3CallTGetattr,
+ Nfs3CallRGetattr,
+ Nfs3CallTSetattr,
+ Nfs3CallRSetattr,
+ Nfs3CallTLookup,
+ Nfs3CallRLookup,
+ Nfs3CallTAccess,
+ Nfs3CallRAccess,
+ Nfs3CallTReadlink,
+ Nfs3CallRReadlink,
+ Nfs3CallTRead,
+ Nfs3CallRRead,
+ Nfs3CallTWrite,
+ Nfs3CallRWrite,
+ Nfs3CallTCreate,
+ Nfs3CallRCreate,
+ Nfs3CallTMkdir,
+ Nfs3CallRMkdir,
+ Nfs3CallTSymlink,
+ Nfs3CallRSymlink,
+ Nfs3CallTMknod,
+ Nfs3CallRMknod,
+ Nfs3CallTRemove,
+ Nfs3CallRRemove,
+ Nfs3CallTRmdir,
+ Nfs3CallRRmdir,
+ Nfs3CallTRename,
+ Nfs3CallRRename,
+ Nfs3CallTLink,
+ Nfs3CallRLink,
+ Nfs3CallTReadDir,
+ Nfs3CallRReadDir,
+ Nfs3CallTReadDirPlus,
+ Nfs3CallRReadDirPlus,
+ Nfs3CallTFsStat,
+ Nfs3CallRFsStat,
+ Nfs3CallTFsInfo,
+ Nfs3CallRFsInfo,
+ Nfs3CallTPathconf,
+ Nfs3CallRPathconf,
+ Nfs3CallTCommit,
+ Nfs3CallRCommit,
+} Nfs3CallType;
+
+typedef struct Nfs3Handle Nfs3Handle;
+typedef struct Nfs3Time Nfs3Time;
+typedef struct Nfs3Attr Nfs3Attr;
+typedef struct Nfs3WccAttr Nfs3WccAttr;
+typedef struct Nfs3Wcc Nfs3Wcc;
+typedef enum
+{
+ Nfs3SetTimeDont = 0,
+ Nfs3SetTimeServer = 1,
+ Nfs3SetTimeClient = 2,
+} Nfs3SetTime;
+
+typedef struct Nfs3SetAttr Nfs3SetAttr;
+typedef struct Nfs3TNull Nfs3TNull;
+typedef struct Nfs3RNull Nfs3RNull;
+typedef struct Nfs3TGetattr Nfs3TGetattr;
+typedef struct Nfs3RGetattr Nfs3RGetattr;
+typedef struct Nfs3TSetattr Nfs3TSetattr;
+typedef struct Nfs3RSetattr Nfs3RSetattr;
+typedef struct Nfs3TLookup Nfs3TLookup;
+typedef struct Nfs3RLookup Nfs3RLookup;
+typedef struct Nfs3TAccess Nfs3TAccess;
+typedef struct Nfs3RAccess Nfs3RAccess;
+typedef struct Nfs3TReadlink Nfs3TReadlink;
+typedef struct Nfs3RReadlink Nfs3RReadlink;
+typedef struct Nfs3TRead Nfs3TRead;
+typedef struct Nfs3RRead Nfs3RRead;
+typedef enum
+{
+ Nfs3SyncNone = 0,
+ Nfs3SyncData = 1,
+ Nfs3SyncFile = 2,
+} Nfs3Sync;
+
+typedef struct Nfs3TWrite Nfs3TWrite;
+typedef struct Nfs3RWrite Nfs3RWrite;
+typedef enum
+{
+ Nfs3CreateUnchecked = 0,
+ Nfs3CreateGuarded = 1,
+ Nfs3CreateExclusive = 2,
+} Nfs3Create;
+
+typedef struct Nfs3TCreate Nfs3TCreate;
+typedef struct Nfs3RCreate Nfs3RCreate;
+typedef struct Nfs3TMkdir Nfs3TMkdir;
+typedef struct Nfs3RMkdir Nfs3RMkdir;
+typedef struct Nfs3TSymlink Nfs3TSymlink;
+typedef struct Nfs3RSymlink Nfs3RSymlink;
+typedef struct Nfs3TMknod Nfs3TMknod;
+typedef struct Nfs3RMknod Nfs3RMknod;
+typedef struct Nfs3TRemove Nfs3TRemove;
+typedef struct Nfs3RRemove Nfs3RRemove;
+typedef struct Nfs3TRmdir Nfs3TRmdir;
+typedef struct Nfs3RRmdir Nfs3RRmdir;
+typedef struct Nfs3TRename Nfs3TRename;
+typedef struct Nfs3RRename Nfs3RRename;
+typedef struct Nfs3TLink Nfs3TLink;
+typedef struct Nfs3RLink Nfs3RLink;
+typedef struct Nfs3TReadDir Nfs3TReadDir;
+typedef struct Nfs3Entry Nfs3Entry;
+typedef struct Nfs3RReadDir Nfs3RReadDir;
+typedef struct Nfs3TReadDirPlus Nfs3TReadDirPlus;
+typedef struct Nfs3EntryPlus Nfs3EntryPlus;
+typedef struct Nfs3RReadDirPlus Nfs3RReadDirPlus;
+typedef struct Nfs3TFsStat Nfs3TFsStat;
+typedef struct Nfs3RFsStat Nfs3RFsStat;
+typedef struct Nfs3TFsInfo Nfs3TFsInfo;
+typedef struct Nfs3RFsInfo Nfs3RFsInfo;
+typedef struct Nfs3TPathconf Nfs3TPathconf;
+typedef struct Nfs3RPathconf Nfs3RPathconf;
+typedef struct Nfs3TCommit Nfs3TCommit;
+typedef struct Nfs3RCommit Nfs3RCommit;
+
+struct Nfs3Handle {
+ uchar h[Nfs3MaxHandleSize];
+ u32int len;
+};
+
+struct Nfs3Time {
+ u32int sec;
+ u32int nsec;
+};
+
+struct Nfs3Attr {
+ Nfs3FileType type;
+ u32int mode;
+ u32int nlink;
+ u32int uid;
+ u32int gid;
+ u64int size;
+ u64int used;
+ u32int major;
+ u32int minor;
+ u64int fsid;
+ u64int fileid;
+ Nfs3Time atime;
+ Nfs3Time mtime;
+ Nfs3Time ctime;
+};
+
+struct Nfs3WccAttr {
+ u64int size;
+ Nfs3Time mtime;
+ Nfs3Time ctime;
+};
+
+struct Nfs3Wcc {
+ u1int haveWccAttr;
+ Nfs3WccAttr wccAttr;
+ u1int haveAttr;
+ Nfs3Attr attr;
+};
+
+struct Nfs3SetAttr {
+ u1int setMode;
+ u32int mode;
+ u1int setUid;
+ u32int uid;
+ u1int setGid;
+ u32int gid;
+ u1int setSize;
+ u64int size;
+ Nfs3SetTime setAtime;
+ Nfs3Time atime;
+ Nfs3SetTime setMtime;
+ Nfs3Time mtime;
+};
+
+struct Nfs3TNull {
+ SunCall call;
+};
+
+struct Nfs3RNull {
+ SunCall call;
+};
+
+struct Nfs3TGetattr {
+ SunCall call;
+ Nfs3Handle handle;
+};
+
+struct Nfs3RGetattr {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Attr attr;
+};
+
+struct Nfs3TSetattr {
+ SunCall call;
+ Nfs3Handle handle;
+ Nfs3SetAttr attr;
+ u1int checkCtime;
+ Nfs3Time ctime;
+};
+
+struct Nfs3RSetattr {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Wcc wcc;
+};
+
+struct Nfs3TLookup {
+ SunCall call;
+ Nfs3Handle handle;
+ char *name;
+};
+
+struct Nfs3RLookup {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Handle handle;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ u1int haveDirAttr;
+ Nfs3Attr dirAttr;
+};
+
+struct Nfs3TAccess {
+ SunCall call;
+ Nfs3Handle handle;
+ u32int access;
+};
+
+struct Nfs3RAccess {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ u32int access;
+};
+
+struct Nfs3TReadlink {
+ SunCall call;
+ Nfs3Handle handle;
+};
+
+struct Nfs3RReadlink {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ char *data;
+};
+
+struct Nfs3TRead {
+ SunCall call;
+ Nfs3Handle handle;
+ u64int offset;
+ u32int count;
+};
+
+struct Nfs3RRead {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ u32int count;
+ u1int eof;
+ uchar *data;
+ u32int ndata;
+};
+
+struct Nfs3TWrite {
+ SunCall call;
+ Nfs3Handle handle;
+ u64int offset;
+ u32int count;
+ Nfs3Sync stable;
+ uchar *data;
+ u32int ndata;
+};
+
+struct Nfs3RWrite {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Wcc wcc;
+ u32int count;
+ Nfs3Sync committed;
+ uchar verf[Nfs3WriteVerfSize];
+};
+
+struct Nfs3TCreate {
+ SunCall call;
+ Nfs3Handle handle;
+ char *name;
+ Nfs3Create mode;
+ Nfs3SetAttr attr;
+ uchar verf[Nfs3CreateVerfSize];
+};
+
+struct Nfs3RCreate {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveHandle;
+ Nfs3Handle handle;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ Nfs3Wcc dirWcc;
+};
+
+struct Nfs3TMkdir {
+ SunCall call;
+ Nfs3Handle handle;
+ char *name;
+ Nfs3SetAttr attr;
+};
+
+struct Nfs3RMkdir {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveHandle;
+ Nfs3Handle handle;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ Nfs3Wcc dirWcc;
+};
+
+struct Nfs3TSymlink {
+ SunCall call;
+ Nfs3Handle handle;
+ char *name;
+ Nfs3SetAttr attr;
+ char *data;
+};
+
+struct Nfs3RSymlink {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveHandle;
+ Nfs3Handle handle;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ Nfs3Wcc dirWcc;
+};
+
+struct Nfs3TMknod {
+ SunCall call;
+ Nfs3Handle handle;
+ char *name;
+ Nfs3FileType type;
+ Nfs3SetAttr attr;
+ u32int major;
+ u32int minor;
+};
+
+struct Nfs3RMknod {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveHandle;
+ Nfs3Handle handle;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ Nfs3Wcc dirWcc;
+};
+
+struct Nfs3TRemove {
+ SunCall call;
+ Nfs3Handle handle;
+ char *name;
+};
+
+struct Nfs3RRemove {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Wcc wcc;
+};
+
+struct Nfs3TRmdir {
+ SunCall call;
+ Nfs3Handle handle;
+ char *name;
+};
+
+struct Nfs3RRmdir {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Wcc wcc;
+};
+
+struct Nfs3TRename {
+ SunCall call;
+ struct {
+ Nfs3Handle handle;
+ char *name;
+ } from;
+ struct {
+ Nfs3Handle handle;
+ char *name;
+ } to;
+};
+
+struct Nfs3RRename {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Wcc fromWcc;
+ Nfs3Wcc toWcc;
+};
+
+struct Nfs3TLink {
+ SunCall call;
+ Nfs3Handle handle;
+ struct {
+ Nfs3Handle handle;
+ char *name;
+ } link;
+};
+
+struct Nfs3RLink {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ Nfs3Wcc dirWcc;
+};
+
+struct Nfs3TReadDir {
+ SunCall call;
+ Nfs3Handle handle;
+ u64int cookie;
+ uchar verf[Nfs3CookieVerfSize];
+ u32int count;
+};
+
+struct Nfs3RReadDir {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ uchar verf[Nfs3CookieVerfSize];
+ uchar *data;
+ u32int count;
+ u1int eof;
+};
+
+struct Nfs3TReadDirPlus {
+ SunCall call;
+ Nfs3Handle handle;
+ u64int cookie;
+ uchar verf[Nfs3CookieVerfSize];
+ u32int dirCount;
+ u32int maxCount;
+};
+
+struct Nfs3Entry {
+ u64int fileid;
+ char *name;
+ u64int cookie;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ u1int haveHandle;
+ Nfs3Handle handle;
+};
+
+struct Nfs3RReadDirPlus {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ uchar verf[Nfs3CookieVerfSize];
+ uchar *data;
+ u32int count;
+ u1int eof;
+};
+
+struct Nfs3TFsStat {
+ SunCall call;
+ Nfs3Handle handle;
+};
+
+struct Nfs3RFsStat {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ u64int totalBytes;
+ u64int freeBytes;
+ u64int availBytes;
+ u64int totalFiles;
+ u64int freeFiles;
+ u64int availFiles;
+ u32int invarSec;
+};
+
+struct Nfs3TFsInfo {
+ SunCall call;
+ Nfs3Handle handle;
+};
+
+struct Nfs3RFsInfo {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ u32int readMax;
+ u32int readPref;
+ u32int readMult;
+ u32int writeMax;
+ u32int writePref;
+ u32int writeMult;
+ u32int readDirPref;
+ u64int maxFileSize;
+ Nfs3Time timePrec;
+ u32int flags;
+};
+
+struct Nfs3TPathconf {
+ SunCall call;
+ Nfs3Handle handle;
+};
+
+struct Nfs3RPathconf {
+ SunCall call;
+ Nfs3Status status;
+ u1int haveAttr;
+ Nfs3Attr attr;
+ u32int maxLink;
+ u32int maxName;
+ u1int noTrunc;
+ u1int chownRestricted;
+ u1int caseInsensitive;
+ u1int casePreserving;
+};
+
+struct Nfs3TCommit {
+ SunCall call;
+ Nfs3Handle handle;
+ u64int offset;
+ u32int count;
+};
+
+struct Nfs3RCommit {
+ SunCall call;
+ Nfs3Status status;
+ Nfs3Wcc wcc;
+ uchar verf[Nfs3WriteVerfSize];
+};
+
+char *nfs3statusstr(Nfs3Status);
+char *nfs3typestr(SunCallType);
+char *nfs3settimestr(Nfs3SetTime);
+char *nfs3syncstr(Nfs3Sync);
+
+void nfs3handleprint(Fmt*, Nfs3Handle*);
+u32int nfs3handlesize(Nfs3Handle*);
+int nfs3handlepack(uchar*, uchar*, uchar**, Nfs3Handle*);
+int nfs3handleunpack(uchar*, uchar*, uchar**, Nfs3Handle*);
+
+void nfs3timeprint(Fmt*, Nfs3Time*);
+u32int nfs3timesize(Nfs3Time*);
+int nfs3timepack(uchar*, uchar*, uchar**, Nfs3Time*);
+int nfs3timeunpack(uchar*, uchar*, uchar**, Nfs3Time*);
+
+void nfs3attrprint(Fmt*, Nfs3Attr*);
+u32int nfs3attrsize(Nfs3Attr*);
+int nfs3attrpack(uchar*, uchar*, uchar**, Nfs3Attr*);
+int nfs3attrunpack(uchar*, uchar*, uchar**, Nfs3Attr*);
+
+void nfs3wccattrprint(Fmt*, Nfs3WccAttr*);
+u32int nfs3wccattrsize(Nfs3WccAttr*);
+int nfs3wccattrpack(uchar*, uchar*, uchar**, Nfs3WccAttr*);
+int nfs3wccattrunpack(uchar*, uchar*, uchar**, Nfs3WccAttr*);
+
+void nfs3wccprint(Fmt*, Nfs3Wcc*);
+u32int nfs3wccsize(Nfs3Wcc*);
+int nfs3wccpack(uchar*, uchar*, uchar**, Nfs3Wcc*);
+int nfs3wccunpack(uchar*, uchar*, uchar**, Nfs3Wcc*);
+
+void nfs3setattrprint(Fmt*, Nfs3SetAttr*);
+u32int nfs3setattrsize(Nfs3SetAttr*);
+int nfs3setattrpack(uchar*, uchar*, uchar**, Nfs3SetAttr*);
+int nfs3setattrunpack(uchar*, uchar*, uchar**, Nfs3SetAttr*);
+
+extern SunProg nfs3prog;
+
+void nfs3entryprint(Fmt*, Nfs3Entry*);
+u32int nfs3entrysize(Nfs3Entry*);
+int nfs3entrypack(uchar*, uchar*, uchar**, Nfs3Entry*);
+int nfs3entryunpack(uchar*, uchar*, uchar**, Nfs3Entry*);
+
+void nfs3entryplusprint(Fmt*, Nfs3Entry*);
+u32int nfs3entryplussize(Nfs3Entry*);
+int nfs3entrypluspack(uchar*, uchar*, uchar**, Nfs3Entry*);
+int nfs3entryplusunpack(uchar*, uchar*, uchar**, Nfs3Entry*);
+
diff --git a/include/sunrpc.h b/include/sunrpc.h
new file mode 100644
index 00000000..4f108aa0
--- /dev/null
+++ b/include/sunrpc.h
@@ -0,0 +1,400 @@
+/*
+ * Sun RPC; see RFC 1057
+ */
+
+/*
+#pragma lib "libsunrpc.a"
+#pragma src "/sys/src/libsunrpc"
+*/
+
+typedef uchar u1int;
+
+typedef struct SunAuthInfo SunAuthInfo;
+typedef struct SunAuthUnix SunAuthUnix;
+typedef struct SunRpc SunRpc;
+typedef struct SunCall SunCall;
+
+enum
+{
+ /* Authinfo.flavor */
+ SunAuthNone = 0,
+ SunAuthSys,
+ SunAuthShort,
+ SunAuthDes,
+};
+
+typedef enum {
+ SunAcceptError = 0x10000,
+ SunRejectError = 0x20000,
+ SunAuthError = 0x40000,
+
+ /* Reply.status */
+ SunSuccess = 0,
+
+ SunProgUnavail = SunAcceptError | 1,
+ SunProgMismatch,
+ SunProcUnavail,
+ SunGarbageArgs,
+ SunSystemErr,
+
+ SunRpcMismatch = SunRejectError | 0,
+
+ SunAuthBadCred = SunAuthError | 1,
+ SunAuthRejectedCred,
+ SunAuthBadVerf,
+ SunAuthRejectedVerf,
+ SunAuthTooWeak,
+ SunAuthInvalidResp,
+ SunAuthFailed,
+} SunStatus;
+
+struct SunAuthInfo
+{
+ uint flavor;
+ uchar *data;
+ uint ndata;
+};
+
+struct SunAuthUnix
+{
+ u32int stamp;
+ char *sysname;
+ u32int uid;
+ u32int gid;
+ u32int g[16];
+ u32int ng;
+};
+
+struct SunRpc
+{
+ u32int xid;
+ uint iscall;
+
+ /*
+ * only sent on wire in call
+ * caller fills in for the reply unpackers.
+ */
+ u32int proc;
+
+ /* call */
+ // uint proc;
+ u32int prog, vers;
+ SunAuthInfo cred;
+ SunAuthInfo verf;
+ uchar *data;
+ uint ndata;
+
+ /* reply */
+ u32int status;
+ // SunAuthInfo verf;
+ u32int low, high;
+ // uchar *data;
+ // uint ndata;
+};
+
+typedef enum
+{
+ SunCallTypeTNull,
+ SunCallTypeRNull,
+} SunCallType;
+
+struct SunCall
+{
+ SunRpc rpc;
+ SunCallType type;
+};
+
+void sunerrstr(SunStatus);
+
+void sunrpcprint(Fmt*, SunRpc*);
+uint sunrpcsize(SunRpc*);
+SunStatus sunrpcpack(uchar*, uchar*, uchar**, SunRpc*);
+SunStatus sunrpcunpack(uchar*, uchar*, uchar**, SunRpc*);
+
+void sunauthinfoprint(Fmt*, SunAuthInfo*);
+uint sunauthinfosize(SunAuthInfo*);
+int sunauthinfopack(uchar*, uchar*, uchar**, SunAuthInfo*);
+int sunauthinfounpack(uchar*, uchar*, uchar**, SunAuthInfo*);
+
+void sunauthunixprint(Fmt*, SunAuthUnix*);
+uint sunauthunixsize(SunAuthUnix*);
+int sunauthunixpack(uchar*, uchar*, uchar**, SunAuthUnix*);
+int sunauthunixunpack(uchar*, uchar*, uchar**, SunAuthUnix*);
+
+int sunenumpack(uchar*, uchar*, uchar**, int*);
+int sunenumunpack(uchar*, uchar*, uchar**, int*);
+int sunuint1pack(uchar*, uchar*, uchar**, u1int*);
+int sunuint1unpack(uchar*, uchar*, uchar**, u1int*);
+
+int sunstringpack(uchar*, uchar*, uchar**, char**, u32int);
+int sunstringunpack(uchar*, uchar*, uchar**, char**, u32int);
+uint sunstringsize(char*);
+
+int sunuint32pack(uchar*, uchar*, uchar**, u32int*);
+int sunuint32unpack(uchar*, uchar*, uchar**, u32int*);
+int sunuint64pack(uchar*, uchar*, uchar**, u64int*);
+int sunuint64unpack(uchar*, uchar*, uchar**, u64int*);
+
+int sunvaropaquepack(uchar*, uchar*, uchar**, uchar**, u32int*, u32int);
+int sunvaropaqueunpack(uchar*, uchar*, uchar**, uchar**, u32int*, u32int);
+uint sunvaropaquesize(u32int);
+
+int sunfixedopaquepack(uchar*, uchar*, uchar**, uchar*, u32int);
+int sunfixedopaqueunpack(uchar*, uchar*, uchar**, uchar*, u32int);
+uint sunfixedopaquesize(u32int);
+
+/*
+ * Sun RPC Program
+ */
+typedef struct SunProc SunProc;
+typedef struct SunProg SunProg;
+struct SunProg
+{
+ uint prog;
+ uint vers;
+ SunProc *proc;
+ int nproc;
+};
+
+struct SunProc
+{
+ int (*pack)(uchar*, uchar*, uchar**, SunCall*);
+ int (*unpack)(uchar*, uchar*, uchar**, SunCall*);
+ uint (*size)(SunCall*);
+ void (*fmt)(Fmt*, SunCall*);
+ uint sizeoftype;
+};
+
+SunStatus suncallpack(SunProg*, uchar*, uchar*, uchar**, SunCall*);
+SunStatus suncallunpack(SunProg*, uchar*, uchar*, uchar**, SunCall*);
+SunStatus suncallunpackalloc(SunProg*, SunCallType, uchar*, uchar*, uchar**, SunCall**);
+void suncallsetup(SunCall*, SunProg*, uint);
+uint suncallsize(SunProg*, SunCall*);
+
+/*
+ * Formatting
+#pragma varargck type "B" SunRpc*
+#pragma varargck type "C" SunCall*
+ */
+
+int sunrpcfmt(Fmt*);
+int suncallfmt(Fmt*);
+void sunfmtinstall(SunProg*);
+
+
+/*
+ * Sun RPC Server
+ */
+typedef struct SunMsg SunMsg;
+typedef struct SunSrv SunSrv;
+
+enum
+{
+ SunStackSize = 32768,
+};
+
+struct SunMsg
+{
+ uchar *data;
+ int count;
+ SunSrv *srv;
+ SunRpc rpc;
+ SunProg *pg;
+ SunCall *call;
+ Channel *creply; /* chan(SunMsg*) */
+};
+
+struct SunSrv
+{
+ int chatty;
+ int cachereplies;
+ int alwaysreject;
+ int localonly;
+ int localparanoia;
+ SunProg **map;
+ Channel *crequest;
+
+/* implementation use only */
+ Channel **cdispatch;
+ SunProg **prog;
+ int nprog;
+ void *cache;
+ Channel *creply;
+ Channel *cthread;
+};
+
+SunSrv *sunsrv(void);
+
+void sunsrvprog(SunSrv *srv, SunProg *prog, Channel *c);
+int sunsrvannounce(SunSrv *srv, char *address);
+int sunsrvudp(SunSrv *srv, char *address);
+int sunsrvnet(SunSrv *srv, char *address);
+int sunsrvfd(SunSrv *srv, int fd);
+void sunsrvthreadcreate(SunSrv *srv, void (*fn)(void*), void*);
+void sunsrvclose(SunSrv*);
+
+int sunmsgreply(SunMsg*, SunCall*);
+int sunmsgdrop(SunMsg*);
+int sunmsgreplyerror(SunMsg*, SunStatus);
+
+/*
+ * Sun RPC Client
+ */
+typedef struct SunClient SunClient;
+
+struct SunClient
+{
+ int fd;
+ int chatty;
+ int needcount;
+ ulong maxwait;
+ ulong xidgen;
+ int nsend;
+ int nresend;
+ struct {
+ ulong min;
+ ulong max;
+ ulong avg;
+ } rtt;
+ Channel *dying;
+ Channel *rpcchan;
+ Channel *timerchan;
+ Channel *flushchan;
+ Channel *readchan;
+ SunProg **prog;
+ int nprog;
+ int timertid;
+ int nettid;
+};
+
+SunClient *sundial(char*);
+
+int sunclientrpc(SunClient*, ulong, SunCall*, SunCall*, uchar**);
+void sunclientclose(SunClient*);
+void sunclientflushrpc(SunClient*, ulong);
+void sunclientprog(SunClient*, SunProg*);
+
+
+/*
+ * Provided by callers.
+ * Should remove dependence on this, but hard.
+ */
+void *emalloc(ulong);
+void *erealloc(void*, ulong);
+
+
+/*
+ * Sun RPC port mapper; see RFC 1057 Appendix A
+ */
+
+typedef struct PortMap PortMap;
+typedef struct PortTNull PortTNull;
+typedef struct PortRNull PortRNull;
+typedef struct PortTSet PortTSet;
+typedef struct PortRSet PortRSet;
+typedef struct PortTUnset PortTUnset;
+typedef struct PortRUnset PortRUnset;
+typedef struct PortTGetport PortTGetport;
+typedef struct PortRGetport PortRGetport;
+typedef struct PortTDump PortTDump;
+typedef struct PortRDump PortRDump;
+typedef struct PortTCallit PortTCallit;
+typedef struct PortRCallit PortRCallit;
+
+typedef enum
+{
+ PortCallTNull,
+ PortCallRNull,
+ PortCallTSet,
+ PortCallRSet,
+ PortCallTUnset,
+ PortCallRUnset,
+ PortCallTGetport,
+ PortCallRGetport,
+ PortCallTDump,
+ PortCallRDump,
+ PortCallTCallit,
+ PortCallRCallit,
+} PortCallType;
+
+enum
+{
+ PortProgram = 100000,
+ PortVersion = 2,
+
+ PortProtoTcp = 6, /* protocol number for TCP/IP */
+ PortProtoUdp = 17 /* protocol number for UDP/IP */
+};
+
+struct PortMap {
+ u32int prog;
+ u32int vers;
+ u32int prot;
+ u32int port;
+};
+
+struct PortTNull {
+ SunCall call;
+};
+
+struct PortRNull {
+ SunCall call;
+};
+
+struct PortTSet {
+ SunCall call;
+ PortMap map;
+};
+
+struct PortRSet {
+ SunCall call;
+ u1int b;
+};
+
+struct PortTUnset {
+ SunCall call;
+ PortMap map;
+};
+
+struct PortRUnset {
+ SunCall call;
+ u1int b;
+};
+
+struct PortTGetport {
+ SunCall call;
+ PortMap map;
+};
+
+struct PortRGetport {
+ SunCall call;
+ u32int port;
+};
+
+struct PortTDump {
+ SunCall call;
+};
+
+struct PortRDump {
+ SunCall call;
+ PortMap *map;
+ int nmap;
+};
+
+struct PortTCallit {
+ SunCall call;
+ u32int prog;
+ u32int vers;
+ u32int proc;
+ uchar *data;
+ u32int count;
+};
+
+struct PortRCallit {
+ SunCall call;
+ u32int port;
+ uchar *data;
+ u32int count;
+};
+
+extern SunProg portprog;