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); +}