diff options
| -rw-r--r-- | lib/libc/xdr/Makefile.inc | 11 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr.3 | 823 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr.c | 578 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr_array.c | 155 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr_float.c | 283 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr_mem.c | 186 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr_rec.c | 586 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr_reference.c | 134 | ||||
| -rw-r--r-- | lib/libc/xdr/xdr_stdio.c | 191 | 
9 files changed, 2947 insertions, 0 deletions
| diff --git a/lib/libc/xdr/Makefile.inc b/lib/libc/xdr/Makefile.inc new file mode 100644 index 000000000000..f547d9dbe476 --- /dev/null +++ b/lib/libc/xdr/Makefile.inc @@ -0,0 +1,11 @@ +#	@(#)Makefile	5.11 (Berkeley) 9/6/90 + +.PATH: ${.CURDIR}/rpc ${.CURDIR}/. +CFLAGS+=-I${.CURDIR} -I${.CURDIR}/rpc +SRCS=	xdr.c xdr_array.c xdr_mem.c \ +	xdr_rec.c xdr_reference.c xdr_stdio.c + +MAN3=	xdr/xdr.3 + +UNSUPPORTED+=	xdr_float.c  + diff --git a/lib/libc/xdr/xdr.3 b/lib/libc/xdr/xdr.3 new file mode 100644 index 000000000000..b656ea804da8 --- /dev/null +++ b/lib/libc/xdr/xdr.3 @@ -0,0 +1,823 @@ +.\" @(#)xdr.3n	2.2 88/08/03 4.0 RPCSRC; from 1.16 88/03/14 SMI +.TH XDR 3N "16 February 1988" +.SH NAME +xdr \- library routines for external data representation +.SH SYNOPSIS AND DESCRIPTION +.LP +These routines allow C programmers to describe +arbitrary data structures in a machine-independent fashion. +Data for remote procedure calls are transmitted using these +routines. +.LP +.ft B +.nf +.sp .5 +xdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc) +\s-1XDR\s0 *xdrs; +char **arrp; +u_int *sizep, maxsize, elsize; +xdrproc_t elproc; +.fi +.ft R +.IP +A filter primitive that translates between variable-length +arrays +and their corresponding external representations. The +parameter +.I arrp +is the address of the pointer to the array, while +.I sizep +is the address of the element count of the array; +this element count cannot exceed +.IR maxsize . +The parameter +.I elsize +is the +.I sizeof +each of the array's elements, and +.I elproc +is an +.SM XDR +filter that translates between +the array elements' C form, and their external +representation. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 8 +.LP +.ft B +.nf +.sp .5 +xdr_bool(xdrs, bp) +\s-1XDR\s0 *xdrs; +bool_t *bp; +.fi +.ft R +.IP +A filter primitive that translates between booleans (C +integers) +and their external representations. When encoding data, this +filter produces values of either one or zero. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 10 +.LP +.ft B +.nf +.sp .5 +xdr_bytes(xdrs, sp, sizep, maxsize) +\s-1XDR\s0 *xdrs; +char **sp; +u_int *sizep, maxsize; +.fi +.ft R +.IP +A filter primitive that translates between counted byte +strings and their external representations. +The parameter +.I sp +is the address of the string pointer. The length of the +string is located at address +.IR sizep ; +strings cannot be longer than +.IR maxsize . +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 7 +.LP +.ft B +.nf +.sp .5 +xdr_char(xdrs, cp) +\s-1XDR\s0 *xdrs; +char *cp; +.fi +.ft R +.IP +A filter primitive that translates between C characters +and their external representations. +This routine returns one if it succeeds, zero otherwise. +Note: encoded characters are not packed, and occupy 4 bytes +each. For arrays of characters, it is worthwhile to +consider +.BR xdr_bytes(\|) , +.B xdr_opaque(\|) +or +.BR xdr_string(\|) . +.br +.if t .ne 8 +.LP +.ft B +.nf +.sp .5 +void +xdr_destroy(xdrs) +\s-1XDR\s0 *xdrs; +.fi +.ft R +.IP +A macro that invokes the destroy routine associated with the +.SM XDR +stream, +.IR xdrs . +Destruction usually involves freeing private data structures +associated with the stream.  Using +.I xdrs +after invoking +.B xdr_destroy(\|) +is undefined. +.br +.if t .ne 7 +.LP +.ft B +.nf +.sp .5 +xdr_double(xdrs, dp) +\s-1XDR\s0 *xdrs; +double *dp; +.fi +.ft R +.IP +A filter primitive that translates between C +.B double +precision numbers and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 7 +.LP +.ft B +.nf +.sp .5 +xdr_enum(xdrs, ep) +\s-1XDR\s0 *xdrs; +enum_t *ep; +.fi +.ft R +.IP +A filter primitive that translates between C +.BR enum s +(actually integers) and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 8 +.LP +.ft B +.nf +.sp .5 +xdr_float(xdrs, fp) +\s-1XDR\s0 *xdrs; +float *fp; +.fi +.ft R +.IP +A filter primitive that translates between C +.BR float s +and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 9 +.LP +.ft B +.nf +.sp .5 +void +xdr_free(proc, objp) +xdrproc_t proc; +char *objp; +.fi +.ft R +.IP +Generic freeing routine. The first argument is the +.SM XDR +routine for the object being freed. The second argument +is a pointer to the object itself. Note: the pointer passed +to this routine is +.I not +freed, but what it points to +.I is +freed (recursively). +.br +.if t .ne 8 +.LP +.ft B +.nf +.sp .5 +u_int +xdr_getpos(xdrs) +\s-1XDR\s0 *xdrs; +.fi +.ft R +.IP +A macro that invokes the get-position routine +associated with the +.SM XDR +stream, +.IR xdrs . +The routine returns an unsigned integer, +which indicates the position of the +.SM XDR +byte stream. +A desirable feature of +.SM XDR +streams is that simple arithmetic works with this number, +although the +.SM XDR +stream instances need not guarantee this. +.br +.if t .ne 4 +.LP +.ft B +.nf +.sp .5 +.br +long * +xdr_inline(xdrs, len) +\s-1XDR\s0 *xdrs; +int len; +.fi +.ft R +.IP +A macro that invokes the in-line routine associated with the +.SM XDR +stream, +.IR xdrs . +The routine returns a pointer +to a contiguous piece of the stream's buffer; +.I len +is the byte length of the desired buffer. +Note: pointer is cast to +.BR "long *" . +.IP +Warning: +.B xdr_inline(\|) +may return +.SM NULL +(0) +if it cannot allocate a contiguous piece of a buffer. +Therefore the behavior may vary among stream instances; +it exists for the sake of efficiency. +.br +.if t .ne 7 +.LP +.ft B +.nf +.sp .5 +xdr_int(xdrs, ip) +\s-1XDR\s0 *xdrs; +int *ip; +.fi +.ft R +.IP +A filter primitive that translates between C integers +and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 7 +.LP +.ft B +.nf +.sp .5 +xdr_long(xdrs, lp) +\s-1XDR\s0 *xdrs; +long *lp; +.fi +.ft R +.IP +A filter primitive that translates between C +.B long +integers and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 12 +.LP +.ft B +.nf +.sp .5 +void +xdrmem_create(xdrs, addr, size, op) +\s-1XDR\s0 *xdrs; +char *addr; +u_int size; +enum xdr_op op; +.fi +.ft R +.IP +This routine initializes the +.SM XDR +stream object pointed to by +.IR xdrs . +The stream's data is written to, or read from, +a chunk of memory at location +.I addr +whose length is no more than +.I size +bytes long.  The +.I op +determines the direction of the +.SM XDR +stream +(either +.BR \s-1XDR_ENCODE\s0 , +.BR \s-1XDR_DECODE\s0 , +or +.BR \s-1XDR_FREE\s0 ). +.br +.if t .ne 10 +.LP +.ft B +.nf +.sp .5 +xdr_opaque(xdrs, cp, cnt) +\s-1XDR\s0 *xdrs; +char *cp; +u_int cnt; +.fi +.ft R +.IP +A filter primitive that translates between fixed size opaque +data +and its external representation. +The parameter +.I cp +is the address of the opaque object, and +.I cnt +is its size in bytes. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 10 +.LP +.ft B +.nf +.sp .5 +xdr_pointer(xdrs, objpp, objsize, xdrobj) +\s-1XDR\s0 *xdrs; +char **objpp; +u_int objsize; +xdrproc_t xdrobj; +.fi +.ft R +.IP +Like +.B xdr_reference(\|) +execpt that it serializes +.SM NULL +pointers, whereas +.B xdr_reference(\|) +does not.  Thus, +.B xdr_pointer(\|) +can represent +recursive data structures, such as binary trees or +linked lists. +.br +.if t .ne 15 +.LP +.ft B +.nf +.sp .5 +void +xdrrec_create(xdrs, sendsize, recvsize, handle, readit, writeit) +\s-1XDR\s0 *xdrs; +u_int sendsize, recvsize; +char *handle; +int (*readit) (\|), (*writeit) (\|); +.fi +.ft R +.IP +This routine initializes the +.SM XDR +stream object pointed to by +.IR xdrs . +The stream's data is written to a buffer of size +.IR sendsize ; +a value of zero indicates the system should use a suitable +default. The stream's data is read from a buffer of size +.IR recvsize ; +it too can be set to a suitable default by passing a zero +value. +When a stream's output buffer is full, +.I writeit +is called.  Similarly, when a stream's input buffer is empty, +.I readit +is called.  The behavior of these two routines is similar to +the +system calls +.B read +and +.BR write , +except that +.I handle +is passed to the former routines as the first parameter. +Note: the +.SM XDR +stream's +.I op +field must be set by the caller. +.IP +Warning: this +.SM XDR +stream implements an intermediate record stream. +Therefore there are additional bytes in the stream +to provide record boundary information. +.br +.if t .ne 9 +.LP +.ft B +.nf +.sp .5 +xdrrec_endofrecord(xdrs, sendnow) +\s-1XDR\s0 *xdrs; +int sendnow; +.fi +.ft R +.IP +This routine can be invoked only on +streams created by +.BR xdrrec_create(\|) . +The data in the output buffer is marked as a completed +record, +and the output buffer is optionally written out if +.I sendnow +is non-zero. This routine returns one if it succeeds, zero +otherwise. +.br +.if t .ne 8 +.LP +.ft B +.nf +.sp .5 +xdrrec_eof(xdrs) +\s-1XDR\s0 *xdrs; +int empty; +.fi +.ft R +.IP +This routine can be invoked only on +streams created by +.BR xdrrec_create(\|) . +After consuming the rest of the current record in the stream, +this routine returns one if the stream has no more input, +zero otherwise. +.br +.if t .ne 3 +.LP +.ft B +.nf +.sp .5 +xdrrec_skiprecord(xdrs) +\s-1XDR\s0 *xdrs; +.fi +.ft R +.IP +This routine can be invoked only on +streams created by +.BR xdrrec_create(\|) . +It tells the +.SM XDR +implementation that the rest of the current record +in the stream's input buffer should be discarded. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 11 +.LP +.ft B +.nf +.sp .5 +xdr_reference(xdrs, pp, size, proc) +\s-1XDR\s0 *xdrs; +char **pp; +u_int size; +xdrproc_t proc; +.fi +.ft R +.IP +A primitive that provides pointer chasing within structures. +The parameter +.I pp +is the address of the pointer; +.I size +is the +.I sizeof +the structure that +.I *pp +points to; and +.I proc +is an +.SM XDR +procedure that filters the structure +between its C form and its external representation. +This routine returns one if it succeeds, zero otherwise. +.IP +Warning: this routine does not understand +.SM NULL +pointers. Use +.B xdr_pointer(\|) +instead. +.br +.if t .ne 10 +.LP +.ft B +.nf +.sp .5 +xdr_setpos(xdrs, pos) +\s-1XDR\s0 *xdrs; +u_int pos; +.fi +.ft R +.IP +A macro that invokes the set position routine associated with +the +.SM XDR +stream +.IR xdrs . +The parameter +.I pos +is a position value obtained from +.BR xdr_getpos(\|) . +This routine returns one if the +.SM XDR +stream could be repositioned, +and zero otherwise. +.IP +Warning: it is difficult to reposition some types of +.SM XDR +streams, so this routine may fail with one +type of stream and succeed with another. +.br +.if t .ne 8 +.LP +.ft B +.nf +.sp .5 +xdr_short(xdrs, sp) +\s-1XDR\s0 *xdrs; +short *sp; +.fi +.ft R +.IP +A filter primitive that translates between C +.B short +integers and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 10 +.LP +.ft B +.nf +.sp .5 +void +xdrstdio_create(xdrs, file, op) +\s-1XDR\s0 *xdrs; +\s-1FILE\s0 *file; +enum xdr_op op; +.fi +.ft R +.IP +This routine initializes the +.SM XDR +stream object pointed to by +.IR xdrs . +The +.SM XDR +stream data is written to, or read from, the Standard +.B I/O +stream +.IR file . +The parameter +.I op +determines the direction of the +.SM XDR +stream (either +.BR \s-1XDR_ENCODE\s0 , +.BR \s-1XDR_DECODE\s0 , +or +.BR \s-1XDR_FREE\s0 ). +.IP +Warning: the destroy routine associated with such +.SM XDR +streams calls +.B fflush(\|) +on the +.I file +stream, but never +.BR fclose(\|) . +.br +.if t .ne 9 +.LP +.ft B +.nf +.sp .5 +xdr_string(xdrs, sp, maxsize) +\s-1XDR\s0 +*xdrs; +char **sp; +u_int maxsize; +.fi +.ft R +.IP +A filter primitive that translates between C strings and +their +corresponding external representations. +Strings cannot be longer than +.IR maxsize . +Note:  +.I sp +is the address of the string's pointer. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 8 +.LP +.ft B +.nf +.sp .5 +xdr_u_char(xdrs, ucp) +\s-1XDR\s0 *xdrs; +unsigned char *ucp; +.fi +.ft R +.IP +A filter primitive that translates between +.B unsigned +C characters and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 9 +.LP +.ft B +.nf +.sp .5 +xdr_u_int(xdrs, up) +\s-1XDR\s0 *xdrs; +unsigned *up; +.fi +.ft R +.IP +A filter primitive that translates between C +.B unsigned +integers and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 7 +.LP +.ft B +.nf +.sp .5 +xdr_u_long(xdrs, ulp) +\s-1XDR\s0 *xdrs; +unsigned long *ulp; +.fi +.ft R +.IP +A filter primitive that translates between C +.B "unsigned long" +integers and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 7 +.LP +.ft B +.nf +.sp .5 +xdr_u_short(xdrs, usp) +\s-1XDR\s0 *xdrs; +unsigned short *usp; +.fi +.ft R +.IP +A filter primitive that translates between C +.B "unsigned short" +integers and their external representations. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 16 +.LP +.ft B +.nf +.sp .5 +xdr_union(xdrs, dscmp, unp, choices, dfault) +\s-1XDR\s0 *xdrs; +int *dscmp; +char *unp; +struct xdr_discrim *choices; +bool_t (*defaultarm) (\|);  /* may equal \s-1NULL\s0 */ +.fi +.ft R +.IP +A filter primitive that translates between a discriminated C +.B union +and its corresponding external representation. It first +translates the discriminant of the union located at +.IR dscmp . +This discriminant is always an +.BR enum_t . +Next the union located at +.I unp +is translated.  The parameter +.I choices +is a pointer to an array of +.B xdr_discrim(\|) +structures. Each structure contains an ordered pair of +.RI [ value , proc ]. +If the union's discriminant is equal to the associated +.IR value , +then the +.I proc +is called to translate the union.  The end of the +.B xdr_discrim(\|) +structure array is denoted by a routine of value +.SM NULL\s0. +If the discriminant is not found in the +.I choices +array, then the +.I defaultarm +procedure is called (if it is not +.SM NULL\s0). +Returns one if it succeeds, zero otherwise. +.br +.if t .ne 6 +.LP +.ft B +.nf +.sp .5 +xdr_vector(xdrs, arrp, size, elsize, elproc) +\s-1XDR\s0 *xdrs; +char *arrp; +u_int size, elsize; +xdrproc_t elproc; +.fi +.ft R +.IP +A filter primitive that translates between fixed-length +arrays +and their corresponding external representations.  The +parameter +.I arrp +is the address of the pointer to the array, while +.I size +is is the element count of the array.  The parameter +.I elsize +is the +.I sizeof +each of the array's elements, and +.I elproc +is an +.SM XDR +filter that translates between +the array elements' C form, and their external +representation. +This routine returns one if it succeeds, zero otherwise. +.br +.if t .ne 5 +.LP +.ft B +.nf +.sp .5 +xdr_void(\|) +.fi +.ft R +.IP +This routine always returns one. +It may be passed to +.SM RPC +routines that require a function parameter, +where nothing is to be done. +.br +.if t .ne 10 +.LP +.ft B +.nf +.sp .5 +xdr_wrapstring(xdrs, sp) +\s-1XDR\s0 *xdrs; +char **sp; +.fi +.ft R +.IP +A primitive that calls +.B "xdr_string(xdrs, sp,\s-1MAXUN.UNSIGNED\s0 );" +where +.B +.SM MAXUN.UNSIGNED +is the maximum value of an unsigned integer. +.B xdr_wrapstring(\|) +is handy because the +.SM RPC +package passes a maximum of two +.SM XDR +routines as parameters, and +.BR xdr_string(\|) , +one of the most frequently used primitives, requires three. +Returns one if it succeeds, zero otherwise. +.SH SEE ALSO +.BR rpc (3N) +.LP +The following manuals: +.RS +.ft I +eXternal Data Representation Standard: Protocol Specification +.br +eXternal Data Representation: Sun Technical Notes +.ft R +.br +.IR "\s-1XDR\s0: External Data Representation Standard" , +.SM RFC1014, Sun Microsystems, Inc., +.SM USC-ISI\s0. diff --git a/lib/libc/xdr/xdr.c b/lib/libc/xdr/xdr.c new file mode 100644 index 000000000000..9f402047aa5a --- /dev/null +++ b/lib/libc/xdr/xdr.c @@ -0,0 +1,578 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part.  Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + *  + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + *  + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + *  + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + *  + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + *  + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California  94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/ +/*static char *sccsid = "from: @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr.c,v 1.1 1993/10/27 05:41:06 paul Exp $"; +#endif + +/* + * xdr.c, Generic XDR routines implementation. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + * + * These are the "generic" xdr routines used to serialize and de-serialize + * most common data items.  See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * constants specific to the xdr "protocol" + */ +#define XDR_FALSE	((long) 0) +#define XDR_TRUE	((long) 1) +#define LASTUNSIGNED	((u_int) 0-1) + +/* + * for unit alignment + */ +static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; + +/* + * Free a data structure using XDR + * Not a filter, but a convenient utility nonetheless + */ +void +xdr_free(proc, objp) +	xdrproc_t proc; +	char *objp; +{ +	XDR x; +	 +	x.x_op = XDR_FREE; +	(*proc)(&x, objp); +} + +/* + * XDR nothing + */ +bool_t +xdr_void(/* xdrs, addr */) +	/* XDR *xdrs; */ +	/* caddr_t addr; */ +{ + +	return (TRUE); +} + +/* + * XDR integers + */ +bool_t +xdr_int(xdrs, ip) +	XDR *xdrs; +	int *ip; +{ + +#ifdef lint +	(void) (xdr_short(xdrs, (short *)ip)); +	return (xdr_long(xdrs, (long *)ip)); +#else +	if (sizeof (int) == sizeof (long)) { +		return (xdr_long(xdrs, (long *)ip)); +	} else { +		return (xdr_short(xdrs, (short *)ip)); +	} +#endif +} + +/* + * XDR unsigned integers + */ +bool_t +xdr_u_int(xdrs, up) +	XDR *xdrs; +	u_int *up; +{ + +#ifdef lint +	(void) (xdr_short(xdrs, (short *)up)); +	return (xdr_u_long(xdrs, (u_long *)up)); +#else +	if (sizeof (u_int) == sizeof (u_long)) { +		return (xdr_u_long(xdrs, (u_long *)up)); +	} else { +		return (xdr_short(xdrs, (short *)up)); +	} +#endif +} + +/* + * XDR long integers + * same as xdr_u_long - open coded to save a proc call! + */ +bool_t +xdr_long(xdrs, lp) +	register XDR *xdrs; +	long *lp; +{ + +	if (xdrs->x_op == XDR_ENCODE) +		return (XDR_PUTLONG(xdrs, lp)); + +	if (xdrs->x_op == XDR_DECODE) +		return (XDR_GETLONG(xdrs, lp)); + +	if (xdrs->x_op == XDR_FREE) +		return (TRUE); + +	return (FALSE); +} + +/* + * XDR unsigned long integers + * same as xdr_long - open coded to save a proc call! + */ +bool_t +xdr_u_long(xdrs, ulp) +	register XDR *xdrs; +	u_long *ulp; +{ + +	if (xdrs->x_op == XDR_DECODE) +		return (XDR_GETLONG(xdrs, (long *)ulp)); +	if (xdrs->x_op == XDR_ENCODE) +		return (XDR_PUTLONG(xdrs, (long *)ulp)); +	if (xdrs->x_op == XDR_FREE) +		return (TRUE); +	return (FALSE); +} + +/* + * XDR short integers + */ +bool_t +xdr_short(xdrs, sp) +	register XDR *xdrs; +	short *sp; +{ +	long l; + +	switch (xdrs->x_op) { + +	case XDR_ENCODE: +		l = (long) *sp; +		return (XDR_PUTLONG(xdrs, &l)); + +	case XDR_DECODE: +		if (!XDR_GETLONG(xdrs, &l)) { +			return (FALSE); +		} +		*sp = (short) l; +		return (TRUE); + +	case XDR_FREE: +		return (TRUE); +	} +	return (FALSE); +} + +/* + * XDR unsigned short integers + */ +bool_t +xdr_u_short(xdrs, usp) +	register XDR *xdrs; +	u_short *usp; +{ +	u_long l; + +	switch (xdrs->x_op) { + +	case XDR_ENCODE: +		l = (u_long) *usp; +		return (XDR_PUTLONG(xdrs, &l)); + +	case XDR_DECODE: +		if (!XDR_GETLONG(xdrs, &l)) { +			return (FALSE); +		} +		*usp = (u_short) l; +		return (TRUE); + +	case XDR_FREE: +		return (TRUE); +	} +	return (FALSE); +} + + +/* + * XDR a char + */ +bool_t +xdr_char(xdrs, cp) +	XDR *xdrs; +	char *cp; +{ +	int i; + +	i = (*cp); +	if (!xdr_int(xdrs, &i)) { +		return (FALSE); +	} +	*cp = i; +	return (TRUE); +} + +/* + * XDR an unsigned char + */ +bool_t +xdr_u_char(xdrs, cp) +	XDR *xdrs; +	char *cp; +{ +	u_int u; + +	u = (*cp); +	if (!xdr_u_int(xdrs, &u)) { +		return (FALSE); +	} +	*cp = u; +	return (TRUE); +} + +/* + * XDR booleans + */ +bool_t +xdr_bool(xdrs, bp) +	register XDR *xdrs; +	bool_t *bp; +{ +	long lb; + +	switch (xdrs->x_op) { + +	case XDR_ENCODE: +		lb = *bp ? XDR_TRUE : XDR_FALSE; +		return (XDR_PUTLONG(xdrs, &lb)); + +	case XDR_DECODE: +		if (!XDR_GETLONG(xdrs, &lb)) { +			return (FALSE); +		} +		*bp = (lb == XDR_FALSE) ? FALSE : TRUE; +		return (TRUE); + +	case XDR_FREE: +		return (TRUE); +	} +	return (FALSE); +} + +/* + * XDR enumerations + */ +bool_t +xdr_enum(xdrs, ep) +	XDR *xdrs; +	enum_t *ep; +{ +#ifndef lint +	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */ + +	/* +	 * enums are treated as ints +	 */ +	if (sizeof (enum sizecheck) == sizeof (long)) { +		return (xdr_long(xdrs, (long *)ep)); +	} else if (sizeof (enum sizecheck) == sizeof (short)) { +		return (xdr_short(xdrs, (short *)ep)); +	} else { +		return (FALSE); +	} +#else +	(void) (xdr_short(xdrs, (short *)ep)); +	return (xdr_long(xdrs, (long *)ep)); +#endif +} + +/* + * XDR opaque data + * Allows the specification of a fixed size sequence of opaque bytes. + * cp points to the opaque object and cnt gives the byte length. + */ +bool_t +xdr_opaque(xdrs, cp, cnt) +	register XDR *xdrs; +	caddr_t cp; +	register u_int cnt; +{ +	register u_int rndup; +	static crud[BYTES_PER_XDR_UNIT]; + +	/* +	 * if no data we are done +	 */ +	if (cnt == 0) +		return (TRUE); + +	/* +	 * round byte count to full xdr units +	 */ +	rndup = cnt % BYTES_PER_XDR_UNIT; +	if (rndup > 0) +		rndup = BYTES_PER_XDR_UNIT - rndup; + +	if (xdrs->x_op == XDR_DECODE) { +		if (!XDR_GETBYTES(xdrs, cp, cnt)) { +			return (FALSE); +		} +		if (rndup == 0) +			return (TRUE); +		return (XDR_GETBYTES(xdrs, crud, rndup)); +	} + +	if (xdrs->x_op == XDR_ENCODE) { +		if (!XDR_PUTBYTES(xdrs, cp, cnt)) { +			return (FALSE); +		} +		if (rndup == 0) +			return (TRUE); +		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); +	} + +	if (xdrs->x_op == XDR_FREE) { +		return (TRUE); +	} + +	return (FALSE); +} + +/* + * XDR counted bytes + * *cpp is a pointer to the bytes, *sizep is the count. + * If *cpp is NULL maxsize bytes are allocated + */ +bool_t +xdr_bytes(xdrs, cpp, sizep, maxsize) +	register XDR *xdrs; +	char **cpp; +	register u_int *sizep; +	u_int maxsize; +{ +	register char *sp = *cpp;  /* sp is the actual string pointer */ +	register u_int nodesize; + +	/* +	 * first deal with the length since xdr bytes are counted +	 */ +	if (! xdr_u_int(xdrs, sizep)) { +		return (FALSE); +	} +	nodesize = *sizep; +	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { +		return (FALSE); +	} + +	/* +	 * now deal with the actual bytes +	 */ +	switch (xdrs->x_op) { + +	case XDR_DECODE: +		if (nodesize == 0) { +			return (TRUE); +		} +		if (sp == NULL) { +			*cpp = sp = (char *)mem_alloc(nodesize); +		} +		if (sp == NULL) { +			(void) fprintf(stderr, "xdr_bytes: out of memory\n"); +			return (FALSE); +		} +		/* fall into ... */ + +	case XDR_ENCODE: +		return (xdr_opaque(xdrs, sp, nodesize)); + +	case XDR_FREE: +		if (sp != NULL) { +			mem_free(sp, nodesize); +			*cpp = NULL; +		} +		return (TRUE); +	} +	return (FALSE); +} + +/* + * Implemented here due to commonality of the object. + */ +bool_t +xdr_netobj(xdrs, np) +	XDR *xdrs; +	struct netobj *np; +{ + +	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); +} + +/* + * XDR a descriminated union + * Support routine for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * an entry with a null procedure pointer.  The routine gets + * the discriminant value and then searches the array of xdrdiscrims + * looking for that value.  It calls the procedure given in the xdrdiscrim + * to handle the discriminant.  If there is no specific routine a default + * routine may be called. + * If there is no specific or default routine an error is returned. + */ +bool_t +xdr_union(xdrs, dscmp, unp, choices, dfault) +	register XDR *xdrs; +	enum_t *dscmp;		/* enum to decide which arm to work on */ +	char *unp;		/* the union itself */ +	struct xdr_discrim *choices;	/* [value, xdr proc] for each arm */ +	xdrproc_t dfault;	/* default xdr routine */ +{ +	register enum_t dscm; + +	/* +	 * we deal with the discriminator;  it's an enum +	 */ +	if (! xdr_enum(xdrs, dscmp)) { +		return (FALSE); +	} +	dscm = *dscmp; + +	/* +	 * search choices for a value that matches the discriminator. +	 * if we find one, execute the xdr routine for that value. +	 */ +	for (; choices->proc != NULL_xdrproc_t; choices++) { +		if (choices->value == dscm) +			return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); +	} + +	/* +	 * no match - execute the default xdr routine if there is one +	 */ +	return ((dfault == NULL_xdrproc_t) ? FALSE : +	    (*dfault)(xdrs, unp, LASTUNSIGNED)); +} + + +/* + * Non-portable xdr primitives. + * Care should be taken when moving these routines to new architectures. + */ + + +/* + * XDR null terminated ASCII strings + * xdr_string deals with "C strings" - arrays of bytes that are + * terminated by a NULL character.  The parameter cpp references a + * pointer to storage; If the pointer is null, then the necessary + * storage is allocated.  The last parameter is the max allowed length + * of the string as specified by a protocol. + */ +bool_t +xdr_string(xdrs, cpp, maxsize) +	register XDR *xdrs; +	char **cpp; +	u_int maxsize; +{ +	register char *sp = *cpp;  /* sp is the actual string pointer */ +	u_int size; +	u_int nodesize; + +	/* +	 * first deal with the length since xdr strings are counted-strings +	 */ +	switch (xdrs->x_op) { +	case XDR_FREE: +		if (sp == NULL) { +			return(TRUE);	/* already free */ +		} +		/* fall through... */ +	case XDR_ENCODE: +		size = strlen(sp); +		break; +	} +	if (! xdr_u_int(xdrs, &size)) { +		return (FALSE); +	} +	if (size > maxsize) { +		return (FALSE); +	} +	nodesize = size + 1; + +	/* +	 * now deal with the actual bytes +	 */ +	switch (xdrs->x_op) { + +	case XDR_DECODE: +		if (nodesize == 0) { +			return (TRUE); +		} +		if (sp == NULL) +			*cpp = sp = (char *)mem_alloc(nodesize); +		if (sp == NULL) { +			(void) fprintf(stderr, "xdr_string: out of memory\n"); +			return (FALSE); +		} +		sp[size] = 0; +		/* fall into ... */ + +	case XDR_ENCODE: +		return (xdr_opaque(xdrs, sp, size)); + +	case XDR_FREE: +		mem_free(sp, nodesize); +		*cpp = NULL; +		return (TRUE); +	} +	return (FALSE); +} + +/*  + * Wrapper for xdr_string that can be called directly from  + * routines like clnt_call + */ +bool_t +xdr_wrapstring(xdrs, cpp) +	XDR *xdrs; +	char **cpp; +{ +	if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { +		return (TRUE); +	} +	return (FALSE); +} diff --git a/lib/libc/xdr/xdr_array.c b/lib/libc/xdr/xdr_array.c new file mode 100644 index 000000000000..a17b534a92e7 --- /dev/null +++ b/lib/libc/xdr/xdr_array.c @@ -0,0 +1,155 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part.  Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + *  + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + *  + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + *  + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + *  + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + *  + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California  94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_array.c	2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_array.c,v 1.1 1993/10/27 05:41:09 paul Exp $"; +#endif + +/* + * xdr_array.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * arrays.  See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED	((u_int)0-1) + + +/* + * XDR an array of arbitrary elements + * *addrp is a pointer to the array, *sizep is the number of elements. + * If addrp is NULL (*sizep * elsize) bytes are allocated. + * elsize is the size (in bytes) of each element, and elproc is the + * xdr procedure to call to handle each element of the array. + */ +bool_t +xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc) +	register XDR *xdrs; +	caddr_t *addrp;		/* array pointer */ +	u_int *sizep;		/* number of elements */ +	u_int maxsize;		/* max numberof elements */ +	u_int elsize;		/* size in bytes of each element */ +	xdrproc_t elproc;	/* xdr routine to handle each element */ +{ +	register u_int i; +	register caddr_t target = *addrp; +	register u_int c;  /* the actual element count */ +	register bool_t stat = TRUE; +	register u_int nodesize; + +	/* like strings, arrays are really counted arrays */ +	if (! xdr_u_int(xdrs, sizep)) { +		return (FALSE); +	} +	c = *sizep; +	if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { +		return (FALSE); +	} +	nodesize = c * elsize; + +	/* +	 * if we are deserializing, we may need to allocate an array. +	 * We also save time by checking for a null array if we are freeing. +	 */ +	if (target == NULL) +		switch (xdrs->x_op) { +		case XDR_DECODE: +			if (c == 0) +				return (TRUE); +			*addrp = target = mem_alloc(nodesize); +			if (target == NULL) { +				(void) fprintf(stderr,  +					"xdr_array: out of memory\n"); +				return (FALSE); +			} +			bzero(target, nodesize); +			break; + +		case XDR_FREE: +			return (TRUE); +	} +	 +	/* +	 * now we xdr each element of array +	 */ +	for (i = 0; (i < c) && stat; i++) { +		stat = (*elproc)(xdrs, target, LASTUNSIGNED); +		target += elsize; +	} + +	/* +	 * the array may need freeing +	 */ +	if (xdrs->x_op == XDR_FREE) { +		mem_free(*addrp, nodesize); +		*addrp = NULL; +	} +	return (stat); +} + +/* + * xdr_vector(): + * + * XDR a fixed length array. Unlike variable-length arrays, + * the storage of fixed length arrays is static and unfreeable. + * > basep: base of the array + * > size: size of the array + * > elemsize: size of each element + * > xdr_elem: routine to XDR each element + */ +bool_t +xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem) +	register XDR *xdrs; +	register char *basep; +	register u_int nelem; +	register u_int elemsize; +	register xdrproc_t xdr_elem;	 +{ +	register u_int i; +	register char *elptr; + +	elptr = basep; +	for (i = 0; i < nelem; i++) { +		if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) { +			return(FALSE); +		} +		elptr += elemsize; +	} +	return(TRUE);	 +} + diff --git a/lib/libc/xdr/xdr_float.c b/lib/libc/xdr/xdr_float.c new file mode 100644 index 000000000000..fae0c8b7f8e3 --- /dev/null +++ b/lib/libc/xdr/xdr_float.c @@ -0,0 +1,283 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part.  Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + *  + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + *  + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + *  + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + *  + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + *  + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California  94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_float.c	2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_float.c,v 1.1 1993/10/27 05:41:10 paul Exp $"; +#endif + +/* + * xdr_float.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "floating point" xdr routines used to (de)serialize + * most common data items.  See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/param.h> +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * NB: Not portable. + * This routine works on Suns (Sky / 68000's), i386's, MIPS, NS32k and Vaxen. + */ + +#if defined(mc68000)||defined(sparc)||defined(i386)||defined(mips)||defined(ns32000) +#define IEEEFP +#endif + +#ifdef vax + +/* What IEEE single precision floating point looks like on a Vax */ +struct	ieee_single { +	unsigned int	mantissa: 23; +	unsigned int	exp     : 8; +	unsigned int	sign    : 1; +}; + +/* Vax single precision floating point */ +struct	vax_single { +	unsigned int	mantissa1 : 7; +	unsigned int	exp       : 8; +	unsigned int	sign      : 1; +	unsigned int	mantissa2 : 16; +}; + +#define VAX_SNG_BIAS	0x81 +#define IEEE_SNG_BIAS	0x7f + +static struct sgl_limits { +	struct vax_single s; +	struct ieee_single ieee; +} sgl_limits[2] = { +	{{ 0x7f, 0xff, 0x0, 0xffff },	/* Max Vax */ +	{ 0x0, 0xff, 0x0 }},		/* Max IEEE */ +	{{ 0x0, 0x0, 0x0, 0x0 },	/* Min Vax */ +	{ 0x0, 0x0, 0x0 }}		/* Min IEEE */ +}; +#endif /* vax */ + +bool_t +xdr_float(xdrs, fp) +	register XDR *xdrs; +	register float *fp; +{ +#ifndef IEEEFP +	struct ieee_single is; +	struct vax_single vs, *vsp; +	struct sgl_limits *lim; +	int i; +#endif +	switch (xdrs->x_op) { + +	case XDR_ENCODE: +#ifdef IEEEFP  +		return (XDR_PUTLONG(xdrs, (long *)fp)); +#else +		vs = *((struct vax_single *)fp); +		for (i = 0, lim = sgl_limits; +			i < sizeof(sgl_limits)/sizeof(struct sgl_limits); +			i++, lim++) { +			if ((vs.mantissa2 == lim->s.mantissa2) && +				(vs.exp == lim->s.exp) && +				(vs.mantissa1 == lim->s.mantissa1)) { +				is = lim->ieee; +				goto shipit; +			} +		} +		is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; +		is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; +	shipit: +		is.sign = vs.sign; +		return (XDR_PUTLONG(xdrs, (long *)&is)); +#endif + +	case XDR_DECODE: +#ifdef IEEEFP +		return (XDR_GETLONG(xdrs, (long *)fp)); +#else +		vsp = (struct vax_single *)fp; +		if (!XDR_GETLONG(xdrs, (long *)&is)) +			return (FALSE); +		for (i = 0, lim = sgl_limits; +			i < sizeof(sgl_limits)/sizeof(struct sgl_limits); +			i++, lim++) { +			if ((is.exp == lim->ieee.exp) && +				(is.mantissa == lim->ieee.mantissa)) { +				*vsp = lim->s; +				goto doneit; +			} +		} +		vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; +		vsp->mantissa2 = is.mantissa; +		vsp->mantissa1 = (is.mantissa >> 16); +	doneit: +		vsp->sign = is.sign; +		return (TRUE); +#endif + +	case XDR_FREE: +		return (TRUE); +	} +	return (FALSE); +} + +/* + * This routine works on Suns (Sky / 68000's), i386's, MIPS and Vaxen. + */ + +#ifdef vax +/* What IEEE double precision floating point looks like on a Vax */ +struct	ieee_double { +	unsigned int	mantissa1 : 20; +	unsigned int	exp       : 11; +	unsigned int	sign      : 1; +	unsigned int	mantissa2 : 32; +}; + +/* Vax double precision floating point */ +struct  vax_double { +	unsigned int	mantissa1 : 7; +	unsigned int	exp       : 8; +	unsigned int	sign      : 1; +	unsigned int	mantissa2 : 16; +	unsigned int	mantissa3 : 16; +	unsigned int	mantissa4 : 16; +}; + +#define VAX_DBL_BIAS	0x81 +#define IEEE_DBL_BIAS	0x3ff +#define MASK(nbits)	((1 << nbits) - 1) + +static struct dbl_limits { +	struct	vax_double d; +	struct	ieee_double ieee; +} dbl_limits[2] = { +	{{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },	/* Max Vax */ +	{ 0x0, 0x7ff, 0x0, 0x0 }},			/* Max IEEE */ +	{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},		/* Min Vax */ +	{ 0x0, 0x0, 0x0, 0x0 }}				/* Min IEEE */ +}; + +#endif /* vax */ + + +bool_t +xdr_double(xdrs, dp) +	register XDR *xdrs; +	double *dp; +{ +	register long *lp; +#ifndef IEEEFP +	struct	ieee_double id; +	struct	vax_double vd; +	register struct dbl_limits *lim; +	int i; +#endif + +	switch (xdrs->x_op) { + +	case XDR_ENCODE: +#ifdef IEEEFP +		lp = (long *)dp; +#if BYTE_ORDER == BIG_ENDIAN +		return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); +#else +		return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp)); +#endif +#else +		vd = *((struct vax_double *)dp); +		for (i = 0, lim = dbl_limits; +			i < sizeof(dbl_limits)/sizeof(struct dbl_limits); +			i++, lim++) { +			if ((vd.mantissa4 == lim->d.mantissa4) && +				(vd.mantissa3 == lim->d.mantissa3) && +				(vd.mantissa2 == lim->d.mantissa2) && +				(vd.mantissa1 == lim->d.mantissa1) && +				(vd.exp == lim->d.exp)) { +				id = lim->ieee; +				goto shipit; +			} +		} +		id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; +		id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); +		id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | +				(vd.mantissa3 << 13) | +				((vd.mantissa4 >> 3) & MASK(13)); +	shipit: +		id.sign = vd.sign; +		lp = (long *)&id; +		return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); +#endif + +	case XDR_DECODE: +#ifdef IEEEFP +		lp = (long *)dp; +#if BYTE_ORDER == BIG_ENDIAN +		return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp)); +#else +		return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp)); +#endif +#else +		lp = (long *)&id; +		if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp)) +			return (FALSE); +		for (i = 0, lim = dbl_limits; +			i < sizeof(dbl_limits)/sizeof(struct dbl_limits); +			i++, lim++) { +			if ((id.mantissa2 == lim->ieee.mantissa2) && +				(id.mantissa1 == lim->ieee.mantissa1) && +				(id.exp == lim->ieee.exp)) { +				vd = lim->d; +				goto doneit; +			} +		} +		vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; +		vd.mantissa1 = (id.mantissa1 >> 13); +		vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | +				(id.mantissa2 >> 29); +		vd.mantissa3 = (id.mantissa2 >> 13); +		vd.mantissa4 = (id.mantissa2 << 3); +	doneit: +		vd.sign = id.sign; +		*dp = *((double *)&vd); +		return (TRUE); +#endif + +	case XDR_FREE: +		return (TRUE); +	} +	return (FALSE); +} diff --git a/lib/libc/xdr/xdr_mem.c b/lib/libc/xdr/xdr_mem.c new file mode 100644 index 000000000000..3909edda4ee8 --- /dev/null +++ b/lib/libc/xdr/xdr_mem.c @@ -0,0 +1,186 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part.  Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + *  + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + *  + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + *  + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + *  + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + *  + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California  94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_mem.c	2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_mem.c,v 1.1 1993/10/27 05:41:11 paul Exp $"; +#endif + +/* + * xdr_mem.h, XDR implementation using memory buffers. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * If you have some data to be interpreted as external data representation + * or to be converted to external data representation in a memory buffer, + * then this is the package for you. + * + */ + + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +static bool_t	xdrmem_getlong(); +static bool_t	xdrmem_putlong(); +static bool_t	xdrmem_getbytes(); +static bool_t	xdrmem_putbytes(); +static u_int	xdrmem_getpos(); +static bool_t	xdrmem_setpos(); +static long *	xdrmem_inline(); +static void	xdrmem_destroy(); + +static struct	xdr_ops xdrmem_ops = { +	xdrmem_getlong, +	xdrmem_putlong, +	xdrmem_getbytes, +	xdrmem_putbytes, +	xdrmem_getpos, +	xdrmem_setpos, +	xdrmem_inline, +	xdrmem_destroy +}; + +/* + * The procedure xdrmem_create initializes a stream descriptor for a + * memory buffer.   + */ +void +xdrmem_create(xdrs, addr, size, op) +	register XDR *xdrs; +	caddr_t addr; +	u_int size; +	enum xdr_op op; +{ + +	xdrs->x_op = op; +	xdrs->x_ops = &xdrmem_ops; +	xdrs->x_private = xdrs->x_base = addr; +	xdrs->x_handy = size; +} + +static void +xdrmem_destroy(/*xdrs*/) +	/*XDR *xdrs;*/ +{ +} + +static bool_t +xdrmem_getlong(xdrs, lp) +	register XDR *xdrs; +	long *lp; +{ + +	if ((xdrs->x_handy -= sizeof(long)) < 0) +		return (FALSE); +	*lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private)))); +	xdrs->x_private += sizeof(long); +	return (TRUE); +} + +static bool_t +xdrmem_putlong(xdrs, lp) +	register XDR *xdrs; +	long *lp; +{ + +	if ((xdrs->x_handy -= sizeof(long)) < 0) +		return (FALSE); +	*(long *)xdrs->x_private = (long)htonl((u_long)(*lp)); +	xdrs->x_private += sizeof(long); +	return (TRUE); +} + +static bool_t +xdrmem_getbytes(xdrs, addr, len) +	register XDR *xdrs; +	caddr_t addr; +	register u_int len; +{ + +	if ((xdrs->x_handy -= len) < 0) +		return (FALSE); +	bcopy(xdrs->x_private, addr, len); +	xdrs->x_private += len; +	return (TRUE); +} + +static bool_t +xdrmem_putbytes(xdrs, addr, len) +	register XDR *xdrs; +	caddr_t addr; +	register u_int len; +{ + +	if ((xdrs->x_handy -= len) < 0) +		return (FALSE); +	bcopy(addr, xdrs->x_private, len); +	xdrs->x_private += len; +	return (TRUE); +} + +static u_int +xdrmem_getpos(xdrs) +	register XDR *xdrs; +{ + +	return ((u_int)xdrs->x_private - (u_int)xdrs->x_base); +} + +static bool_t +xdrmem_setpos(xdrs, pos) +	register XDR *xdrs; +	u_int pos; +{ +	register caddr_t newaddr = xdrs->x_base + pos; +	register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; + +	if ((long)newaddr > (long)lastaddr) +		return (FALSE); +	xdrs->x_private = newaddr; +	xdrs->x_handy = (int)lastaddr - (int)newaddr; +	return (TRUE); +} + +static long * +xdrmem_inline(xdrs, len) +	register XDR *xdrs; +	int len; +{ +	long *buf = 0; + +	if (xdrs->x_handy >= len) { +		xdrs->x_handy -= len; +		buf = (long *) xdrs->x_private; +		xdrs->x_private += len; +	} +	return (buf); +} diff --git a/lib/libc/xdr/xdr_rec.c b/lib/libc/xdr/xdr_rec.c new file mode 100644 index 000000000000..f2559d4b4f6b --- /dev/null +++ b/lib/libc/xdr/xdr_rec.c @@ -0,0 +1,586 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part.  Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + *  + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + *  + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + *  + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + *  + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + *  + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California  94043 + */ +#if defined(LIBC_SCCS) && !defined(lint)  +/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_rec.c	2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_rec.c,v 1.1 1993/10/27 05:41:12 paul Exp $"; +#endif + +/* + * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" + * layer above tcp (for rpc's use). + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These routines interface XDRSTREAMS to a tcp/ip connection. + * There is a record marking layer between the xdr stream + * and the tcp transport level.  A record is composed on one or more + * record fragments.  A record fragment is a thirty-two bit header followed + * by n bytes of data, where n is contained in the header.  The header + * is represented as a htonl(u_long).  Thegh order bit encodes + * whether or not the fragment is the last fragment of the record + * (1 => fragment is last, 0 => more fragments to follow.  + * The other 31 bits encode the byte length of the fragment. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +extern long	lseek(); + +static u_int	fix_buf_size(); +static bool_t	flush_out(); +static bool_t	get_input_bytes(); +static bool_t	set_input_fragment(); +static bool_t	skip_input_bytes(); + +static bool_t	xdrrec_getlong(); +static bool_t	xdrrec_putlong(); +static bool_t	xdrrec_getbytes(); +static bool_t	xdrrec_putbytes(); +static u_int	xdrrec_getpos(); +static bool_t	xdrrec_setpos(); +static long *	xdrrec_inline(); +static void	xdrrec_destroy(); + +static struct  xdr_ops xdrrec_ops = { +	xdrrec_getlong, +	xdrrec_putlong, +	xdrrec_getbytes, +	xdrrec_putbytes, +	xdrrec_getpos, +	xdrrec_setpos, +	xdrrec_inline, +	xdrrec_destroy +}; + +/* + * A record is composed of one or more record fragments. + * A record fragment is a two-byte header followed by zero to + * 2**32-1 bytes.  The header is treated as a long unsigned and is + * encode/decoded to the network via htonl/ntohl.  The low order 31 bits + * are a byte count of the fragment.  The highest order bit is a boolean: + * 1 => this fragment is the last fragment of the record, + * 0 => this fragment is followed by more fragment(s). + * + * The fragment/record machinery is not general;  it is constructed to + * meet the needs of xdr and rpc based on tcp. + */ + +#define LAST_FRAG ((u_long)(1 << 31)) + +typedef struct rec_strm { +	caddr_t tcp_handle; +	caddr_t the_buffer; +	/* +	 * out-goung bits +	 */ +	int (*writeit)(); +	caddr_t out_base;	/* output buffer (points to frag header) */ +	caddr_t out_finger;	/* next output position */ +	caddr_t out_boundry;	/* data cannot up to this address */ +	u_long *frag_header;	/* beginning of curren fragment */ +	bool_t frag_sent;	/* true if buffer sent in middle of record */ +	/* +	 * in-coming bits +	 */ +	int (*readit)(); +	u_long in_size;	/* fixed size of the input buffer */ +	caddr_t in_base; +	caddr_t in_finger;	/* location of next byte to be had */ +	caddr_t in_boundry;	/* can read up to this location */ +	long fbtbc;		/* fragment bytes to be consumed */ +	bool_t last_frag; +	u_int sendsize; +	u_int recvsize; +} RECSTREAM; + + +/* + * Create an xdr handle for xdrrec + * xdrrec_create fills in xdrs.  Sendsize and recvsize are + * send and recv buffer sizes (0 => use default). + * tcp_handle is an opaque handle that is passed as the first parameter to + * the procedures readit and writeit.  Readit and writeit are read and + * write respectively.   They are like the system + * calls expect that they take an opaque handle rather than an fd. + */ +void +xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit) +	register XDR *xdrs; +	register u_int sendsize; +	register u_int recvsize; +	caddr_t tcp_handle; +	int (*readit)();  /* like read, but pass it a tcp_handle, not sock */ +	int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */ +{ +	register RECSTREAM *rstrm = +		(RECSTREAM *)mem_alloc(sizeof(RECSTREAM)); + +	if (rstrm == NULL) { +		(void)fprintf(stderr, "xdrrec_create: out of memory\n"); +		/*  +		 *  This is bad.  Should rework xdrrec_create to  +		 *  return a handle, and in this case return NULL +		 */ +		return; +	} +	/* +	 * adjust sizes and allocate buffer quad byte aligned +	 */ +	rstrm->sendsize = sendsize = fix_buf_size(sendsize); +	rstrm->recvsize = recvsize = fix_buf_size(recvsize); +	rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); +	if (rstrm->the_buffer == NULL) { +		(void)fprintf(stderr, "xdrrec_create: out of memory\n"); +		return; +	} +	for (rstrm->out_base = rstrm->the_buffer; +		(u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; +		rstrm->out_base++); +	rstrm->in_base = rstrm->out_base + sendsize; +	/* +	 * now the rest ... +	 */ +	xdrs->x_ops = &xdrrec_ops; +	xdrs->x_private = (caddr_t)rstrm; +	rstrm->tcp_handle = tcp_handle; +	rstrm->readit = readit; +	rstrm->writeit = writeit; +	rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; +	rstrm->frag_header = (u_long *)rstrm->out_base; +	rstrm->out_finger += sizeof(u_long); +	rstrm->out_boundry += sendsize; +	rstrm->frag_sent = FALSE; +	rstrm->in_size = recvsize; +	rstrm->in_boundry = rstrm->in_base; +	rstrm->in_finger = (rstrm->in_boundry += recvsize); +	rstrm->fbtbc = 0; +	rstrm->last_frag = TRUE; +} + + +/* + * The reoutines defined below are the xdr ops which will go into the + * xdr handle filled in by xdrrec_create. + */ + +static bool_t +xdrrec_getlong(xdrs, lp) +	XDR *xdrs; +	long *lp; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); +	register long *buflp = (long *)(rstrm->in_finger); +	long mylong; + +	/* first try the inline, fast case */ +	if ((rstrm->fbtbc >= sizeof(long)) && +		(((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) { +		*lp = (long)ntohl((u_long)(*buflp)); +		rstrm->fbtbc -= sizeof(long); +		rstrm->in_finger += sizeof(long); +	} else { +		if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long))) +			return (FALSE); +		*lp = (long)ntohl((u_long)mylong); +	} +	return (TRUE); +} + +static bool_t +xdrrec_putlong(xdrs, lp) +	XDR *xdrs; +	long *lp; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); +	register long *dest_lp = ((long *)(rstrm->out_finger)); + +	if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) { +		/* +		 * this case should almost never happen so the code is +		 * inefficient +		 */ +		rstrm->out_finger -= sizeof(long); +		rstrm->frag_sent = TRUE; +		if (! flush_out(rstrm, FALSE)) +			return (FALSE); +		dest_lp = ((long *)(rstrm->out_finger)); +		rstrm->out_finger += sizeof(long); +	} +	*dest_lp = (long)htonl((u_long)(*lp)); +	return (TRUE); +} + +static bool_t  /* must manage buffers, fragments, and records */ +xdrrec_getbytes(xdrs, addr, len) +	XDR *xdrs; +	register caddr_t addr; +	register u_int len; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); +	register int current; + +	while (len > 0) { +		current = rstrm->fbtbc; +		if (current == 0) { +			if (rstrm->last_frag) +				return (FALSE); +			if (! set_input_fragment(rstrm)) +				return (FALSE); +			continue; +		} +		current = (len < current) ? len : current; +		if (! get_input_bytes(rstrm, addr, current)) +			return (FALSE); +		addr += current;  +		rstrm->fbtbc -= current; +		len -= current; +	} +	return (TRUE); +} + +static bool_t +xdrrec_putbytes(xdrs, addr, len) +	XDR *xdrs; +	register caddr_t addr; +	register u_int len; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); +	register int current; + +	while (len > 0) { +		current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger; +		current = (len < current) ? len : current; +		bcopy(addr, rstrm->out_finger, current); +		rstrm->out_finger += current; +		addr += current; +		len -= current; +		if (rstrm->out_finger == rstrm->out_boundry) { +			rstrm->frag_sent = TRUE; +			if (! flush_out(rstrm, FALSE)) +				return (FALSE); +		} +	} +	return (TRUE); +} + +static u_int +xdrrec_getpos(xdrs) +	register XDR *xdrs; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; +	register long pos; + +	pos = lseek((int)rstrm->tcp_handle, (long) 0, 1); +	if (pos != -1) +		switch (xdrs->x_op) { + +		case XDR_ENCODE: +			pos += rstrm->out_finger - rstrm->out_base; +			break; + +		case XDR_DECODE: +			pos -= rstrm->in_boundry - rstrm->in_finger; +			break; + +		default: +			pos = (u_int) -1; +			break; +		} +	return ((u_int) pos); +} + +static bool_t +xdrrec_setpos(xdrs, pos) +	register XDR *xdrs; +	u_int pos; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; +	u_int currpos = xdrrec_getpos(xdrs); +	int delta = currpos - pos; +	caddr_t newpos; + +	if ((int)currpos != -1) +		switch (xdrs->x_op) { + +		case XDR_ENCODE: +			newpos = rstrm->out_finger - delta; +			if ((newpos > (caddr_t)(rstrm->frag_header)) && +				(newpos < rstrm->out_boundry)) { +				rstrm->out_finger = newpos; +				return (TRUE); +			} +			break; + +		case XDR_DECODE: +			newpos = rstrm->in_finger - delta; +			if ((delta < (int)(rstrm->fbtbc)) && +				(newpos <= rstrm->in_boundry) && +				(newpos >= rstrm->in_base)) { +				rstrm->in_finger = newpos; +				rstrm->fbtbc -= delta; +				return (TRUE); +			} +			break; +		} +	return (FALSE); +} + +static long * +xdrrec_inline(xdrs, len) +	register XDR *xdrs; +	int len; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; +	long * buf = NULL; + +	switch (xdrs->x_op) { + +	case XDR_ENCODE: +		if ((rstrm->out_finger + len) <= rstrm->out_boundry) { +			buf = (long *) rstrm->out_finger; +			rstrm->out_finger += len; +		} +		break; + +	case XDR_DECODE: +		if ((len <= rstrm->fbtbc) && +			((rstrm->in_finger + len) <= rstrm->in_boundry)) { +			buf = (long *) rstrm->in_finger; +			rstrm->fbtbc -= len; +			rstrm->in_finger += len; +		} +		break; +	} +	return (buf); +} + +static void +xdrrec_destroy(xdrs) +	register XDR *xdrs; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + +	mem_free(rstrm->the_buffer, +		rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); +	mem_free((caddr_t)rstrm, sizeof(RECSTREAM)); +} + + +/* + * Exported routines to manage xdr records + */ + +/* + * Before reading (deserializing from the stream, one should always call + * this procedure to guarantee proper record alignment. + */ +bool_t +xdrrec_skiprecord(xdrs) +	XDR *xdrs; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + +	while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { +		if (! skip_input_bytes(rstrm, rstrm->fbtbc)) +			return (FALSE); +		rstrm->fbtbc = 0; +		if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) +			return (FALSE); +	} +	rstrm->last_frag = FALSE; +	return (TRUE); +} + +/* + * Look ahead fuction. + * Returns TRUE iff there is no more input in the buffer  + * after consuming the rest of the current record. + */ +bool_t +xdrrec_eof(xdrs) +	XDR *xdrs; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + +	while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { +		if (! skip_input_bytes(rstrm, rstrm->fbtbc)) +			return (TRUE); +		rstrm->fbtbc = 0; +		if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) +			return (TRUE); +	} +	if (rstrm->in_finger == rstrm->in_boundry) +		return (TRUE); +	return (FALSE); +} + +/* + * The client must tell the package when an end-of-record has occurred. + * The second paraemters tells whether the record should be flushed to the + * (output) tcp stream.  (This let's the package support batched or + * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection. + */ +bool_t +xdrrec_endofrecord(xdrs, sendnow) +	XDR *xdrs; +	bool_t sendnow; +{ +	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); +	register u_long len;  /* fragment length */ + +	if (sendnow || rstrm->frag_sent || +		((u_long)rstrm->out_finger + sizeof(u_long) >= +		(u_long)rstrm->out_boundry)) { +		rstrm->frag_sent = FALSE; +		return (flush_out(rstrm, TRUE)); +	} +	len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - +	   sizeof(u_long); +	*(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG); +	rstrm->frag_header = (u_long *)rstrm->out_finger; +	rstrm->out_finger += sizeof(u_long); +	return (TRUE); +} + + +/* + * Internal useful routines + */ +static bool_t +flush_out(rstrm, eor) +	register RECSTREAM *rstrm; +	bool_t eor; +{ +	register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0; +	register u_long len = (u_long)(rstrm->out_finger) -  +		(u_long)(rstrm->frag_header) - sizeof(u_long); + +	*(rstrm->frag_header) = htonl(len | eormask); +	len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base); +	if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len) +		!= (int)len) +		return (FALSE); +	rstrm->frag_header = (u_long *)rstrm->out_base; +	rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long); +	return (TRUE); +} + +static bool_t  /* knows nothing about records!  Only about input buffers */ +fill_input_buf(rstrm) +	register RECSTREAM *rstrm; +{ +	register caddr_t where; +	u_int i; +	register int len; + +	where = rstrm->in_base; +	i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT; +	where += i; +	len = rstrm->in_size - i; +	if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) +		return (FALSE); +	rstrm->in_finger = where; +	where += len; +	rstrm->in_boundry = where; +	return (TRUE); +} + +static bool_t  /* knows nothing about records!  Only about input buffers */ +get_input_bytes(rstrm, addr, len) +	register RECSTREAM *rstrm; +	register caddr_t addr; +	register int len; +{ +	register int current; + +	while (len > 0) { +		current = (int)rstrm->in_boundry - (int)rstrm->in_finger; +		if (current == 0) { +			if (! fill_input_buf(rstrm)) +				return (FALSE); +			continue; +		} +		current = (len < current) ? len : current; +		bcopy(rstrm->in_finger, addr, current); +		rstrm->in_finger += current; +		addr += current; +		len -= current; +	} +	return (TRUE); +} + +static bool_t  /* next two bytes of the input stream are treated as a header */ +set_input_fragment(rstrm) +	register RECSTREAM *rstrm; +{ +	u_long header; + +	if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header))) +		return (FALSE); +	header = (long)ntohl(header); +	rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE; +	rstrm->fbtbc = header & (~LAST_FRAG); +	return (TRUE); +} + +static bool_t  /* consumes input bytes; knows nothing about records! */ +skip_input_bytes(rstrm, cnt) +	register RECSTREAM *rstrm; +	long cnt; +{ +	register int current; + +	while (cnt > 0) { +		current = (int)rstrm->in_boundry - (int)rstrm->in_finger; +		if (current == 0) { +			if (! fill_input_buf(rstrm)) +				return (FALSE); +			continue; +		} +		current = (cnt < current) ? cnt : current; +		rstrm->in_finger += current; +		cnt -= current; +	} +	return (TRUE); +} + +static u_int +fix_buf_size(s) +	register u_int s; +{ + +	if (s < 100) +		s = 4000; +	return (RNDUP(s)); +} diff --git a/lib/libc/xdr/xdr_reference.c b/lib/libc/xdr/xdr_reference.c new file mode 100644 index 000000000000..c955f8820256 --- /dev/null +++ b/lib/libc/xdr/xdr_reference.c @@ -0,0 +1,134 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part.  Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + *  + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + *  + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + *  + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + *  + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + *  + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California  94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint)  +/*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/ +/*static char *sccsid = "from: @(#)xdr_reference.c	2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_reference.c,v 1.1 1993/10/27 05:41:13 paul Exp $"; +#endif + +/* + * xdr_reference.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1987, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * "pointers".  See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED	((u_int)0-1) + +/* + * XDR an indirect pointer + * xdr_reference is for recursively translating a structure that is + * referenced by a pointer inside the structure that is currently being + * translated.  pp references a pointer to storage. If *pp is null + * the  necessary storage is allocated. + * size is the sizeof the referneced structure. + * proc is the routine to handle the referenced structure. + */ +bool_t +xdr_reference(xdrs, pp, size, proc) +	register XDR *xdrs; +	caddr_t *pp;		/* the pointer to work on */ +	u_int size;		/* size of the object pointed to */ +	xdrproc_t proc;		/* xdr routine to handle the object */ +{ +	register caddr_t loc = *pp; +	register bool_t stat; + +	if (loc == NULL) +		switch (xdrs->x_op) { +		case XDR_FREE: +			return (TRUE); + +		case XDR_DECODE: +			*pp = loc = (caddr_t) mem_alloc(size); +			if (loc == NULL) { +				(void) fprintf(stderr, +				    "xdr_reference: out of memory\n"); +				return (FALSE); +			} +			bzero(loc, (int)size); +			break; +	} + +	stat = (*proc)(xdrs, loc, LASTUNSIGNED); + +	if (xdrs->x_op == XDR_FREE) { +		mem_free(loc, size); +		*pp = NULL; +	} +	return (stat); +} + + +/* + * xdr_pointer(): + * + * XDR a pointer to a possibly recursive data structure. This + * differs with xdr_reference in that it can serialize/deserialiaze + * trees correctly. + * + *  What's sent is actually a union: + * + *  union object_pointer switch (boolean b) { + *  case TRUE: object_data data; + *  case FALSE: void nothing; + *  } + * + * > objpp: Pointer to the pointer to the object. + * > obj_size: size of the object. + * > xdr_obj: routine to XDR an object. + * + */ +bool_t +xdr_pointer(xdrs,objpp,obj_size,xdr_obj) +	register XDR *xdrs; +	char **objpp; +	u_int obj_size; +	xdrproc_t xdr_obj; +{ + +	bool_t more_data; + +	more_data = (*objpp != NULL); +	if (! xdr_bool(xdrs,&more_data)) { +		return (FALSE); +	} +	if (! more_data) { +		*objpp = NULL; +		return (TRUE); +	} +	return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); +} diff --git a/lib/libc/xdr/xdr_stdio.c b/lib/libc/xdr/xdr_stdio.c new file mode 100644 index 000000000000..9761b13d5f2a --- /dev/null +++ b/lib/libc/xdr/xdr_stdio.c @@ -0,0 +1,191 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part.  Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + *  + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + *  + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + *  + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + *  + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + *  + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California  94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_stdio.c	2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_stdio.c,v 1.1 1993/10/27 05:41:14 paul Exp $"; +#endif + +/* + * xdr_stdio.c, XDR implementation on standard i/o file. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements a XDR on a stdio stream. + * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes + * from the stream. + */ + +#include <rpc/types.h> +#include <stdio.h> +#include <rpc/xdr.h> + +static bool_t	xdrstdio_getlong(); +static bool_t	xdrstdio_putlong(); +static bool_t	xdrstdio_getbytes(); +static bool_t	xdrstdio_putbytes(); +static u_int	xdrstdio_getpos(); +static bool_t	xdrstdio_setpos(); +static long *	xdrstdio_inline(); +static void	xdrstdio_destroy(); + +/* + * Ops vector for stdio type XDR + */ +static struct xdr_ops	xdrstdio_ops = { +	xdrstdio_getlong,	/* deseraialize a long int */ +	xdrstdio_putlong,	/* seraialize a long int */ +	xdrstdio_getbytes,	/* deserialize counted bytes */ +	xdrstdio_putbytes,	/* serialize counted bytes */ +	xdrstdio_getpos,	/* get offset in the stream */ +	xdrstdio_setpos,	/* set offset in the stream */ +	xdrstdio_inline,	/* prime stream for inline macros */ +	xdrstdio_destroy	/* destroy stream */ +}; + +/* + * Initialize a stdio xdr stream. + * Sets the xdr stream handle xdrs for use on the stream file. + * Operation flag is set to op. + */ +void +xdrstdio_create(xdrs, file, op) +	register XDR *xdrs; +	FILE *file; +	enum xdr_op op; +{ + +	xdrs->x_op = op; +	xdrs->x_ops = &xdrstdio_ops; +	xdrs->x_private = (caddr_t)file; +	xdrs->x_handy = 0; +	xdrs->x_base = 0; +} + +/* + * Destroy a stdio xdr stream. + * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. + */ +static void +xdrstdio_destroy(xdrs) +	register XDR *xdrs; +{ +	(void)fflush((FILE *)xdrs->x_private); +	/* xx should we close the file ?? */ +}; + +static bool_t +xdrstdio_getlong(xdrs, lp) +	XDR *xdrs; +	register long *lp; +{ + +	if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) +		return (FALSE); +#ifndef mc68000 +	*lp = ntohl(*lp); +#endif +	return (TRUE); +} + +static bool_t +xdrstdio_putlong(xdrs, lp) +	XDR *xdrs; +	long *lp; +{ + +#ifndef mc68000 +	long mycopy = htonl(*lp); +	lp = &mycopy; +#endif +	if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) +		return (FALSE); +	return (TRUE); +} + +static bool_t +xdrstdio_getbytes(xdrs, addr, len) +	XDR *xdrs; +	caddr_t addr; +	u_int len; +{ + +	if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) +		return (FALSE); +	return (TRUE); +} + +static bool_t +xdrstdio_putbytes(xdrs, addr, len) +	XDR *xdrs; +	caddr_t addr; +	u_int len; +{ + +	if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) +		return (FALSE); +	return (TRUE); +} + +static u_int +xdrstdio_getpos(xdrs) +	XDR *xdrs; +{ + +	return ((u_int) ftell((FILE *)xdrs->x_private)); +} + +static bool_t +xdrstdio_setpos(xdrs, pos)  +	XDR *xdrs; +	u_int pos; +{  + +	return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ? +		FALSE : TRUE); +} + +static long * +xdrstdio_inline(xdrs, len) +	XDR *xdrs; +	u_int len; +{ + +	/* +	 * Must do some work to implement this: must insure +	 * enough data in the underlying stdio buffer, +	 * that the buffer is aligned so that we can indirect through a +	 * long *, and stuff this pointer in xdrs->x_buf.  Doing +	 * a fread or fwrite to a scratch buffer would defeat +	 * most of the gains to be had here and require storage +	 * management on this buffer, so we don't do this. +	 */ +	return (NULL); +} | 
