Sun RPC part 10 of 10
sources-request at genrad.UUCP
sources-request at genrad.UUCP
Thu Apr 18 01:54:23 AEST 1985
From: blyon at sun (Bob Lyon)
----------------- cut here --------------------
# run this script through "sh" to extract files
echo x - xdr.c
sed 's/^X//' >xdr.c <<'!Funky!Stuff!'
/*
* 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
*/
#ifndef lint
static char sccsid[] = "@(#)xdr.c 1.3 85/02/26 Copyr 1984 Sun Micro";
#endif
/*
* xdr.c, Generic XDR routines impelmentation.
*
* Copyright (C) 1984, 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 "types.h"
#include "xdr.h"
#include <stdio.h>
char *mem_alloc();
/*
* 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 };
/*
* 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;
{
if (sizeof(int) == sizeof(long)) {
return (xdr_long(xdrs, (long *)ip));
} else {
return (xdr_short(xdrs, (short *)ip));
}
}
/*
* XDR unsigned integers
*/
bool_t
xdr_u_int(xdrs, up)
XDR *xdrs;
u_int *up;
{
if (sizeof(u_int) == sizeof(u_long)) {
return (xdr_u_long(xdrs, (u_long *)up));
} else {
return (xdr_short(xdrs, (short *)up));
}
}
/*
* 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 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;
{
/*
* enums are treated as ints
*/
if (sizeof(enum_t) == sizeof(long)) {
return (xdr_long(xdrs, (long *)ep));
} else {
return (xdr_short(xdrs, (short *)ep));
}
}
/*
* 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 (sp == NULL) {
*cpp = sp = mem_alloc(nodesize);
}
if (sp == NULL) {
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);
}
/*
* 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 */
caddr_t 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
*/
if ((xdrs->x_op) != XDR_DECODE)
size = strlen(sp);
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 (sp == NULL)
*cpp = sp = mem_alloc(nodesize);
if (sp == NULL) {
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:
if (sp != NULL) {
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, BUFSIZ)) {
return(TRUE);
}
return(FALSE);
}
!Funky!Stuff!
echo x - xdr.h
sed 's/^X//' >xdr.h <<'!Funky!Stuff!'
/*
* 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
*/
/* @(#)xdr.h 1.4 85/02/08 SMI */
/*
* xdr.h, External Data Representation Serialization Routines.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
/*
* XDR provides a conventional way for converting between C data
* types and an external bit-string representation. Library supplied
* routines provide for the conversion on built-in C data types. These
* routines and utility routines defined here are used to help implement
* a type encode/decode routine for each user-defined type.
*
* Each data type provides a single procedure which takes two arguments:
*
* bool_t
* xdrproc(xdrs, argresp)
* XDR *xdrs;
* <type> *argresp;
*
* xdrs is an instance of a XDR handle, to which or from which the data
* type is to be converted. argresp is a pointer to the structure to be
* converted. The XDR handle contains an operation field which indicates
* which of the operations (ENCODE, DECODE * or FREE) is to be performed.
*
* XDR_DECODE may allocate space if the pointer argresp is null. This
* data can be freed with the XDR_FREE operation.
*
* We write only one procedure per data type to make it easy
* to keep the encode and decode procedures for a data type consistent.
* In many cases the same code performs all operations on a user defined type,
* because all the hard work is done in the component type routines.
* decode as a series of calls on the nested data types.
*/
/*
* Xdr operations. XDR_ENCODE causes the type to be encoded into the
* stream. XDR_DECODE causes the type to be extracted from the stream.
* XDR_FREE can be used to release the space allocated by an XDR_DECODE
* request.
*/
enum xdr_op {
XDR_ENCODE=0,
XDR_DECODE=1,
XDR_FREE=2
};
/*
* This is the number of bytes per unit of external data.
*/
#define BYTES_PER_XDR_UNIT (4)
/*
* A xdrproc_t exists for each data type which is to be encoded or decoded.
*
* The second argument to the xdrproc_t is a pointer to an opaque pointer.
* The opaque pointer generally points to a structure of the data type
* to be decoded. If this pointer is 0, then the type routines should
* allocate dynamic storage of the appropriate size and return it.
* bool_t (*xdrproc_t)(XDR *, caddr_t *);
*/
typedef bool_t (*xdrproc_t)();
/*
* The XDR handle.
* Contains operation which is being applied to the stream,
* an operations vector for the paticular implementation (e.g. see xdr_mem.c),
* and two private fields for the use of the particular impelementation.
*/
typedef struct {
enum xdr_op x_op; /* operation; fast additional param */
struct xdr_ops {
bool_t (*x_getlong)(); /* get a long from underlying stream */
bool_t (*x_putlong)(); /* put a long to " */
bool_t (*x_getbytes)();/* get some bytes from " */
bool_t (*x_putbytes)();/* put some bytes to " */
u_int (*x_getpostn)();/* returns bytes off from beginning */
bool_t (*x_setpostn)();/* lets you reposition the stream */
long * (*x_inline)(); /* buf quick ptr to buffered data */
void (*x_destroy)(); /* free privates of this xdr_stream */
} *x_ops;
caddr_t x_public; /* users' data */
caddr_t x_private; /* pointer to private data */
caddr_t x_base; /* private used for position info */
int x_handy; /* extra private word */
} XDR;
/*
* Operations defined on a XDR handle
*
* XDR *xdrs;
* long *longp;
* caddr_t addr;
* u_int len;
* u_int pos;
*/
#define XDR_GETLONG(xdrs, longp) \
(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
#define xdr_getlong(xdrs, longp) \
(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
#define XDR_PUTLONG(xdrs, longp) \
(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
#define xdr_putlong(xdrs, longp) \
(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
#define XDR_GETBYTES(xdrs, addr, len) \
(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
#define xdr_getbytes(xdrs, addr, len) \
(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
#define XDR_PUTBYTES(xdrs, addr, len) \
(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
#define xdr_putbytes(xdrs, addr, len) \
(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
#define XDR_GETPOS(xdrs) \
(*(xdrs)->x_ops->x_getpostn)(xdrs)
#define xdr_getpos(xdrs) \
(*(xdrs)->x_ops->x_getpostn)(xdrs)
#define XDR_SETPOS(xdrs, pos) \
(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
#define xdr_setpos(xdrs, pos) \
(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
#define XDR_INLINE(xdrs, len) \
(*(xdrs)->x_ops->x_inline)(xdrs, len)
#define xdr_inline(xdrs, len) \
(*(xdrs)->x_ops->x_inline)(xdrs, len)
#define XDR_DESTROY(xdrs) \
if ((xdrs)->x_ops->x_destroy) \
(*(xdrs)->x_ops->x_destroy)(xdrs)
#define xdr_destroy(xdrs) \
if ((xdrs)->x_ops->x_destroy) \
(*(xdrs)->x_ops->x_destroy)(xdrs)
/*
* Support struct for discriminated unions.
* You create an array of xdrdiscrim structures, terminated with
* a entry with a null procedure pointer. The xdr_union routine gets
* the discriminant value and then searches the array of structures
* for a matching value. If a match is found the associated xdr routine
* is called to handle that part of the union. If there is
* no match, then a default routine may be called.
* If there is no match and no default routine it is an error.
*/
#define NULL_xdrproc_t ((xdrproc_t)0)
struct xdr_discrim {
int value;
xdrproc_t proc;
};
/*
* In-line routines for fast encode/decode of primitve data types.
* Caveat emptor: these use single memory cycles to get the
* data from the underlying buffer, and will fail to operate
* properly if the data is not aligned. The standard way to use these
* is to say:
* if ((buf = XDR_INLINE(xdrs, count)) == NULL)
* return (FALSE);
* <<< macro calls >>>
* where ``count'' is the number of bytes of data occupied
* by the primitive data types.
*
* N.B. and frozen for all time: each data type here uses 4 bytes
* of external representation.
*/
#define IXDR_GET_LONG(buf) ntohl(*buf++)
#define IXDR_PUT_LONG(buf, v) (*buf++ = htonl(v))
#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
/*
* These are the "generic" xdr routines.
*/
extern bool_t xdr_void();
extern bool_t xdr_int();
extern bool_t xdr_u_int();
extern bool_t xdr_long();
extern bool_t xdr_u_long();
extern bool_t xdr_short();
extern bool_t xdr_u_short();
extern bool_t xdr_float();
extern bool_t xdr_double();
extern bool_t xdr_bool();
extern bool_t xdr_enum();
extern bool_t xdr_array();
extern bool_t xdr_bytes();
extern bool_t xdr_opaque();
extern bool_t xdr_string();
extern bool_t xdr_wrapstring();
extern bool_t xdr_union();
extern bool_t xdr_reference();
/*
* These are the public routines for the various implementations of
* xdr streams.
*/
extern void xdrmem_create(); /* XDR using memory buffers */
extern void xdrstdio_create(); /* XDR using stdio library */
extern void xdrrec_create(); /* XDR pseudo records for tcp */
extern bool_t xdrrec_endofrecord(); /* make end of xdr record */
extern bool_t xdrrec_skiprecord(); /* move to begining of next record */
extern bool_t xdrrec_eof(); /* true iff no more input */
!Funky!Stuff!
echo x - xdr_array.c
sed 's/^X//' >xdr_array.c <<'!Funky!Stuff!'
/*
* 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
*/
#ifndef lint
static char sccsid[] = "@(#)xdr_array.c 1.2 85/02/26 Copyr 1984 Sun Micro";
#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 "types.h"
#include "xdr.h"
#include <stdio.h>
#define LASTUNSIGNED ((u_int)0-1)
char *mem_alloc();
/*
* 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 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) {
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);
}
!Funky!Stuff!
echo x - xdr_float.c
sed 's/^X//' >xdr_float.c <<'!Funky!Stuff!'
/*
* 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
*/
#ifndef lint
static char sccsid[] = "@(#)xdr_float.c 1.2 85/03/14 Copyr 1984 Sun Micro";
#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 "types.h"
#include "xdr.h"
#include <stdio.h>
/*
* NB: Not portable.
* This routine works on Suns (Sky / 68000's) and Vaxen.
*/
/* 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] = {
{{ 0x3f, 0xff, 0x0, 0xffff }, /* Max Vax */
{ 0x0, 0xff, 0x0 }}, /* Max IEEE */
{{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
{ 0x0, 0x0, 0x0 }} /* Min IEEE */
};
bool_t
xdr_float(xdrs, fp)
register XDR *xdrs;
register float *fp;
{
struct ieee_single is;
struct vax_single vs, *vsp;
struct sgl_limits *lim;
int i;
switch (xdrs->x_op) {
case XDR_ENCODE:
#ifdef mc68000
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 mc68000
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) and Vaxen.
*/
/* 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 */
};
bool_t
xdr_double(xdrs, dp)
register XDR *xdrs;
double *dp;
{
register long *lp;
struct ieee_double id;
struct vax_double vd;
register struct dbl_limits *lim;
int i;
switch (xdrs->x_op) {
case XDR_ENCODE:
#ifdef mc68000
lp = (long *)dp;
#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;
#endif
return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
case XDR_DECODE:
#ifdef mc68000
lp = (long *)dp;
return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
#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);
}
!Funky!Stuff!
echo x - xdr_mem.c
sed 's/^X//' >xdr_mem.c <<'!Funky!Stuff!'
/*
* 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
*/
#ifndef lint
static char sccsid[] = "@(#)xdr_mem.c 1.4 85/03/14 Copyr 1984 Sun Micro";
#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 "types.h"
#include "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 = ntohl(*((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 = htonl(*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);
}
!Funky!Stuff!
echo x - xdr_rec.c
sed 's/^X//' >xdr_rec.c <<'!Funky!Stuff!'
/*
* 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
*/
#ifndef lint
static char sccsid[] = "@(#)xdr_rec.c 1.5 85/03/14 Copyr 1984 Sun Micro";
#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 "types.h"
#include "xdr.h"
#include <sys/time.h>
#include <netinet/in.h>
char *mem_alloc();
static u_int fix_buf_size();
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;
/*
* 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;
u_int sendsize;
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) {
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;
}
xdrs->x_ops = &xdrrec_ops;
xdrs->x_private = (caddr_t)rstrm;
rstrm->tcp_handle = tcp_handle;
rstrm->readit = readit;
rstrm->writeit = writeit;
sendsize = fix_buf_size(sendsize);
if ((rstrm->out_base = rstrm->out_finger = rstrm->out_boundry =
mem_alloc(sendsize)) == NULL) {
fprintf(stderr, "xdrrec_create: out of memory\n");
return;
}
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 = fix_buf_size(recvsize);
if ((rstrm->in_base = rstrm->in_boundry=mem_alloc(recvsize)) == NULL) {
fprintf(stderr, "xdrrec_create: out of memory\n");
return;
}
rstrm->in_finger = (rstrm->in_boundry += recvsize);
rstrm->fbtbc = 0;
rstrm->last_frag = TRUE;
rstrm->sendsize = sendsize;
rstrm->recvsize = recvsize;
}
/*
* 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 = ntohl(*buflp);
rstrm->fbtbc -= sizeof(long);
rstrm->in_finger += sizeof(long);
} else {
if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
return (FALSE);
*lp = ntohl(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 = htonl(*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 u_int pos;
pos = lseek((int)rstrm->tcp_handle, 0, 1);
if ((int)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 (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->out_base, rstrm->sendsize);
mem_free(rstrm->in_base, rstrm->recvsize);
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(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 = rstrm->in_base;
register int len = rstrm->in_size;
if (((int)rstrm->in_boundry % 2) != 0) {
/* keep stream odd bytes aligned with memory odd bytes */
where++;
len--;
}
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 = 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;
int 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)
return (3998);
for (; (s % 4) != 2; --s);
return (s);
}
!Funky!Stuff!
echo x - xdr_reference.c
sed 's/^X//' >xdr_reference.c <<'!Funky!Stuff!'
/*
* 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
*/
#ifndef lint
static char sccsid[] = "@(#)xdr_reference.c 1.2 85/02/26 Copyr 1984 Sun Micro";
#endif
/*
* xdr_reference.c, Generic XDR routines impelmentation.
*
* Copyright (C) 1984, 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 "types.h"
#include "xdr.h"
#include <stdio.h>
#define LASTUNSIGNED ((u_int)0-1)
char *mem_alloc();
/*
* 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 = mem_alloc(size);
if (loc == NULL) {
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);
}
!Funky!Stuff!
echo x - xdr_stdio.c
sed 's/^X//' >xdr_stdio.c <<'!Funky!Stuff!'
/*
* 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
*/
#ifndef lint
static char sccsid[] = "@(#)xdr_stdio.c 1.4 85/03/14 Copyr 1984 Sun Micro";
#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 "types.h"
#include <stdio.h>
#include "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);
}
!Funky!Stuff!
exit
More information about the Mod.sources
mailing list