diff options
author | wollman <wollman@FreeBSD.org> | 1994-08-07 18:39:35 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1994-08-07 18:39:35 +0000 |
commit | 39d367d32ed8e86a00d841b572a4544dc7ca339e (patch) | |
tree | b266d1b1898dec07a189a26f924914b83887a507 /lib/libc/xdr | |
parent | ad3e7cd01dd88965992ef4f0a5d33ca2af3b2dce (diff) | |
download | FreeBSD-src-39d367d32ed8e86a00d841b572a4544dc7ca339e.zip FreeBSD-src-39d367d32ed8e86a00d841b572a4544dc7ca339e.tar.gz |
Moving RPC stuff into libc, part 2.
Diffstat (limited to 'lib/libc/xdr')
-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 0000000..f547d9d --- /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 0000000..b656ea8 --- /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 0000000..9f40204 --- /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 0000000..a17b534 --- /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 0000000..fae0c8b --- /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 0000000..3909edd --- /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 0000000..f2559d4 --- /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 0000000..c955f882 --- /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 0000000..9761b13 --- /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); +} |