Import TBBT (NFS trace replay).
[bluesky.git] / TBBT / trace_play / rpc / xdr.c
diff --git a/TBBT/trace_play/rpc/xdr.c b/TBBT/trace_play/rpc/xdr.c
new file mode 100755 (executable)
index 0000000..3a1fc88
--- /dev/null
@@ -0,0 +1,685 @@
+#ifndef lint
+static char sfs_xdr_c_id[] = "@(#)xdr.c     2.1     97/10/23";
+#endif
+/* @(#)xdr.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ *   Copyright (c) 1992-1997,2001 by Standard Performance Evaluation Corporation
+ *     All rights reserved.
+ *             Standard Performance Evaluation Corporation (SPEC)
+ *             6585 Merchant Place, Suite 100
+ *             Warrenton, VA 20187
+ *
+ *     This product contains benchmarks acquired from several sources who
+ *     understand and agree with SPEC's goal of creating fair and objective
+ *     benchmarks to measure computer performance.
+ *
+ *     This copyright notice is placed here only to protect SPEC in the
+ *     event the source is misused in any manner that is contrary to the
+ *     spirit, the goals and the intent of SPEC.
+ *
+ *     The source code is provided to the user or company under the license
+ *     agreement for the SPEC Benchmark Suite for this product.
+ */
+/*
+ * 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.
+ */
+#ifndef lint
+static char sfs_clnt_id[] = "@(#)xdr.c     2.1     97/10/23";
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rpc/types.h"
+#include "rpc/xdr.h"
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE      ((int32_t) 0)
+#define XDR_TRUE       ((int32_t) 1)
+#define LASTUNSIGNED   ((uint_t) 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(
+       xdrproc_t proc,
+       char *objp)
+{
+       XDR x;
+       
+       x.x_op = XDR_FREE;
+       (*proc)(&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t
+xdr_void(void)
+{
+
+       return (TRUE);
+}
+
+/*
+ * XDR integers
+ */
+bool_t
+xdr_int(
+       XDR *xdrs,
+       int *ip)
+{
+
+#ifdef lint
+       (void) (xdr_int16_t(xdrs, (int16_t *)ip));
+       return (xdr_int32_t(xdrs, (int32_t *)ip));
+#else
+       if (sizeof (int) == sizeof (int32_t)) {
+               return (xdr_int32_t(xdrs, (int32_t *)ip));
+       } else {
+               return (xdr_int16_t(xdrs, (int16_t *)ip));
+       }
+#endif
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(
+       XDR *xdrs,
+       uint_t *up)
+{
+
+#ifdef lint
+       (void) (xdr_int16_t(xdrs, (int16_t *)up));
+       return (xdr_uint32_t(xdrs, (uint32_t *)up));
+#else
+       if (sizeof (uint_t) == sizeof (uint32_t)) {
+               return (xdr_uint32_t(xdrs, (uint32_t *)up));
+       } else {
+               return (xdr_int16_t(xdrs, (int16_t *)up));
+       }
+#endif
+}
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(
+       XDR *xdrs,
+       int32_t *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);
+}
+
+bool_t
+xdr_int32_t(
+       XDR *xdrs,
+       int32_t *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(
+       XDR *xdrs,
+       uint32_t *ulp)
+{
+
+       if (xdrs->x_op == XDR_DECODE)
+               return (XDR_GETLONG(xdrs, (int32_t *)ulp));
+       if (xdrs->x_op == XDR_ENCODE)
+               return (XDR_PUTLONG(xdrs, (int32_t *)ulp));
+       if (xdrs->x_op == XDR_FREE)
+               return (TRUE);
+       return (FALSE);
+}
+
+bool_t
+xdr_uint32_t(
+       XDR *xdrs,
+       uint32_t *ulp)
+{
+
+       if (xdrs->x_op == XDR_DECODE)
+               return (XDR_GETLONG(xdrs, (int32_t *)ulp));
+       if (xdrs->x_op == XDR_ENCODE)
+               return (XDR_PUTLONG(xdrs, (int32_t *)ulp));
+       if (xdrs->x_op == XDR_FREE)
+               return (TRUE);
+       return (FALSE);
+}
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(
+       XDR *xdrs,
+       int16_t *sp)
+{
+       int32_t l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (int32_t) *sp;
+               return (XDR_PUTLONG(xdrs, &l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &l)) {
+                       return (FALSE);
+               }
+               *sp = (int16_t) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+bool_t
+xdr_int16_t(
+       XDR *xdrs,
+       int16_t *sp)
+{
+       int32_t l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (int32_t) *sp;
+               return (XDR_PUTLONG(xdrs, &l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, &l)) {
+                       return (FALSE);
+               }
+               *sp = (int16_t) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(
+       XDR *xdrs,
+       uint16_t *usp)
+{
+       uint32_t l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (uint32_t) *usp;
+               return (XDR_PUTLONG(xdrs, (int32_t *)&l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, (int32_t *)&l)) {
+                       return (FALSE);
+               }
+               *usp = (uint16_t) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+bool_t
+xdr_uint16_t(
+       XDR *xdrs,
+       uint16_t *usp)
+{
+       uint32_t l;
+
+       switch (xdrs->x_op) {
+
+       case XDR_ENCODE:
+               l = (uint32_t) *usp;
+               return (XDR_PUTLONG(xdrs, (int32_t *)&l));
+
+       case XDR_DECODE:
+               if (!XDR_GETLONG(xdrs, (int32_t *)&l)) {
+                       return (FALSE);
+               }
+               *usp = (uint16_t) l;
+               return (TRUE);
+
+       case XDR_FREE:
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(
+       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(
+       XDR *xdrs,
+       uchar_t *cp)
+{
+       uint_t u;
+
+       u = (*cp);
+       if (!xdr_u_int(xdrs, &u)) {
+               return (FALSE);
+       }
+       *cp = u;
+       return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t
+xdr_bool(
+       XDR *xdrs,
+       bool_t *bp)
+{
+       int32_t 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(
+       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 (int32_t)) {
+               return (xdr_int32_t(xdrs, (int32_t *)ep));
+       } else if (sizeof (enum sizecheck) == sizeof (int16_t)) {
+               return (xdr_int16_t(xdrs, (int16_t *)ep));
+       } else {
+               return (FALSE);
+       }
+#else
+       (void) (xdr_int16_t(xdrs, (int16_t *)ep));
+       return (xdr_int32_t(xdrs, (int32_t *)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(
+       XDR *xdrs,
+       void *cp,
+       uint_t cnt)
+{
+       uint_t 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(
+       XDR *xdrs,
+       char **cpp,
+       uint_t *sizep,
+       uint_t maxsize)
+{
+       char *sp = *cpp;  /* sp is the actual string pointer */
+       uint_t 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(
+       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(
+       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 */
+{
+       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(
+       XDR *xdrs,
+       char **cpp,
+       uint_t maxsize)
+{
+       char *sp = *cpp;  /* sp is the actual string pointer */
+       uint_t size;
+       uint_t 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(
+       XDR *xdrs,
+       char **cpp)
+{
+       if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
+               return (TRUE);
+       }
+       return (FALSE);
+}