Module Name:    src
Committed By:   hannken
Date:           Tue Jun  4 15:07:55 UTC 2019

Modified Files:
        src/common/lib/libc: Makefile.inc
        src/include: Makefile
        src/include/rpc: Makefile
Added Files:
        src/common/include/rpc: Makefile types.h xdr.h
        src/common/lib/libc/rpc: xdr.c xdr_array.c xdr_mem.c
Removed Files:
        src/include/rpc: types.h xdr.h
        src/lib/libc/rpc: xdr.c xdr_array.c xdr_mem.c

Log Message:
Move the basic part of XDR to common/include/rpc and common/lib/libc/rpc.

No functional change intended.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/common/include/rpc/Makefile \
    src/common/include/rpc/types.h src/common/include/rpc/xdr.h
cvs rdiff -u -r1.18 -r1.19 src/common/lib/libc/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/common/lib/libc/rpc/xdr.c \
    src/common/lib/libc/rpc/xdr_array.c src/common/lib/libc/rpc/xdr_mem.c
cvs rdiff -u -r1.145 -r1.146 src/include/Makefile
cvs rdiff -u -r1.12 -r1.13 src/include/rpc/Makefile
cvs rdiff -u -r1.15 -r0 src/include/rpc/types.h
cvs rdiff -u -r1.31 -r0 src/include/rpc/xdr.h
cvs rdiff -u -r1.34 -r0 src/lib/libc/rpc/xdr.c
cvs rdiff -u -r1.19 -r0 src/lib/libc/rpc/xdr_array.c
cvs rdiff -u -r1.20 -r0 src/lib/libc/rpc/xdr_mem.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/common/lib/libc/Makefile.inc
diff -u src/common/lib/libc/Makefile.inc:1.18 src/common/lib/libc/Makefile.inc:1.19
--- src/common/lib/libc/Makefile.inc:1.18	Fri Aug  3 03:35:17 2018
+++ src/common/lib/libc/Makefile.inc	Tue Jun  4 15:07:55 2019
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile.inc,v 1.18 2018/08/03 03:35:17 kamil Exp $
+# $NetBSD: Makefile.inc,v 1.19 2019/06/04 15:07:55 hannken Exp $
 
 .include <bsd.own.mk>
 
 COMMON_DIR:=${.PARSEDIR}
-COMMON_CODEDIRS=atomic gen gmon inet md misc net stdlib string sys
+COMMON_CODEDIRS=atomic gen gmon inet md misc net rpc stdlib string sys
 COMMON_CODEDIRS+=hash/sha1 hash/sha2 hash/sha3 hash/rmd160 hash/murmurhash
 
 .if defined(COMMON_MACHINE_ARCH) && !empty(COMMON_MACHINE_ARCH) && \

Index: src/include/Makefile
diff -u src/include/Makefile:1.145 src/include/Makefile:1.146
--- src/include/Makefile:1.145	Wed Apr 24 10:26:08 2019
+++ src/include/Makefile	Tue Jun  4 15:07:55 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.145 2019/04/24 10:26:08 roy Exp $
+#	$NetBSD: Makefile,v 1.146 2019/06/04 15:07:55 hannken Exp $
 #	@(#)Makefile	8.2 (Berkeley) 1/4/94
 
 # Doing a make includes builds /usr/include
@@ -47,6 +47,7 @@ INCSDIR=	/usr/include
 SUBDIR=		rpc
 SUBDIR+=	../common/include/prop
 SUBDIR+=	../common/include/ppath
+SUBDIR+=	../common/include/rpc
 
 .include <bsd.prog.mk>
 .include <bsd.subdir.mk>

Index: src/include/rpc/Makefile
diff -u src/include/rpc/Makefile:1.12 src/include/rpc/Makefile:1.13
--- src/include/rpc/Makefile:1.12	Sat Jan 11 13:28:43 2003
+++ src/include/rpc/Makefile	Tue Jun  4 15:07:55 2019
@@ -1,10 +1,10 @@
-#	$NetBSD: Makefile,v 1.12 2003/01/11 13:28:43 tron Exp $
+#	$NetBSD: Makefile,v 1.13 2019/06/04 15:07:55 hannken Exp $
 #
 
 INCS=	auth.h auth_unix.h clnt.h clnt_soc.h nettype.h \
 	pmap_clnt.h pmap_prot.h pmap_rmt.h raw.h rpc.h \
 	rpc_com.h rpc_msg.h rpcb_clnt.h rpcb_prot.h rpcent.h \
-	svc.h svc_auth.h svc_soc.h types.h xdr.h
+	svc.h svc_auth.h svc_soc.h
 RPC_INCS=	rpcb_prot.h
 
 INCSDIR=	/usr/include/rpc

Added files:

Index: src/common/include/rpc/Makefile
diff -u /dev/null src/common/include/rpc/Makefile:1.1
--- /dev/null	Tue Jun  4 15:07:55 2019
+++ src/common/include/rpc/Makefile	Tue Jun  4 15:07:55 2019
@@ -0,0 +1,8 @@
+#	$NetBSD: Makefile,v 1.1 2019/06/04 15:07:55 hannken Exp $
+#
+
+INCS=	types.h xdr.h
+
+INCSDIR=	/usr/include/rpc
+
+.include <bsd.prog.mk>
Index: src/common/include/rpc/types.h
diff -u /dev/null src/common/include/rpc/types.h:1.1
--- /dev/null	Tue Jun  4 15:07:55 2019
+++ src/common/include/rpc/types.h	Tue Jun  4 15:07:55 2019
@@ -0,0 +1,107 @@
+/*	$NetBSD: types.h,v 1.1 2019/06/04 15:07:55 hannken Exp $	*/
+
+/*
+ * 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
+ *
+ *	from: @(#)types.h 1.18 87/07/24 SMI
+ *	@(#)types.h	2.3 88/08/15 4.0 RPCSRC
+ */
+
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef _RPC_TYPES_H_
+#define _RPC_TYPES_H_
+
+#include <sys/types.h>
+
+typedef int32_t bool_t;
+typedef int32_t enum_t;
+
+typedef uint32_t rpcprog_t;
+typedef uint32_t rpcvers_t;
+typedef uint32_t rpcproc_t;
+typedef uint32_t rpcprot_t;
+typedef uint32_t rpcport_t;
+typedef   int32_t rpc_inline_t;
+
+#define __dontcare__	-1
+
+#ifndef FALSE
+#	define FALSE	(0)
+#endif
+#ifndef TRUE
+#	define TRUE	(1)
+#endif
+#ifndef NULL
+#	define NULL	0
+#endif
+
+#define mem_alloc(bsize)	calloc((size_t)1, bsize)
+#define mem_free(ptr, bsize)	free(ptr)
+
+#include <sys/time.h>
+#include <netconfig.h>
+
+/*
+ * The netbuf structure is defined here, because NetBSD only uses it inside
+ * the RPC code. It's in <xti.h> on SVR4, but it would be confusing to
+ * have an xti.h, since NetBSD does not support XTI/TLI.
+ */
+
+/*
+ * The netbuf structure is used for transport-independent address storage.
+ */
+struct netbuf {
+	unsigned int maxlen;
+	unsigned int len;
+	void *buf;
+};
+
+/*
+ * The format of the addres and options arguments of the XTI t_bind call.
+ * Only provided for compatibility, it should not be used.
+ */
+
+struct t_bind {
+	struct netbuf   addr;
+	unsigned int    qlen;
+};
+
+/*
+ * Internal library and rpcbind use. This is not an exported interface, do
+ * not use.
+ */
+struct __rpc_sockinfo {
+	int si_af; 
+	int si_proto;
+	int si_socktype;
+	int si_alen;
+};
+
+#endif /* !_RPC_TYPES_H_ */
Index: src/common/include/rpc/xdr.h
diff -u /dev/null src/common/include/rpc/xdr.h:1.1
--- /dev/null	Tue Jun  4 15:07:55 2019
+++ src/common/include/rpc/xdr.h	Tue Jun  4 15:07:55 2019
@@ -0,0 +1,370 @@
+/*	$NetBSD: xdr.h,v 1.1 2019/06/04 15:07:55 hannken Exp $	*/
+
+/*
+ * 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
+ *
+ *	from: @(#)xdr.h 1.19 87/04/22 SMI
+ *	@(#)xdr.h	2.2 88/07/29 4.0 RPCSRC
+ */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_XDR_H_
+#define _RPC_XDR_H_
+#include <sys/cdefs.h>
+
+/*
+ * 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)
+
+/*
+ * 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 __rpc_xdr {
+	enum xdr_op	x_op;		/* operation; fast additional param */
+	const struct xdr_ops {
+		/* get a long from underlying stream */
+		bool_t	(*x_getlong)(struct __rpc_xdr *, long *);
+		/* put a long to " */
+		bool_t	(*x_putlong)(struct __rpc_xdr *, const long *);
+		/* get some bytes from " */
+		bool_t	(*x_getbytes)(struct __rpc_xdr *, char *, unsigned int);
+		/* put some bytes to " */
+		bool_t	(*x_putbytes)(struct __rpc_xdr *, const char *,
+					unsigned int);
+		/* returns bytes off from beginning */
+		unsigned (*x_getpostn)(struct __rpc_xdr *);
+		/* lets you reposition the stream */
+		bool_t  (*x_setpostn)(struct __rpc_xdr *, unsigned int);
+		/* buf quick ptr to buffered data */
+		int32_t	*(*x_inline)(struct __rpc_xdr *, unsigned int);
+		/* free privates of this xdr_stream */
+		void	(*x_destroy)(struct __rpc_xdr *);
+		bool_t	(*x_control)(struct __rpc_xdr *, int, void *);
+	} *x_ops;
+	char *	 	x_public;	/* users' data */
+	void *		x_private;	/* pointer to private data */
+	char * 		x_base;		/* private used for position info */
+	unsigned int	x_handy;	/* extra private word */
+} XDR;
+
+/*
+ * 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.
+ */
+typedef	bool_t (*xdrproc_t)(XDR *, const void *); 
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR		*xdrs;
+ * long		*longp;
+ * char *	 addr;
+ * unsigned	 len;
+ * unsigned	 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)
+
+static __inline int
+xdr_getint32(XDR *xdrs, int32_t *ip)
+{
+	long l;
+
+	if (!xdr_getlong(xdrs, &l))
+		return 0;
+	*ip = (int32_t)l;
+	return 1;
+}
+
+static __inline int
+xdr_putint32(XDR *xdrs, int32_t *ip)
+{
+	long l;
+
+	l = (long)*ip;
+	return xdr_putlong(xdrs, &l);
+}
+
+#define XDR_GETINT32(xdrs, int32p)	xdr_getint32(xdrs, int32p)
+#define XDR_PUTINT32(xdrs, int32p)	xdr_putint32(xdrs, int32p)
+
+#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)
+
+#define XDR_CONTROL(xdrs, req, op)			\
+	(((xdrs)->x_ops->x_control == NULL) ? (FALSE) : \
+		(*(xdrs)->x_ops->x_control)(xdrs, req, op))
+#define xdr_control(xdrs, req, op) XDR_CONTROL(xdrs, req, op)
+
+#define xdr_rpcvers(xdrs, versp) xdr_u_int32_t(xdrs, versp)
+#define xdr_rpcprog(xdrs, progp) xdr_u_int32_t(xdrs, progp)
+#define xdr_rpcproc(xdrs, procp) xdr_u_int32_t(xdrs, procp)
+#define xdr_rpcprot(xdrs, protp) xdr_u_int32_t(xdrs, protp)
+#define xdr_rpcport(xdrs, portp) xdr_u_int32_t(xdrs, portp)
+
+/*
+ * 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 primitive 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 (0);
+ *	<<< 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_INT32(buf)		((int32_t)ntohl((uint32_t)*(buf)++))
+#define IXDR_PUT_INT32(buf, v)		(*(buf)++ =(int32_t)htonl((uint32_t)v))
+#define IXDR_GET_U_INT32(buf)		((uint32_t)IXDR_GET_INT32(buf))
+#define IXDR_PUT_U_INT32(buf, v)	IXDR_PUT_INT32((buf), ((int32_t)(v)))
+
+#define IXDR_GET_LONG(buf)		((long)ntohl((uint32_t)*(buf)++))
+#define IXDR_PUT_LONG(buf, v)		(*(buf)++ =(int32_t)htonl((uint32_t)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)		((unsigned long)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf)		((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf)		((unsigned short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v)		IXDR_PUT_LONG((buf), (v))
+#define IXDR_PUT_ENUM(buf, v)		IXDR_PUT_LONG((buf), (v))
+#define IXDR_PUT_U_LONG(buf, v)		IXDR_PUT_LONG((buf), (v))
+#define IXDR_PUT_SHORT(buf, v)		IXDR_PUT_LONG((buf), (v))
+#define IXDR_PUT_U_SHORT(buf, v)	IXDR_PUT_LONG((buf), (v))
+
+/*
+ * These are the "generic" xdr routines.
+ */
+__BEGIN_DECLS
+extern bool_t	xdr_void(void);
+extern bool_t	xdr_int(XDR *, int *);
+extern bool_t	xdr_u_int(XDR *, unsigned int *);
+extern bool_t	xdr_long(XDR *, long *);
+extern bool_t	xdr_u_long(XDR *, unsigned long *);
+extern bool_t	xdr_short(XDR *, short *);
+extern bool_t	xdr_u_short(XDR *, unsigned short *);
+extern bool_t	xdr_int16_t(XDR *, int16_t *);
+extern bool_t	xdr_u_int16_t(XDR *, uint16_t *);
+extern bool_t	xdr_int32_t(XDR *, int32_t *);
+extern bool_t	xdr_u_int32_t(XDR *, uint32_t *);
+extern bool_t	xdr_int64_t(XDR *, int64_t *);
+extern bool_t	xdr_u_int64_t(XDR *, uint64_t *);
+extern bool_t	xdr_bool(XDR *, bool_t *);
+extern bool_t	xdr_enum(XDR *, enum_t *);
+extern bool_t	xdr_array(XDR *, char **, unsigned int *, unsigned int,
+			unsigned int, xdrproc_t);
+extern bool_t	xdr_bytes(XDR *, char **, unsigned int *, unsigned int);
+extern bool_t	xdr_opaque(XDR *, char *, unsigned int);
+extern bool_t	xdr_string(XDR *, char **, unsigned int);
+extern bool_t	xdr_union(XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t);
+extern bool_t	xdr_char(XDR *, char *);
+extern bool_t	xdr_u_char(XDR *, unsigned char *);
+extern bool_t	xdr_vector(XDR *, char *, unsigned int, unsigned int,
+			xdrproc_t);
+extern bool_t	xdr_float(XDR *, float *);
+extern bool_t	xdr_double(XDR *, double *);
+extern bool_t	xdr_quadruple(XDR *, long double *);
+extern bool_t	xdr_reference(XDR *, char **, unsigned int, xdrproc_t);
+extern bool_t	xdr_pointer(XDR *, char **, unsigned int, xdrproc_t);
+extern bool_t	xdr_wrapstring(XDR *, char **);
+extern void	xdr_free(xdrproc_t, char *);
+extern bool_t	xdr_hyper(XDR *, longlong_t *);
+extern bool_t	xdr_u_hyper(XDR *, u_longlong_t *);
+extern bool_t	xdr_longlong_t(XDR *, longlong_t *);
+extern bool_t	xdr_u_longlong_t(XDR *, u_longlong_t *);
+extern unsigned long xdr_sizeof(xdrproc_t, void *);
+__END_DECLS
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024 
+struct netobj {
+	unsigned int n_len;
+	char	*n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t   xdr_netobj(XDR *, struct netobj *);
+
+/*
+ * These are XDR control operators
+ */
+
+#define XDR_GET_BYTES_AVAIL	1
+
+struct xdr_bytesrec {
+	bool_t xc_is_last_record;
+	size_t xc_num_avail;
+};
+
+typedef struct xdr_bytesrec xdr_bytesrec;
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+__BEGIN_DECLS
+/* XDR using memory buffers */
+extern void   xdrmem_create(XDR *, char *, unsigned int, enum xdr_op);
+
+/* XDR using stdio library */
+#ifdef _STDIO_H_
+extern void   xdrstdio_create(XDR *, FILE *, enum xdr_op);
+#endif
+
+/* XDR pseudo records for tcp */
+extern void   xdrrec_create(XDR *, unsigned int, unsigned int, char *,
+				int (*)(char *, char *, int),
+				int (*)(char *, char *, int));
+
+/* make end of xdr record */
+extern bool_t xdrrec_endofrecord(XDR *, int);
+
+/* move to beginning of next record */
+extern bool_t xdrrec_skiprecord(XDR *);
+
+/* true if no more input */
+extern bool_t xdrrec_eof(XDR *);
+extern unsigned xdrrec_readbytes(XDR *, caddr_t, unsigned int);
+__END_DECLS
+
+#endif /* !_RPC_XDR_H_ */

Index: src/common/lib/libc/rpc/xdr.c
diff -u /dev/null src/common/lib/libc/rpc/xdr.c:1.1
--- /dev/null	Tue Jun  4 15:07:55 2019
+++ src/common/lib/libc/rpc/xdr.c	Tue Jun  4 15:07:55 2019
@@ -0,0 +1,972 @@
+/*	$NetBSD: xdr.c,v 1.1 2019/06/04 15:07:55 hannken Exp $	*/
+
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *     * Neither the name of the "Oracle America, Inc." nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char *sccsid = "@(#)xdr.c 1.35 87/08/12";
+static char *sccsid = "@(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";
+#else
+__RCSID("$NetBSD: xdr.c,v 1.1 2019/06/04 15:07:55 hannken Exp $");
+#endif
+#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 "namespace.h"
+
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/rpc_com.h>
+
+#ifdef __weak_alias
+__weak_alias(xdr_bool,_xdr_bool)
+__weak_alias(xdr_bytes,_xdr_bytes)
+__weak_alias(xdr_char,_xdr_char)
+__weak_alias(xdr_enum,_xdr_enum)
+__weak_alias(xdr_free,_xdr_free)
+__weak_alias(xdr_hyper,_xdr_hyper)
+__weak_alias(xdr_int,_xdr_int)
+__weak_alias(xdr_int16_t,_xdr_int16_t)
+__weak_alias(xdr_int32_t,_xdr_int32_t)
+__weak_alias(xdr_int64_t,_xdr_int64_t)
+__weak_alias(xdr_long,_xdr_long)
+__weak_alias(xdr_longlong_t,_xdr_longlong_t)
+__weak_alias(xdr_netobj,_xdr_netobj)
+__weak_alias(xdr_opaque,_xdr_opaque)
+__weak_alias(xdr_short,_xdr_short)
+__weak_alias(xdr_string,_xdr_string)
+__weak_alias(xdr_u_char,_xdr_u_char)
+__weak_alias(xdr_u_hyper,_xdr_u_hyper)
+__weak_alias(xdr_u_int,_xdr_u_int)
+__weak_alias(xdr_u_int16_t,_xdr_u_int16_t)
+__weak_alias(xdr_u_int32_t,_xdr_u_int32_t)
+__weak_alias(xdr_u_int64_t,_xdr_u_int64_t)
+__weak_alias(xdr_u_long,_xdr_u_long)
+__weak_alias(xdr_u_longlong_t,_xdr_u_longlong_t)
+__weak_alias(xdr_u_short,_xdr_u_short)
+__weak_alias(xdr_union,_xdr_union)
+__weak_alias(xdr_void,_xdr_void)
+__weak_alias(xdr_wrapstring,_xdr_wrapstring)
+#endif
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE	((long) 0)
+#define XDR_TRUE	((long) 1)
+
+/*
+ * for unit alignment
+ */
+static const 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)
+{
+	long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(ip != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (long) *ip;
+		return (XDR_PUTLONG(xdrs, &l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l)) {
+			return (FALSE);
+		}
+		*ip = (int) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(XDR *xdrs, u_int *up)
+{
+	u_long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(up != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (u_long) *up;
+		return (XDR_PUTLONG(xdrs, (long *)&l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, (long *)&l)) {
+			return (FALSE);
+		}
+		*up = (u_int) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(XDR *xdrs, long *lp)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(lp != NULL);
+
+	switch (xdrs->x_op) {
+	case XDR_ENCODE:
+		return (XDR_PUTLONG(xdrs, lp));
+	case XDR_DECODE:
+		return (XDR_GETLONG(xdrs, lp));
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t
+xdr_u_long(XDR *xdrs, u_long *ulp)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(ulp != NULL);
+
+	switch (xdrs->x_op) {
+	case XDR_ENCODE:
+		return (XDR_PUTLONG(xdrs, (long *)ulp));
+	case XDR_DECODE:
+		return (XDR_GETLONG(xdrs, (long *)ulp));
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+
+/*
+ * XDR 32-bit integers
+ * same as xdr_u_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_int32_t(XDR *xdrs, int32_t *int32_p)
+{
+	long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(int32_p != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (long) *int32_p;
+		return (XDR_PUTLONG(xdrs, &l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l)) {
+			return (FALSE);
+		}
+		*int32_p = (int32_t) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned 32-bit integers
+ * same as xdr_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p)
+{
+	u_long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(u_int32_p != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (u_long) *u_int32_p;
+		return (XDR_PUTLONG(xdrs, (long *)&l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, (long *)&l)) {
+			return (FALSE);
+		}
+		*u_int32_p = (u_int32_t) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(XDR *xdrs, short *sp)
+{
+	long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(sp != NULL);
+
+	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);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(XDR *xdrs, u_short *usp)
+{
+	u_long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(usp != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (u_long) *usp;
+		return (XDR_PUTLONG(xdrs, (long *)&l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, (long *)&l)) {
+			return (FALSE);
+		}
+		*usp = (u_short) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+
+/*
+ * XDR 16-bit integers
+ */
+bool_t
+xdr_int16_t(XDR *xdrs, int16_t *int16_p)
+{
+	long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(int16_p != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (long) *int16_p;
+		return (XDR_PUTLONG(xdrs, &l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l)) {
+			return (FALSE);
+		}
+		*int16_p = (int16_t) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned 16-bit integers
+ */
+bool_t
+xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p)
+{
+	u_long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(u_int16_p != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (u_long) *u_int16_p;
+		return (XDR_PUTLONG(xdrs, (long *)&l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, (long *)&l)) {
+			return (FALSE);
+		}
+		*u_int16_p = (u_int16_t) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(XDR *xdrs, char *cp)
+{
+	int i;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(cp != NULL);
+
+	i = (*cp);
+	if (!xdr_int(xdrs, &i)) {
+		return (FALSE);
+	}
+	*cp = i;
+	return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t
+xdr_u_char(XDR *xdrs, u_char *cp)
+{
+	u_int u;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(cp != NULL);
+
+	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)
+{
+	long lb;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(bp != NULL);
+
+	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);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t
+xdr_enum(XDR *xdrs, enum_t *ep)
+{
+	long l;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(ep != NULL);
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (long) *ep;
+		return (XDR_PUTLONG(xdrs, &l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l)) {
+			return (FALSE);
+		}
+		*ep = (enum_t) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * 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, caddr_t cp, u_int cnt)
+{
+	u_int rndup;
+	static int crud[BYTES_PER_XDR_UNIT];
+
+	_DIAGASSERT(xdrs != NULL);
+		/*
+		 * if no data we are done
+		 */
+	if (cnt == 0)
+		return (TRUE);
+	_DIAGASSERT(cp != NULL);
+
+	/*
+	 * 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, (caddr_t)(void *)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, u_int *sizep, u_int maxsize)
+{
+	char *sp;  		/* sp is the actual string pointer */
+	u_int nodesize;
+	bool_t ret, allocated = FALSE;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(cpp != NULL);
+	_DIAGASSERT(sizep != NULL);
+
+	sp = *cpp;
+
+	/*
+	 * 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 = mem_alloc(nodesize);
+			allocated = TRUE;
+		}
+		if (sp == NULL) {
+			warn("%s: out of memory", __func__);
+			return (FALSE);
+		}
+		/* FALLTHROUGH */
+
+	case XDR_ENCODE:
+		ret = xdr_opaque(xdrs, sp, nodesize);
+		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
+			if (allocated == TRUE) {
+				free(sp);
+				*cpp = NULL;
+			}
+		}
+		return (ret);
+
+	case XDR_FREE:
+		if (sp != NULL) {
+			mem_free(sp, nodesize);
+			*cpp = NULL;
+		}
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t
+xdr_netobj(XDR *xdrs, struct netobj *np)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(np != NULL);
+
+	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 */
+	const struct xdr_discrim *choices, /* [value, xdr proc] for each arm */
+	xdrproc_t dfault	/* default xdr routine */
+)
+{
+	enum_t dscm;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(dscmp != NULL);
+	_DIAGASSERT(unp != NULL);
+	_DIAGASSERT(choices != NULL);
+	/* dfault may be NULL */
+
+	/*
+	 * 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));
+	}
+
+	/*
+	 * no match - execute the default xdr routine if there is one
+	 */
+	return ((dfault == NULL_xdrproc_t) ? FALSE :
+	    (*dfault)(xdrs, unp));
+}
+
+
+/*
+ * 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, u_int maxsize)
+{
+	char *sp;  		/* sp is the actual string pointer */
+	u_int size = 0;		/* XXX: GCC */
+	u_int nodesize;
+	size_t len;
+	bool_t ret, allocated = FALSE;
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(cpp != NULL);
+
+	sp = *cpp;
+
+	/*
+	 * 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 */
+		}
+		/* FALLTHROUGH */
+	case XDR_ENCODE:
+		len = strlen(sp);
+		_DIAGASSERT(__type_fit(u_int, len));
+		size = (u_int)len;
+		break;
+	case XDR_DECODE:
+		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 = mem_alloc(nodesize);
+			allocated = TRUE;
+		}
+		if (sp == NULL) {
+			warn("%s: out of memory", __func__);
+			return (FALSE);
+		}
+		sp[size] = 0;
+		/* FALLTHROUGH */
+
+	case XDR_ENCODE:
+		ret = xdr_opaque(xdrs, sp, size);
+		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
+			if (allocated == TRUE) {
+				free(sp);
+				*cpp = NULL;
+			}
+		}
+		return (ret);
+
+	case XDR_FREE:
+		mem_free(sp, nodesize);
+		*cpp = NULL;
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+/* 
+ * Wrapper for xdr_string that can be called directly from 
+ * routines like clnt_call
+ */
+bool_t
+xdr_wrapstring(XDR *xdrs, char **cpp)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(cpp != NULL);
+
+	return xdr_string(xdrs, cpp, RPC_MAXDATASIZE);
+}
+
+/*
+ * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
+ * are in the "non-portable" section because they require that a `long long'
+ * be a 64-bit type.
+ *
+ *	--thor...@netbsd.org, November 30, 1999
+ */
+
+/*
+ * XDR 64-bit integers
+ */
+bool_t
+xdr_int64_t(XDR *xdrs, int64_t *llp)
+{
+	u_long ul[2];
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(llp != NULL);
+
+	switch (xdrs->x_op) {
+	case XDR_ENCODE:
+		ul[0] = (u_long)(((uint64_t)*llp >> 32) &
+		    (uint64_t)0xffffffffULL);
+		ul[1] = (u_long)(((uint64_t)*llp) &
+		    (uint64_t)0xffffffffULL);
+		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
+			return (FALSE);
+		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
+	case XDR_DECODE:
+		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
+			return (FALSE);
+		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
+			return (FALSE);
+		*llp = (int64_t)
+		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
+		return (TRUE);
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+
+/*
+ * XDR unsigned 64-bit integers
+ */
+bool_t
+xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp)
+{
+	u_long ul[2];
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(ullp != NULL);
+
+	switch (xdrs->x_op) {
+	case XDR_ENCODE:
+		ul[0] = (u_long)(*ullp >> 32) & 0xffffffffUL;
+		ul[1] = (u_long)(*ullp) & 0xffffffffUL;
+		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
+			return (FALSE);
+		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
+	case XDR_DECODE:
+		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
+			return (FALSE);
+		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
+			return (FALSE);
+		*ullp = (u_int64_t)
+		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
+		return (TRUE);
+	case XDR_FREE:
+		return (TRUE);
+	}
+	/* NOTREACHED */
+	return (FALSE);
+}
+
+
+/*
+ * XDR hypers
+ */
+bool_t
+xdr_hyper(XDR *xdrs, longlong_t *llp)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(llp != NULL);
+
+	/*
+	 * Don't bother open-coding this; it's a fair amount of code.  Just
+	 * call xdr_int64_t().
+	 */
+	return (xdr_int64_t(xdrs, (int64_t *)llp));
+}
+
+
+/*
+ * XDR unsigned hypers
+ */
+bool_t
+xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(ullp != NULL);
+
+	/*
+	 * Don't bother open-coding this; it's a fair amount of code.  Just
+	 * call xdr_u_int64_t().
+	 */
+	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
+}
+
+
+/*
+ * XDR longlong_t's
+ */
+bool_t
+xdr_longlong_t(XDR *xdrs, longlong_t *llp)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(llp != NULL);
+
+	/*
+	 * Don't bother open-coding this; it's a fair amount of code.  Just
+	 * call xdr_int64_t().
+	 */
+	return (xdr_int64_t(xdrs, (int64_t *)llp));
+}
+
+
+/*
+ * XDR u_longlong_t's
+ */
+bool_t
+xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
+{
+
+	_DIAGASSERT(xdrs != NULL);
+	_DIAGASSERT(ullp != NULL);
+
+	/*
+	 * Don't bother open-coding this; it's a fair amount of code.  Just
+	 * call xdr_u_int64_t().
+	 */
+	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
+}
Index: src/common/lib/libc/rpc/xdr_array.c
diff -u /dev/null src/common/lib/libc/rpc/xdr_array.c:1.1
--- /dev/null	Tue Jun  4 15:07:55 2019
+++ src/common/lib/libc/rpc/xdr_array.c	Tue Jun  4 15:07:55 2019
@@ -0,0 +1,163 @@
+/*	$NetBSD: xdr_array.c,v 1.1 2019/06/04 15:07:55 hannken Exp $	*/
+
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *     * Neither the name of the "Oracle America, Inc." nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char *sccsid = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+static char *sccsid = "@(#)xdr_array.c	2.1 88/07/29 4.0 RPCSRC";
+#else
+__RCSID("$NetBSD: xdr_array.c,v 1.1 2019/06/04 15:07:55 hannken Exp $");
+#endif
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines implementation.
+ *
+ * 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 "namespace.h"
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#ifdef __weak_alias
+__weak_alias(xdr_array,_xdr_array)
+__weak_alias(xdr_vector,_xdr_vector)
+#endif
+
+/*
+ * 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(XDR *xdrs, caddr_t *addrp, u_int *sizep, u_int maxsize, u_int elsize,
+    xdrproc_t elproc)
+{
+	u_int i;
+	caddr_t target = *addrp;
+	u_int c;  /* the actual element count */
+	bool_t stat = TRUE;
+	u_int nodesize;
+
+	/* like strings, arrays are really counted arrays */
+	if (!xdr_u_int(xdrs, sizep))
+		return (FALSE);
+
+	c = *sizep;
+	if ((c > maxsize || UINT_MAX/elsize < c) &&
+	    (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) {
+				warn("%s: out of memory", __func__);
+				return (FALSE);
+			}
+			memset(target, 0, nodesize);
+			break;
+
+		case XDR_FREE:
+			return (TRUE);
+
+		case XDR_ENCODE:
+			break;
+	}
+	
+	/*
+	 * now we xdr each element of array
+	 */
+	for (i = 0; (i < c) && stat; i++) {
+		stat = (*elproc)(xdrs, target);
+		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(XDR *xdrs, char *basep, u_int nelem, u_int elemsize,
+    xdrproc_t xdr_elem)
+{
+	u_int i;
+	char *elptr;
+
+	elptr = basep;
+	for (i = 0; i < nelem; i++) {
+		if (!(*xdr_elem)(xdrs, elptr)) {
+			return(FALSE);
+		}
+		elptr += elemsize;
+	}
+	return(TRUE);	
+}
Index: src/common/lib/libc/rpc/xdr_mem.c
diff -u /dev/null src/common/lib/libc/rpc/xdr_mem.c:1.1
--- /dev/null	Tue Jun  4 15:07:55 2019
+++ src/common/lib/libc/rpc/xdr_mem.c	Tue Jun  4 15:07:55 2019
@@ -0,0 +1,263 @@
+/*	$NetBSD: xdr_mem.c,v 1.1 2019/06/04 15:07:55 hannken Exp $	*/
+
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *     * Neither the name of the "Oracle America, Inc." nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char *sccsid = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+static char *sccsid = "@(#)xdr_mem.c	2.1 88/07/29 4.0 RPCSRC";
+#else
+__RCSID("$NetBSD: xdr_mem.c,v 1.1 2019/06/04 15:07:55 hannken Exp $");
+#endif
+#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 "namespace.h"
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+
+#include <string.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#ifdef __weak_alias
+__weak_alias(xdrmem_create,_xdrmem_create)
+#endif
+
+static void xdrmem_destroy(XDR *);
+static bool_t xdrmem_getlong_aligned(XDR *, long *);
+static bool_t xdrmem_putlong_aligned(XDR *, const long *);
+static bool_t xdrmem_getlong_unaligned(XDR *, long *);
+static bool_t xdrmem_putlong_unaligned(XDR *, const long *);
+static bool_t xdrmem_getbytes(XDR *, char *, u_int);
+static bool_t xdrmem_putbytes(XDR *, const char *, u_int);
+/* XXX: w/64-bit pointers, u_int not enough! */
+static u_int xdrmem_getpos(XDR *);
+static bool_t xdrmem_setpos(XDR *, u_int);
+static int32_t *xdrmem_inline_aligned(XDR *, u_int);
+static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
+static bool_t xdrmem_control(XDR *xdrs, int request, void *info);
+
+static const struct	xdr_ops xdrmem_ops_aligned = {
+	xdrmem_getlong_aligned,
+	xdrmem_putlong_aligned,
+	xdrmem_getbytes,
+	xdrmem_putbytes,
+	xdrmem_getpos,
+	xdrmem_setpos,
+	xdrmem_inline_aligned,
+	xdrmem_destroy,
+	xdrmem_control
+};
+
+static const struct	xdr_ops xdrmem_ops_unaligned = {
+	xdrmem_getlong_unaligned,
+	xdrmem_putlong_unaligned,
+	xdrmem_getbytes,
+	xdrmem_putbytes,
+	xdrmem_getpos,
+	xdrmem_setpos,
+	xdrmem_inline_unaligned,
+	xdrmem_destroy,
+	xdrmem_control
+};
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.  
+ */
+void
+xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
+{
+
+	xdrs->x_op = op;
+	xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1))
+	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
+	xdrs->x_private = xdrs->x_base = addr;
+	xdrs->x_handy = size;
+}
+
+/*ARGSUSED*/
+static void
+xdrmem_destroy(XDR *xdrs)
+{
+
+}
+
+static bool_t
+xdrmem_getlong_aligned(XDR *xdrs, long *lp)
+{
+
+	if (xdrs->x_handy < sizeof(int32_t))
+		return (FALSE);
+	xdrs->x_handy -= sizeof(int32_t);
+	*lp = ntohl(*(u_int32_t *)xdrs->x_private);
+	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_aligned(XDR *xdrs, const long *lp)
+{
+
+	if (xdrs->x_handy < sizeof(int32_t))
+		return (FALSE);
+	xdrs->x_handy -= sizeof(int32_t);
+	*(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
+	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_getlong_unaligned(XDR *xdrs, long *lp)
+{
+	u_int32_t l;
+
+	if (xdrs->x_handy < sizeof(int32_t))
+		return (FALSE);
+	xdrs->x_handy -= sizeof(int32_t);
+	memmove(&l, xdrs->x_private, sizeof(int32_t));
+	*lp = ntohl(l);
+	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_unaligned(XDR *xdrs, const long *lp)
+{
+	u_int32_t l;
+
+	if (xdrs->x_handy < sizeof(int32_t))
+		return (FALSE);
+	xdrs->x_handy -= sizeof(int32_t);
+	l = htonl((u_int32_t)*lp);
+	memmove(xdrs->x_private, &l, sizeof(int32_t));
+	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes(XDR *xdrs, char *addr, u_int len)
+{
+
+	if (xdrs->x_handy < len)
+		return (FALSE);
+	xdrs->x_handy -= len;
+	memmove(addr, xdrs->x_private, len);
+	xdrs->x_private = (char *)xdrs->x_private + len;
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_putbytes(XDR *xdrs, const char *addr, u_int len)
+{
+
+	if (xdrs->x_handy < len)
+		return (FALSE);
+	xdrs->x_handy -= len;
+	memmove(xdrs->x_private, addr, len);
+	xdrs->x_private = (char *)xdrs->x_private + len;
+	return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(XDR *xdrs)
+{
+
+	/* XXX w/64-bit pointers, u_int not enough! */
+	return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base);
+}
+
+static bool_t
+xdrmem_setpos(XDR *xdrs, u_int pos)
+{
+	char *newaddr = xdrs->x_base + pos;
+	char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
+
+	if ((long)newaddr > (long)lastaddr)
+		return (FALSE);
+	xdrs->x_private = newaddr;
+	xdrs->x_handy = (int)((long)lastaddr - (long)newaddr);
+	return (TRUE);
+}
+
+static int32_t *
+xdrmem_inline_aligned(XDR *xdrs, u_int len)
+{
+	int32_t *buf = 0;
+
+	if (xdrs->x_handy >= len) {
+		xdrs->x_handy -= len;
+		buf = (int32_t *)xdrs->x_private;
+		xdrs->x_private = (char *)xdrs->x_private + len;
+	}
+	return (buf);
+}
+
+/* ARGSUSED */
+static int32_t *
+xdrmem_inline_unaligned(XDR *xdrs, u_int len)
+{
+
+	return (0);
+}
+
+static bool_t
+xdrmem_control(XDR *xdrs, int request, void *info)
+{
+	xdr_bytesrec *xptr;
+
+	switch (request) {
+
+	case XDR_GET_BYTES_AVAIL:
+		xptr = (xdr_bytesrec *)info;
+		xptr->xc_is_last_record = TRUE;
+		xptr->xc_num_avail = xdrs->x_handy;
+		return (TRUE);
+
+	}
+	return (FALSE);
+}

Reply via email to