entered into RCS
authorroland <roland>
Sun, 6 Feb 1994 21:42:41 +0000 (21:42 +0000)
committerroland <roland>
Sun, 6 Feb 1994 21:42:41 +0000 (21:42 +0000)
44 files changed:
sunrpc/auth_none.c [new file with mode: 0644]
sunrpc/auth_unix.c [new file with mode: 0644]
sunrpc/authuxprot.c [new file with mode: 0644]
sunrpc/bindrsvprt.c [new file with mode: 0644]
sunrpc/clnt_gen.c [new file with mode: 0644]
sunrpc/clnt_raw.c [new file with mode: 0644]
sunrpc/clnt_simp.c [new file with mode: 0644]
sunrpc/clnt_tcp.c [new file with mode: 0644]
sunrpc/clnt_udp.c [new file with mode: 0644]
sunrpc/getrpcport.c [new file with mode: 0644]
sunrpc/pm_getmaps.c [new file with mode: 0644]
sunrpc/pm_getport.c [new file with mode: 0644]
sunrpc/pmap_clnt.c [new file with mode: 0644]
sunrpc/pmap_prot.c [new file with mode: 0644]
sunrpc/pmap_prot2.c [new file with mode: 0644]
sunrpc/rpc/auth_unix.h [new file with mode: 0644]
sunrpc/rpc/clnt.h [new file with mode: 0644]
sunrpc/rpc/pmap_clnt.h [new file with mode: 0644]
sunrpc/rpc/pmap_prot.h [new file with mode: 0644]
sunrpc/rpc/pmap_rmt.h [new file with mode: 0644]
sunrpc/rpc/rpc.h [new file with mode: 0644]
sunrpc/rpc/rpc_msg.h [new file with mode: 0644]
sunrpc/rpc/svc.h [new file with mode: 0644]
sunrpc/rpc/svc_auth.h [new file with mode: 0644]
sunrpc/rpc/types.h [new file with mode: 0644]
sunrpc/rpc/xdr.h [new file with mode: 0644]
sunrpc/rpc_cmsg.c [new file with mode: 0644]
sunrpc/rpc_common.c [new file with mode: 0644]
sunrpc/rpc_dtable.c [new file with mode: 0644]
sunrpc/rpc_prot.c [new file with mode: 0644]
sunrpc/svc.c [new file with mode: 0644]
sunrpc/svc_auth.c [new file with mode: 0644]
sunrpc/svc_authux.c [new file with mode: 0644]
sunrpc/svc_raw.c [new file with mode: 0644]
sunrpc/svc_run.c [new file with mode: 0644]
sunrpc/svc_simple.c [new file with mode: 0644]
sunrpc/svc_tcp.c [new file with mode: 0644]
sunrpc/svc_udp.c [new file with mode: 0644]
sunrpc/xdr.c [new file with mode: 0644]
sunrpc/xdr_array.c [new file with mode: 0644]
sunrpc/xdr_mem.c [new file with mode: 0644]
sunrpc/xdr_rec.c [new file with mode: 0644]
sunrpc/xdr_ref.c [new file with mode: 0644]
sunrpc/xdr_stdio.c [new file with mode: 0644]

diff --git a/sunrpc/auth_none.c b/sunrpc/auth_none.c
new file mode 100644 (file)
index 0000000..630037f
--- /dev/null
@@ -0,0 +1,133 @@
+/* @(#)auth_none.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null" 
+ * credentials and verifiers to remote systems. 
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc. 
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#define MAX_MARSHEL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+static void    authnone_verf();
+static void    authnone_destroy();
+static bool_t  authnone_marshal();
+static bool_t  authnone_validate();
+static bool_t  authnone_refresh();
+
+static struct auth_ops ops = {
+       authnone_verf,
+       authnone_marshal,
+       authnone_validate,
+       authnone_refresh,
+       authnone_destroy
+};
+
+static struct authnone_private {
+       AUTH    no_client;
+       char    marshalled_client[MAX_MARSHEL_SIZE];
+       u_int   mcnt;
+} *authnone_private;
+
+AUTH *
+authnone_create()
+{
+       register struct authnone_private *ap = authnone_private;
+       XDR xdr_stream;
+       register XDR *xdrs;
+
+       if (ap == 0) {
+               ap = (struct authnone_private *)calloc(1, sizeof (*ap));
+               if (ap == 0)
+                       return (0);
+               authnone_private = ap;
+       }
+       if (!ap->mcnt) {
+               ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+               ap->no_client.ah_ops = &ops;
+               xdrs = &xdr_stream;
+               xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE,
+                   XDR_ENCODE);
+               (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+               (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+               ap->mcnt = XDR_GETPOS(xdrs);
+               XDR_DESTROY(xdrs);
+       }
+       return (&ap->no_client);
+}
+
+/*ARGSUSED*/
+static bool_t
+authnone_marshal(client, xdrs)
+       AUTH *client;
+       XDR *xdrs;
+{
+       register struct authnone_private *ap = authnone_private;
+
+       if (ap == 0)
+               return (0);
+       return ((*xdrs->x_ops->x_putbytes)(xdrs,
+           ap->marshalled_client, ap->mcnt));
+}
+
+static void 
+authnone_verf()
+{
+}
+
+static bool_t
+authnone_validate()
+{
+
+       return (TRUE);
+}
+
+static bool_t
+authnone_refresh()
+{
+
+       return (FALSE);
+}
+
+static void
+authnone_destroy()
+{
+}
diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
new file mode 100644 (file)
index 0000000..87ff2b6
--- /dev/null
@@ -0,0 +1,319 @@
+/* @(#)auth_unix.c     2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters. 
+ *  
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The system is very weak.  The client uses no encryption for it's
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ *
+ */
+
+#include <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * Unix authenticator operations vector
+ */
+static void    authunix_nextverf();
+static bool_t  authunix_marshal();
+static bool_t  authunix_validate();
+static bool_t  authunix_refresh();
+static void    authunix_destroy();
+
+static struct auth_ops auth_unix_ops = {
+       authunix_nextverf,
+       authunix_marshal,
+       authunix_validate,
+       authunix_refresh,
+       authunix_destroy
+};
+
+/*
+ * This struct is pointed to by the ah_private field of an auth_handle.
+ */
+struct audata {
+       struct opaque_auth      au_origcred;    /* original credentials */
+       struct opaque_auth      au_shcred;      /* short hand cred */
+       u_long                  au_shfaults;    /* short hand cache faults */
+       char                    au_marshed[MAX_AUTH_BYTES];
+       u_int                   au_mpos;        /* xdr pos at end of marshed */
+};
+#define        AUTH_PRIVATE(auth)      ((struct audata *)auth->ah_private)
+
+static bool_t marshal_new_auth();
+
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+AUTH *
+authunix_create(machname, uid, gid, len, aup_gids)
+       char *machname;
+       int uid;
+       int gid;
+       register int len;
+       int *aup_gids;
+{
+       struct authunix_parms aup;
+       char mymem[MAX_AUTH_BYTES];
+       struct timeval now;
+       XDR xdrs;
+       register AUTH *auth;
+       register struct audata *au;
+
+       /*
+        * Allocate and set up auth handle
+        */
+       auth = (AUTH *)mem_alloc(sizeof(*auth));
+#ifndef KERNEL
+       if (auth == NULL) {
+               (void)fprintf(stderr, "authunix_create: out of memory\n");
+               return (NULL);
+       }
+#endif
+       au = (struct audata *)mem_alloc(sizeof(*au));
+#ifndef KERNEL
+       if (au == NULL) {
+               (void)fprintf(stderr, "authunix_create: out of memory\n");
+               return (NULL);
+       }
+#endif
+       auth->ah_ops = &auth_unix_ops;
+       auth->ah_private = (caddr_t)au;
+       auth->ah_verf = au->au_shcred = _null_auth;
+       au->au_shfaults = 0;
+
+       /*
+        * fill in param struct from the given params
+        */
+       (void)gettimeofday(&now,  (struct timezone *)0);
+       aup.aup_time = now.tv_sec;
+       aup.aup_machname = machname;
+       aup.aup_uid = uid;
+       aup.aup_gid = gid;
+       aup.aup_len = (u_int)len;
+       aup.aup_gids = aup_gids;
+
+       /*
+        * Serialize the parameters into origcred
+        */
+       xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
+       if (! xdr_authunix_parms(&xdrs, &aup)) 
+               abort();
+       au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
+       au->au_origcred.oa_flavor = AUTH_UNIX;
+#ifdef KERNEL
+       au->au_origcred.oa_base = mem_alloc((u_int) len);
+#else
+       if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
+               (void)fprintf(stderr, "authunix_create: out of memory\n");
+               return (NULL);
+       }
+#endif
+       bcopy(mymem, au->au_origcred.oa_base, (u_int)len);
+
+       /*
+        * set auth handle to reflect new cred.
+        */
+       auth->ah_cred = au->au_origcred;
+       marshal_new_auth(auth);
+       return (auth);
+}
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default()
+{
+       register int len;
+       char machname[MAX_MACHINE_NAME + 1];
+       register int uid;
+       register int gid;
+       int gids[NGRPS];
+
+       if (gethostname(machname, MAX_MACHINE_NAME) == -1)
+               abort();
+       machname[MAX_MACHINE_NAME] = 0;
+       uid = geteuid();
+       gid = getegid();
+       if ((len = getgroups(NGRPS, gids)) < 0)
+               abort();
+       return (authunix_create(machname, uid, gid, len, gids));
+}
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf(auth)
+       AUTH *auth;
+{
+       /* no action necessary */
+}
+
+static bool_t
+authunix_marshal(auth, xdrs)
+       AUTH *auth;
+       XDR *xdrs;
+{
+       register struct audata *au = AUTH_PRIVATE(auth);
+
+       return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
+}
+
+static bool_t
+authunix_validate(auth, verf)
+       register AUTH *auth;
+       struct opaque_auth verf;
+{
+       register struct audata *au;
+       XDR xdrs;
+
+       if (verf.oa_flavor == AUTH_SHORT) {
+               au = AUTH_PRIVATE(auth);
+               xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
+
+               if (au->au_shcred.oa_base != NULL) {
+                       mem_free(au->au_shcred.oa_base,
+                           au->au_shcred.oa_length);
+                       au->au_shcred.oa_base = NULL;
+               }
+               if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
+                       auth->ah_cred = au->au_shcred;
+               } else {
+                       xdrs.x_op = XDR_FREE;
+                       (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
+                       au->au_shcred.oa_base = NULL;
+                       auth->ah_cred = au->au_origcred;
+               }
+               marshal_new_auth(auth);
+       }
+       return (TRUE);
+}
+
+static bool_t
+authunix_refresh(auth)
+       register AUTH *auth;
+{
+       register struct audata *au = AUTH_PRIVATE(auth);
+       struct authunix_parms aup;
+       struct timeval now;
+       XDR xdrs;
+       register int stat;
+
+       if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
+               /* there is no hope.  Punt */
+               return (FALSE);
+       }
+       au->au_shfaults ++;
+
+       /* first deserialize the creds back into a struct authunix_parms */
+       aup.aup_machname = NULL;
+       aup.aup_gids = (int *)NULL;
+       xdrmem_create(&xdrs, au->au_origcred.oa_base,
+           au->au_origcred.oa_length, XDR_DECODE);
+       stat = xdr_authunix_parms(&xdrs, &aup);
+       if (! stat) 
+               goto done;
+
+       /* update the time and serialize in place */
+       (void)gettimeofday(&now, (struct timezone *)0);
+       aup.aup_time = now.tv_sec;
+       xdrs.x_op = XDR_ENCODE;
+       XDR_SETPOS(&xdrs, 0);
+       stat = xdr_authunix_parms(&xdrs, &aup);
+       if (! stat)
+               goto done;
+       auth->ah_cred = au->au_origcred;
+       marshal_new_auth(auth);
+done:
+       /* free the struct authunix_parms created by deserializing */
+       xdrs.x_op = XDR_FREE;
+       (void)xdr_authunix_parms(&xdrs, &aup);
+       XDR_DESTROY(&xdrs);
+       return (stat);
+}
+
+static void
+authunix_destroy(auth)
+       register AUTH *auth;
+{
+       register struct audata *au = AUTH_PRIVATE(auth);
+
+       mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
+
+       if (au->au_shcred.oa_base != NULL)
+               mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
+
+       mem_free(auth->ah_private, sizeof(struct audata));
+
+       if (auth->ah_verf.oa_base != NULL)
+               mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
+
+       mem_free((caddr_t)auth, sizeof(*auth));
+}
+
+/*
+ * Marshals (pre-serializes) an auth struct.
+ * sets private data, au_marshed and au_mpos
+ */
+static bool_t
+marshal_new_auth(auth)
+       register AUTH *auth;
+{
+       XDR             xdr_stream;
+       register XDR    *xdrs = &xdr_stream;
+       register struct audata *au = AUTH_PRIVATE(auth);
+
+       xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
+       if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
+           (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
+               perror("auth_none.c - Fatal marshalling problem");
+       } else {
+               au->au_mpos = XDR_GETPOS(xdrs);
+       }
+       XDR_DESTROY(xdrs);
+}
diff --git a/sunrpc/authuxprot.c b/sunrpc/authuxprot.c
new file mode 100644 (file)
index 0000000..a60d99a
--- /dev/null
@@ -0,0 +1,66 @@
+/* @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * XDR for unix authentication parameters.
+ */
+bool_t
+xdr_authunix_parms(xdrs, p)
+       register XDR *xdrs;
+       register struct authunix_parms *p;
+{
+
+       if (xdr_u_long(xdrs, &(p->aup_time))
+           && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
+           && xdr_int(xdrs, &(p->aup_uid))
+           && xdr_int(xdrs, &(p->aup_gid))
+           && xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
+                   &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) {
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
diff --git a/sunrpc/bindrsvprt.c b/sunrpc/bindrsvprt.c
new file mode 100644 (file)
index 0000000..71803dd
--- /dev/null
@@ -0,0 +1,78 @@
+static  char sccsid[] = "@(#)bindresvport.c    2.2 88/07/29 4.0 RPCSRC 1.8 88/02/08 SMI";
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+bindresvport(sd, sin)
+       int sd;
+       struct sockaddr_in *sin;
+{
+       int res;
+       static short port;
+       struct sockaddr_in myaddr;
+       extern int errno;
+       int i;
+
+#define STARTPORT 600
+#define ENDPORT (IPPORT_RESERVED - 1)
+#define NPORTS (ENDPORT - STARTPORT + 1)
+
+       if (sin == (struct sockaddr_in *)0) {
+               sin = &myaddr;
+               bzero(sin, sizeof (*sin));
+               sin->sin_family = AF_INET;
+       } else if (sin->sin_family != AF_INET) {
+               errno = EPFNOSUPPORT;
+               return (-1);
+       }
+       if (port == 0) {
+               port = (getpid() % NPORTS) + STARTPORT;
+       }
+       res = -1;
+       errno = EADDRINUSE;
+       for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
+               sin->sin_port = htons(port++);
+               if (port > ENDPORT) {
+                       port = STARTPORT;
+               }
+               res = bind(sd, sin, sizeof(struct sockaddr_in));
+       }
+       return (res);
+}
diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c
new file mode 100644 (file)
index 0000000..e54e778
--- /dev/null
@@ -0,0 +1,110 @@
+/* @(#)clnt_generic.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";
+#endif
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can 
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *
+clnt_create(hostname, prog, vers, proto)
+       char *hostname;
+       unsigned prog;
+       unsigned vers;
+       char *proto;
+{
+       struct hostent *h;
+       struct protoent *p;
+       struct sockaddr_in sin;
+       int sock;
+       struct timeval tv;
+       CLIENT *client;
+
+       h = gethostbyname(hostname);
+       if (h == NULL) {
+               rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+               return (NULL);
+       }
+       if (h->h_addrtype != AF_INET) {
+               /*
+                * Only support INET for now
+                */
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; 
+               return (NULL);
+       }
+       sin.sin_family = h->h_addrtype;
+       sin.sin_port = 0;
+       bzero(sin.sin_zero, sizeof(sin.sin_zero));
+       bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length);
+       p = getprotobyname(proto);
+       if (p == NULL) {
+               rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
+               rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; 
+               return (NULL);
+       }
+       sock = RPC_ANYSOCK;
+       switch (p->p_proto) {
+       case IPPROTO_UDP:
+               tv.tv_sec = 5;
+               tv.tv_usec = 0;
+               client = clntudp_create(&sin, prog, vers, tv, &sock);
+               if (client == NULL) {
+                       return (NULL);
+               }
+               tv.tv_sec = 25;
+               clnt_control(client, CLSET_TIMEOUT, &tv);
+               break;
+       case IPPROTO_TCP:
+               client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
+               if (client == NULL) {
+                       return (NULL);
+               }
+               tv.tv_sec = 25;
+               tv.tv_usec = 0;
+               clnt_control(client, CLSET_TIMEOUT, &tv);
+               break;
+       default:
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; 
+               return (NULL);
+       }
+       return (client);
+}
diff --git a/sunrpc/clnt_raw.c b/sunrpc/clnt_raw.c
new file mode 100644 (file)
index 0000000..89059ae
--- /dev/null
@@ -0,0 +1,238 @@
+/* @(#)clnt_raw.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us similate rpc and get round trip overhead, without
+ * any interference from the kernal.
+ */
+
+#include <rpc/rpc.h>
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+static struct clntraw_private {
+       CLIENT  client_object;
+       XDR     xdr_stream;
+       char    _raw_buf[UDPMSGSIZE];
+       char    mashl_callmsg[MCALL_MSG_SIZE];
+       u_int   mcnt;
+} *clntraw_private;
+
+static enum clnt_stat  clntraw_call();
+static void            clntraw_abort();
+static void            clntraw_geterr();
+static bool_t          clntraw_freeres();
+static bool_t          clntraw_control();
+static void            clntraw_destroy();
+
+static struct clnt_ops client_ops = {
+       clntraw_call,
+       clntraw_abort,
+       clntraw_geterr,
+       clntraw_freeres,
+       clntraw_destroy,
+       clntraw_control
+};
+
+void   svc_getreq();
+
+/*
+ * Create a client handle for memory based rpc.
+ */
+CLIENT *
+clntraw_create(prog, vers)
+       u_long prog;
+       u_long vers;
+{
+       register struct clntraw_private *clp = clntraw_private;
+       struct rpc_msg call_msg;
+       XDR *xdrs = &clp->xdr_stream;
+       CLIENT  *client = &clp->client_object;
+
+       if (clp == 0) {
+               clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
+               if (clp == 0)
+                       return (0);
+               clntraw_private = clp;
+       }
+       /*
+        * pre-serialize the staic part of the call msg and stash it away
+        */
+       call_msg.rm_direction = CALL;
+       call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       call_msg.rm_call.cb_prog = prog;
+       call_msg.rm_call.cb_vers = vers;
+       xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); 
+       if (! xdr_callhdr(xdrs, &call_msg)) {
+               perror("clnt_raw.c - Fatal header serialization error.");
+       }
+       clp->mcnt = XDR_GETPOS(xdrs);
+       XDR_DESTROY(xdrs);
+
+       /*
+        * Set xdrmem for client/server shared buffer
+        */
+       xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+
+       /*
+        * create client handle
+        */
+       client->cl_ops = &client_ops;
+       client->cl_auth = authnone_create();
+       return (client);
+}
+
+static enum clnt_stat 
+clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
+       CLIENT *h;
+       u_long proc;
+       xdrproc_t xargs;
+       caddr_t argsp;
+       xdrproc_t xresults;
+       caddr_t resultsp;
+       struct timeval timeout;
+{
+       register struct clntraw_private *clp = clntraw_private;
+       register XDR *xdrs = &clp->xdr_stream;
+       struct rpc_msg msg;
+       enum clnt_stat status;
+       struct rpc_err error;
+
+       if (clp == 0)
+               return (RPC_FAILED);
+call_again:
+       /*
+        * send request
+        */
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, 0);
+       ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
+       if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
+           (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+           (! (*xargs)(xdrs, argsp))) {
+               return (RPC_CANTENCODEARGS);
+       }
+       (void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
+
+       /*
+        * We have to call server input routine here because this is
+        * all going on in one process. Yuk.
+        */
+       svc_getreq(1);
+
+       /*
+        * get results
+        */
+       xdrs->x_op = XDR_DECODE;
+       XDR_SETPOS(xdrs, 0);
+       msg.acpted_rply.ar_verf = _null_auth;
+       msg.acpted_rply.ar_results.where = resultsp;
+       msg.acpted_rply.ar_results.proc = xresults;
+       if (! xdr_replymsg(xdrs, &msg))
+               return (RPC_CANTDECODERES);
+       _seterr_reply(&msg, &error);
+       status = error.re_status;
+
+       if (status == RPC_SUCCESS) {
+               if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+                       status = RPC_AUTHERROR;
+               }
+       }  /* end successful completion */
+       else {
+               if (AUTH_REFRESH(h->cl_auth))
+                       goto call_again;
+       }  /* end of unsuccessful completion */
+
+       if (status == RPC_SUCCESS) {
+               if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+                       status = RPC_AUTHERROR;
+               }
+               if (msg.acpted_rply.ar_verf.oa_base != NULL) {
+                       xdrs->x_op = XDR_FREE;
+                       (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
+               }
+       }
+
+       return (status);
+}
+
+static void
+clntraw_geterr()
+{
+}
+
+
+static bool_t
+clntraw_freeres(cl, xdr_res, res_ptr)
+       CLIENT *cl;
+       xdrproc_t xdr_res;
+       caddr_t res_ptr;
+{
+       register struct clntraw_private *clp = clntraw_private;
+       register XDR *xdrs = &clp->xdr_stream;
+       bool_t rval;
+
+       if (clp == 0)
+       {
+               rval = (bool_t) RPC_FAILED;
+               return (rval);
+       }
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntraw_abort()
+{
+}
+
+static bool_t
+clntraw_control()
+{
+       return (FALSE);
+}
+
+static void
+clntraw_destroy()
+{
+}
diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c
new file mode 100644 (file)
index 0000000..043ce0a
--- /dev/null
@@ -0,0 +1,112 @@
+/* @(#)clnt_simple.c   2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/* 
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <strings.h>
+
+static struct callrpc_private {
+       CLIENT  *client;
+       int     socket;
+       int     oldprognum, oldversnum, valid;
+       char    *oldhost;
+} *callrpc_private;
+
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+       char *host;
+       xdrproc_t inproc, outproc;
+       char *in, *out;
+{
+       register struct callrpc_private *crp = callrpc_private;
+       struct sockaddr_in server_addr;
+       enum clnt_stat clnt_stat;
+       struct hostent *hp;
+       struct timeval timeout, tottimeout;
+
+       if (crp == 0) {
+               crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
+               if (crp == 0)
+                       return (0);
+               callrpc_private = crp;
+       }
+       if (crp->oldhost == NULL) {
+               crp->oldhost = malloc(256);
+               crp->oldhost[0] = 0;
+               crp->socket = RPC_ANYSOCK;
+       }
+       if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
+               && strcmp(crp->oldhost, host) == 0) {
+               /* reuse old client */          
+       } else {
+               crp->valid = 0;
+               (void)close(crp->socket);
+               crp->socket = RPC_ANYSOCK;
+               if (crp->client) {
+                       clnt_destroy(crp->client);
+                       crp->client = NULL;
+               }
+               if ((hp = gethostbyname(host)) == NULL)
+                       return ((int) RPC_UNKNOWNHOST);
+               timeout.tv_usec = 0;
+               timeout.tv_sec = 5;
+               bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
+               server_addr.sin_family = AF_INET;
+               server_addr.sin_port =  0;
+               if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
+                   (u_long)versnum, timeout, &crp->socket)) == NULL)
+                       return ((int) rpc_createerr.cf_stat);
+               crp->valid = 1;
+               crp->oldprognum = prognum;
+               crp->oldversnum = versnum;
+               (void) strcpy(crp->oldhost, host);
+       }
+       tottimeout.tv_sec = 25;
+       tottimeout.tv_usec = 0;
+       clnt_stat = clnt_call(crp->client, procnum, inproc, in,
+           outproc, out, tottimeout);
+       /* 
+        * if call failed, empty cache
+        */
+       if (clnt_stat != RPC_SUCCESS)
+               crp->valid = 0;
+       return ((int) clnt_stat);
+}
diff --git a/sunrpc/clnt_tcp.c b/sunrpc/clnt_tcp.c
new file mode 100644 (file)
index 0000000..2222bc6
--- /dev/null
@@ -0,0 +1,466 @@
+/* @(#)clnt_tcp.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
+#endif
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer.  The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message.  Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+#define MCALL_MSG_SIZE 24
+
+extern int errno;
+
+static int     readtcp();
+static int     writetcp();
+
+static enum clnt_stat  clnttcp_call();
+static void            clnttcp_abort();
+static void            clnttcp_geterr();
+static bool_t          clnttcp_freeres();
+static bool_t           clnttcp_control();
+static void            clnttcp_destroy();
+
+static struct clnt_ops tcp_ops = {
+       clnttcp_call,
+       clnttcp_abort,
+       clnttcp_geterr,
+       clnttcp_freeres,
+       clnttcp_destroy,
+       clnttcp_control
+};
+
+struct ct_data {
+       int             ct_sock;
+       bool_t          ct_closeit;
+       struct timeval  ct_wait;
+       bool_t          ct_waitset;       /* wait set by clnt_control? */
+       struct sockaddr_in ct_addr; 
+       struct rpc_err  ct_error;
+       char            ct_mcall[MCALL_MSG_SIZE];       /* marshalled callmsg */
+       u_int           ct_mpos;                        /* pos after marshal */
+       XDR             ct_xdrs;
+};
+
+/*
+ * Create a client handle for a tcp/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr.  If *sockp non-negative then
+ * raddr is ignored.  The rpc/tcp package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+       struct sockaddr_in *raddr;
+       u_long prog;
+       u_long vers;
+       register int *sockp;
+       u_int sendsz;
+       u_int recvsz;
+{
+       CLIENT *h;
+       register struct ct_data *ct;
+       struct timeval now;
+       struct rpc_msg call_msg;
+
+       h  = (CLIENT *)mem_alloc(sizeof(*h));
+       if (h == NULL) {
+               (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+       ct = (struct ct_data *)mem_alloc(sizeof(*ct));
+       if (ct == NULL) {
+               (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+
+       /*
+        * If no port number given ask the pmap for one
+        */
+       if (raddr->sin_port == 0) {
+               u_short port;
+               if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
+                       mem_free((caddr_t)ct, sizeof(struct ct_data));
+                       mem_free((caddr_t)h, sizeof(CLIENT));
+                       return ((CLIENT *)NULL);
+               }
+               raddr->sin_port = htons(port);
+       }
+
+       /*
+        * If no socket given, open one
+        */
+       if (*sockp < 0) {
+               *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+               (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+               if ((*sockp < 0)
+                   || (connect(*sockp, (struct sockaddr *)raddr,
+                   sizeof(*raddr)) < 0)) {
+                       rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+                       rpc_createerr.cf_error.re_errno = errno;
+                       (void)close(*sockp);
+                       goto fooy;
+               }
+               ct->ct_closeit = TRUE;
+       } else {
+               ct->ct_closeit = FALSE;
+       }
+
+       /*
+        * Set up private data struct
+        */
+       ct->ct_sock = *sockp;
+       ct->ct_wait.tv_usec = 0;
+       ct->ct_waitset = FALSE;
+       ct->ct_addr = *raddr;
+
+       /*
+        * Initialize call message
+        */
+       (void)gettimeofday(&now, (struct timezone *)0);
+       call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
+       call_msg.rm_direction = CALL;
+       call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       call_msg.rm_call.cb_prog = prog;
+       call_msg.rm_call.cb_vers = vers;
+
+       /*
+        * pre-serialize the staic part of the call msg and stash it away
+        */
+       xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
+           XDR_ENCODE);
+       if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
+               if (ct->ct_closeit) {
+                       (void)close(*sockp);
+               }
+               goto fooy;
+       }
+       ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
+       XDR_DESTROY(&(ct->ct_xdrs));
+
+       /*
+        * Create a client handle which uses xdrrec for serialization
+        * and authnone for authentication.
+        */
+       xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
+           (caddr_t)ct, readtcp, writetcp);
+       h->cl_ops = &tcp_ops;
+       h->cl_private = (caddr_t) ct;
+       h->cl_auth = authnone_create();
+       return (h);
+
+fooy:
+       /*
+        * Something goofed, free stuff and barf
+        */
+       mem_free((caddr_t)ct, sizeof(struct ct_data));
+       mem_free((caddr_t)h, sizeof(CLIENT));
+       return ((CLIENT *)NULL);
+}
+
+static enum clnt_stat
+clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
+       register CLIENT *h;
+       u_long proc;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+       xdrproc_t xdr_results;
+       caddr_t results_ptr;
+       struct timeval timeout;
+{
+       register struct ct_data *ct = (struct ct_data *) h->cl_private;
+       register XDR *xdrs = &(ct->ct_xdrs);
+       struct rpc_msg reply_msg;
+       u_long x_id;
+       u_long *msg_x_id = (u_long *)(ct->ct_mcall);    /* yuk */
+       register bool_t shipnow;
+       int refreshes = 2;
+
+       if (!ct->ct_waitset) {
+               ct->ct_wait = timeout;
+       }
+
+       shipnow =
+           (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
+           && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+       xdrs->x_op = XDR_ENCODE;
+       ct->ct_error.re_status = RPC_SUCCESS;
+       x_id = ntohl(--(*msg_x_id));
+       if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
+           (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+           (! (*xdr_args)(xdrs, args_ptr))) {
+               if (ct->ct_error.re_status == RPC_SUCCESS)
+                       ct->ct_error.re_status = RPC_CANTENCODEARGS;
+               (void)xdrrec_endofrecord(xdrs, TRUE);
+               return (ct->ct_error.re_status);
+       }
+       if (! xdrrec_endofrecord(xdrs, shipnow))
+               return (ct->ct_error.re_status = RPC_CANTSEND);
+       if (! shipnow)
+               return (RPC_SUCCESS);
+       /*
+        * Hack to provide rpc-based message passing
+        */
+       if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+               return(ct->ct_error.re_status = RPC_TIMEDOUT);
+       }
+
+
+       /*
+        * Keep receiving until we get a valid transaction id
+        */
+       xdrs->x_op = XDR_DECODE;
+       while (TRUE) {
+               reply_msg.acpted_rply.ar_verf = _null_auth;
+               reply_msg.acpted_rply.ar_results.where = NULL;
+               reply_msg.acpted_rply.ar_results.proc = xdr_void;
+               if (! xdrrec_skiprecord(xdrs))
+                       return (ct->ct_error.re_status);
+               /* now decode and validate the response header */
+               if (! xdr_replymsg(xdrs, &reply_msg)) {
+                       if (ct->ct_error.re_status == RPC_SUCCESS)
+                               continue;
+                       return (ct->ct_error.re_status);
+               }
+               if (reply_msg.rm_xid == x_id)
+                       break;
+       }
+
+       /*
+        * process header
+        */
+       _seterr_reply(&reply_msg, &(ct->ct_error));
+       if (ct->ct_error.re_status == RPC_SUCCESS) {
+               if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
+                       ct->ct_error.re_status = RPC_AUTHERROR;
+                       ct->ct_error.re_why = AUTH_INVALIDRESP;
+               } else if (! (*xdr_results)(xdrs, results_ptr)) {
+                       if (ct->ct_error.re_status == RPC_SUCCESS)
+                               ct->ct_error.re_status = RPC_CANTDECODERES;
+               }
+               /* free verifier ... */
+               if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+                       xdrs->x_op = XDR_FREE;
+                       (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
+               }
+       }  /* end successful completion */
+       else {
+               /* maybe our credentials need to be refreshed ... */
+               if (refreshes-- && AUTH_REFRESH(h->cl_auth))
+                       goto call_again;
+       }  /* end of unsuccessful completion */
+       return (ct->ct_error.re_status);
+}
+
+static void
+clnttcp_geterr(h, errp)
+       CLIENT *h;
+       struct rpc_err *errp;
+{
+       register struct ct_data *ct =
+           (struct ct_data *) h->cl_private;
+
+       *errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres(cl, xdr_res, res_ptr)
+       CLIENT *cl;
+       xdrproc_t xdr_res;
+       caddr_t res_ptr;
+{
+       register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+       register XDR *xdrs = &(ct->ct_xdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clnttcp_abort()
+{
+}
+
+static bool_t
+clnttcp_control(cl, request, info)
+       CLIENT *cl;
+       int request;
+       char *info;
+{
+       register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+
+       switch (request) {
+       case CLSET_TIMEOUT:
+               ct->ct_wait = *(struct timeval *)info;
+               ct->ct_waitset = TRUE;
+               break;
+       case CLGET_TIMEOUT:
+               *(struct timeval *)info = ct->ct_wait;
+               break;
+       case CLGET_SERVER_ADDR:
+               *(struct sockaddr_in *)info = ct->ct_addr;
+               break;
+       default:
+               return (FALSE);
+       }
+       return (TRUE);
+}
+
+
+static void
+clnttcp_destroy(h)
+       CLIENT *h;
+{
+       register struct ct_data *ct =
+           (struct ct_data *) h->cl_private;
+
+       if (ct->ct_closeit) {
+               (void)close(ct->ct_sock);
+       }
+       XDR_DESTROY(&(ct->ct_xdrs));
+       mem_free((caddr_t)ct, sizeof(struct ct_data));
+       mem_free((caddr_t)h, sizeof(CLIENT));
+}
+
+/*
+ * Interface between xdr serializer and tcp connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readtcp(ct, buf, len)
+       register struct ct_data *ct;
+       caddr_t buf;
+       register int len;
+{
+#ifdef FD_SETSIZE
+       fd_set mask;
+       fd_set readfds;
+
+       if (len == 0)
+               return (0);
+       FD_ZERO(&mask);
+       FD_SET(ct->ct_sock, &mask);
+#else
+       register int mask = 1 << (ct->ct_sock);
+       int readfds;
+
+       if (len == 0)
+               return (0);
+
+#endif /* def FD_SETSIZE */
+       while (TRUE) {
+               readfds = mask;
+               switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
+                              &(ct->ct_wait))) {
+               case 0:
+                       ct->ct_error.re_status = RPC_TIMEDOUT;
+                       return (-1);
+
+               case -1:
+                       if (errno == EINTR)
+                               continue;
+                       ct->ct_error.re_status = RPC_CANTRECV;
+                       ct->ct_error.re_errno = errno;
+                       return (-1);
+               }
+               break;
+       }
+       switch (len = read(ct->ct_sock, buf, len)) {
+
+       case 0:
+               /* premature eof */
+               ct->ct_error.re_errno = ECONNRESET;
+               ct->ct_error.re_status = RPC_CANTRECV;
+               len = -1;  /* it's really an error */
+               break;
+
+       case -1:
+               ct->ct_error.re_errno = errno;
+               ct->ct_error.re_status = RPC_CANTRECV;
+               break;
+       }
+       return (len);
+}
+
+static int
+writetcp(ct, buf, len)
+       struct ct_data *ct;
+       caddr_t buf;
+       int len;
+{
+       register int i, cnt;
+
+       for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+               if ((i = write(ct->ct_sock, buf, cnt)) == -1) {
+                       ct->ct_error.re_errno = errno;
+                       ct->ct_error.re_status = RPC_CANTSEND;
+                       return (-1);
+               }
+       }
+       return (len);
+}
diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
new file mode 100644 (file)
index 0000000..815cbb4
--- /dev/null
@@ -0,0 +1,442 @@
+/* @(#)clnt_udp.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+extern int errno;
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat  clntudp_call();
+static void            clntudp_abort();
+static void            clntudp_geterr();
+static bool_t          clntudp_freeres();
+static bool_t           clntudp_control();
+static void            clntudp_destroy();
+
+static struct clnt_ops udp_ops = {
+       clntudp_call,
+       clntudp_abort,
+       clntudp_geterr,
+       clntudp_freeres,
+       clntudp_destroy,
+       clntudp_control
+};
+
+/* 
+ * Private data kept per client handle
+ */
+struct cu_data {
+       int                cu_sock;
+       bool_t             cu_closeit;
+       struct sockaddr_in cu_raddr;
+       int                cu_rlen;
+       struct timeval     cu_wait;
+       struct timeval     cu_total;
+       struct rpc_err     cu_error;
+       XDR                cu_outxdrs;
+       u_int              cu_xdrpos;
+       u_int              cu_sendsz;
+       char               *cu_outbuf;
+       u_int              cu_recvsz;
+       char               cu_inbuf[1];
+};
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ *     Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard;  retransmition occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *
+clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+       struct sockaddr_in *raddr;
+       u_long program;
+       u_long version;
+       struct timeval wait;
+       register int *sockp;
+       u_int sendsz;
+       u_int recvsz;
+{
+       CLIENT *cl;
+       register struct cu_data *cu;
+       struct timeval now;
+       struct rpc_msg call_msg;
+
+       cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
+       if (cl == NULL) {
+               (void) fprintf(stderr, "clntudp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+       sendsz = ((sendsz + 3) / 4) * 4;
+       recvsz = ((recvsz + 3) / 4) * 4;
+       cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
+       if (cu == NULL) {
+               (void) fprintf(stderr, "clntudp_create: out of memory\n");
+               rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+               rpc_createerr.cf_error.re_errno = errno;
+               goto fooy;
+       }
+       cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+       (void)gettimeofday(&now, (struct timezone *)0);
+       if (raddr->sin_port == 0) {
+               u_short port;
+               if ((port =
+                   pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
+                       goto fooy;
+               }
+               raddr->sin_port = htons(port);
+       }
+       cl->cl_ops = &udp_ops;
+       cl->cl_private = (caddr_t)cu;
+       cu->cu_raddr = *raddr;
+       cu->cu_rlen = sizeof (cu->cu_raddr);
+       cu->cu_wait = wait;
+       cu->cu_total.tv_sec = -1;
+       cu->cu_total.tv_usec = -1;
+       cu->cu_sendsz = sendsz;
+       cu->cu_recvsz = recvsz;
+       call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
+       call_msg.rm_direction = CALL;
+       call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       call_msg.rm_call.cb_prog = program;
+       call_msg.rm_call.cb_vers = version;
+       xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
+           sendsz, XDR_ENCODE);
+       if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+               goto fooy;
+       }
+       cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+       if (*sockp < 0) {
+               int dontblock = 1;
+
+               *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+               if (*sockp < 0) {
+                       rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+                       rpc_createerr.cf_error.re_errno = errno;
+                       goto fooy;
+               }
+               /* attempt to bind to prov port */
+               (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+               /* the sockets rpc controls are non-blocking */
+               (void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
+               cu->cu_closeit = TRUE;
+       } else {
+               cu->cu_closeit = FALSE;
+       }
+       cu->cu_sock = *sockp;
+       cl->cl_auth = authnone_create();
+       return (cl);
+fooy:
+       if (cu)
+               mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
+       if (cl)
+               mem_free((caddr_t)cl, sizeof(CLIENT));
+       return ((CLIENT *)NULL);
+}
+
+CLIENT *
+clntudp_create(raddr, program, version, wait, sockp)
+       struct sockaddr_in *raddr;
+       u_long program;
+       u_long version;
+       struct timeval wait;
+       register int *sockp;
+{
+
+       return(clntudp_bufcreate(raddr, program, version, wait, sockp,
+           UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum clnt_stat 
+clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
+       register CLIENT *cl;            /* client handle */
+       u_long          proc;           /* procedure number */
+       xdrproc_t       xargs;          /* xdr routine for args */
+       caddr_t         argsp;          /* pointer to args */
+       xdrproc_t       xresults;       /* xdr routine for results */
+       caddr_t         resultsp;       /* pointer to results */
+       struct timeval  utimeout;       /* seconds to wait before giving up */
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+       register XDR *xdrs;
+       register int outlen;
+       register int inlen;
+       int fromlen;
+#ifdef FD_SETSIZE
+       fd_set readfds;
+       fd_set mask;
+#else
+       int readfds;
+       register int mask;
+#endif /* def FD_SETSIZE */
+       struct sockaddr_in from;
+       struct rpc_msg reply_msg;
+       XDR reply_xdrs;
+       struct timeval time_waited;
+       bool_t ok;
+       int nrefreshes = 2;     /* number of times to refresh cred */
+       struct timeval timeout;
+
+       if (cu->cu_total.tv_usec == -1) {
+               timeout = utimeout;     /* use supplied timeout */
+       } else {
+               timeout = cu->cu_total; /* use default timeout */
+       }
+
+       time_waited.tv_sec = 0;
+       time_waited.tv_usec = 0;
+call_again:
+       xdrs = &(cu->cu_outxdrs);
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, cu->cu_xdrpos);
+       /*
+        * the transaction is the first thing in the out buffer
+        */
+       (*(u_short *)(cu->cu_outbuf))++;
+       if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+           (! (*xargs)(xdrs, argsp)))
+               return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+       outlen = (int)XDR_GETPOS(xdrs);
+
+send_again:
+       if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+           (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
+           != outlen) {
+               cu->cu_error.re_errno = errno;
+               return (cu->cu_error.re_status = RPC_CANTSEND);
+       }
+
+       /*
+        * Hack to provide rpc-based message passing
+        */
+       if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+               return (cu->cu_error.re_status = RPC_TIMEDOUT);
+       }
+       /*
+        * sub-optimal code appears here because we have
+        * some clock time to spare while the packets are in flight.
+        * (We assume that this is actually only executed once.)
+        */
+       reply_msg.acpted_rply.ar_verf = _null_auth;
+       reply_msg.acpted_rply.ar_results.where = resultsp;
+       reply_msg.acpted_rply.ar_results.proc = xresults;
+#ifdef FD_SETSIZE
+       FD_ZERO(&mask);
+       FD_SET(cu->cu_sock, &mask);
+#else
+       mask = 1 << cu->cu_sock;
+#endif /* def FD_SETSIZE */
+       for (;;) {
+               readfds = mask;
+               switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, 
+                              (int *)NULL, &(cu->cu_wait))) {
+
+               case 0:
+                       time_waited.tv_sec += cu->cu_wait.tv_sec;
+                       time_waited.tv_usec += cu->cu_wait.tv_usec;
+                       while (time_waited.tv_usec >= 1000000) {
+                               time_waited.tv_sec++;
+                               time_waited.tv_usec -= 1000000;
+                       }
+                       if ((time_waited.tv_sec < timeout.tv_sec) ||
+                               ((time_waited.tv_sec == timeout.tv_sec) &&
+                               (time_waited.tv_usec < timeout.tv_usec)))
+                               goto send_again;        
+                       return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+               /*
+                * buggy in other cases because time_waited is not being
+                * updated.
+                */
+               case -1:
+                       if (errno == EINTR)
+                               continue;       
+                       cu->cu_error.re_errno = errno;
+                       return (cu->cu_error.re_status = RPC_CANTRECV);
+               }
+               do {
+                       fromlen = sizeof(struct sockaddr);
+                       inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, 
+                               (int) cu->cu_recvsz, 0,
+                               (struct sockaddr *)&from, &fromlen);
+               } while (inlen < 0 && errno == EINTR);
+               if (inlen < 0) {
+                       if (errno == EWOULDBLOCK)
+                               continue;       
+                       cu->cu_error.re_errno = errno;
+                       return (cu->cu_error.re_status = RPC_CANTRECV);
+               }
+               if (inlen < sizeof(u_long))
+                       continue;       
+               /* see if reply transaction id matches sent id */
+               if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf)))
+                       continue;       
+               /* we now assume we have the proper reply */
+               break;
+       }
+
+       /*
+        * now decode and validate the response
+        */
+       xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
+       ok = xdr_replymsg(&reply_xdrs, &reply_msg);
+       /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
+       if (ok) {
+               _seterr_reply(&reply_msg, &(cu->cu_error));
+               if (cu->cu_error.re_status == RPC_SUCCESS) {
+                       if (! AUTH_VALIDATE(cl->cl_auth,
+                               &reply_msg.acpted_rply.ar_verf)) {
+                               cu->cu_error.re_status = RPC_AUTHERROR;
+                               cu->cu_error.re_why = AUTH_INVALIDRESP;
+                       }
+                       if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+                               xdrs->x_op = XDR_FREE;
+                               (void)xdr_opaque_auth(xdrs,
+                                   &(reply_msg.acpted_rply.ar_verf));
+                       } 
+               }  /* end successful completion */
+               else {
+                       /* maybe our credentials need to be refreshed ... */
+                       if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
+                               nrefreshes--;
+                               goto call_again;
+                       }
+               }  /* end of unsuccessful completion */
+       }  /* end of valid reply message */
+       else {
+               cu->cu_error.re_status = RPC_CANTDECODERES;
+       }
+       return (cu->cu_error.re_status);
+}
+
+static void
+clntudp_geterr(cl, errp)
+       CLIENT *cl;
+       struct rpc_err *errp;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+       *errp = cu->cu_error;
+}
+
+
+static bool_t
+clntudp_freeres(cl, xdr_res, res_ptr)
+       CLIENT *cl;
+       xdrproc_t xdr_res;
+       caddr_t res_ptr;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+       register XDR *xdrs = &(cu->cu_outxdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void 
+clntudp_abort(/*h*/)
+       /*CLIENT *h;*/
+{
+}
+
+static bool_t
+clntudp_control(cl, request, info)
+       CLIENT *cl;
+       int request;
+       char *info;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+       switch (request) {
+       case CLSET_TIMEOUT:
+               cu->cu_total = *(struct timeval *)info;
+               break;
+       case CLGET_TIMEOUT:
+               *(struct timeval *)info = cu->cu_total;
+               break;
+       case CLSET_RETRY_TIMEOUT:
+               cu->cu_wait = *(struct timeval *)info;
+               break;
+       case CLGET_RETRY_TIMEOUT:
+               *(struct timeval *)info = cu->cu_wait;
+               break;
+       case CLGET_SERVER_ADDR:
+               *(struct sockaddr_in *)info = cu->cu_raddr;
+               break;
+       default:
+               return (FALSE);
+       }
+       return (TRUE);
+}
+       
+static void
+clntudp_destroy(cl)
+       CLIENT *cl;
+{
+       register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+       if (cu->cu_closeit) {
+               (void)close(cu->cu_sock);
+       }
+       XDR_DESTROY(&(cu->cu_outxdrs));
+       mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
+       mem_free((caddr_t)cl, sizeof(CLIENT));
+}
diff --git a/sunrpc/getrpcport.c b/sunrpc/getrpcport.c
new file mode 100644 (file)
index 0000000..9b13bac
--- /dev/null
@@ -0,0 +1,55 @@
+/* @(#)getrpcport.c    2.1 88/07/29 4.0 RPCSRC */
+#if !defined(lint) && defined(SCCSIDS)
+static  char sccsid[] = "@(#)getrpcport.c 1.3 87/08/11 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+getrpcport(host, prognum, versnum, proto)
+       char *host;
+{
+       struct sockaddr_in addr;
+       struct hostent *hp;
+
+       if ((hp = gethostbyname(host)) == NULL)
+               return (0);
+       bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length);
+       addr.sin_family = AF_INET;
+       addr.sin_port =  0;
+       return (pmap_getport(&addr, prognum, versnum, proto));
+}
diff --git a/sunrpc/pm_getmaps.c b/sunrpc/pm_getmaps.c
new file mode 100644 (file)
index 0000000..e4a9c49
--- /dev/null
@@ -0,0 +1,84 @@
+/* @(#)pmap_getmaps.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#define NAMELEN 255
+#define MAX_BROADCAST_SIZE 1400
+
+extern int errno;
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps(address)
+        struct sockaddr_in *address;
+{
+       struct pmaplist *head = (struct pmaplist *)NULL;
+       int socket = -1;
+       struct timeval minutetimeout;
+       register CLIENT *client;
+
+       minutetimeout.tv_sec = 60;
+       minutetimeout.tv_usec = 0;
+       address->sin_port = htons(PMAPPORT);
+       client = clnttcp_create(address, PMAPPROG,
+           PMAPVERS, &socket, 50, 500);
+       if (client != (CLIENT *)NULL) {
+               if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
+                   &head, minutetimeout) != RPC_SUCCESS) {
+                       clnt_perror(client, "pmap_getmaps rpc problem");
+               }
+               CLNT_DESTROY(client);
+       }
+       (void)close(socket);
+       address->sin_port = 0;
+       return (head);
+}
diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c
new file mode 100644 (file)
index 0000000..77b9cf7
--- /dev/null
@@ -0,0 +1,87 @@
+/* @(#)pmap_getport.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+pmap_getport(address, program, version, protocol)
+       struct sockaddr_in *address;
+       u_long program;
+       u_long version;
+       u_int protocol;
+{
+       u_short port = 0;
+       int socket = -1;
+       register CLIENT *client;
+       struct pmap parms;
+
+       address->sin_port = htons(PMAPPORT);
+       client = clntudp_bufcreate(address, PMAPPROG,
+           PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+       if (client != (CLIENT *)NULL) {
+               parms.pm_prog = program;
+               parms.pm_vers = version;
+               parms.pm_prot = protocol;
+               parms.pm_port = 0;  /* not needed or used */
+               if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
+                   xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
+                       rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+                       clnt_geterr(client, &rpc_createerr.cf_error);
+               } else if (port == 0) {
+                       rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+               }
+               CLNT_DESTROY(client);
+       }
+       (void)close(socket);
+       address->sin_port = 0;
+       return (port);
+}
diff --git a/sunrpc/pmap_clnt.c b/sunrpc/pmap_clnt.c
new file mode 100644 (file)
index 0000000..09220e7
--- /dev/null
@@ -0,0 +1,115 @@
+/* @(#)pmap_clnt.c     2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+void clnt_perror();
+
+
+/*
+ * Set a mapping between program,version and port.
+ * Calls the pmap service remotely to do the mapping.
+ */
+bool_t
+pmap_set(program, version, protocol, port)
+       u_long program;
+       u_long version;
+       int protocol;
+       u_short port;
+{
+       struct sockaddr_in myaddress;
+       int socket = -1;
+       register CLIENT *client;
+       struct pmap parms;
+       bool_t rslt;
+
+       get_myaddress(&myaddress);
+       client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+           timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+       if (client == (CLIENT *)NULL)
+               return (FALSE);
+       parms.pm_prog = program;
+       parms.pm_vers = version;
+       parms.pm_prot = protocol;
+       parms.pm_port = port;
+       if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
+           tottimeout) != RPC_SUCCESS) {
+               clnt_perror(client, "Cannot register service");
+               return (FALSE);
+       }
+       CLNT_DESTROY(client);
+       (void)close(socket);
+       return (rslt);
+}
+
+/*
+ * Remove the mapping between program,version and port.
+ * Calls the pmap service remotely to do the un-mapping.
+ */
+bool_t
+pmap_unset(program, version)
+       u_long program;
+       u_long version;
+{
+       struct sockaddr_in myaddress;
+       int socket = -1;
+       register CLIENT *client;
+       struct pmap parms;
+       bool_t rslt;
+
+       get_myaddress(&myaddress);
+       client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+           timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+       if (client == (CLIENT *)NULL)
+               return (FALSE);
+       parms.pm_prog = program;
+       parms.pm_vers = version;
+       parms.pm_port = parms.pm_prot = 0;
+       CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
+           tottimeout);
+       CLNT_DESTROY(client);
+       (void)close(socket);
+       return (rslt);
+}
diff --git a/sunrpc/pmap_prot.c b/sunrpc/pmap_prot.c
new file mode 100644 (file)
index 0000000..643c2ff
--- /dev/null
@@ -0,0 +1,57 @@
+/* @(#)pmap_prot.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+bool_t
+xdr_pmap(xdrs, regs)
+       XDR *xdrs;
+       struct pmap *regs;
+{
+
+       if (xdr_u_long(xdrs, &regs->pm_prog) && 
+               xdr_u_long(xdrs, &regs->pm_vers) && 
+               xdr_u_long(xdrs, &regs->pm_prot))
+               return (xdr_u_long(xdrs, &regs->pm_port));
+       return (FALSE);
+}
diff --git a/sunrpc/pmap_prot2.c b/sunrpc/pmap_prot2.c
new file mode 100644 (file)
index 0000000..e2a8214
--- /dev/null
@@ -0,0 +1,116 @@
+/* @(#)pmap_prot2.c    2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+/* 
+ * What is going on with linked lists? (!)
+ * First recall the link list declaration from pmap_prot.h:
+ *
+ * struct pmaplist {
+ *     struct pmap pml_map;
+ *     struct pmaplist *pml_map;
+ * };
+ *
+ * Compare that declaration with a corresponding xdr declaration that 
+ * is (a) pointer-less, and (b) recursive:
+ *
+ * typedef union switch (bool_t) {
+ * 
+ *     case TRUE: struct {
+ *             struct pmap;
+ *             pmaplist_t foo;
+ *     };
+ *
+ *     case FALSE: struct {};
+ * } pmaplist_t;
+ *
+ * Notice that the xdr declaration has no nxt pointer while
+ * the C declaration has no bool_t variable.  The bool_t can be
+ * interpreted as ``more data follows me''; if FALSE then nothing
+ * follows this bool_t; if TRUE then the bool_t is followed by
+ * an actual struct pmap, and then (recursively) by the 
+ * xdr union, pamplist_t.  
+ *
+ * This could be implemented via the xdr_union primitive, though this
+ * would cause a one recursive call per element in the list.  Rather than do
+ * that we can ``unwind'' the recursion
+ * into a while loop and do the union arms in-place.
+ *
+ * The head of the list is what the C programmer wishes to past around
+ * the net, yet is the data that the pointer points to which is interesting;
+ * this sounds like a job for xdr_reference!
+ */
+bool_t
+xdr_pmaplist(xdrs, rp)
+       register XDR *xdrs;
+       register struct pmaplist **rp;
+{
+       /*
+        * more_elements is pre-computed in case the direction is
+        * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
+        * xdr_bool when the direction is XDR_DECODE.
+        */
+       bool_t more_elements;
+       register int freeing = (xdrs->x_op == XDR_FREE);
+       register struct pmaplist **next;
+
+       while (TRUE) {
+               more_elements = (bool_t)(*rp != NULL);
+               if (! xdr_bool(xdrs, &more_elements))
+                       return (FALSE);
+               if (! more_elements)
+                       return (TRUE);  /* we are done */
+               /*
+                * the unfortunate side effect of non-recursion is that in
+                * the case of freeing we must remember the next object
+                * before we free the current object ...
+                */
+               if (freeing)
+                       next = &((*rp)->pml_next); 
+               if (! xdr_reference(xdrs, (caddr_t *)rp,
+                   (u_int)sizeof(struct pmaplist), xdr_pmap))
+                       return (FALSE);
+               rp = (freeing) ? next : &((*rp)->pml_next);
+       }
+}
diff --git a/sunrpc/rpc/auth_unix.h b/sunrpc/rpc/auth_unix.h
new file mode 100644 (file)
index 0000000..705741e
--- /dev/null
@@ -0,0 +1,72 @@
+/* @(#)auth_unix.h     2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)auth_unix.h 1.5 86/07/16 SMI      */
+
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * The system is very weak.  The client uses no encryption for  it
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ */
+
+/* The machine name is part of a credential; it may not exceed 255 bytes */
+#define MAX_MACHINE_NAME 255
+
+/* gids compose part of a credential; there may not be more than 16 of them */
+#define NGRPS 16
+
+/*
+ * Unix style credentials.
+ */
+struct authunix_parms {
+       u_long   aup_time;
+       char    *aup_machname;
+       int      aup_uid;
+       int      aup_gid;
+       u_int    aup_len;
+       int     *aup_gids;
+};
+
+extern bool_t xdr_authunix_parms();
+
+/* 
+ * If a response verifier has flavor AUTH_SHORT, 
+ * then the body of the response verifier encapsulates the following structure;
+ * again it is serialized in the obvious fashion.
+ */
+struct short_hand_verf {
+       struct opaque_auth new_cred;
+};
diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h
new file mode 100644 (file)
index 0000000..8c002a1
--- /dev/null
@@ -0,0 +1,331 @@
+/* @(#)clnt.h  2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _CLNT_
+#define _CLNT_
+
+/*
+ * Rpc calls return an enum clnt_stat.  This should be looked at more,
+ * since each implementation is required to live with this (implementation
+ * independent) list of errors.
+ */
+enum clnt_stat {
+       RPC_SUCCESS=0,                  /* call succeeded */
+       /*
+        * local errors
+        */
+       RPC_CANTENCODEARGS=1,           /* can't encode arguments */
+       RPC_CANTDECODERES=2,            /* can't decode results */
+       RPC_CANTSEND=3,                 /* failure in sending call */
+       RPC_CANTRECV=4,                 /* failure in receiving result */
+       RPC_TIMEDOUT=5,                 /* call timed out */
+       /*
+        * remote errors
+        */
+       RPC_VERSMISMATCH=6,             /* rpc versions not compatible */
+       RPC_AUTHERROR=7,                /* authentication error */
+       RPC_PROGUNAVAIL=8,              /* program not available */
+       RPC_PROGVERSMISMATCH=9,         /* program version mismatched */
+       RPC_PROCUNAVAIL=10,             /* procedure unavailable */
+       RPC_CANTDECODEARGS=11,          /* decode arguments error */
+       RPC_SYSTEMERROR=12,             /* generic "other problem" */
+
+       /*
+        * callrpc & clnt_create errors
+        */
+       RPC_UNKNOWNHOST=13,             /* unknown host name */
+       RPC_UNKNOWNPROTO=17,            /* unkown protocol */
+
+       /*
+        * _ create errors
+        */
+       RPC_PMAPFAILURE=14,             /* the pmapper failed in its call */
+       RPC_PROGNOTREGISTERED=15,       /* remote program is not registered */
+       /*
+        * unspecified error
+        */
+       RPC_FAILED=16
+};
+
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+       enum clnt_stat re_status;
+       union {
+               int RE_errno;           /* realated system error */
+               enum auth_stat RE_why;  /* why the auth error occurred */
+               struct {
+                       u_long low;     /* lowest verion supported */
+                       u_long high;    /* highest verion supported */
+               } RE_vers;
+               struct {                /* maybe meaningful if RPC_FAILED */
+                       long s1;
+                       long s2;
+               } RE_lb;                /* life boot & debugging only */
+       } ru;
+#define        re_errno        ru.RE_errno
+#define        re_why          ru.RE_why
+#define        re_vers         ru.RE_vers
+#define        re_lb           ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations, see e.g. rpc_udp.c.
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct {
+       AUTH    *cl_auth;                       /* authenticator */
+       struct clnt_ops {
+               enum clnt_stat  (*cl_call)();   /* call remote procedure */
+               void            (*cl_abort)();  /* abort a call */
+               void            (*cl_geterr)(); /* get specific error code */
+               bool_t          (*cl_freeres)(); /* frees results */
+               void            (*cl_destroy)();/* destroy this structure */
+               bool_t          (*cl_control)();/* the ioctl() of rpc */
+       } *cl_ops;
+       caddr_t                 cl_private;     /* private stuff */
+} CLIENT;
+
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ *     CLIENT *rh;
+ *     u_long proc;
+ *     xdrproc_t xargs;
+ *     caddr_t argsp;
+ *     xdrproc_t xres;
+ *     caddr_t resp;
+ *     struct timeval timeout;
+ */
+#define        CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)     \
+       ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+#define        clnt_call(rh, proc, xargs, argsp, xres, resp, secs)     \
+       ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_ABORT(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
+#define        clnt_abort(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_GETERR(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define        clnt_geterr(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ *     CLIENT *rh;
+ *     xdrproc_t xres;
+ *     caddr_t resp;
+ */
+#define        CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+#define        clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ *      CLIENT *cl;
+ *      u_int request;
+ *      char *info;
+ */
+#define        CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define        clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to both udp and tcp transports
+ */
+#define CLSET_TIMEOUT       1   /* set timeout (timeval) */
+#define CLGET_TIMEOUT       2   /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR   3   /* get server's address (sockaddr) */
+/*
+ * udp only control operations
+ */
+#define CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_DESTROY(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
+#define        clnt_destroy(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessable on every rpc
+ * transport/port.  It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM                ((u_long)1)
+#define RPCTEST_VERSION                ((u_long)1)
+#define RPCTEST_NULL_PROC      ((u_long)2)
+#define RPCTEST_NULL_BATCH_PROC        ((u_long)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((u_long)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc.  They can return NULL if a 
+ * creation failure occurs.
+ */
+
+/*
+ * Memory based rpc (for speed check and testing)
+ * CLIENT *
+ * clntraw_create(prog, vers)
+ *     u_long prog;
+ *     u_long vers;
+ */
+extern CLIENT *clntraw_create();
+
+
+/*
+ * Generic client creation routine. Supported protocols are "udp" and "tcp"
+ */
+extern CLIENT *
+clnt_create(/*host, prog, vers, prot*/); /*
+       char *host;     -- hostname
+       u_long prog;    -- program number
+       u_long vers;    -- version number
+       char *prot;     -- protocol
+*/
+
+
+
+
+/*
+ * TCP based rpc
+ * CLIENT *
+ * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ *     struct sockaddr_in *raddr;
+ *     u_long prog;
+ *     u_long version;
+ *     register int *sockp;
+ *     u_int sendsz;
+ *     u_int recvsz;
+ */
+extern CLIENT *clnttcp_create();
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ *     struct sockaddr_in *raddr;
+ *     u_long program;
+ *     u_long version;
+ *     struct timeval wait;
+ *     int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ *     struct sockaddr_in *raddr;
+ *     u_long program;
+ *     u_long version;
+ *     struct timeval wait;
+ *     int *sockp;
+ *     u_int sendsz;
+ *     u_int recvsz;
+ */
+extern CLIENT *clntudp_create();
+extern CLIENT *clntudp_bufcreate();
+
+/*
+ * Print why creation failed
+ */
+void clnt_pcreateerror(/* char *msg */);       /* stderr */
+char *clnt_spcreateerror(/* char *msg */);     /* string */
+
+/*
+ * Like clnt_perror(), but is more verbose in its output
+ */ 
+void clnt_perrno(/* enum clnt_stat num */);    /* stderr */
+
+/*
+ * Print an English error message, given the client error code
+ */
+void clnt_perror(/* CLIENT *clnt, char *msg */);       /* stderr */
+char *clnt_sperror(/* CLIENT *clnt, char *msg */);     /* string */
+
+/* 
+ * If a creation fails, the following allows the user to figure out why.
+ */
+struct rpc_createerr {
+       enum clnt_stat cf_stat;
+       struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
+};
+
+extern struct rpc_createerr rpc_createerr;
+
+
+
+/*
+ * Copy error message to buffer.
+ */
+char *clnt_sperrno(/* enum clnt_stat num */);  /* string */
+
+
+
+#define UDPMSGSIZE     8800    /* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE        400     /* a more reasonable packet size */
+
+#endif /*!_CLNT_*/
diff --git a/sunrpc/rpc/pmap_clnt.h b/sunrpc/rpc/pmap_clnt.h
new file mode 100644 (file)
index 0000000..d2ea2a8
--- /dev/null
@@ -0,0 +1,65 @@
+/* @(#)pmap_clnt.h     2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * Usage:
+ *     success = pmap_set(program, version, protocol, port);
+ *     success = pmap_unset(program, version);
+ *     port = pmap_getport(address, program, version, protocol);
+ *     head = pmap_getmaps(address);
+ *     clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ *             xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ *             (works for udp only.) 
+ *     clnt_stat = clnt_broadcast(program, version, procedure,
+ *             xdrargs, argsp, xdrres, resp, eachresult)
+ *             (like pmap_rmtcall, except the call is broadcasted to all
+ *             locally connected nets.  For each valid response received,
+ *             the procedure eachresult is called.  Its form is:
+ *     done = eachresult(resp, raddr)
+ *             bool_t done;
+ *             caddr_t resp;
+ *             struct sockaddr_in raddr;
+ *             where resp points to the results of the call and raddr is the
+ *             address if the responder to the broadcast.
+ */
+
+extern bool_t          pmap_set();
+extern bool_t          pmap_unset();
+extern struct pmaplist *pmap_getmaps();
+enum clnt_stat         pmap_rmtcall();
+enum clnt_stat         clnt_broadcast();
+extern u_short         pmap_getport();
diff --git a/sunrpc/rpc/pmap_prot.h b/sunrpc/rpc/pmap_prot.h
new file mode 100644 (file)
index 0000000..ccf7a77
--- /dev/null
@@ -0,0 +1,94 @@
+/* @(#)pmap_prot.h     2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ *     takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ *     TRUE is success, FALSE is failure.  Registers the tuple
+ *     [prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ *     TRUE is success, FALSE is failure.  Un-registers pair
+ *     [prog, vers].  prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ *     0 is failure.  Otherwise returns the port number where the pair
+ *     [prog, vers] is registered.  It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ *     RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ *     Calls the procedure on the local machine.  If it is not registered,
+ *     this procedure is quite; ie it does not return error information!!!
+ *     This procedure only is supported on rpc/udp and calls via
+ *     rpc/udp.  This routine only passes null authentication parameters.
+ *     This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#define PMAPPORT               ((u_short)111)
+#define PMAPPROG               ((u_long)100000)
+#define PMAPVERS               ((u_long)2)
+#define PMAPVERS_PROTO         ((u_long)2)
+#define PMAPVERS_ORIG          ((u_long)1)
+#define PMAPPROC_NULL          ((u_long)0)
+#define PMAPPROC_SET           ((u_long)1)
+#define PMAPPROC_UNSET         ((u_long)2)
+#define PMAPPROC_GETPORT       ((u_long)3)
+#define PMAPPROC_DUMP          ((u_long)4)
+#define PMAPPROC_CALLIT                ((u_long)5)
+
+struct pmap {
+       long unsigned pm_prog;
+       long unsigned pm_vers;
+       long unsigned pm_prot;
+       long unsigned pm_port;
+};
+
+extern bool_t xdr_pmap();
+
+struct pmaplist {
+       struct pmap     pml_map;
+       struct pmaplist *pml_next;
+};
+
+extern bool_t xdr_pmaplist();
diff --git a/sunrpc/rpc/pmap_rmt.h b/sunrpc/rpc/pmap_rmt.h
new file mode 100644 (file)
index 0000000..ee68ceb
--- /dev/null
@@ -0,0 +1,53 @@
+/* @(#)pmap_rmt.h      2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+struct rmtcallargs {
+       u_long prog, vers, proc, arglen;
+       caddr_t args_ptr;
+       xdrproc_t xdr_args;
+};
+
+bool_t xdr_rmtcall_args();
+
+struct rmtcallres {
+       u_long *port_ptr;
+       u_long resultslen;
+       caddr_t results_ptr;
+       xdrproc_t xdr_results;
+};
+
+bool_t xdr_rmtcallres();
diff --git a/sunrpc/rpc/rpc.h b/sunrpc/rpc/rpc.h
new file mode 100644 (file)
index 0000000..83a124a
--- /dev/null
@@ -0,0 +1,73 @@
+/* @(#)rpc.h   2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+#ifndef __RPC_HEADER__
+#define __RPC_HEADER__
+
+#include <rpc/types.h>         /* some typedefs */
+#include <netinet/in.h>
+
+/* external data representation interfaces */
+#include <rpc/xdr.h>           /* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h>          /* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h>          /* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h>       /* protocol for rpc messages */
+#include <rpc/auth_unix.h>     /* protocol for unix style cred */
+/*
+ *  Uncomment-out the next line if you are building the rpc library with    
+ *  DES Authentication (see the README file in the secure_rpc/ directory).
+ */
+/*#include <rpc/auth_des.h>    /* protocol for des style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h>           /* service manager and multiplexer */
+#include <rpc/svc_auth.h>      /* service side authenticator */
+
+/*
+ * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION
+ * OF UNIX BASED ON NFSSRC.  These systems will already have the structures
+ * defined by <rpc/netdb.h> included in <netdb.h>.
+ */
+/* routines for parsing /etc/rpc */
+#include <rpc/netdb.h>         /* structures and routines to parse /etc/rpc */
+
+#endif /* ndef __RPC_HEADER__ */
diff --git a/sunrpc/rpc/rpc_msg.h b/sunrpc/rpc/rpc_msg.h
new file mode 100644 (file)
index 0000000..b78872b
--- /dev/null
@@ -0,0 +1,187 @@
+/* @(#)rpc_msg.h       2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)rpc_msg.h 1.7 86/07/16 SMI      */
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#define RPC_MSG_VERSION                ((u_long) 2)
+#define RPC_SERVICE_PORT       ((u_short) 2048)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall stuct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+       CALL=0,
+       REPLY=1
+};
+
+enum reply_stat {
+       MSG_ACCEPTED=0,
+       MSG_DENIED=1
+};
+
+enum accept_stat {
+       SUCCESS=0,
+       PROG_UNAVAIL=1,
+       PROG_MISMATCH=2,
+       PROC_UNAVAIL=3,
+       GARBAGE_ARGS=4,
+       SYSTEM_ERR=5
+};
+
+enum reject_stat {
+       RPC_MISMATCH=0,
+       AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+       struct opaque_auth      ar_verf;
+       enum accept_stat        ar_stat;
+       union {
+               struct {
+                       u_long  low;
+                       u_long  high;
+               } AR_versions;
+               struct {
+                       caddr_t where;
+                       xdrproc_t proc;
+               } AR_results;
+               /* and many other null cases */
+       } ru;
+#define        ar_results      ru.AR_results
+#define        ar_vers         ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+       enum reject_stat rj_stat;
+       union {
+               struct {
+                       u_long low;
+                       u_long high;
+               } RJ_versions;
+               enum auth_stat RJ_why;  /* why authentication did not work */
+       } ru;
+#define        rj_vers ru.RJ_versions
+#define        rj_why  ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+       enum reply_stat rp_stat;
+       union {
+               struct accepted_reply RP_ar;
+               struct rejected_reply RP_dr;
+       } ru;
+#define        rp_acpt ru.RP_ar
+#define        rp_rjct ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+       u_long cb_rpcvers;      /* must be equal to two */
+       u_long cb_prog;
+       u_long cb_vers;
+       u_long cb_proc;
+       struct opaque_auth cb_cred;
+       struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+       u_long                  rm_xid;
+       enum msg_type           rm_direction;
+       union {
+               struct call_body RM_cmb;
+               struct reply_body RM_rmb;
+       } ru;
+#define        rm_call         ru.RM_cmb
+#define        rm_reply        ru.RM_rmb
+};
+#define        acpted_rply     ru.RM_rmb.ru.RP_ar
+#define        rjcted_rply     ru.RM_rmb.ru.RP_dr
+
+
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *cmsg;
+ */
+extern bool_t  xdr_callmsg();
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *cmsg;
+ */
+extern bool_t  xdr_callhdr();
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *rmsg;
+ */
+extern bool_t  xdr_replymsg();
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ *     struct rpc_msg *msg;
+ *     struct rpc_err *error;
+ */
+extern void    _seterr_reply();
diff --git a/sunrpc/rpc/svc.h b/sunrpc/rpc/svc.h
new file mode 100644 (file)
index 0000000..3cb07ef
--- /dev/null
@@ -0,0 +1,280 @@
+/* @(#)svc.h   2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef __SVC_HEADER__
+#define __SVC_HEADER__
+
+/*
+ * This interface must manage two items concerning remote procedure calling:
+ *
+ * 1) An arbitrary number of transport connections upon which rpc requests
+ * are received.  The two most notable transports are TCP and UDP;  they are
+ * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
+ * they in turn call xprt_register and xprt_unregister.
+ *
+ * 2) An arbitrary number of locally registered services.  Services are
+ * described by the following four data: program number, version number,
+ * "service dispatch" function, a transport handle, and a boolean that
+ * indicates whether or not the exported program should be registered with a
+ * local binder service;  if true the program's number and version and the
+ * port number from the transport handle are registered with the binder.
+ * These data are registered with the rpc svc system via svc_register.
+ *
+ * A service's dispatch function is called whenever an rpc request comes in
+ * on a transport.  The request's program and version numbers must match
+ * those of the registered service.  The dispatch function is passed two
+ * parameters, struct svc_req * and SVCXPRT *, defined below.
+ */
+
+enum xprt_stat {
+       XPRT_DIED,
+       XPRT_MOREREQS,
+       XPRT_IDLE
+};
+
+/*
+ * Server side transport handle
+ */
+typedef struct {
+       int             xp_sock;
+       u_short         xp_port;         /* associated port number */
+       struct xp_ops {
+           bool_t      (*xp_recv)();    /* receive incomming requests */
+           enum xprt_stat (*xp_stat)(); /* get transport status */
+           bool_t      (*xp_getargs)(); /* get arguments */
+           bool_t      (*xp_reply)();   /* send reply */
+           bool_t      (*xp_freeargs)();/* free mem allocated for args */
+           void        (*xp_destroy)(); /* destroy this struct */
+       } *xp_ops;
+       int             xp_addrlen;      /* length of remote address */
+       struct sockaddr_in xp_raddr;     /* remote address */
+       struct opaque_auth xp_verf;      /* raw response verifier */
+       caddr_t         xp_p1;           /* private */
+       caddr_t         xp_p2;           /* private */
+} SVCXPRT;
+
+/*
+ *  Approved way of getting address of caller
+ */
+#define svc_getcaller(x) (&(x)->xp_raddr)
+
+/*
+ * Operations defined on an SVCXPRT handle
+ *
+ * SVCXPRT             *xprt;
+ * struct rpc_msg      *msg;
+ * xdrproc_t            xargs;
+ * caddr_t              argsp;
+ */
+#define SVC_RECV(xprt, msg)                            \
+       (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+#define svc_recv(xprt, msg)                            \
+       (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+
+#define SVC_STAT(xprt)                                 \
+       (*(xprt)->xp_ops->xp_stat)(xprt)
+#define svc_stat(xprt)                                 \
+       (*(xprt)->xp_ops->xp_stat)(xprt)
+
+#define SVC_GETARGS(xprt, xargs, argsp)                        \
+       (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+#define svc_getargs(xprt, xargs, argsp)                        \
+       (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+
+#define SVC_REPLY(xprt, msg)                           \
+       (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+#define svc_reply(xprt, msg)                           \
+       (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+
+#define SVC_FREEARGS(xprt, xargs, argsp)               \
+       (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+#define svc_freeargs(xprt, xargs, argsp)               \
+       (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+
+#define SVC_DESTROY(xprt)                              \
+       (*(xprt)->xp_ops->xp_destroy)(xprt)
+#define svc_destroy(xprt)                              \
+       (*(xprt)->xp_ops->xp_destroy)(xprt)
+
+
+/*
+ * Service request
+ */
+struct svc_req {
+       u_long          rq_prog;        /* service program number */
+       u_long          rq_vers;        /* service protocol version */
+       u_long          rq_proc;        /* the desired procedure */
+       struct opaque_auth rq_cred;     /* raw creds from the wire */
+       caddr_t         rq_clntcred;    /* read only cooked cred */
+       SVCXPRT *rq_xprt;               /* associated transport */
+};
+
+
+/*
+ * Service registration
+ *
+ * svc_register(xprt, prog, vers, dispatch, protocol)
+ *     SVCXPRT *xprt;
+ *     u_long prog;
+ *     u_long vers;
+ *     void (*dispatch)();
+ *     int protocol;  /* like TCP or UDP, zero means do not register 
+ */
+extern bool_t  svc_register();
+
+/*
+ * Service un-registration
+ *
+ * svc_unregister(prog, vers)
+ *     u_long prog;
+ *     u_long vers;
+ */
+extern void    svc_unregister();
+
+/*
+ * Transport registration.
+ *
+ * xprt_register(xprt)
+ *     SVCXPRT *xprt;
+ */
+extern void    xprt_register();
+
+/*
+ * Transport un-register
+ *
+ * xprt_unregister(xprt)
+ *     SVCXPRT *xprt;
+ */
+extern void    xprt_unregister();
+
+
+
+
+/*
+ * When the service routine is called, it must first check to see if it
+ * knows about the procedure;  if not, it should call svcerr_noproc
+ * and return.  If so, it should deserialize its arguments via 
+ * SVC_GETARGS (defined above).  If the deserialization does not work,
+ * svcerr_decode should be called followed by a return.  Successful
+ * decoding of the arguments should be followed the execution of the
+ * procedure's code and a call to svc_sendreply.
+ *
+ * Also, if the service refuses to execute the procedure due to too-
+ * weak authentication parameters, svcerr_weakauth should be called.
+ * Note: do not confuse access-control failure with weak authentication!
+ *
+ * NB: In pure implementations of rpc, the caller always waits for a reply
+ * msg.  This message is sent when svc_sendreply is called.  
+ * Therefore pure service implementations should always call
+ * svc_sendreply even if the function logically returns void;  use
+ * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
+ * for the abuse of pure rpc via batched calling or pipelining.  In the
+ * case of a batched call, svc_sendreply should NOT be called since
+ * this would send a return message, which is what batching tries to avoid.
+ * It is the service/protocol writer's responsibility to know which calls are
+ * batched and which are not.  Warning: responding to batch calls may
+ * deadlock the caller and server processes!
+ */
+
+extern bool_t  svc_sendreply();
+extern void    svcerr_decode();
+extern void    svcerr_weakauth();
+extern void    svcerr_noproc();
+extern void    svcerr_progvers();
+extern void    svcerr_auth();
+extern void    svcerr_noprog();
+extern void    svcerr_systemerr();
+    
+/*
+ * Lowest level dispatching -OR- who owns this process anyway.
+ * Somebody has to wait for incoming requests and then call the correct
+ * service routine.  The routine svc_run does infinite waiting; i.e.,
+ * svc_run never returns.
+ * Since another (co-existant) package may wish to selectively wait for
+ * incoming calls or other events outside of the rpc architecture, the
+ * routine svc_getreq is provided.  It must be passed readfds, the
+ * "in-place" results of a select system call (see select, section 2).
+ */
+
+/*
+ * Global keeper of rpc service descriptors in use
+ * dynamic; must be inspected before each call to select 
+ */
+#ifdef FD_SETSIZE
+extern fd_set svc_fdset;
+#define svc_fds svc_fdset.fds_bits[0]  /* compatibility */
+#else
+extern int svc_fds;
+#endif /* def FD_SETSIZE */
+
+/*
+ * a small program implemented by the svc_rpc implementation itself;
+ * also see clnt.h for protocol numbers.
+ */
+extern void rpctest_service();
+
+extern void    svc_getreq();
+extern void    svc_getreqset();        /* takes fdset instead of int */
+extern void    svc_run();       /* never returns */
+
+/*
+ * Socket to use on svcxxx_create call to get default socket
+ */
+#define        RPC_ANYSOCK     -1
+
+/*
+ * These are the existing service side transport implementations
+ */
+
+/*
+ * Memory based rpc for testing and timing.
+ */
+extern SVCXPRT *svcraw_create();
+
+/*
+ * Udp based rpc.
+ */
+extern SVCXPRT *svcudp_create();
+extern SVCXPRT *svcudp_bufcreate();
+
+/*
+ * Tcp based rpc.
+ */
+extern SVCXPRT *svctcp_create();
+
+
+
+#endif !__SVC_HEADER__
diff --git a/sunrpc/rpc/svc_auth.h b/sunrpc/rpc/svc_auth.h
new file mode 100644 (file)
index 0000000..a36a01a
--- /dev/null
@@ -0,0 +1,42 @@
+/* @(#)svc_auth.h      2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)svc_auth.h 1.6 86/07/16 SMI      */
+
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+/*
+ * Server side authenticator
+ */
+extern enum auth_stat _authenticate();
diff --git a/sunrpc/rpc/types.h b/sunrpc/rpc/types.h
new file mode 100644 (file)
index 0000000..1f620ef
--- /dev/null
@@ -0,0 +1,63 @@
+/* @(#)types.h 2.3 88/08/15 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)types.h 1.18 87/07/24 SMI      */
+
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef __TYPES_RPC_HEADER__
+#define __TYPES_RPC_HEADER__
+
+#define        bool_t  int
+#define        enum_t  int
+#define        FALSE   (0)
+#define        TRUE    (1)
+#define __dontcare__   -1
+#ifndef NULL
+#      define NULL 0
+#endif
+
+extern char *malloc();
+#define mem_alloc(bsize)       malloc(bsize)
+#define mem_free(ptr, bsize)   free(ptr)
+
+#ifndef makedev /* ie, we haven't already included it */
+#include <sys/types.h>
+#endif
+#include <sys/time.h>
+
+#ifndef INADDR_LOOPBACK
+#define       INADDR_LOOPBACK         (u_long)0x7F000001
+#endif
+#ifndef MAXHOSTNAMELEN
+#define        MAXHOSTNAMELEN  64
+#endif
+
+#endif /* ndef __TYPES_RPC_HEADER__ */
diff --git a/sunrpc/rpc/xdr.h b/sunrpc/rpc/xdr.h
new file mode 100644 (file)
index 0000000..6cd3e6f
--- /dev/null
@@ -0,0 +1,270 @@
+/* @(#)xdr.h   2.2 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)xdr.h 1.19 87/04/22 SMI      */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef __XDR_HEADER__
+#define __XDR_HEADER__
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation.  Library supplied
+ * routines provide for the conversion on built-in C data types.  These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ *     bool_t
+ *     xdrproc(xdrs, argresp)
+ *             XDR *xdrs;
+ *             <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted.  argresp is a pointer to the structure to be
+ * converted.  The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null.  This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
+ * stream.  XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+       XDR_ENCODE=0,
+       XDR_DECODE=1,
+       XDR_FREE=2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT     (4)
+#define RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+                   * BYTES_PER_XDR_UNIT)
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded.  If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ * bool_t      (*xdrproc_t)(XDR *, caddr_t *);
+ */
+typedef        bool_t (*xdrproc_t)();
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular impelementation.
+ */
+typedef struct {
+       enum xdr_op     x_op;           /* operation; fast additional param */
+       struct xdr_ops {
+               bool_t  (*x_getlong)(); /* get a long from underlying stream */
+               bool_t  (*x_putlong)(); /* put a long to " */
+               bool_t  (*x_getbytes)();/* get some bytes from " */
+               bool_t  (*x_putbytes)();/* put some bytes to " */
+               u_int   (*x_getpostn)();/* returns bytes off from beginning */
+               bool_t  (*x_setpostn)();/* lets you reposition the stream */
+               long *  (*x_inline)();  /* buf quick ptr to buffered data */
+               void    (*x_destroy)(); /* free privates of this xdr_stream */
+       } *x_ops;
+       caddr_t         x_public;       /* users' data */
+       caddr_t         x_private;      /* pointer to private data */
+       caddr_t         x_base;         /* private used for position info */
+       int             x_handy;        /* extra private word */
+} XDR;
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR         *xdrs;
+ * long                *longp;
+ * caddr_t      addr;
+ * u_int        len;
+ * u_int        pos;
+ */
+#define XDR_GETLONG(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs)                               \
+       (*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs)                               \
+       (*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos)                          \
+       (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos)                          \
+       (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define        XDR_INLINE(xdrs, len)                           \
+       (*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define        xdr_inline(xdrs, len)                           \
+       (*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define        XDR_DESTROY(xdrs)                               \
+       if ((xdrs)->x_ops->x_destroy)                   \
+               (*(xdrs)->x_ops->x_destroy)(xdrs)
+#define        xdr_destroy(xdrs)                               \
+       if ((xdrs)->x_ops->x_destroy)                   \
+               (*(xdrs)->x_ops->x_destroy)(xdrs)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * a entry with a null procedure pointer.  The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value.  If a match is found the associated xdr routine
+ * is called to handle that part of the union.  If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim {
+       int     value;
+       xdrproc_t proc;
+};
+
+/*
+ * In-line routines for fast encode/decode of primitve data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned.  The standard way to use these
+ * is to say:
+ *     if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ *             return (FALSE);
+ *     <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+#define IXDR_GET_LONG(buf)             ((long)ntohl((u_long)*(buf)++))
+#define IXDR_PUT_LONG(buf, v)          (*(buf)++ = (long)htonl((u_long)v))
+
+#define IXDR_GET_BOOL(buf)             ((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t)          ((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_LONG(buf)           ((u_long)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf)            ((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf)          ((u_short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v)          IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_ENUM(buf, v)          IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_LONG(buf, v)                IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_SHORT(buf, v)         IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_SHORT(buf, v)       IXDR_PUT_LONG((buf), ((long)(v)))
+
+/*
+ * These are the "generic" xdr routines.
+ */
+extern bool_t  xdr_void();
+extern bool_t  xdr_int();
+extern bool_t  xdr_u_int();
+extern bool_t  xdr_long();
+extern bool_t  xdr_u_long();
+extern bool_t  xdr_short();
+extern bool_t  xdr_u_short();
+extern bool_t  xdr_bool();
+extern bool_t  xdr_enum();
+extern bool_t  xdr_array();
+extern bool_t  xdr_bytes();
+extern bool_t  xdr_opaque();
+extern bool_t  xdr_string();
+extern bool_t  xdr_union();
+extern bool_t  xdr_char();
+extern bool_t  xdr_u_char();
+extern bool_t  xdr_vector();
+extern bool_t  xdr_float();
+extern bool_t  xdr_double();
+extern bool_t  xdr_reference();
+extern bool_t  xdr_pointer();
+extern bool_t  xdr_wrapstring();
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024 
+struct netobj {
+       u_int   n_len;
+       char    *n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t   xdr_netobj();
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+extern void   xdrmem_create();         /* XDR using memory buffers */
+extern void   xdrstdio_create();       /* XDR using stdio library */
+extern void   xdrrec_create();         /* XDR pseudo records for tcp */
+extern bool_t xdrrec_endofrecord();    /* make end of xdr record */
+extern bool_t xdrrec_skiprecord();     /* move to beginning of next record */
+extern bool_t xdrrec_eof();            /* true if no more input */
+
+#endif !__XDR_HEADER__
diff --git a/sunrpc/rpc_cmsg.c b/sunrpc/rpc_cmsg.c
new file mode 100644 (file)
index 0000000..d9d815a
--- /dev/null
@@ -0,0 +1,190 @@
+/* @(#)rpc_callmsg.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/*
+ * XDR a call message
+ */
+bool_t
+xdr_callmsg(xdrs, cmsg)
+       register XDR *xdrs;
+       register struct rpc_msg *cmsg;
+{
+       register long *buf;
+       register struct opaque_auth *oa;
+
+       if (xdrs->x_op == XDR_ENCODE) {
+               if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
+                       return (FALSE);
+               }
+               if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
+                       return (FALSE);
+               }
+               buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
+                       + RNDUP(cmsg->rm_call.cb_cred.oa_length)
+                       + 2 * BYTES_PER_XDR_UNIT
+                       + RNDUP(cmsg->rm_call.cb_verf.oa_length));
+               if (buf != NULL) {
+                       IXDR_PUT_LONG(buf, cmsg->rm_xid);
+                       IXDR_PUT_ENUM(buf, cmsg->rm_direction);
+                       if (cmsg->rm_direction != CALL) {
+                               return (FALSE);
+                       }
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
+                       if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+                               return (FALSE);
+                       }
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
+                       IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
+                       oa = &cmsg->rm_call.cb_cred;
+                       IXDR_PUT_ENUM(buf, oa->oa_flavor);
+                       IXDR_PUT_LONG(buf, oa->oa_length);
+                       if (oa->oa_length) {
+                               bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+                               buf += RNDUP(oa->oa_length) / sizeof (long);
+                       }
+                       oa = &cmsg->rm_call.cb_verf;
+                       IXDR_PUT_ENUM(buf, oa->oa_flavor);
+                       IXDR_PUT_LONG(buf, oa->oa_length);
+                       if (oa->oa_length) {
+                               bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+                               /* no real need....
+                               buf += RNDUP(oa->oa_length) / sizeof (long);
+                               */
+                       }
+                       return (TRUE);
+               }
+       }
+       if (xdrs->x_op == XDR_DECODE) {
+               buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+               if (buf != NULL) {
+                       cmsg->rm_xid = IXDR_GET_LONG(buf);
+                       cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
+                       if (cmsg->rm_direction != CALL) {
+                               return (FALSE);
+                       }
+                       cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
+                       if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+                               return (FALSE);
+                       }
+                       cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
+                       cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
+                       cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
+                       oa = &cmsg->rm_call.cb_cred;
+                       oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+                       oa->oa_length = IXDR_GET_LONG(buf);
+                       if (oa->oa_length) {
+                               if (oa->oa_length > MAX_AUTH_BYTES) {
+                                       return (FALSE);
+                               }
+                               if (oa->oa_base == NULL) {
+                                       oa->oa_base = (caddr_t)
+                                               mem_alloc(oa->oa_length);
+                               }
+                               buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+                               if (buf == NULL) {
+                                       if (xdr_opaque(xdrs, oa->oa_base,
+                                           oa->oa_length) == FALSE) {
+                                               return (FALSE);
+                                       }
+                               } else {
+                                       bcopy((caddr_t)buf, oa->oa_base,
+                                           oa->oa_length);
+                                       /* no real need....
+                                       buf += RNDUP(oa->oa_length) /
+                                               sizeof (long);
+                                       */
+                               }
+                       }
+                       oa = &cmsg->rm_call.cb_verf;
+                       buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+                       if (buf == NULL) {
+                               if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
+                                   xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
+                                       return (FALSE);
+                               }
+                       } else {
+                               oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+                               oa->oa_length = IXDR_GET_LONG(buf);
+                       }
+                       if (oa->oa_length) {
+                               if (oa->oa_length > MAX_AUTH_BYTES) {
+                                       return (FALSE);
+                               }
+                               if (oa->oa_base == NULL) {
+                                       oa->oa_base = (caddr_t)
+                                               mem_alloc(oa->oa_length);
+                               }
+                               buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+                               if (buf == NULL) {
+                                       if (xdr_opaque(xdrs, oa->oa_base,
+                                           oa->oa_length) == FALSE) {
+                                               return (FALSE);
+                                       }
+                               } else {
+                                       bcopy((caddr_t)buf, oa->oa_base,
+                                           oa->oa_length);
+                                       /* no real need...
+                                       buf += RNDUP(oa->oa_length) /
+                                               sizeof (long);
+                                       */
+                               }
+                       }
+                       return (TRUE);
+               }
+       }
+       if (
+           xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+           xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+           (cmsg->rm_direction == CALL) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+           (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) &&
+           xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
+           return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
+       return (FALSE);
+}
+
diff --git a/sunrpc/rpc_common.c b/sunrpc/rpc_common.c
new file mode 100644 (file)
index 0000000..75cead0
--- /dev/null
@@ -0,0 +1,41 @@
+/* @(#)rpc_commondata.c        2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#include <rpc/rpc.h>
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces 
+ */
+struct opaque_auth _null_auth;
+#ifdef FD_SETSIZE
+fd_set svc_fdset;
+#else
+int svc_fds;
+#endif /* def FD_SETSIZE */
+struct rpc_createerr rpc_createerr;
diff --git a/sunrpc/rpc_dtable.c b/sunrpc/rpc_dtable.c
new file mode 100644 (file)
index 0000000..a848817
--- /dev/null
@@ -0,0 +1,46 @@
+/* @(#)rpc_dtablesize.c        2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";
+#endif
+
+/*
+ * Cache the result of getdtablesize(), so we don't have to do an
+ * expensive system call every time.
+ */
+_rpc_dtablesize()
+{
+       static int size;
+       
+       if (size == 0) {
+               size = getdtablesize();
+       }
+       return (size);
+}
diff --git a/sunrpc/rpc_prot.c b/sunrpc/rpc_prot.c
new file mode 100644 (file)
index 0000000..4b1319a
--- /dev/null
@@ -0,0 +1,289 @@
+/* @(#)rpc_prot.c      2.3 88/08/07 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+struct opaque_auth _null_auth;
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t
+xdr_opaque_auth(xdrs, ap)
+       register XDR *xdrs;
+       register struct opaque_auth *ap;
+{
+
+       if (xdr_enum(xdrs, &(ap->oa_flavor)))
+               return (xdr_bytes(xdrs, &ap->oa_base,
+                       &ap->oa_length, MAX_AUTH_BYTES));
+       return (FALSE);
+}
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block(xdrs, blkp)
+       register XDR *xdrs;
+       register des_block *blkp;
+{
+       return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+bool_t 
+xdr_accepted_reply(xdrs, ar)
+       register XDR *xdrs;   
+       register struct accepted_reply *ar;
+{
+
+       /* personalized union, rather than calling xdr_union */
+       if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
+               return (FALSE);
+       if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
+               return (FALSE);
+       switch (ar->ar_stat) {
+
+       case SUCCESS:
+               return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
+
+       case PROG_MISMATCH:
+               if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
+                       return (FALSE);
+               return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
+       }
+       return (TRUE);  /* TRUE => open ended set of problems */
+}
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+bool_t 
+xdr_rejected_reply(xdrs, rr)
+       register XDR *xdrs;
+       register struct rejected_reply *rr;
+{
+
+       /* personalized union, rather than calling xdr_union */
+       if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
+               return (FALSE);
+       switch (rr->rj_stat) {
+
+       case RPC_MISMATCH:
+               if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
+                       return (FALSE);
+               return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
+
+       case AUTH_ERROR:
+               return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
+       }
+       return (FALSE);
+}
+
+static struct xdr_discrim reply_dscrm[3] = {
+       { (int)MSG_ACCEPTED, xdr_accepted_reply },
+       { (int)MSG_DENIED, xdr_rejected_reply },
+       { __dontcare__, NULL_xdrproc_t } };
+
+/*
+ * XDR a reply message
+ */
+bool_t
+xdr_replymsg(xdrs, rmsg)
+       register XDR *xdrs;
+       register struct rpc_msg *rmsg;
+{
+       if (
+           xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
+           xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
+           (rmsg->rm_direction == REPLY) )
+               return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
+                  (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
+       return (FALSE);
+}
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t
+xdr_callhdr(xdrs, cmsg)
+       register XDR *xdrs;
+       register struct rpc_msg *cmsg;
+{
+
+       cmsg->rm_direction = CALL;
+       cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
+       if (
+           (xdrs->x_op == XDR_ENCODE) &&
+           xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+           xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+           xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
+           return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
+       return (FALSE);
+}
+
+/* ************************** Client utility routine ************* */
+
+static void
+accepted(acpt_stat, error)
+       register enum accept_stat acpt_stat;
+       register struct rpc_err *error;
+{
+
+       switch (acpt_stat) {
+
+       case PROG_UNAVAIL:
+               error->re_status = RPC_PROGUNAVAIL;
+               return;
+
+       case PROG_MISMATCH:
+               error->re_status = RPC_PROGVERSMISMATCH;
+               return;
+
+       case PROC_UNAVAIL:
+               error->re_status = RPC_PROCUNAVAIL;
+               return;
+
+       case GARBAGE_ARGS:
+               error->re_status = RPC_CANTDECODEARGS;
+               return;
+
+       case SYSTEM_ERR:
+               error->re_status = RPC_SYSTEMERROR;
+               return;
+
+       case SUCCESS:
+               error->re_status = RPC_SUCCESS;
+               return;
+       }
+       /* something's wrong, but we don't know what ... */
+       error->re_status = RPC_FAILED;
+       error->re_lb.s1 = (long)MSG_ACCEPTED;
+       error->re_lb.s2 = (long)acpt_stat;
+}
+
+static void 
+rejected(rjct_stat, error)
+       register enum reject_stat rjct_stat;
+       register struct rpc_err *error;
+{
+
+       switch (rjct_stat) {
+
+       case RPC_VERSMISMATCH:
+               error->re_status = RPC_VERSMISMATCH;
+               return;
+
+       case AUTH_ERROR:
+               error->re_status = RPC_AUTHERROR;
+               return;
+       }
+       /* something's wrong, but we don't know what ... */
+       error->re_status = RPC_FAILED;
+       error->re_lb.s1 = (long)MSG_DENIED;
+       error->re_lb.s2 = (long)rjct_stat;
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void
+_seterr_reply(msg, error)
+       register struct rpc_msg *msg;
+       register struct rpc_err *error;
+{
+
+       /* optimized for normal, SUCCESSful case */
+       switch (msg->rm_reply.rp_stat) {
+
+       case MSG_ACCEPTED:
+               if (msg->acpted_rply.ar_stat == SUCCESS) {
+                       error->re_status = RPC_SUCCESS;
+                       return;
+               };
+               accepted(msg->acpted_rply.ar_stat, error);
+               break;
+
+       case MSG_DENIED:
+               rejected(msg->rjcted_rply.rj_stat, error);
+               break;
+
+       default:
+               error->re_status = RPC_FAILED;
+               error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
+               break;
+       }
+       switch (error->re_status) {
+
+       case RPC_VERSMISMATCH:
+               error->re_vers.low = msg->rjcted_rply.rj_vers.low;
+               error->re_vers.high = msg->rjcted_rply.rj_vers.high;
+               break;
+
+       case RPC_AUTHERROR:
+               error->re_why = msg->rjcted_rply.rj_why;
+               break;
+
+       case RPC_PROGVERSMISMATCH:
+               error->re_vers.low = msg->acpted_rply.ar_vers.low;
+               error->re_vers.high = msg->acpted_rply.ar_vers.high;
+               break;
+       }
+}
diff --git a/sunrpc/svc.c b/sunrpc/svc.c
new file mode 100644 (file)
index 0000000..3327ee5
--- /dev/null
@@ -0,0 +1,479 @@
+/* @(#)svc.c   2.4 88/08/11 4.0 RPCSRC; from 1.44 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc.c, Server-side remote procedure call interface.
+ *
+ * There are two sets of procedures here.  The xprt routines are
+ * for handling transport handles.  The svc routines handle the
+ * list of service routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <sys/errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+extern int errno;
+
+#ifdef FD_SETSIZE
+static SVCXPRT **xports;
+#else
+#define NOFILE 32
+
+static SVCXPRT *xports[NOFILE];
+#endif /* def FD_SETSIZE */
+
+#define NULL_SVC ((struct svc_callout *)0)
+#define        RQCRED_SIZE     400             /* this size is excessive */
+
+/*
+ * The services list
+ * Each entry represents a set of procedures (an rpc program).
+ * The dispatch routine takes request structs and runs the
+ * apropriate procedure.
+ */
+static struct svc_callout {
+       struct svc_callout *sc_next;
+       u_long              sc_prog;
+       u_long              sc_vers;
+       void                (*sc_dispatch)();
+} *svc_head;
+
+static struct svc_callout *svc_find();
+
+/* ***************  SVCXPRT related stuff **************** */
+
+/*
+ * Activate a transport handle.
+ */
+void
+xprt_register(xprt)
+       SVCXPRT *xprt;
+{
+       register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+       if (xports == NULL) {
+               xports = (SVCXPRT **)
+                       mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *));
+       }
+       if (sock < _rpc_dtablesize()) {
+               xports[sock] = xprt;
+               FD_SET(sock, &svc_fdset);
+       }
+#else
+       if (sock < NOFILE) {
+               xports[sock] = xprt;
+               svc_fds |= (1 << sock);
+       }
+#endif /* def FD_SETSIZE */
+
+}
+
+/*
+ * De-activate a transport handle. 
+ */
+void
+xprt_unregister(xprt) 
+       SVCXPRT *xprt;
+{ 
+       register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+       if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) {
+               xports[sock] = (SVCXPRT *)0;
+               FD_CLR(sock, &svc_fdset);
+       }
+#else
+       if ((sock < NOFILE) && (xports[sock] == xprt)) {
+               xports[sock] = (SVCXPRT *)0;
+               svc_fds &= ~(1 << sock);
+       }
+#endif /* def FD_SETSIZE */
+}
+
+
+/* ********************** CALLOUT list related stuff ************* */
+
+/*
+ * Add a service program to the callout list.
+ * The dispatch routine will be called when a rpc request for this
+ * program number comes in.
+ */
+bool_t
+svc_register(xprt, prog, vers, dispatch, protocol)
+       SVCXPRT *xprt;
+       u_long prog;
+       u_long vers;
+       void (*dispatch)();
+       int protocol;
+{
+       struct svc_callout *prev;
+       register struct svc_callout *s;
+
+       if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
+               if (s->sc_dispatch == dispatch)
+                       goto pmap_it;  /* he is registering another xptr */
+               return (FALSE);
+       }
+       s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
+       if (s == (struct svc_callout *)0) {
+               return (FALSE);
+       }
+       s->sc_prog = prog;
+       s->sc_vers = vers;
+       s->sc_dispatch = dispatch;
+       s->sc_next = svc_head;
+       svc_head = s;
+pmap_it:
+       /* now register the information with the local binder service */
+       if (protocol) {
+               return (pmap_set(prog, vers, protocol, xprt->xp_port));
+       }
+       return (TRUE);
+}
+
+/*
+ * Remove a service program from the callout list.
+ */
+void
+svc_unregister(prog, vers)
+       u_long prog;
+       u_long vers;
+{
+       struct svc_callout *prev;
+       register struct svc_callout *s;
+
+       if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
+               return;
+       if (prev == NULL_SVC) {
+               svc_head = s->sc_next;
+       } else {
+               prev->sc_next = s->sc_next;
+       }
+       s->sc_next = NULL_SVC;
+       mem_free((char *) s, (u_int) sizeof(struct svc_callout));
+       /* now unregister the information with the local binder service */
+       (void)pmap_unset(prog, vers);
+}
+
+/*
+ * Search the callout list for a program number, return the callout
+ * struct.
+ */
+static struct svc_callout *
+svc_find(prog, vers, prev)
+       u_long prog;
+       u_long vers;
+       struct svc_callout **prev;
+{
+       register struct svc_callout *s, *p;
+
+       p = NULL_SVC;
+       for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+               if ((s->sc_prog == prog) && (s->sc_vers == vers))
+                       goto done;
+               p = s;
+       }
+done:
+       *prev = p;
+       return (s);
+}
+
+/* ******************* REPLY GENERATION ROUTINES  ************ */
+
+/*
+ * Send a reply to an rpc request
+ */
+bool_t
+svc_sendreply(xprt, xdr_results, xdr_location)
+       register SVCXPRT *xprt;
+       xdrproc_t xdr_results;
+       caddr_t xdr_location;
+{
+       struct rpc_msg rply; 
+
+       rply.rm_direction = REPLY;  
+       rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+       rply.acpted_rply.ar_verf = xprt->xp_verf; 
+       rply.acpted_rply.ar_stat = SUCCESS;
+       rply.acpted_rply.ar_results.where = xdr_location;
+       rply.acpted_rply.ar_results.proc = xdr_results;
+       return (SVC_REPLY(xprt, &rply)); 
+}
+
+/*
+ * No procedure error reply
+ */
+void
+svcerr_noproc(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply;
+
+       rply.rm_direction = REPLY;
+       rply.rm_reply.rp_stat = MSG_ACCEPTED;
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = PROC_UNAVAIL;
+       SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Can't decode args error reply
+ */
+void
+svcerr_decode(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply; 
+
+       rply.rm_direction = REPLY; 
+       rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = GARBAGE_ARGS;
+       SVC_REPLY(xprt, &rply); 
+}
+
+/*
+ * Some system error
+ */
+void
+svcerr_systemerr(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply; 
+
+       rply.rm_direction = REPLY; 
+       rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = SYSTEM_ERR;
+       SVC_REPLY(xprt, &rply); 
+}
+
+/*
+ * Authentication error reply
+ */
+void
+svcerr_auth(xprt, why)
+       SVCXPRT *xprt;
+       enum auth_stat why;
+{
+       struct rpc_msg rply;
+
+       rply.rm_direction = REPLY;
+       rply.rm_reply.rp_stat = MSG_DENIED;
+       rply.rjcted_rply.rj_stat = AUTH_ERROR;
+       rply.rjcted_rply.rj_why = why;
+       SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Auth too weak error reply
+ */
+void
+svcerr_weakauth(xprt)
+       SVCXPRT *xprt;
+{
+
+       svcerr_auth(xprt, AUTH_TOOWEAK);
+}
+
+/*
+ * Program unavailable error reply
+ */
+void 
+svcerr_noprog(xprt)
+       register SVCXPRT *xprt;
+{
+       struct rpc_msg rply;  
+
+       rply.rm_direction = REPLY;   
+       rply.rm_reply.rp_stat = MSG_ACCEPTED;  
+       rply.acpted_rply.ar_verf = xprt->xp_verf;  
+       rply.acpted_rply.ar_stat = PROG_UNAVAIL;
+       SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Program version mismatch error reply
+ */
+void  
+svcerr_progvers(xprt, low_vers, high_vers)
+       register SVCXPRT *xprt; 
+       u_long low_vers;
+       u_long high_vers;
+{
+       struct rpc_msg rply;
+
+       rply.rm_direction = REPLY;
+       rply.rm_reply.rp_stat = MSG_ACCEPTED;
+       rply.acpted_rply.ar_verf = xprt->xp_verf;
+       rply.acpted_rply.ar_stat = PROG_MISMATCH;
+       rply.acpted_rply.ar_vers.low = low_vers;
+       rply.acpted_rply.ar_vers.high = high_vers;
+       SVC_REPLY(xprt, &rply);
+}
+
+/* ******************* SERVER INPUT STUFF ******************* */
+
+/*
+ * Get server side input from some transport.
+ *
+ * Statement of authentication parameters management:
+ * This function owns and manages all authentication parameters, specifically
+ * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
+ * the "cooked" credentials (rqst->rq_clntcred).
+ * However, this function does not know the structure of the cooked
+ * credentials, so it make the following assumptions: 
+ *   a) the structure is contiguous (no pointers), and
+ *   b) the cred structure size does not exceed RQCRED_SIZE bytes. 
+ * In all events, all three parameters are freed upon exit from this routine.
+ * The storage is trivially management on the call stack in user land, but
+ * is mallocated in kernel land.
+ */
+
+void
+svc_getreq(rdfds)
+       int rdfds;
+{
+#ifdef FD_SETSIZE
+       fd_set readfds;
+
+       FD_ZERO(&readfds);
+       readfds.fds_bits[0] = rdfds;
+       svc_getreqset(&readfds);
+#else
+       int readfds = rdfds & svc_fds;
+
+       svc_getreqset(&readfds);
+#endif /* def FD_SETSIZE */
+}
+
+void
+svc_getreqset(readfds)
+#ifdef FD_SETSIZE
+       fd_set *readfds;
+{
+#else
+       int *readfds;
+{
+    int readfds_local = *readfds;
+#endif /* def FD_SETSIZE */
+       enum xprt_stat stat;
+       struct rpc_msg msg;
+       int prog_found;
+       u_long low_vers;
+       u_long high_vers;
+       struct svc_req r;
+       register SVCXPRT *xprt;
+       register u_long mask;
+       register int bit;
+       register u_long *maskp;
+       register int setsize;
+       register int sock;
+       char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
+       msg.rm_call.cb_cred.oa_base = cred_area;
+       msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
+       r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
+
+
+#ifdef FD_SETSIZE
+       setsize = _rpc_dtablesize();    
+       maskp = (u_long *)readfds->fds_bits;
+       for (sock = 0; sock < setsize; sock += NFDBITS) {
+           for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
+               /* sock has input waiting */
+               xprt = xports[sock + bit - 1];
+#else
+       for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) {
+           if ((readfds_local & 1) != 0) {
+               /* sock has input waiting */
+               xprt = xports[sock];
+#endif /* def FD_SETSIZE */
+               /* now receive msgs from xprtprt (support batch calls) */
+               do {
+                       if (SVC_RECV(xprt, &msg)) {
+
+                               /* now find the exported program and call it */
+                               register struct svc_callout *s;
+                               enum auth_stat why;
+
+                               r.rq_xprt = xprt;
+                               r.rq_prog = msg.rm_call.cb_prog;
+                               r.rq_vers = msg.rm_call.cb_vers;
+                               r.rq_proc = msg.rm_call.cb_proc;
+                               r.rq_cred = msg.rm_call.cb_cred;
+                               /* first authenticate the message */
+                               if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
+                                       svcerr_auth(xprt, why);
+                                       goto call_done;
+                               }
+                               /* now match message with a registered service*/
+                               prog_found = FALSE;
+                               low_vers = 0 - 1;
+                               high_vers = 0;
+                               for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+                                       if (s->sc_prog == r.rq_prog) {
+                                               if (s->sc_vers == r.rq_vers) {
+                                                       (*s->sc_dispatch)(&r, xprt);
+                                                       goto call_done;
+                                               }  /* found correct version */
+                                               prog_found = TRUE;
+                                               if (s->sc_vers < low_vers)
+                                                       low_vers = s->sc_vers;
+                                               if (s->sc_vers > high_vers)
+                                                       high_vers = s->sc_vers;
+                                       }   /* found correct program */
+                               }
+                               /*
+                                * if we got here, the program or version
+                                * is not served ...
+                                */
+                               if (prog_found)
+                                       svcerr_progvers(xprt,
+                                       low_vers, high_vers);
+                               else
+                                        svcerr_noprog(xprt);
+                               /* Fall through to ... */
+                       }
+               call_done:
+                       if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
+                               SVC_DESTROY(xprt);
+                               break;
+                       }
+               } while (stat == XPRT_MOREREQS);
+           }
+       }
+}
diff --git a/sunrpc/svc_auth.c b/sunrpc/svc_auth.c
new file mode 100644 (file)
index 0000000..ab7ab69
--- /dev/null
@@ -0,0 +1,114 @@
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC; from 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc_auth_nodes.c, Server-side rpc authenticator interface,
+ * *WITHOUT* DES authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+
+/*
+ * svcauthsw is the bdevsw of server side authentication. 
+ * 
+ * Server side authenticators are called from authenticate by
+ * using the client auth struct flavor field to index into svcauthsw.
+ * The server auth flavors must implement a routine that looks  
+ * like: 
+ * 
+ *     enum auth_stat
+ *     flavorx_auth(rqst, msg)
+ *             register struct svc_req *rqst; 
+ *             register struct rpc_msg *msg;
+ *
+ */
+
+enum auth_stat _svcauth_null();                /* no authentication */
+enum auth_stat _svcauth_unix();                /* unix style (uid, gids) */
+enum auth_stat _svcauth_short();       /* short hand unix style */
+
+static struct {
+       enum auth_stat (*authenticator)();
+} svcauthsw[] = {
+       _svcauth_null,                  /* AUTH_NULL */
+       _svcauth_unix,                  /* AUTH_UNIX */
+       _svcauth_short,                 /* AUTH_SHORT */
+};
+#define        AUTH_MAX        2               /* HIGHEST AUTH NUMBER */
+
+
+/*
+ * The call rpc message, msg has been obtained from the wire.  The msg contains
+ * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
+ * if the msg is successfully authenticated.  If AUTH_OK then the routine also
+ * does the following things:
+ * set rqst->rq_xprt->verf to the appropriate response verifier;
+ * sets rqst->rq_client_cred to the "cooked" form of the credentials.
+ *
+ * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
+ * its length is set appropriately.
+ *
+ * The caller still owns and is responsible for msg->u.cmb.cred and
+ * msg->u.cmb.verf.  The authentication system retains ownership of
+ * rqst->rq_client_cred, the cooked credentials.
+ *
+ * There is an assumption that any flavour less than AUTH_NULL is
+ * invalid.
+ */
+enum auth_stat
+_authenticate(rqst, msg)
+       register struct svc_req *rqst;
+       struct rpc_msg *msg;
+{
+       register int cred_flavor;
+
+       rqst->rq_cred = msg->rm_call.cb_cred;
+       rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
+       rqst->rq_xprt->xp_verf.oa_length = 0;
+       cred_flavor = rqst->rq_cred.oa_flavor;
+       if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) {
+               return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg));
+       }
+
+       return (AUTH_REJECTEDCRED);
+}
+
+enum auth_stat
+_svcauth_null(/*rqst, msg*/)
+       /*struct svc_req *rqst;
+       struct rpc_msg *msg;*/
+{
+
+       return (AUTH_OK);
+}
diff --git a/sunrpc/svc_authux.c b/sunrpc/svc_authux.c
new file mode 100644 (file)
index 0000000..ea00b78
--- /dev/null
@@ -0,0 +1,134 @@
+/* @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC; from 1.28 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_auth_unix.c
+ * Handles UNIX flavor authentication parameters on the service side of rpc.
+ * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
+ * _svcauth_unix does full blown unix style uid,gid+gids auth,
+ * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
+ * Note: the shorthand has been gutted for efficiency.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+/*
+ * Unix longhand authenticator
+ */
+enum auth_stat
+_svcauth_unix(rqst, msg)
+       register struct svc_req *rqst;
+       register struct rpc_msg *msg;
+{
+       register enum auth_stat stat;
+       XDR xdrs;
+       register struct authunix_parms *aup;
+       register long *buf;
+       struct area {
+               struct authunix_parms area_aup;
+               char area_machname[MAX_MACHINE_NAME+1];
+               int area_gids[NGRPS];
+       } *area;
+       u_int auth_len;
+       int str_len, gid_len;
+       register int i;
+
+       area = (struct area *) rqst->rq_clntcred;
+       aup = &area->area_aup;
+       aup->aup_machname = area->area_machname;
+       aup->aup_gids = area->area_gids;
+       auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
+       xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
+       buf = XDR_INLINE(&xdrs, auth_len);
+       if (buf != NULL) {
+               aup->aup_time = IXDR_GET_LONG(buf);
+               str_len = IXDR_GET_U_LONG(buf);
+               if (str_len > MAX_MACHINE_NAME) {
+                       stat = AUTH_BADCRED;
+                       goto done;
+               }
+               bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len);
+               aup->aup_machname[str_len] = 0;
+               str_len = RNDUP(str_len);
+               buf += str_len / sizeof (long);
+               aup->aup_uid = IXDR_GET_LONG(buf);
+               aup->aup_gid = IXDR_GET_LONG(buf);
+               gid_len = IXDR_GET_U_LONG(buf);
+               if (gid_len > NGRPS) {
+                       stat = AUTH_BADCRED;
+                       goto done;
+               }
+               aup->aup_len = gid_len;
+               for (i = 0; i < gid_len; i++) {
+                       aup->aup_gids[i] = IXDR_GET_LONG(buf);
+               }
+               /*
+                * five is the smallest unix credentials structure -
+                * timestamp, hostname len (0), uid, gid, and gids len (0).
+                */
+               if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
+                       (void) printf("bad auth_len gid %d str %d auth %d\n",
+                           gid_len, str_len, auth_len);
+                       stat = AUTH_BADCRED;
+                       goto done;
+               }
+       } else if (! xdr_authunix_parms(&xdrs, aup)) {
+               xdrs.x_op = XDR_FREE;
+               (void)xdr_authunix_parms(&xdrs, aup);
+               stat = AUTH_BADCRED;
+               goto done;
+       }
+       rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
+       rqst->rq_xprt->xp_verf.oa_length = 0;
+       stat = AUTH_OK;
+done:
+       XDR_DESTROY(&xdrs);
+       return (stat);
+}
+
+
+/*
+ * Shorthand unix authenticator
+ * Looks up longhand in a cache.
+ */
+/*ARGSUSED*/
+enum auth_stat 
+_svcauth_short(rqst, msg)
+       struct svc_req *rqst;
+       struct rpc_msg *msg;
+{
+       return (AUTH_REJECTEDCRED);
+}
diff --git a/sunrpc/svc_raw.c b/sunrpc/svc_raw.c
new file mode 100644 (file)
index 0000000..1170ece
--- /dev/null
@@ -0,0 +1,166 @@
+/* @(#)svc_raw.c       2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_raw.c,   This a toy for simple testing and timing.
+ * Interface to create an rpc client and server in the same UNIX process.
+ * This lets us similate rpc and get rpc (round trip) overhead, without
+ * any interference from the kernal.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+
+
+/*
+ * This is the "network" that we will be moving data over
+ */
+static struct svcraw_private {
+       char    _raw_buf[UDPMSGSIZE];
+       SVCXPRT server;
+       XDR     xdr_stream;
+       char    verf_body[MAX_AUTH_BYTES];
+} *svcraw_private;
+
+static bool_t          svcraw_recv();
+static enum xprt_stat  svcraw_stat();
+static bool_t          svcraw_getargs();
+static bool_t          svcraw_reply();
+static bool_t          svcraw_freeargs();
+static void            svcraw_destroy();
+
+static struct xp_ops server_ops = {
+       svcraw_recv,
+       svcraw_stat,
+       svcraw_getargs,
+       svcraw_reply,
+       svcraw_freeargs,
+       svcraw_destroy
+};
+
+SVCXPRT *
+svcraw_create()
+{
+       register struct svcraw_private *srp = svcraw_private;
+
+       if (srp == 0) {
+               srp = (struct svcraw_private *)calloc(1, sizeof (*srp));
+               if (srp == 0)
+                       return (0);
+       }
+       srp->server.xp_sock = 0;
+       srp->server.xp_port = 0;
+       srp->server.xp_ops = &server_ops;
+       srp->server.xp_verf.oa_base = srp->verf_body;
+       xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+       return (&srp->server);
+}
+
+static enum xprt_stat
+svcraw_stat()
+{
+
+       return (XPRT_IDLE);
+}
+
+static bool_t
+svcraw_recv(xprt, msg)
+       SVCXPRT *xprt;
+       struct rpc_msg *msg;
+{
+       register struct svcraw_private *srp = svcraw_private;
+       register XDR *xdrs;
+
+       if (srp == 0)
+               return (0);
+       xdrs = &srp->xdr_stream;
+       xdrs->x_op = XDR_DECODE;
+       XDR_SETPOS(xdrs, 0);
+       if (! xdr_callmsg(xdrs, msg))
+              return (FALSE);
+       return (TRUE);
+}
+
+static bool_t
+svcraw_reply(xprt, msg)
+       SVCXPRT *xprt;
+       struct rpc_msg *msg;
+{
+       register struct svcraw_private *srp = svcraw_private;
+       register XDR *xdrs;
+
+       if (srp == 0)
+               return (FALSE);
+       xdrs = &srp->xdr_stream;
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, 0);
+       if (! xdr_replymsg(xdrs, msg))
+              return (FALSE);
+       (void)XDR_GETPOS(xdrs);  /* called just for overhead */
+       return (TRUE);
+}
+
+static bool_t
+svcraw_getargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+       register struct svcraw_private *srp = svcraw_private;
+
+       if (srp == 0)
+               return (FALSE);
+       return ((*xdr_args)(&srp->xdr_stream, args_ptr));
+}
+
+static bool_t
+svcraw_freeargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{ 
+       register struct svcraw_private *srp = svcraw_private;
+       register XDR *xdrs;
+
+       if (srp == 0)
+               return (FALSE);
+       xdrs = &srp->xdr_stream;
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_args)(xdrs, args_ptr));
+} 
+
+static void
+svcraw_destroy()
+{
+}
diff --git a/sunrpc/svc_run.c b/sunrpc/svc_run.c
new file mode 100644 (file)
index 0000000..c1c3e04
--- /dev/null
@@ -0,0 +1,72 @@
+/* @(#)svc_run.c       2.1 88/07/29 4.0 RPCSRC */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+#include <rpc/rpc.h>
+#include <sys/errno.h>
+
+void
+svc_run()
+{
+#ifdef FD_SETSIZE
+       fd_set readfds;
+#else
+      int readfds;
+#endif /* def FD_SETSIZE */
+       extern int errno;
+
+       for (;;) {
+#ifdef FD_SETSIZE
+               readfds = svc_fdset;
+#else
+               readfds = svc_fds;
+#endif /* def FD_SETSIZE */
+               switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
+                              (struct timeval *)0)) {
+               case -1:
+                       if (errno == EINTR) {
+                               continue;
+                       }
+                       perror("svc_run: - select failed");
+                       return;
+               case 0:
+                       continue;
+               default:
+                       svc_getreqset(&readfds);
+               }
+       }
+}
diff --git a/sunrpc/svc_simple.c b/sunrpc/svc_simple.c
new file mode 100644 (file)
index 0000000..d6bcbd3
--- /dev/null
@@ -0,0 +1,143 @@
+/* @(#)svc_simple.c    2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/* 
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+static struct proglst {
+       char *(*p_progname)();
+       int  p_prognum;
+       int  p_procnum;
+       xdrproc_t p_inproc, p_outproc;
+       struct proglst *p_nxt;
+} *proglst;
+static void universal();
+static SVCXPRT *transp;
+struct proglst *pl;
+
+registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
+       char *(*progname)();
+       xdrproc_t inproc, outproc;
+{
+       
+       if (procnum == NULLPROC) {
+               (void) fprintf(stderr,
+                   "can't reassign procedure number %d\n", NULLPROC);
+               return (-1);
+       }
+       if (transp == 0) {
+               transp = svcudp_create(RPC_ANYSOCK);
+               if (transp == NULL) {
+                       (void) fprintf(stderr, "couldn't create an rpc server\n");
+                       return (-1);
+               }
+       }
+       (void) pmap_unset((u_long)prognum, (u_long)versnum);
+       if (!svc_register(transp, (u_long)prognum, (u_long)versnum, 
+           universal, IPPROTO_UDP)) {
+               (void) fprintf(stderr, "couldn't register prog %d vers %d\n",
+                   prognum, versnum);
+               return (-1);
+       }
+       pl = (struct proglst *)malloc(sizeof(struct proglst));
+       if (pl == NULL) {
+               (void) fprintf(stderr, "registerrpc: out of memory\n");
+               return (-1);
+       }
+       pl->p_progname = progname;
+       pl->p_prognum = prognum;
+       pl->p_procnum = procnum;
+       pl->p_inproc = inproc;
+       pl->p_outproc = outproc;
+       pl->p_nxt = proglst;
+       proglst = pl;
+       return (0);
+}
+
+static void
+universal(rqstp, transp)
+       struct svc_req *rqstp;
+       SVCXPRT *transp;
+{
+       int prog, proc;
+       char *outdata;
+       char xdrbuf[UDPMSGSIZE];
+       struct proglst *pl;
+
+       /* 
+        * enforce "procnum 0 is echo" convention
+        */
+       if (rqstp->rq_proc == NULLPROC) {
+               if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) {
+                       (void) fprintf(stderr, "xxx\n");
+                       exit(1);
+               }
+               return;
+       }
+       prog = rqstp->rq_prog;
+       proc = rqstp->rq_proc;
+       for (pl = proglst; pl != NULL; pl = pl->p_nxt)
+               if (pl->p_prognum == prog && pl->p_procnum == proc) {
+                       /* decode arguments into a CLEAN buffer */
+                       bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */
+                       if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
+                               svcerr_decode(transp);
+                               return;
+                       }
+                       outdata = (*(pl->p_progname))(xdrbuf);
+                       if (outdata == NULL && pl->p_outproc != xdr_void)
+                               /* there was an error */
+                               return;
+                       if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
+                               (void) fprintf(stderr,
+                                   "trouble replying to prog %d\n",
+                                   pl->p_prognum);
+                               exit(1);
+                       }
+                       /* free the decoded arguments */
+                       (void)svc_freeargs(transp, pl->p_inproc, xdrbuf);
+                       return;
+               }
+       (void) fprintf(stderr, "never registered prog %d\n", prog);
+       exit(1);
+}
+
diff --git a/sunrpc/svc_tcp.c b/sunrpc/svc_tcp.c
new file mode 100644 (file)
index 0000000..587e0f0
--- /dev/null
@@ -0,0 +1,419 @@
+/* @(#)svc_tcp.c       2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_tcp.c, Server side for TCP/IP based RPC. 
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a tcp rendezvouser (a listner and connection establisher)
+ * and a record/tcp stream.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+extern bool_t abort();
+extern errno;
+
+/*
+ * Ops vector for TCP/IP based rpc service handle
+ */
+static bool_t          svctcp_recv();
+static enum xprt_stat  svctcp_stat();
+static bool_t          svctcp_getargs();
+static bool_t          svctcp_reply();
+static bool_t          svctcp_freeargs();
+static void            svctcp_destroy();
+
+static struct xp_ops svctcp_op = {
+       svctcp_recv,
+       svctcp_stat,
+       svctcp_getargs,
+       svctcp_reply,
+       svctcp_freeargs,
+       svctcp_destroy
+};
+
+/*
+ * Ops vector for TCP/IP rendezvous handler
+ */
+static bool_t          rendezvous_request();
+static enum xprt_stat  rendezvous_stat();
+
+static struct xp_ops svctcp_rendezvous_op = {
+       rendezvous_request,
+       rendezvous_stat,
+       abort,
+       abort,
+       abort,
+       svctcp_destroy
+};
+
+static int readtcp(), writetcp();
+static SVCXPRT *makefd_xprt();
+
+struct tcp_rendezvous { /* kept in xprt->xp_p1 */
+       u_int sendsize;
+       u_int recvsize;
+};
+
+struct tcp_conn {  /* kept in xprt->xp_p1 */
+       enum xprt_stat strm_stat;
+       u_long x_id;
+       XDR xdrs;
+       char verf_body[MAX_AUTH_BYTES];
+};
+
+/*
+ * Usage:
+ *     xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) tcp based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register).  This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svctcp_create
+ * binds it to an arbitrary port.  The routine then starts a tcp
+ * listener on the socket's associated port.  In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since tcp streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svctcp_create(sock, sendsize, recvsize)
+       register int sock;
+       u_int sendsize;
+       u_int recvsize;
+{
+       bool_t madesock = FALSE;
+       register SVCXPRT *xprt;
+       register struct tcp_rendezvous *r;
+       struct sockaddr_in addr;
+       int len = sizeof(struct sockaddr_in);
+
+       if (sock == RPC_ANYSOCK) {
+               if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+                       perror("svctcp_.c - udp socket creation problem");
+                       return ((SVCXPRT *)NULL);
+               }
+               madesock = TRUE;
+       }
+       bzero((char *)&addr, sizeof (addr));
+       addr.sin_family = AF_INET;
+       if (bindresvport(sock, &addr)) {
+               addr.sin_port = 0;
+               (void)bind(sock, (struct sockaddr *)&addr, len);
+       }
+       if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0)  ||
+           (listen(sock, 2) != 0)) {
+               perror("svctcp_.c - cannot getsockname or listen");
+               if (madesock)
+                      (void)close(sock);
+               return ((SVCXPRT *)NULL);
+       }
+       r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
+       if (r == NULL) {
+               (void) fprintf(stderr, "svctcp_create: out of memory\n");
+               return (NULL);
+       }
+       r->sendsize = sendsize;
+       r->recvsize = recvsize;
+       xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+       if (xprt == NULL) {
+               (void) fprintf(stderr, "svctcp_create: out of memory\n");
+               return (NULL);
+       }
+       xprt->xp_p2 = NULL;
+       xprt->xp_p1 = (caddr_t)r;
+       xprt->xp_verf = _null_auth;
+       xprt->xp_ops = &svctcp_rendezvous_op;
+       xprt->xp_port = ntohs(addr.sin_port);
+       xprt->xp_sock = sock;
+       xprt_register(xprt);
+       return (xprt);
+}
+
+/*
+ * Like svtcp_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcfd_create(fd, sendsize, recvsize)
+       int fd;
+       u_int sendsize;
+       u_int recvsize;
+{
+
+       return (makefd_xprt(fd, sendsize, recvsize));
+}
+
+static SVCXPRT *
+makefd_xprt(fd, sendsize, recvsize)
+       int fd;
+       u_int sendsize;
+       u_int recvsize;
+{
+       register SVCXPRT *xprt;
+       register struct tcp_conn *cd;
+       xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+       if (xprt == (SVCXPRT *)NULL) {
+               (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+               goto done;
+       }
+       cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
+       if (cd == (struct tcp_conn *)NULL) {
+               (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+               mem_free((char *) xprt, sizeof(SVCXPRT));
+               xprt = (SVCXPRT *)NULL;
+               goto done;
+       }
+       cd->strm_stat = XPRT_IDLE;
+       xdrrec_create(&(cd->xdrs), sendsize, recvsize,
+           (caddr_t)xprt, readtcp, writetcp);
+       xprt->xp_p2 = NULL;
+       xprt->xp_p1 = (caddr_t)cd;
+       xprt->xp_verf.oa_base = cd->verf_body;
+       xprt->xp_addrlen = 0;
+       xprt->xp_ops = &svctcp_op;  /* truely deals with calls */
+       xprt->xp_port = 0;  /* this is a connection, not a rendezvouser */
+       xprt->xp_sock = fd;
+       xprt_register(xprt);
+    done:
+       return (xprt);
+}
+
+static bool_t
+rendezvous_request(xprt)
+       register SVCXPRT *xprt;
+{
+       int sock;
+       struct tcp_rendezvous *r;
+       struct sockaddr_in addr;
+       int len;
+
+       r = (struct tcp_rendezvous *)xprt->xp_p1;
+    again:
+       len = sizeof(struct sockaddr_in);
+       if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
+           &len)) < 0) {
+               if (errno == EINTR)
+                       goto again;
+              return (FALSE);
+       }
+       /*
+        * make a new transporter (re-uses xprt)
+        */
+       xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
+       xprt->xp_raddr = addr;
+       xprt->xp_addrlen = len;
+       return (FALSE); /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat()
+{
+
+       return (XPRT_IDLE);
+}
+
+static void
+svctcp_destroy(xprt)
+       register SVCXPRT *xprt;
+{
+       register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
+
+       xprt_unregister(xprt);
+       (void)close(xprt->xp_sock);
+       if (xprt->xp_port != 0) {
+               /* a rendezvouser socket */
+               xprt->xp_port = 0;
+       } else {
+               /* an actual connection socket */
+               XDR_DESTROY(&(cd->xdrs));
+       }
+       mem_free((caddr_t)cd, sizeof(struct tcp_conn));
+       mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = { 35, 0 };
+
+/*
+ * reads data from the tcp conection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ */
+static int
+readtcp(xprt, buf, len)
+       register SVCXPRT *xprt;
+       caddr_t buf;
+       register int len;
+{
+       register int sock = xprt->xp_sock;
+#ifdef FD_SETSIZE
+       fd_set mask;
+       fd_set readfds;
+
+       FD_ZERO(&mask);
+       FD_SET(sock, &mask);
+#else
+       register int mask = 1 << sock;
+       int readfds;
+#endif /* def FD_SETSIZE */
+       do {
+               readfds = mask;
+               if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, 
+                          &wait_per_try) <= 0) {
+                       if (errno == EINTR) {
+                               continue;
+                       }
+                       goto fatal_err;
+               }
+#ifdef FD_SETSIZE
+       } while (!FD_ISSET(sock, &readfds));
+#else
+       } while (readfds != mask);
+#endif /* def FD_SETSIZE */
+       if ((len = read(sock, buf, len)) > 0) {
+               return (len);
+       }
+fatal_err:
+       ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+       return (-1);
+}
+
+/*
+ * writes data to the tcp connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writetcp(xprt, buf, len)
+       register SVCXPRT *xprt;
+       caddr_t buf;
+       int len;
+{
+       register int i, cnt;
+
+       for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+               if ((i = write(xprt->xp_sock, buf, cnt)) < 0) {
+                       ((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
+                           XPRT_DIED;
+                       return (-1);
+               }
+       }
+       return (len);
+}
+
+static enum xprt_stat
+svctcp_stat(xprt)
+       SVCXPRT *xprt;
+{
+       register struct tcp_conn *cd =
+           (struct tcp_conn *)(xprt->xp_p1);
+
+       if (cd->strm_stat == XPRT_DIED)
+               return (XPRT_DIED);
+       if (! xdrrec_eof(&(cd->xdrs)))
+               return (XPRT_MOREREQS);
+       return (XPRT_IDLE);
+}
+
+static bool_t
+svctcp_recv(xprt, msg)
+       SVCXPRT *xprt;
+       register struct rpc_msg *msg;
+{
+       register struct tcp_conn *cd =
+           (struct tcp_conn *)(xprt->xp_p1);
+       register XDR *xdrs = &(cd->xdrs);
+
+       xdrs->x_op = XDR_DECODE;
+       (void)xdrrec_skiprecord(xdrs);
+       if (xdr_callmsg(xdrs, msg)) {
+               cd->x_id = msg->rm_xid;
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+static bool_t
+svctcp_getargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+
+       return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
+}
+
+static bool_t
+svctcp_freeargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+       register XDR *xdrs =
+           &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static bool_t
+svctcp_reply(xprt, msg)
+       SVCXPRT *xprt;
+       register struct rpc_msg *msg;
+{
+       register struct tcp_conn *cd =
+           (struct tcp_conn *)(xprt->xp_p1);
+       register XDR *xdrs = &(cd->xdrs);
+       register bool_t stat;
+
+       xdrs->x_op = XDR_ENCODE;
+       msg->rm_xid = cd->x_id;
+       stat = xdr_replymsg(xdrs, msg);
+       (void)xdrrec_endofrecord(xdrs, TRUE);
+       return (stat);
+}
diff --git a/sunrpc/svc_udp.c b/sunrpc/svc_udp.c
new file mode 100644 (file)
index 0000000..69ef7a1
--- /dev/null
@@ -0,0 +1,475 @@
+/* @(#)svc_udp.c       2.2 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_udp.c,
+ * Server side for UDP/IP based RPC.  (Does some caching in the hopes of
+ * achieving execute-at-most-once semantics.)
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+
+#define rpc_buffer(xprt) ((xprt)->xp_p1)
+#define MAX(a, b)     ((a > b) ? a : b)
+
+static bool_t          svcudp_recv();
+static bool_t          svcudp_reply();
+static enum xprt_stat  svcudp_stat();
+static bool_t          svcudp_getargs();
+static bool_t          svcudp_freeargs();
+static void            svcudp_destroy();
+
+static struct xp_ops svcudp_op = {
+       svcudp_recv,
+       svcudp_stat,
+       svcudp_getargs,
+       svcudp_reply,
+       svcudp_freeargs,
+       svcudp_destroy
+};
+
+extern int errno;
+
+/*
+ * kept in xprt->xp_p2
+ */
+struct svcudp_data {
+       u_int   su_iosz;        /* byte size of send.recv buffer */
+       u_long  su_xid;         /* transaction id */
+       XDR     su_xdrs;        /* XDR handle */
+       char    su_verfbody[MAX_AUTH_BYTES];    /* verifier body */
+       char *  su_cache;       /* cached data, NULL if no cache */
+};
+#define        su_data(xprt)   ((struct svcudp_data *)(xprt->xp_p2))
+
+/*
+ * Usage:
+ *     xprt = svcudp_create(sock);
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcudp_create
+ * binds it to an arbitrary port.  In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ * Once *xprt is initialized, it is registered as a transporter;
+ * see (svc.h, xprt_register).
+ * The routines returns NULL if a problem occurred.
+ */
+SVCXPRT *
+svcudp_bufcreate(sock, sendsz, recvsz)
+       register int sock;
+       u_int sendsz, recvsz;
+{
+       bool_t madesock = FALSE;
+       register SVCXPRT *xprt;
+       register struct svcudp_data *su;
+       struct sockaddr_in addr;
+       int len = sizeof(struct sockaddr_in);
+
+       if (sock == RPC_ANYSOCK) {
+               if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+                       perror("svcudp_create: socket creation problem");
+                       return ((SVCXPRT *)NULL);
+               }
+               madesock = TRUE;
+       }
+       bzero((char *)&addr, sizeof (addr));
+       addr.sin_family = AF_INET;
+       if (bindresvport(sock, &addr)) {
+               addr.sin_port = 0;
+               (void)bind(sock, (struct sockaddr *)&addr, len);
+       }
+       if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+               perror("svcudp_create - cannot getsockname");
+               if (madesock)
+                       (void)close(sock);
+               return ((SVCXPRT *)NULL);
+       }
+       xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+       if (xprt == NULL) {
+               (void)fprintf(stderr, "svcudp_create: out of memory\n");
+               return (NULL);
+       }
+       su = (struct svcudp_data *)mem_alloc(sizeof(*su));
+       if (su == NULL) {
+               (void)fprintf(stderr, "svcudp_create: out of memory\n");
+               return (NULL);
+       }
+       su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
+       if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
+               (void)fprintf(stderr, "svcudp_create: out of memory\n");
+               return (NULL);
+       }
+       xdrmem_create(
+           &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
+       su->su_cache = NULL;
+       xprt->xp_p2 = (caddr_t)su;
+       xprt->xp_verf.oa_base = su->su_verfbody;
+       xprt->xp_ops = &svcudp_op;
+       xprt->xp_port = ntohs(addr.sin_port);
+       xprt->xp_sock = sock;
+       xprt_register(xprt);
+       return (xprt);
+}
+
+SVCXPRT *
+svcudp_create(sock)
+       int sock;
+{
+
+       return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum xprt_stat
+svcudp_stat(xprt)
+       SVCXPRT *xprt;
+{
+
+       return (XPRT_IDLE); 
+}
+
+static bool_t
+svcudp_recv(xprt, msg)
+       register SVCXPRT *xprt;
+       struct rpc_msg *msg;
+{
+       register struct svcudp_data *su = su_data(xprt);
+       register XDR *xdrs = &(su->su_xdrs);
+       register int rlen;
+       char *reply;
+       u_long replylen;
+
+    again:
+       xprt->xp_addrlen = sizeof(struct sockaddr_in);
+       rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
+           0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
+       if (rlen == -1 && errno == EINTR)
+               goto again;
+       if (rlen < 4*sizeof(u_long))
+               return (FALSE);
+       xdrs->x_op = XDR_DECODE;
+       XDR_SETPOS(xdrs, 0);
+       if (! xdr_callmsg(xdrs, msg))
+               return (FALSE);
+       su->su_xid = msg->rm_xid;
+       if (su->su_cache != NULL) {
+               if (cache_get(xprt, msg, &reply, &replylen)) {
+                       (void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
+                         (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
+                       return (TRUE);
+               }
+       }
+       return (TRUE);
+}
+
+static bool_t
+svcudp_reply(xprt, msg)
+       register SVCXPRT *xprt; 
+       struct rpc_msg *msg; 
+{
+       register struct svcudp_data *su = su_data(xprt);
+       register XDR *xdrs = &(su->su_xdrs);
+       register int slen;
+       register bool_t stat = FALSE;
+
+       xdrs->x_op = XDR_ENCODE;
+       XDR_SETPOS(xdrs, 0);
+       msg->rm_xid = su->su_xid;
+       if (xdr_replymsg(xdrs, msg)) {
+               slen = (int)XDR_GETPOS(xdrs);
+               if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+                   (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
+                   == slen) {
+                       stat = TRUE;
+                       if (su->su_cache && slen >= 0) {
+                               cache_set(xprt, (u_long) slen);
+                       }
+               }
+       }
+       return (stat);
+}
+
+static bool_t
+svcudp_getargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+
+       return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
+}
+
+static bool_t
+svcudp_freeargs(xprt, xdr_args, args_ptr)
+       SVCXPRT *xprt;
+       xdrproc_t xdr_args;
+       caddr_t args_ptr;
+{
+       register XDR *xdrs = &(su_data(xprt)->su_xdrs);
+
+       xdrs->x_op = XDR_FREE;
+       return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcudp_destroy(xprt)
+       register SVCXPRT *xprt;
+{
+       register struct svcudp_data *su = su_data(xprt);
+
+       xprt_unregister(xprt);
+       (void)close(xprt->xp_sock);
+       XDR_DESTROY(&(su->su_xdrs));
+       mem_free(rpc_buffer(xprt), su->su_iosz);
+       mem_free((caddr_t)su, sizeof(struct svcudp_data));
+       mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+
+/***********this could be a separate file*********************/
+
+/*
+ * Fifo cache for udp server
+ * Copies pointers to reply buffers into fifo cache
+ * Buffers are sent again if retransmissions are detected.
+ */
+
+#define SPARSENESS 4   /* 75% sparse */
+
+#define CACHE_PERROR(msg)      \
+       (void) fprintf(stderr,"%s\n", msg)
+
+#define ALLOC(type, size)      \
+       (type *) mem_alloc((unsigned) (sizeof(type) * (size)))
+
+#define BZERO(addr, type, size)         \
+       bzero((char *) addr, sizeof(type) * (int) (size)) 
+
+/*
+ * An entry in the cache
+ */
+typedef struct cache_node *cache_ptr;
+struct cache_node {
+       /*
+        * Index into cache is xid, proc, vers, prog and address
+        */
+       u_long cache_xid;
+       u_long cache_proc;
+       u_long cache_vers;
+       u_long cache_prog;
+       struct sockaddr_in cache_addr;
+       /*
+        * The cached reply and length
+        */
+       char * cache_reply;
+       u_long cache_replylen;
+       /*
+        * Next node on the list, if there is a collision
+        */
+       cache_ptr cache_next;   
+};
+
+
+
+/*
+ * The entire cache
+ */
+struct udp_cache {
+       u_long uc_size;         /* size of cache */
+       cache_ptr *uc_entries;  /* hash table of entries in cache */
+       cache_ptr *uc_fifo;     /* fifo list of entries in cache */
+       u_long uc_nextvictim;   /* points to next victim in fifo list */
+       u_long uc_prog;         /* saved program number */
+       u_long uc_vers;         /* saved version number */
+       u_long uc_proc;         /* saved procedure number */
+       struct sockaddr_in uc_addr; /* saved caller's address */
+};
+
+
+/*
+ * the hashing function
+ */
+#define CACHE_LOC(transp, xid) \
+ (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))        
+
+
+/*
+ * Enable use of the cache. 
+ * Note: there is no disable.
+ */
+svcudp_enablecache(transp, size)
+       SVCXPRT *transp;
+       u_long size;
+{
+       struct svcudp_data *su = su_data(transp);
+       struct udp_cache *uc;
+
+       if (su->su_cache != NULL) {
+               CACHE_PERROR("enablecache: cache already enabled");
+               return(0);      
+       }
+       uc = ALLOC(struct udp_cache, 1);
+       if (uc == NULL) {
+               CACHE_PERROR("enablecache: could not allocate cache");
+               return(0);
+       }
+       uc->uc_size = size;
+       uc->uc_nextvictim = 0;
+       uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS);
+       if (uc->uc_entries == NULL) {
+               CACHE_PERROR("enablecache: could not allocate cache data");
+               return(0);
+       }
+       BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS);
+       uc->uc_fifo = ALLOC(cache_ptr, size);
+       if (uc->uc_fifo == NULL) {
+               CACHE_PERROR("enablecache: could not allocate cache fifo");
+               return(0);
+       }
+       BZERO(uc->uc_fifo, cache_ptr, size);
+       su->su_cache = (char *) uc;
+       return(1);
+}
+
+
+/*
+ * Set an entry in the cache
+ */
+static
+cache_set(xprt, replylen)
+       SVCXPRT *xprt;
+       u_long replylen;        
+{
+       register cache_ptr victim;      
+       register cache_ptr *vicp;
+       register struct svcudp_data *su = su_data(xprt);
+       struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+       u_int loc;
+       char *newbuf;
+
+       /*
+        * Find space for the new entry, either by
+        * reusing an old entry, or by mallocing a new one
+        */
+       victim = uc->uc_fifo[uc->uc_nextvictim];
+       if (victim != NULL) {
+               loc = CACHE_LOC(xprt, victim->cache_xid);
+               for (vicp = &uc->uc_entries[loc]; 
+                 *vicp != NULL && *vicp != victim; 
+                 vicp = &(*vicp)->cache_next) 
+                               ;
+               if (*vicp == NULL) {
+                       CACHE_PERROR("cache_set: victim not found");
+                       return;
+               }
+               *vicp = victim->cache_next;     /* remote from cache */
+               newbuf = victim->cache_reply;
+       } else {
+               victim = ALLOC(struct cache_node, 1);
+               if (victim == NULL) {
+                       CACHE_PERROR("cache_set: victim alloc failed");
+                       return;
+               }
+               newbuf = mem_alloc(su->su_iosz);
+               if (newbuf == NULL) {
+                       CACHE_PERROR("cache_set: could not allocate new rpc_buffer");
+                       return;
+               }
+       }
+
+       /*
+        * Store it away
+        */
+       victim->cache_replylen = replylen;
+       victim->cache_reply = rpc_buffer(xprt);
+       rpc_buffer(xprt) = newbuf;
+       xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
+       victim->cache_xid = su->su_xid;
+       victim->cache_proc = uc->uc_proc;
+       victim->cache_vers = uc->uc_vers;
+       victim->cache_prog = uc->uc_prog;
+       victim->cache_addr = uc->uc_addr;
+       loc = CACHE_LOC(xprt, victim->cache_xid);
+       victim->cache_next = uc->uc_entries[loc];       
+       uc->uc_entries[loc] = victim;
+       uc->uc_fifo[uc->uc_nextvictim++] = victim;
+       uc->uc_nextvictim %= uc->uc_size;
+}
+
+/*
+ * Try to get an entry from the cache
+ * return 1 if found, 0 if not found
+ */
+static
+cache_get(xprt, msg, replyp, replylenp)
+       SVCXPRT *xprt;
+       struct rpc_msg *msg;
+       char **replyp;
+       u_long *replylenp;
+{
+       u_int loc;
+       register cache_ptr ent;
+       register struct svcudp_data *su = su_data(xprt);
+       register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+
+#      define EQADDR(a1, a2)   (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0)
+
+       loc = CACHE_LOC(xprt, su->su_xid);
+       for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {
+               if (ent->cache_xid == su->su_xid &&
+                 ent->cache_proc == uc->uc_proc &&
+                 ent->cache_vers == uc->uc_vers &&
+                 ent->cache_prog == uc->uc_prog &&
+                 EQADDR(ent->cache_addr, uc->uc_addr)) {
+                       *replyp = ent->cache_reply;
+                       *replylenp = ent->cache_replylen;
+                       return(1);
+               }
+       }
+       /*
+        * Failed to find entry
+        * Remember a few things so we can do a set later
+        */
+       uc->uc_proc = msg->rm_call.cb_proc;
+       uc->uc_vers = msg->rm_call.cb_vers;
+       uc->uc_prog = msg->rm_call.cb_prog;
+       uc->uc_addr = xprt->xp_raddr;
+       return(0);
+}
+
diff --git a/sunrpc/xdr.c b/sunrpc/xdr.c
new file mode 100644 (file)
index 0000000..b8248c2
--- /dev/null
@@ -0,0 +1,577 @@
+/* @(#)xdr.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+char *malloc();
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE      ((long) 0)
+#define XDR_TRUE       ((long) 1)
+#define LASTUNSIGNED   ((u_int) 0-1)
+
+/*
+ * for unit alignment
+ */
+static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
+
+/*
+ * Free a data structure using XDR
+ * Not a filter, but a convenient utility nonetheless
+ */
+void
+xdr_free(proc, objp)
+       xdrproc_t proc;
+       char *objp;
+{
+       XDR x;
+       
+       x.x_op = XDR_FREE;
+       (*proc)(&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t
+xdr_void(/* xdrs, addr */)
+       /* XDR *xdrs; */
+       /* caddr_t addr; */
+{
+
+       return (TRUE);
+}
+
+/*
+ * XDR integers
+ */
+bool_t
+xdr_int(xdrs, ip)
+       XDR *xdrs;
+       int *ip;
+{
+
+#ifdef lint
+       (void) (xdr_short(xdrs, (short *)ip));
+       return (xdr_long(xdrs, (long *)ip));
+#else
+       if (sizeof (int) == sizeof (long)) {
+               return (xdr_long(xdrs, (long *)ip));
+       } else {
+               return (xdr_short(xdrs, (short *)ip));
+       }
+#endif
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(xdrs, up)
+       XDR *xdrs;
+       u_int *up;
+{
+
+#ifdef lint
+       (void) (xdr_short(xdrs, (short *)up));
+       return (xdr_u_long(xdrs, (u_long *)up));
+#else
+       if (sizeof (u_int) == sizeof (u_long)) {
+               return (xdr_u_long(xdrs, (u_long *)up));
+       } else {
+               return (xdr_short(xdrs, (short *)up));
+       }
+#endif
+}
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(xdrs, lp)
+       register XDR *xdrs;
+       long *lp;
+{
+
+       if (xdrs->x_op == XDR_ENCODE)
+               return (XDR_PUTLONG(xdrs, lp));
+
+       if (xdrs->x_op == XDR_DECODE)
+               return (XDR_GETLONG(xdrs, lp));
+
+       if (xdrs->x_op == XDR_FREE)
+               return (TRUE);
+
+       return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t
+xdr_u_long(xdrs, ulp)
+       register XDR *xdrs;
+       u_long *ulp;
+{
+
+       if (xdrs->x_op == XDR_DECODE)
+               return (XDR_GETLONG(xdrs, (long *)ulp));
+       if (xdrs->x_op == XDR_ENCODE)
+               return (XDR_PUTLONG(xdrs, (long *)ulp));
+       if (xdrs->x_op == XDR_FREE)
+               return (TRUE);
+       return (FALSE);
+}
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(xdrs, sp)
+       register XDR *xdrs;
+       short *sp;
+{
+       long l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (long) *sp;
+               return (XDR_PUTLONG(xdrs, &l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &l)) {
+                       return (FALSE);
+               }
+               *sp = (short) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(xdrs, usp)
+       register XDR *xdrs;
+       u_short *usp;
+{
+       u_long l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (u_long) *usp;
+               return (XDR_PUTLONG(xdrs, &l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &l)) {
+                       return (FALSE);
+               }
+               *usp = (u_short) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(xdrs, cp)
+       XDR *xdrs;
+       char *cp;
+{
+       int i;
+
+       i = (*cp);
+       if (!xdr_int(xdrs, &i)) {
+               return (FALSE);
+       }
+       *cp = i;
+       return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t
+xdr_u_char(xdrs, cp)
+       XDR *xdrs;
+       char *cp;
+{
+       u_int u;
+
+       u = (*cp);
+       if (!xdr_u_int(xdrs, &u)) {
+               return (FALSE);
+       }
+       *cp = u;
+       return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t
+xdr_bool(xdrs, bp)
+       register XDR *xdrs;
+       bool_t *bp;
+{
+       long lb;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               lb = *bp ? XDR_TRUE : XDR_FALSE;
+               return (XDR_PUTLONG(xdrs, &lb));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &lb)) {
+                       return (FALSE);
+               }
+               *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t
+xdr_enum(xdrs, ep)
+       XDR *xdrs;
+       enum_t *ep;
+{
+#ifndef lint
+       enum sizecheck { SIZEVAL };     /* used to find the size of an enum */
+
+       /*
+        * enums are treated as ints
+        */
+       if (sizeof (enum sizecheck) == sizeof (long)) {
+               return (xdr_long(xdrs, (long *)ep));
+       } else if (sizeof (enum sizecheck) == sizeof (short)) {
+               return (xdr_short(xdrs, (short *)ep));
+       } else {
+               return (FALSE);
+       }
+#else
+       (void) (xdr_short(xdrs, (short *)ep));
+       return (xdr_long(xdrs, (long *)ep));
+#endif
+}
+
+/*
+ * XDR opaque data
+ * Allows the specification of a fixed size sequence of opaque bytes.
+ * cp points to the opaque object and cnt gives the byte length.
+ */
+bool_t
+xdr_opaque(xdrs, cp, cnt)
+       register XDR *xdrs;
+       caddr_t cp;
+       register u_int cnt;
+{
+       register u_int rndup;
+       static crud[BYTES_PER_XDR_UNIT];
+
+       /*
+        * if no data we are done
+        */
+       if (cnt == 0)
+               return (TRUE);
+
+       /*
+        * round byte count to full xdr units
+        */
+       rndup = cnt % BYTES_PER_XDR_UNIT;
+       if (rndup > 0)
+               rndup = BYTES_PER_XDR_UNIT - rndup;
+
+       if (xdrs->x_op == XDR_DECODE) {
+               if (!XDR_GETBYTES(xdrs, cp, cnt)) {
+                       return (FALSE);
+               }
+               if (rndup == 0)
+                       return (TRUE);
+               return (XDR_GETBYTES(xdrs, crud, rndup));
+       }
+
+       if (xdrs->x_op == XDR_ENCODE) {
+               if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
+                       return (FALSE);
+               }
+               if (rndup == 0)
+                       return (TRUE);
+               return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
+       }
+
+       if (xdrs->x_op == XDR_FREE) {
+               return (TRUE);
+       }
+
+       return (FALSE);
+}
+
+/*
+ * XDR counted bytes
+ * *cpp is a pointer to the bytes, *sizep is the count.
+ * If *cpp is NULL maxsize bytes are allocated
+ */
+bool_t
+xdr_bytes(xdrs, cpp, sizep, maxsize)
+       register XDR *xdrs;
+       char **cpp;
+       register u_int *sizep;
+       u_int maxsize;
+{
+       register char *sp = *cpp;  /* sp is the actual string pointer */
+       register u_int nodesize;
+
+       /*
+        * first deal with the length since xdr bytes are counted
+        */
+       if (! xdr_u_int(xdrs, sizep)) {
+               return (FALSE);
+       }
+       nodesize = *sizep;
+       if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
+               return (FALSE);
+       }
+
+       /*
+        * now deal with the actual bytes
+        */
+       switch (xdrs->x_op) {
+
+       case XDR_DECODE:
+               if (nodesize == 0) {
+                       return (TRUE);
+               }
+               if (sp == NULL) {
+                       *cpp = sp = (char *)mem_alloc(nodesize);
+               }
+               if (sp == NULL) {
+                       (void) fprintf(stderr, "xdr_bytes: out of memory\n");
+                       return (FALSE);
+               }
+               /* fall into ... */
+
+       case XDR_ENCODE:
+               return (xdr_opaque(xdrs, sp, nodesize));
+
+       case XDR_FREE:
+               if (sp != NULL) {
+                       mem_free(sp, nodesize);
+                       *cpp = NULL;
+               }
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t
+xdr_netobj(xdrs, np)
+       XDR *xdrs;
+       struct netobj *np;
+{
+
+       return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
+}
+
+/*
+ * XDR a descriminated union
+ * Support routine for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer.  The routine gets
+ * the discriminant value and then searches the array of xdrdiscrims
+ * looking for that value.  It calls the procedure given in the xdrdiscrim
+ * to handle the discriminant.  If there is no specific routine a default
+ * routine may be called.
+ * If there is no specific or default routine an error is returned.
+ */
+bool_t
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+       register XDR *xdrs;
+       enum_t *dscmp;          /* enum to decide which arm to work on */
+       char *unp;              /* the union itself */
+       struct xdr_discrim *choices;    /* [value, xdr proc] for each arm */
+       xdrproc_t dfault;       /* default xdr routine */
+{
+       register enum_t dscm;
+
+       /*
+        * we deal with the discriminator;  it's an enum
+        */
+       if (! xdr_enum(xdrs, dscmp)) {
+               return (FALSE);
+       }
+       dscm = *dscmp;
+
+       /*
+        * search choices for a value that matches the discriminator.
+        * if we find one, execute the xdr routine for that value.
+        */
+       for (; choices->proc != NULL_xdrproc_t; choices++) {
+               if (choices->value == dscm)
+                       return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
+       }
+
+       /*
+        * no match - execute the default xdr routine if there is one
+        */
+       return ((dfault == NULL_xdrproc_t) ? FALSE :
+           (*dfault)(xdrs, unp, LASTUNSIGNED));
+}
+
+
+/*
+ * Non-portable xdr primitives.
+ * Care should be taken when moving these routines to new architectures.
+ */
+
+
+/*
+ * XDR null terminated ASCII strings
+ * xdr_string deals with "C strings" - arrays of bytes that are
+ * terminated by a NULL character.  The parameter cpp references a
+ * pointer to storage; If the pointer is null, then the necessary
+ * storage is allocated.  The last parameter is the max allowed length
+ * of the string as specified by a protocol.
+ */
+bool_t
+xdr_string(xdrs, cpp, maxsize)
+       register XDR *xdrs;
+       char **cpp;
+       u_int maxsize;
+{
+       register char *sp = *cpp;  /* sp is the actual string pointer */
+       u_int size;
+       u_int nodesize;
+
+       /*
+        * first deal with the length since xdr strings are counted-strings
+        */
+       switch (xdrs->x_op) {
+       case XDR_FREE:
+               if (sp == NULL) {
+                       return(TRUE);   /* already free */
+               }
+               /* fall through... */
+       case XDR_ENCODE:
+               size = strlen(sp);
+               break;
+       }
+       if (! xdr_u_int(xdrs, &size)) {
+               return (FALSE);
+       }
+       if (size > maxsize) {
+               return (FALSE);
+       }
+       nodesize = size + 1;
+
+       /*
+        * now deal with the actual bytes
+        */
+       switch (xdrs->x_op) {
+
+       case XDR_DECODE:
+               if (nodesize == 0) {
+                       return (TRUE);
+               }
+               if (sp == NULL)
+                       *cpp = sp = (char *)mem_alloc(nodesize);
+               if (sp == NULL) {
+                       (void) fprintf(stderr, "xdr_string: out of memory\n");
+                       return (FALSE);
+               }
+               sp[size] = 0;
+               /* fall into ... */
+
+       case XDR_ENCODE:
+               return (xdr_opaque(xdrs, sp, size));
+
+       case XDR_FREE:
+               mem_free(sp, nodesize);
+               *cpp = NULL;
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/* 
+ * Wrapper for xdr_string that can be called directly from 
+ * routines like clnt_call
+ */
+bool_t
+xdr_wrapstring(xdrs, cpp)
+       XDR *xdrs;
+       char **cpp;
+{
+       if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
+               return (TRUE);
+       }
+       return (FALSE);
+}
diff --git a/sunrpc/xdr_array.c b/sunrpc/xdr_array.c
new file mode 100644 (file)
index 0000000..7c2831c
--- /dev/null
@@ -0,0 +1,153 @@
+/* @(#)xdr_array.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * arrays.  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED   ((u_int)0-1)
+
+
+/*
+ * XDR an array of arbitrary elements
+ * *addrp is a pointer to the array, *sizep is the number of elements.
+ * If addrp is NULL (*sizep * elsize) bytes are allocated.
+ * elsize is the size (in bytes) of each element, and elproc is the
+ * xdr procedure to call to handle each element of the array.
+ */
+bool_t
+xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
+       register XDR *xdrs;
+       caddr_t *addrp;         /* array pointer */
+       u_int *sizep;           /* number of elements */
+       u_int maxsize;          /* max numberof elements */
+       u_int elsize;           /* size in bytes of each element */
+       xdrproc_t elproc;       /* xdr routine to handle each element */
+{
+       register u_int i;
+       register caddr_t target = *addrp;
+       register u_int c;  /* the actual element count */
+       register bool_t stat = TRUE;
+       register u_int nodesize;
+
+       /* like strings, arrays are really counted arrays */
+       if (! xdr_u_int(xdrs, sizep)) {
+               return (FALSE);
+       }
+       c = *sizep;
+       if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+               return (FALSE);
+       }
+       nodesize = c * elsize;
+
+       /*
+        * if we are deserializing, we may need to allocate an array.
+        * We also save time by checking for a null array if we are freeing.
+        */
+       if (target == NULL)
+               switch (xdrs->x_op) {
+               case XDR_DECODE:
+                       if (c == 0)
+                               return (TRUE);
+                       *addrp = target = mem_alloc(nodesize);
+                       if (target == NULL) {
+                               (void) fprintf(stderr, 
+                                       "xdr_array: out of memory\n");
+                               return (FALSE);
+                       }
+                       bzero(target, nodesize);
+                       break;
+
+               case XDR_FREE:
+                       return (TRUE);
+       }
+       
+       /*
+        * now we xdr each element of array
+        */
+       for (i = 0; (i < c) && stat; i++) {
+               stat = (*elproc)(xdrs, target, LASTUNSIGNED);
+               target += elsize;
+       }
+
+       /*
+        * the array may need freeing
+        */
+       if (xdrs->x_op == XDR_FREE) {
+               mem_free(*addrp, nodesize);
+               *addrp = NULL;
+       }
+       return (stat);
+}
+
+/*
+ * xdr_vector():
+ *
+ * XDR a fixed length array. Unlike variable-length arrays,
+ * the storage of fixed length arrays is static and unfreeable.
+ * > basep: base of the array
+ * > size: size of the array
+ * > elemsize: size of each element
+ * > xdr_elem: routine to XDR each element
+ */
+bool_t
+xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
+       register XDR *xdrs;
+       register char *basep;
+       register u_int nelem;
+       register u_int elemsize;
+       register xdrproc_t xdr_elem;    
+{
+       register u_int i;
+       register char *elptr;
+
+       elptr = basep;
+       for (i = 0; i < nelem; i++) {
+               if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
+                       return(FALSE);
+               }
+               elptr += elemsize;
+       }
+       return(TRUE);   
+}
+
diff --git a/sunrpc/xdr_mem.c b/sunrpc/xdr_mem.c
new file mode 100644 (file)
index 0000000..558d369
--- /dev/null
@@ -0,0 +1,184 @@
+/* @(#)xdr_mem.c       2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static bool_t  xdrmem_getlong();
+static bool_t  xdrmem_putlong();
+static bool_t  xdrmem_getbytes();
+static bool_t  xdrmem_putbytes();
+static u_int   xdrmem_getpos();
+static bool_t  xdrmem_setpos();
+static long *  xdrmem_inline();
+static void    xdrmem_destroy();
+
+static struct  xdr_ops xdrmem_ops = {
+       xdrmem_getlong,
+       xdrmem_putlong,
+       xdrmem_getbytes,
+       xdrmem_putbytes,
+       xdrmem_getpos,
+       xdrmem_setpos,
+       xdrmem_inline,
+       xdrmem_destroy
+};
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.  
+ */
+void
+xdrmem_create(xdrs, addr, size, op)
+       register XDR *xdrs;
+       caddr_t addr;
+       u_int size;
+       enum xdr_op op;
+{
+
+       xdrs->x_op = op;
+       xdrs->x_ops = &xdrmem_ops;
+       xdrs->x_private = xdrs->x_base = addr;
+       xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy(/*xdrs*/)
+       /*XDR *xdrs;*/
+{
+}
+
+static bool_t
+xdrmem_getlong(xdrs, lp)
+       register XDR *xdrs;
+       long *lp;
+{
+
+       if ((xdrs->x_handy -= sizeof(long)) < 0)
+               return (FALSE);
+       *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private))));
+       xdrs->x_private += sizeof(long);
+       return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong(xdrs, lp)
+       register XDR *xdrs;
+       long *lp;
+{
+
+       if ((xdrs->x_handy -= sizeof(long)) < 0)
+               return (FALSE);
+       *(long *)xdrs->x_private = (long)htonl((u_long)(*lp));
+       xdrs->x_private += sizeof(long);
+       return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes(xdrs, addr, len)
+       register XDR *xdrs;
+       caddr_t addr;
+       register u_int len;
+{
+
+       if ((xdrs->x_handy -= len) < 0)
+               return (FALSE);
+       bcopy(xdrs->x_private, addr, len);
+       xdrs->x_private += len;
+       return (TRUE);
+}
+
+static bool_t
+xdrmem_putbytes(xdrs, addr, len)
+       register XDR *xdrs;
+       caddr_t addr;
+       register u_int len;
+{
+
+       if ((xdrs->x_handy -= len) < 0)
+               return (FALSE);
+       bcopy(addr, xdrs->x_private, len);
+       xdrs->x_private += len;
+       return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(xdrs)
+       register XDR *xdrs;
+{
+
+       return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
+}
+
+static bool_t
+xdrmem_setpos(xdrs, pos)
+       register XDR *xdrs;
+       u_int pos;
+{
+       register caddr_t newaddr = xdrs->x_base + pos;
+       register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
+
+       if ((long)newaddr > (long)lastaddr)
+               return (FALSE);
+       xdrs->x_private = newaddr;
+       xdrs->x_handy = (int)lastaddr - (int)newaddr;
+       return (TRUE);
+}
+
+static long *
+xdrmem_inline(xdrs, len)
+       register XDR *xdrs;
+       int len;
+{
+       long *buf = 0;
+
+       if (xdrs->x_handy >= len) {
+               xdrs->x_handy -= len;
+               buf = (long *) xdrs->x_private;
+               xdrs->x_private += len;
+       }
+       return (buf);
+}
diff --git a/sunrpc/xdr_rec.c b/sunrpc/xdr_rec.c
new file mode 100644 (file)
index 0000000..4d0d4ec
--- /dev/null
@@ -0,0 +1,580 @@
+/* @(#)xdr_rec.c       2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
+ * layer above tcp (for rpc's use).
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These routines interface XDRSTREAMS to a tcp/ip connection.
+ * There is a record marking layer between the xdr stream
+ * and the tcp transport level.  A record is composed on one or more
+ * record fragments.  A record fragment is a thirty-two bit header followed
+ * by n bytes of data, where n is contained in the header.  The header
+ * is represented as a htonl(u_long).  Thegh order bit encodes
+ * whether or not the fragment is the last fragment of the record
+ * (1 => fragment is last, 0 => more fragments to follow. 
+ * The other 31 bits encode the byte length of the fragment.
+ */
+
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+extern long    lseek();
+
+static u_int   fix_buf_size();
+
+static bool_t  xdrrec_getlong();
+static bool_t  xdrrec_putlong();
+static bool_t  xdrrec_getbytes();
+static bool_t  xdrrec_putbytes();
+static u_int   xdrrec_getpos();
+static bool_t  xdrrec_setpos();
+static long *  xdrrec_inline();
+static void    xdrrec_destroy();
+
+static struct  xdr_ops xdrrec_ops = {
+       xdrrec_getlong,
+       xdrrec_putlong,
+       xdrrec_getbytes,
+       xdrrec_putbytes,
+       xdrrec_getpos,
+       xdrrec_setpos,
+       xdrrec_inline,
+       xdrrec_destroy
+};
+
+/*
+ * A record is composed of one or more record fragments.
+ * A record fragment is a two-byte header followed by zero to
+ * 2**32-1 bytes.  The header is treated as a long unsigned and is
+ * encode/decoded to the network via htonl/ntohl.  The low order 31 bits
+ * are a byte count of the fragment.  The highest order bit is a boolean:
+ * 1 => this fragment is the last fragment of the record,
+ * 0 => this fragment is followed by more fragment(s).
+ *
+ * The fragment/record machinery is not general;  it is constructed to
+ * meet the needs of xdr and rpc based on tcp.
+ */
+
+#define LAST_FRAG ((u_long)(1 << 31))
+
+typedef struct rec_strm {
+       caddr_t tcp_handle;
+       caddr_t the_buffer;
+       /*
+        * out-goung bits
+        */
+       int (*writeit)();
+       caddr_t out_base;       /* output buffer (points to frag header) */
+       caddr_t out_finger;     /* next output position */
+       caddr_t out_boundry;    /* data cannot up to this address */
+       u_long *frag_header;    /* beginning of curren fragment */
+       bool_t frag_sent;       /* true if buffer sent in middle of record */
+       /*
+        * in-coming bits
+        */
+       int (*readit)();
+       u_long in_size; /* fixed size of the input buffer */
+       caddr_t in_base;
+       caddr_t in_finger;      /* location of next byte to be had */
+       caddr_t in_boundry;     /* can read up to this location */
+       long fbtbc;             /* fragment bytes to be consumed */
+       bool_t last_frag;
+       u_int sendsize;
+       u_int recvsize;
+} RECSTREAM;
+
+
+/*
+ * Create an xdr handle for xdrrec
+ * xdrrec_create fills in xdrs.  Sendsize and recvsize are
+ * send and recv buffer sizes (0 => use default).
+ * tcp_handle is an opaque handle that is passed as the first parameter to
+ * the procedures readit and writeit.  Readit and writeit are read and
+ * write respectively.   They are like the system
+ * calls expect that they take an opaque handle rather than an fd.
+ */
+void
+xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
+       register XDR *xdrs;
+       register u_int sendsize;
+       register u_int recvsize;
+       caddr_t tcp_handle;
+       int (*readit)();  /* like read, but pass it a tcp_handle, not sock */
+       int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */
+{
+       register RECSTREAM *rstrm =
+               (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
+
+       if (rstrm == NULL) {
+               (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+               /* 
+                *  This is bad.  Should rework xdrrec_create to 
+                *  return a handle, and in this case return NULL
+                */
+               return;
+       }
+       /*
+        * adjust sizes and allocate buffer quad byte aligned
+        */
+       rstrm->sendsize = sendsize = fix_buf_size(sendsize);
+       rstrm->recvsize = recvsize = fix_buf_size(recvsize);
+       rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
+       if (rstrm->the_buffer == NULL) {
+               (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+               return;
+       }
+       for (rstrm->out_base = rstrm->the_buffer;
+               (u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
+               rstrm->out_base++);
+       rstrm->in_base = rstrm->out_base + sendsize;
+       /*
+        * now the rest ...
+        */
+       xdrs->x_ops = &xdrrec_ops;
+       xdrs->x_private = (caddr_t)rstrm;
+       rstrm->tcp_handle = tcp_handle;
+       rstrm->readit = readit;
+       rstrm->writeit = writeit;
+       rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
+       rstrm->frag_header = (u_long *)rstrm->out_base;
+       rstrm->out_finger += sizeof(u_long);
+       rstrm->out_boundry += sendsize;
+       rstrm->frag_sent = FALSE;
+       rstrm->in_size = recvsize;
+       rstrm->in_boundry = rstrm->in_base;
+       rstrm->in_finger = (rstrm->in_boundry += recvsize);
+       rstrm->fbtbc = 0;
+       rstrm->last_frag = TRUE;
+}
+
+
+/*
+ * The reoutines defined below are the xdr ops which will go into the
+ * xdr handle filled in by xdrrec_create.
+ */
+
+static bool_t
+xdrrec_getlong(xdrs, lp)
+       XDR *xdrs;
+       long *lp;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register long *buflp = (long *)(rstrm->in_finger);
+       long mylong;
+
+       /* first try the inline, fast case */
+       if ((rstrm->fbtbc >= sizeof(long)) &&
+               (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
+               *lp = (long)ntohl((u_long)(*buflp));
+               rstrm->fbtbc -= sizeof(long);
+               rstrm->in_finger += sizeof(long);
+       } else {
+               if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
+                       return (FALSE);
+               *lp = (long)ntohl((u_long)mylong);
+       }
+       return (TRUE);
+}
+
+static bool_t
+xdrrec_putlong(xdrs, lp)
+       XDR *xdrs;
+       long *lp;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register long *dest_lp = ((long *)(rstrm->out_finger));
+
+       if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
+               /*
+                * this case should almost never happen so the code is
+                * inefficient
+                */
+               rstrm->out_finger -= sizeof(long);
+               rstrm->frag_sent = TRUE;
+               if (! flush_out(rstrm, FALSE))
+                       return (FALSE);
+               dest_lp = ((long *)(rstrm->out_finger));
+               rstrm->out_finger += sizeof(long);
+       }
+       *dest_lp = (long)htonl((u_long)(*lp));
+       return (TRUE);
+}
+
+static bool_t  /* must manage buffers, fragments, and records */
+xdrrec_getbytes(xdrs, addr, len)
+       XDR *xdrs;
+       register caddr_t addr;
+       register u_int len;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register int current;
+
+       while (len > 0) {
+               current = rstrm->fbtbc;
+               if (current == 0) {
+                       if (rstrm->last_frag)
+                               return (FALSE);
+                       if (! set_input_fragment(rstrm))
+                               return (FALSE);
+                       continue;
+               }
+               current = (len < current) ? len : current;
+               if (! get_input_bytes(rstrm, addr, current))
+                       return (FALSE);
+               addr += current; 
+               rstrm->fbtbc -= current;
+               len -= current;
+       }
+       return (TRUE);
+}
+
+static bool_t
+xdrrec_putbytes(xdrs, addr, len)
+       XDR *xdrs;
+       register caddr_t addr;
+       register u_int len;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register int current;
+
+       while (len > 0) {
+               current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
+               current = (len < current) ? len : current;
+               bcopy(addr, rstrm->out_finger, current);
+               rstrm->out_finger += current;
+               addr += current;
+               len -= current;
+               if (rstrm->out_finger == rstrm->out_boundry) {
+                       rstrm->frag_sent = TRUE;
+                       if (! flush_out(rstrm, FALSE))
+                               return (FALSE);
+               }
+       }
+       return (TRUE);
+}
+
+static u_int
+xdrrec_getpos(xdrs)
+       register XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+       register long pos;
+
+       pos = lseek((int)rstrm->tcp_handle, (long) 0, 1);
+       if (pos != -1)
+               switch (xdrs->x_op) {
+
+               case XDR_ENCODE:
+                       pos += rstrm->out_finger - rstrm->out_base;
+                       break;
+
+               case XDR_DECODE:
+                       pos -= rstrm->in_boundry - rstrm->in_finger;
+                       break;
+
+               default:
+                       pos = (u_int) -1;
+                       break;
+               }
+       return ((u_int) pos);
+}
+
+static bool_t
+xdrrec_setpos(xdrs, pos)
+       register XDR *xdrs;
+       u_int pos;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+       u_int currpos = xdrrec_getpos(xdrs);
+       int delta = currpos - pos;
+       caddr_t newpos;
+
+       if ((int)currpos != -1)
+               switch (xdrs->x_op) {
+
+               case XDR_ENCODE:
+                       newpos = rstrm->out_finger - delta;
+                       if ((newpos > (caddr_t)(rstrm->frag_header)) &&
+                               (newpos < rstrm->out_boundry)) {
+                               rstrm->out_finger = newpos;
+                               return (TRUE);
+                       }
+                       break;
+
+               case XDR_DECODE:
+                       newpos = rstrm->in_finger - delta;
+                       if ((delta < (int)(rstrm->fbtbc)) &&
+                               (newpos <= rstrm->in_boundry) &&
+                               (newpos >= rstrm->in_base)) {
+                               rstrm->in_finger = newpos;
+                               rstrm->fbtbc -= delta;
+                               return (TRUE);
+                       }
+                       break;
+               }
+       return (FALSE);
+}
+
+static long *
+xdrrec_inline(xdrs, len)
+       register XDR *xdrs;
+       int len;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+       long * buf = NULL;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
+                       buf = (long *) rstrm->out_finger;
+                       rstrm->out_finger += len;
+               }
+               break;
+
+       case XDR_DECODE:
+               if ((len <= rstrm->fbtbc) &&
+                       ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
+                       buf = (long *) rstrm->in_finger;
+                       rstrm->fbtbc -= len;
+                       rstrm->in_finger += len;
+               }
+               break;
+       }
+       return (buf);
+}
+
+static void
+xdrrec_destroy(xdrs)
+       register XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+
+       mem_free(rstrm->the_buffer,
+               rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
+       mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
+}
+
+
+/*
+ * Exported routines to manage xdr records
+ */
+
+/*
+ * Before reading (deserializing from the stream, one should always call
+ * this procedure to guarantee proper record alignment.
+ */
+bool_t
+xdrrec_skiprecord(xdrs)
+       XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+       while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+               if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+                       return (FALSE);
+               rstrm->fbtbc = 0;
+               if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+                       return (FALSE);
+       }
+       rstrm->last_frag = FALSE;
+       return (TRUE);
+}
+
+/*
+ * Look ahead fuction.
+ * Returns TRUE iff there is no more input in the buffer 
+ * after consuming the rest of the current record.
+ */
+bool_t
+xdrrec_eof(xdrs)
+       XDR *xdrs;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+       while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+               if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+                       return (TRUE);
+               rstrm->fbtbc = 0;
+               if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+                       return (TRUE);
+       }
+       if (rstrm->in_finger == rstrm->in_boundry)
+               return (TRUE);
+       return (FALSE);
+}
+
+/*
+ * The client must tell the package when an end-of-record has occurred.
+ * The second paraemters tells whether the record should be flushed to the
+ * (output) tcp stream.  (This let's the package support batched or
+ * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
+ */
+bool_t
+xdrrec_endofrecord(xdrs, sendnow)
+       XDR *xdrs;
+       bool_t sendnow;
+{
+       register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+       register u_long len;  /* fragment length */
+
+       if (sendnow || rstrm->frag_sent ||
+               ((u_long)rstrm->out_finger + sizeof(u_long) >=
+               (u_long)rstrm->out_boundry)) {
+               rstrm->frag_sent = FALSE;
+               return (flush_out(rstrm, TRUE));
+       }
+       len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
+          sizeof(u_long);
+       *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
+       rstrm->frag_header = (u_long *)rstrm->out_finger;
+       rstrm->out_finger += sizeof(u_long);
+       return (TRUE);
+}
+
+
+/*
+ * Internal useful routines
+ */
+static bool_t
+flush_out(rstrm, eor)
+       register RECSTREAM *rstrm;
+       bool_t eor;
+{
+       register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
+       register u_long len = (u_long)(rstrm->out_finger) - 
+               (u_long)(rstrm->frag_header) - sizeof(u_long);
+
+       *(rstrm->frag_header) = htonl(len | eormask);
+       len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
+       if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
+               != (int)len)
+               return (FALSE);
+       rstrm->frag_header = (u_long *)rstrm->out_base;
+       rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
+       return (TRUE);
+}
+
+static bool_t  /* knows nothing about records!  Only about input buffers */
+fill_input_buf(rstrm)
+       register RECSTREAM *rstrm;
+{
+       register caddr_t where;
+       u_int i;
+       register int len;
+
+       where = rstrm->in_base;
+       i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
+       where += i;
+       len = rstrm->in_size - i;
+       if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
+               return (FALSE);
+       rstrm->in_finger = where;
+       where += len;
+       rstrm->in_boundry = where;
+       return (TRUE);
+}
+
+static bool_t  /* knows nothing about records!  Only about input buffers */
+get_input_bytes(rstrm, addr, len)
+       register RECSTREAM *rstrm;
+       register caddr_t addr;
+       register int len;
+{
+       register int current;
+
+       while (len > 0) {
+               current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
+               if (current == 0) {
+                       if (! fill_input_buf(rstrm))
+                               return (FALSE);
+                       continue;
+               }
+               current = (len < current) ? len : current;
+               bcopy(rstrm->in_finger, addr, current);
+               rstrm->in_finger += current;
+               addr += current;
+               len -= current;
+       }
+       return (TRUE);
+}
+
+static bool_t  /* next two bytes of the input stream are treated as a header */
+set_input_fragment(rstrm)
+       register RECSTREAM *rstrm;
+{
+       u_long header;
+
+       if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
+               return (FALSE);
+       header = (long)ntohl(header);
+       rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
+       rstrm->fbtbc = header & (~LAST_FRAG);
+       return (TRUE);
+}
+
+static bool_t  /* consumes input bytes; knows nothing about records! */
+skip_input_bytes(rstrm, cnt)
+       register RECSTREAM *rstrm;
+       long cnt;
+{
+       register int current;
+
+       while (cnt > 0) {
+               current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
+               if (current == 0) {
+                       if (! fill_input_buf(rstrm))
+                               return (FALSE);
+                       continue;
+               }
+               current = (cnt < current) ? cnt : current;
+               rstrm->in_finger += current;
+               cnt -= current;
+       }
+       return (TRUE);
+}
+
+static u_int
+fix_buf_size(s)
+       register u_int s;
+{
+
+       if (s < 100)
+               s = 4000;
+       return (RNDUP(s));
+}
diff --git a/sunrpc/xdr_ref.c b/sunrpc/xdr_ref.c
new file mode 100644 (file)
index 0000000..32d91d9
--- /dev/null
@@ -0,0 +1,132 @@
+/* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers".  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED   ((u_int)0-1)
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated.  pp references a pointer to storage. If *pp is null
+ * the  necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t
+xdr_reference(xdrs, pp, size, proc)
+       register XDR *xdrs;
+       caddr_t *pp;            /* the pointer to work on */
+       u_int size;             /* size of the object pointed to */
+       xdrproc_t proc;         /* xdr routine to handle the object */
+{
+       register caddr_t loc = *pp;
+       register bool_t stat;
+
+       if (loc == NULL)
+               switch (xdrs->x_op) {
+               case XDR_FREE:
+                       return (TRUE);
+
+               case XDR_DECODE:
+                       *pp = loc = (caddr_t) mem_alloc(size);
+                       if (loc == NULL) {
+                               (void) fprintf(stderr,
+                                   "xdr_reference: out of memory\n");
+                               return (FALSE);
+                       }
+                       bzero(loc, (int)size);
+                       break;
+       }
+
+       stat = (*proc)(xdrs, loc, LASTUNSIGNED);
+
+       if (xdrs->x_op == XDR_FREE) {
+               mem_free(loc, size);
+               *pp = NULL;
+       }
+       return (stat);
+}
+
+
+/*
+ * xdr_pointer():
+ *
+ * XDR a pointer to a possibly recursive data structure. This
+ * differs with xdr_reference in that it can serialize/deserialiaze
+ * trees correctly.
+ *
+ *  What's sent is actually a union:
+ *
+ *  union object_pointer switch (boolean b) {
+ *  case TRUE: object_data data;
+ *  case FALSE: void nothing;
+ *  }
+ *
+ * > objpp: Pointer to the pointer to the object.
+ * > obj_size: size of the object.
+ * > xdr_obj: routine to XDR an object.
+ *
+ */
+bool_t
+xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
+       register XDR *xdrs;
+       char **objpp;
+       u_int obj_size;
+       xdrproc_t xdr_obj;
+{
+
+       bool_t more_data;
+
+       more_data = (*objpp != NULL);
+       if (! xdr_bool(xdrs,&more_data)) {
+               return (FALSE);
+       }
+       if (! more_data) {
+               *objpp = NULL;
+               return (TRUE);
+       }
+       return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
+}
diff --git a/sunrpc/xdr_stdio.c b/sunrpc/xdr_stdio.c
new file mode 100644 (file)
index 0000000..694774f
--- /dev/null
@@ -0,0 +1,189 @@
+/* @(#)xdr_stdio.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_stdio.c, XDR implementation on standard i/o file.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements a XDR on a stdio stream.
+ * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
+ * from the stream.
+ */
+
+#include <rpc/types.h>
+#include <stdio.h>
+#include <rpc/xdr.h>
+
+static bool_t  xdrstdio_getlong();
+static bool_t  xdrstdio_putlong();
+static bool_t  xdrstdio_getbytes();
+static bool_t  xdrstdio_putbytes();
+static u_int   xdrstdio_getpos();
+static bool_t  xdrstdio_setpos();
+static long *  xdrstdio_inline();
+static void    xdrstdio_destroy();
+
+/*
+ * Ops vector for stdio type XDR
+ */
+static struct xdr_ops  xdrstdio_ops = {
+       xdrstdio_getlong,       /* deseraialize a long int */
+       xdrstdio_putlong,       /* seraialize a long int */
+       xdrstdio_getbytes,      /* deserialize counted bytes */
+       xdrstdio_putbytes,      /* serialize counted bytes */
+       xdrstdio_getpos,        /* get offset in the stream */
+       xdrstdio_setpos,        /* set offset in the stream */
+       xdrstdio_inline,        /* prime stream for inline macros */
+       xdrstdio_destroy        /* destroy stream */
+};
+
+/*
+ * Initialize a stdio xdr stream.
+ * Sets the xdr stream handle xdrs for use on the stream file.
+ * Operation flag is set to op.
+ */
+void
+xdrstdio_create(xdrs, file, op)
+       register XDR *xdrs;
+       FILE *file;
+       enum xdr_op op;
+{
+
+       xdrs->x_op = op;
+       xdrs->x_ops = &xdrstdio_ops;
+       xdrs->x_private = (caddr_t)file;
+       xdrs->x_handy = 0;
+       xdrs->x_base = 0;
+}
+
+/*
+ * Destroy a stdio xdr stream.
+ * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
+ */
+static void
+xdrstdio_destroy(xdrs)
+       register XDR *xdrs;
+{
+       (void)fflush((FILE *)xdrs->x_private);
+       /* xx should we close the file ?? */
+};
+
+static bool_t
+xdrstdio_getlong(xdrs, lp)
+       XDR *xdrs;
+       register long *lp;
+{
+
+       if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
+               return (FALSE);
+#ifndef mc68000
+       *lp = ntohl(*lp);
+#endif
+       return (TRUE);
+}
+
+static bool_t
+xdrstdio_putlong(xdrs, lp)
+       XDR *xdrs;
+       long *lp;
+{
+
+#ifndef mc68000
+       long mycopy = htonl(*lp);
+       lp = &mycopy;
+#endif
+       if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
+               return (FALSE);
+       return (TRUE);
+}
+
+static bool_t
+xdrstdio_getbytes(xdrs, addr, len)
+       XDR *xdrs;
+       caddr_t addr;
+       u_int len;
+{
+
+       if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+               return (FALSE);
+       return (TRUE);
+}
+
+static bool_t
+xdrstdio_putbytes(xdrs, addr, len)
+       XDR *xdrs;
+       caddr_t addr;
+       u_int len;
+{
+
+       if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+               return (FALSE);
+       return (TRUE);
+}
+
+static u_int
+xdrstdio_getpos(xdrs)
+       XDR *xdrs;
+{
+
+       return ((u_int) ftell((FILE *)xdrs->x_private));
+}
+
+static bool_t
+xdrstdio_setpos(xdrs, pos) 
+       XDR *xdrs;
+       u_int pos;
+{ 
+
+       return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
+               FALSE : TRUE);
+}
+
+static long *
+xdrstdio_inline(xdrs, len)
+       XDR *xdrs;
+       u_int len;
+{
+
+       /*
+        * Must do some work to implement this: must insure
+        * enough data in the underlying stdio buffer,
+        * that the buffer is aligned so that we can indirect through a
+        * long *, and stuff this pointer in xdrs->x_buf.  Doing
+        * a fread or fwrite to a scratch buffer would defeat
+        * most of the gains to be had here and require storage
+        * management on this buffer, so we don't do this.
+        */
+       return (NULL);
+}