[mod.sources] v06i097: Sun RPC Source

sources-request@mirror.UUCP (08/07/86)

Submitted by: cca!SUN.COM!marks (Mark Stein)
Mod.sources: Volume 6, Issue 97
Archive-name: rpc2/Part09

[ #include <same-disclaimer-you've-seen-on-all-other-parts.h> --r$ ]

Sun RPC source (part 9 of 11).  This software package contains code
and documentation for Revision 3.0 of the Sun Remote Procedure Call
library.  In addition, a beta version of the XDR/RPC protocol compiler
is included.  Comments about this latest release may be mailed to
sun!rpc or rpc@sun.com.

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.

- - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - -
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	rpc/rpclib/xdr_float.c
#	rpc/rpclib/xdr_mem.c
#	rpc/rpclib/xdr_rec.c
#	rpc/rpclib/xdr_reference.c
#	rpc/rpclib/xdr_stdio.c
#	rpc/tools/portmap.8c
#	rpc/tools/portmap.c
# This archive created: Mon Jul 14 16:55:40 1986
export PATH; PATH=/bin:/usr/bin:$PATH
for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test
do
	if test ! -d $d
	then
		echo "shar: Making directory $d"
		mkdir $d
		chmod 755 $d
	fi
done
echo shar: "extracting 'rpc/rpclib/xdr_float.c'" '(6623 characters)'
if test -f 'rpc/rpclib/xdr_float.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/xdr_float.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_float.c'
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part.  Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X * 
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X * 
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X * 
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X * 
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X * 
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California  94043
X */
X#ifndef lint
Xstatic char sccsid[] = "@(#)xdr_float.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr_float.c, Generic XDR routines impelmentation.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * These are the "floating point" xdr routines used to (de)serialize
X * most common data items.  See xdr.h for more info on the interface to
X * xdr.
X */
X
X#include "types.h"
X#include "xdr.h"
X#include <stdio.h>
X
X/*
X * NB: Not portable.
X * This routine works on Suns (Sky / 68000's) and Vaxen.
X */
X   
X/* What IEEE single precision floating point looks like on a Vax */
Xstruct  ieee_single {
X	unsigned int	mantissa: 23;
X	unsigned int	exp     : 8;
X	unsigned int	sign    : 1;
X};
X
X/* Vax single precision floating point */
Xstruct  vax_single {
X	unsigned int	mantissa1 : 7;
X	unsigned int	exp       : 8;
X	unsigned int	sign      : 1;
X	unsigned int	mantissa2 : 16;
X		
X};
X
X#define VAX_SNG_BIAS    0x81
X#define IEEE_SNG_BIAS   0x7f
X 
Xstatic struct sgl_limits {
X	struct vax_single s;
X	struct ieee_single ieee;
X} sgl_limits[2] = {
X	{{ 0x3f, 0xff, 0x0, 0xffff },	/* Max Vax */
X	{ 0x0, 0xff, 0x0 }},		/* Max IEEE */
X	{{ 0x0, 0x0, 0x0, 0x0 },	/* Min Vax */
X	{ 0x0, 0x0, 0x0 }}		/* Min IEEE */
X};
X
Xbool_t 
Xxdr_float(xdrs, fp)
X	register XDR *xdrs;
X	register float *fp;
X{
X	struct ieee_single is;
X	struct vax_single vs, *vsp;
X	struct sgl_limits *lim;
X	int i;
X
X	switch (xdrs->x_op) {
X
X	case XDR_ENCODE:
X#ifdef mc68000
X		return (XDR_PUTLONG(xdrs, (long *)fp));
X#else
X		vs = *((struct vax_single *)fp);
X		for (i = 0, lim = sgl_limits;
X			i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
X			i++, lim++) {
X			if ((vs.mantissa2 == lim->s.mantissa2) &&
X				(vs.exp == lim->s.exp) &&
X				(vs.mantissa1 == lim->s.mantissa1)) {
X				is = lim->ieee;
X				goto shipit;
X			}
X		}
X		is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
X		is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
X	shipit:
X		is.sign = vs.sign;
X		return (XDR_PUTLONG(xdrs, (long *)&is));
X#endif
X
X	case XDR_DECODE:
X#ifdef mc68000
X		return (XDR_GETLONG(xdrs, (long *)fp));
X#else
X		vsp = (struct vax_single *)fp;
X		if (!XDR_GETLONG(xdrs, (long *)&is))
X			return (FALSE);
X		for (i = 0, lim = sgl_limits;
X			i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
X			i++, lim++) {
X			if ((is.exp == lim->ieee.exp) &&
X				(is.mantissa = lim->ieee.mantissa)) {
X				*vsp = lim->s;
X				goto doneit;
X			}
X		}
X		vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
X		vsp->mantissa2 = is.mantissa;
X		vsp->mantissa1 = (is.mantissa >> 16);
X	doneit:
X		vsp->sign = is.sign;
X		return (TRUE);
X#endif
X
X	case XDR_FREE:
X		return (TRUE);
X	}
X	return (FALSE);
X}
X
X/*
X * This routine works on Suns (Sky / 68000's) and Vaxen.
X */
X
X/* What IEEE double precision floating point looks like on a Vax */
Xstruct  ieee_double {
X	unsigned int	mantissa1 : 20;
X	unsigned int	exp	  : 11;
X	unsigned int	sign	  : 1;
X	unsigned int	mantissa2 : 32;
X};
X 
X/* Vax double precision floating point */
Xstruct  vax_double {
X	unsigned int	mantissa1 : 7;
X	unsigned int	exp       : 8;
X	unsigned int	sign      : 1;
X	unsigned int	mantissa2 : 16;
X	unsigned int	mantissa3 : 16;
X	unsigned int	mantissa4 : 16;
X};
X
X#define VAX_DBL_BIAS    0x81
X#define IEEE_DBL_BIAS   0x3ff
X#define MASK(nbits)     ((1 << nbits) - 1)
X
Xstatic struct dbl_limits {
X	struct  vax_double d;
X	struct  ieee_double ieee;
X} dbl_limits[2] = {
X	{{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },	/* Max Vax */
X	{ 0x0, 0x7ff, 0x0, 0x0 }},			/* Max IEEE */
X	{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},		/* Min Vax */
X	{ 0x0, 0x0, 0x0, 0x0 }}				/* Min IEEE */
X};
X
Xbool_t           
Xxdr_double(xdrs, dp)
X	register XDR *xdrs;
X	double *dp;
X{
X	register long *lp;
X	struct  ieee_double id;
X	struct  vax_double vd;
X	register struct dbl_limits *lim;
X	int i;
X
X	switch (xdrs->x_op) {
X
X	case XDR_ENCODE:
X#ifdef mc68000
X		lp = (long *)dp;
X#else
X		vd = *((struct  vax_double *)dp);
X		for (i = 0, lim = dbl_limits;
X			i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
X			i++, lim++) {
X			if ((vd.mantissa4 == lim->d.mantissa4) &&
X				(vd.mantissa3 == lim->d.mantissa3) &&
X				(vd.mantissa2 == lim->d.mantissa2) &&
X				(vd.mantissa1 == lim->d.mantissa1) &&
X				(vd.exp == lim->d.exp)) {
X				id = lim->ieee;
X				goto shipit;
X			}
X		}
X		id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
X		id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
X		id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
X				(vd.mantissa3 << 13) |
X				((vd.mantissa4 >> 3) & MASK(13));
X	shipit:
X		id.sign = vd.sign;
X		lp = (long *)&id;
X#endif
X		return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
X
X	case XDR_DECODE:
X#ifdef mc68000
X		lp = (long *)dp;
X		return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
X#else
X		lp = (long *)&id;
X		if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
X			return (FALSE);
X		for (i = 0, lim = dbl_limits;
X			i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
X			i++, lim++) {
X			if ((id.mantissa2 == lim->ieee.mantissa2) &&
X				(id.mantissa1 == lim->ieee.mantissa1) &&
X				(id.exp == lim->ieee.exp)) {
X				vd = lim->d;
X				goto doneit;
X			}
X		}
X		vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
X		vd.mantissa1 = (id.mantissa1 >> 13);
X		vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
X				(id.mantissa2 >> 29);
X		vd.mantissa3 = (id.mantissa2 >> 13);
X		vd.mantissa4 = (id.mantissa2 << 3);
X	doneit:
X		vd.sign = id.sign;
X		*dp = *((double *)&vd);
X		return (TRUE);
X#endif
X
X	case XDR_FREE:
X		return (TRUE);
X	}
X	return (FALSE);
X}
SHAR_EOF
if test 6623 -ne "`wc -c < 'rpc/rpclib/xdr_float.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/xdr_float.c'" '(should have been 6623 characters)'
fi
chmod 444 'rpc/rpclib/xdr_float.c'
fi
echo shar: "extracting 'rpc/rpclib/xdr_mem.c'" '(4139 characters)'
if test -f 'rpc/rpclib/xdr_mem.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/xdr_mem.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_mem.c'
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part.  Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X * 
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X * 
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X * 
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X * 
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X * 
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California  94043
X */
X#ifndef lint
Xstatic char sccsid[] = "@(#)xdr_mem.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr_mem.h, XDR implementation using memory buffers.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * If you have some data to be interpreted as external data representation
X * or to be converted to external data representation in a memory buffer,
X * then this is the package for you.
X *
X */
X
X#include "types.h"
X#include "xdr.h"
X#include <netinet/in.h>
X
Xstatic bool_t	xdrmem_getlong();
Xstatic bool_t	xdrmem_putlong();
Xstatic bool_t	xdrmem_getbytes();
Xstatic bool_t	xdrmem_putbytes();
Xstatic u_int	xdrmem_getpos();
Xstatic bool_t	xdrmem_setpos();
Xstatic long *	xdrmem_inline();
Xstatic void	xdrmem_destroy();
X
Xstatic struct	xdr_ops xdrmem_ops = {
X	xdrmem_getlong,
X	xdrmem_putlong,
X	xdrmem_getbytes,
X	xdrmem_putbytes,
X	xdrmem_getpos,
X	xdrmem_setpos,
X	xdrmem_inline,
X	xdrmem_destroy
X};
X
X/*
X * The procedure xdrmem_create initializes a stream descriptor for a
X * memory buffer.  
X */
Xvoid
Xxdrmem_create(xdrs, addr, size, op)
X	register XDR *xdrs;
X	caddr_t addr;
X	u_int size;
X	enum xdr_op op;
X{
X
X	xdrs->x_op = op;
X	xdrs->x_ops = &xdrmem_ops;
X	xdrs->x_private = xdrs->x_base = addr;
X	xdrs->x_handy = size;
X}
X
Xstatic void
Xxdrmem_destroy(/*xdrs*/)
X	/*XDR *xdrs;*/
X{
X}
X
Xstatic bool_t
Xxdrmem_getlong(xdrs, lp)
X	register XDR *xdrs;
X	long *lp;
X{
X
X	if ((xdrs->x_handy -= sizeof(long)) < 0)
X		return (FALSE);
X	*lp = ntohl(*((long *)(xdrs->x_private)));
X	xdrs->x_private += sizeof(long);
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrmem_putlong(xdrs, lp)
X	register XDR *xdrs;
X	long *lp;
X{
X
X	if ((xdrs->x_handy -= sizeof(long)) < 0)
X		return (FALSE);
X	*(long *)xdrs->x_private = htonl(*lp);
X	xdrs->x_private += sizeof(long);
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrmem_getbytes(xdrs, addr, len)
X	register XDR *xdrs;
X	caddr_t addr;
X	register u_int len;
X{
X
X	if ((xdrs->x_handy -= len) < 0)
X		return (FALSE);
X	bcopy(xdrs->x_private, addr, len);
X	xdrs->x_private += len;
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrmem_putbytes(xdrs, addr, len)
X	register XDR *xdrs;
X	caddr_t addr;
X	register u_int len;
X{
X
X	if ((xdrs->x_handy -= len) < 0)
X		return (FALSE);
X	bcopy(addr, xdrs->x_private, len);
X	xdrs->x_private += len;
X	return (TRUE);
X}
X
Xstatic u_int
Xxdrmem_getpos(xdrs)
X	register XDR *xdrs;
X{
X
X	return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
X}
X
Xstatic bool_t
Xxdrmem_setpos(xdrs, pos)
X	register XDR *xdrs;
X	u_int pos;
X{
X	register caddr_t newaddr = xdrs->x_base + pos;
X	register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
X
X	if ((long)newaddr > (long)lastaddr)
X		return (FALSE);
X	xdrs->x_private = newaddr;
X	xdrs->x_handy = (int)lastaddr - (int)newaddr;
X	return (TRUE);
X}
X
Xstatic long *
Xxdrmem_inline(xdrs, len)
X	register XDR *xdrs;
X	int len;
X{
X	long *buf = 0;
X
X	if (xdrs->x_handy >= len) {
X		xdrs->x_handy -= len;
X		buf = (long *) xdrs->x_private;
X		xdrs->x_private += len;
X	}
X	return (buf);
X}
SHAR_EOF
if test 4139 -ne "`wc -c < 'rpc/rpclib/xdr_mem.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/xdr_mem.c'" '(should have been 4139 characters)'
fi
chmod 444 'rpc/rpclib/xdr_mem.c'
fi
echo shar: "extracting 'rpc/rpclib/xdr_rec.c'" '(15063 characters)'
if test -f 'rpc/rpclib/xdr_rec.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/xdr_rec.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_rec.c'
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part.  Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X * 
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X * 
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X * 
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X * 
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X * 
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California  94043
X */
X#ifndef lint
Xstatic char sccsid[] = "@(#)xdr_rec.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
X * layer above tcp (for rpc's use).
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * These routines interface XDRSTREAMS to a tcp/ip connection.
X * There is a record marking layer between the xdr stream
X * and the tcp transport level.  A record is composed on one or more
X * record fragments.  A record fragment is a thirty-two bit header followed
X * by n bytes of data, where n is contained in the header.  The header
X * is represented as a htonl(u_long).  Thegh order bit encodes
X * whether or not the fragment is the last fragment of the record
X * (1 => fragment is last, 0 => more fragments to follow. 
X * The other 31 bits encode the byte length of the fragment.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include "xdr.h"
X#include <sys/time.h>
X#include <netinet/in.h>
X
Xchar *mem_alloc();
X
Xstatic u_int	fix_buf_size();
X
Xstatic bool_t	xdrrec_getlong();
Xstatic bool_t	xdrrec_putlong();
Xstatic bool_t	xdrrec_getbytes();
Xstatic bool_t	xdrrec_putbytes();
Xstatic u_int	xdrrec_getpos();
Xstatic bool_t	xdrrec_setpos();
Xstatic long *	xdrrec_inline();
Xstatic void	xdrrec_destroy();
X
Xstatic struct  xdr_ops xdrrec_ops = {
X	xdrrec_getlong,
X	xdrrec_putlong,
X	xdrrec_getbytes,
X	xdrrec_putbytes,
X	xdrrec_getpos,
X	xdrrec_setpos,
X	xdrrec_inline,
X	xdrrec_destroy
X};
X
X/*
X * A record is composed of one or more record fragments.
X * A record fragment is a two-byte header followed by zero to
X * 2**32-1 bytes.  The header is treated as a long unsigned and is
X * encode/decoded to the network via htonl/ntohl.  The low order 31 bits
X * are a byte count of the fragment.  The highest order bit is a boolean:
X * 1 => this fragment is the last fragment of the record,
X * 0 => this fragment is followed by more fragment(s).
X *
X * The fragment/record machinery is not general;  it is constructed to
X * meet the needs of xdr and rpc based on tcp.
X */
X
X#define LAST_FRAG ((u_long)(1 << 31))
X
Xtypedef struct rec_strm {
X	caddr_t tcp_handle;
X	/*
X	 * out-goung bits
X	 */
X	int (*writeit)();
X	caddr_t out_base;	/* output buffer (points to frag header) */
X	caddr_t out_finger;	/* next output position */
X	caddr_t out_boundry;	/* data cannot up to this address */
X	u_long *frag_header;	/* beginning of curren fragment */
X	bool_t frag_sent;	/* true if buffer sent in middle of record */
X	/*
X	 * in-coming bits
X	 */
X	int (*readit)();
X	u_long in_size;	/* fixed size of the input buffer */
X	caddr_t in_base;
X	caddr_t in_finger;	/* location of next byte to be had */
X	caddr_t in_boundry;	/* can read up to this location */
X	long fbtbc;		/* fragment bytes to be consumed */
X	bool_t last_frag;
X	u_int sendsize;
X	u_int recvsize;
X} RECSTREAM;
X
X
X/*
X * Create an xdr handle for xdrrec
X * xdrrec_create fills in xdrs.  Sendsize and recvsize are
X * send and recv buffer sizes (0 => use default).
X * tcp_handle is an opaque handle that is passed as the first parameter to
X * the procedures readit and writeit.  Readit and writeit are read and
X * write respectively.   They are like the system
X * calls expect that they take an opaque handle rather than an fd.
X */
Xvoid
Xxdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
X	register XDR *xdrs;
X	u_int sendsize;
X	u_int recvsize;
X	caddr_t tcp_handle;
X	int (*readit)();  /* like read, but pass it a tcp_handle, not sock */
X	int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */
X{
X	register RECSTREAM *rstrm =
X	    (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
X
X	if (rstrm == NULL) {
X		fprintf(stderr, "xdrrec_create: out of memory\n");
X		/* 
X		 *  This is bad.  Should rework xdrrec_create to 
X		 *  return a handle, and in this case return NULL
X		 */
X		return;
X	}
X	xdrs->x_ops = &xdrrec_ops;
X	xdrs->x_private = (caddr_t)rstrm;
X	rstrm->tcp_handle = tcp_handle;
X	rstrm->readit = readit;
X	rstrm->writeit = writeit;
X	sendsize = fix_buf_size(sendsize);
X	if ((rstrm->out_base = rstrm->out_finger = rstrm->out_boundry =
X	    mem_alloc(sendsize)) == NULL) {
X		fprintf(stderr, "xdrrec_create: out of memory\n");
X		return;
X	}
X	rstrm->frag_header = (u_long *)rstrm->out_base;
X	rstrm->out_finger += sizeof(u_long);
X	rstrm->out_boundry += sendsize;
X	rstrm->frag_sent = FALSE;
X	rstrm->in_size = recvsize = fix_buf_size(recvsize);
X	if ((rstrm->in_base = rstrm->in_boundry=mem_alloc(recvsize)) == NULL) {
X		fprintf(stderr, "xdrrec_create: out of memory\n");
X		return;
X	}
X	rstrm->in_finger = (rstrm->in_boundry += recvsize);
X	rstrm->fbtbc = 0;
X	rstrm->last_frag = TRUE;
X	rstrm->sendsize = sendsize;
X	rstrm->recvsize = recvsize;
X}
X
X
X/*
X * The reoutines defined below are the xdr ops which will go into the
X * xdr handle filled in by xdrrec_create.
X */
X
Xstatic bool_t
Xxdrrec_getlong(xdrs, lp)
X	XDR *xdrs;
X	long *lp;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
X	register long *buflp = (long *)(rstrm->in_finger);
X	long mylong;
X
X	/* first try the inline, fast case */
X	if ((rstrm->fbtbc >= sizeof(long)) &&
X	    (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
X		*lp = ntohl(*buflp);
X		rstrm->fbtbc -= sizeof(long);
X		rstrm->in_finger += sizeof(long);
X	} else {
X		if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
X			return (FALSE);
X		*lp = ntohl(mylong);
X	}
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrrec_putlong(xdrs, lp)
X	XDR *xdrs;
X	long *lp;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
X	register long *dest_lp = ((long *)(rstrm->out_finger));
X
X	if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
X		/*
X		 * this case should almost never happen so the code is
X		 * inefficient
X		 */
X		rstrm->out_finger -= sizeof(long);
X		rstrm->frag_sent = TRUE;
X		if (! flush_out(rstrm, FALSE))
X			return (FALSE);
X		dest_lp = ((long *)(rstrm->out_finger));
X		rstrm->out_finger += sizeof(long);
X	}
X	*dest_lp = htonl(*lp);
X	return (TRUE);
X}
X
Xstatic bool_t  /* must manage buffers, fragments, and records */
Xxdrrec_getbytes(xdrs, addr, len)
X	XDR *xdrs;
X	register caddr_t addr;
X	register u_int len;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
X	register int current;
X
X	while (len > 0) {
X		current = rstrm->fbtbc;
X		if (current == 0) {
X			if (rstrm->last_frag)
X				return (FALSE);
X			if (! set_input_fragment(rstrm))
X				return (FALSE);
X			continue;
X		}
X		current = (len < current) ? len : current;
X		if (! get_input_bytes(rstrm, addr, current))
X			return (FALSE);
X		addr += current; 
X		rstrm->fbtbc -= current;
X		len -= current;
X	}
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrrec_putbytes(xdrs, addr, len)
X	XDR *xdrs;
X	register caddr_t addr;
X	register u_int len;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
X	register int current;
X
X	while (len > 0) {
X		current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
X		current = (len < current) ? len : current;
X		bcopy(addr, rstrm->out_finger, current);
X		rstrm->out_finger += current;
X		addr += current;
X		len -= current;
X		if (rstrm->out_finger == rstrm->out_boundry) {
X			rstrm->frag_sent = TRUE;
X			if (! flush_out(rstrm, FALSE))
X				return (FALSE);
X		}
X	}
X	return (TRUE);
X}
X
Xstatic u_int
Xxdrrec_getpos(xdrs)
X	register XDR *xdrs;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
X	register u_int pos;
X
X	pos = lseek((int)rstrm->tcp_handle, 0, 1);
X	if ((int)pos != -1)
X		switch (xdrs->x_op) {
X
X		case XDR_ENCODE:
X			pos += rstrm->out_finger - rstrm->out_base;
X			break;
X
X		case XDR_DECODE:
X			pos -= rstrm->in_boundry - rstrm->in_finger;
X			break;
X
X		default:
X			pos = (u_int) -1;
X			break;
X		}
X	return (pos);
X}
X
Xstatic bool_t
Xxdrrec_setpos(xdrs, pos)
X	register XDR *xdrs;
X	u_int pos;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
X	u_int currpos = xdrrec_getpos(xdrs);
X	int delta = currpos - pos;
X	caddr_t newpos;
X
X	if ((int)currpos != -1)
X		switch (xdrs->x_op) {
X
X		case XDR_ENCODE:
X			newpos = rstrm->out_finger - delta;
X			if ((newpos > (caddr_t)(rstrm->frag_header)) &&
X			    (newpos < rstrm->out_boundry)) {
X				rstrm->out_finger = newpos;
X				return (TRUE);
X			}
X			break;
X
X		case XDR_DECODE:
X			newpos = rstrm->in_finger - delta;
X			if ((delta < (int)(rstrm->fbtbc)) &&
X			    (newpos <= rstrm->in_boundry) &&
X			    (newpos >= rstrm->in_base)) {
X				rstrm->in_finger = newpos;
X				rstrm->fbtbc -= delta;
X				return (TRUE);
X			}
X			break;
X		}
X	return (FALSE);
X}
X
Xstatic long *
Xxdrrec_inline(xdrs, len)
X	register XDR *xdrs;
X	int len;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
X	long * buf = NULL;
X
X	switch (xdrs->x_op) {
X
X	case XDR_ENCODE:
X		if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
X			buf = (long *) rstrm->out_finger;
X			rstrm->out_finger += len;
X		}
X		break;
X
X	case XDR_DECODE:
X		if ((len <= rstrm->fbtbc) &&
X		    ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
X			buf = (long *) rstrm->in_finger;
X			rstrm->fbtbc -= len;
X			rstrm->in_finger += len;
X		}
X		break;
X	}
X	return (buf);
X}
X
Xstatic void
Xxdrrec_destroy(xdrs)
X	register XDR *xdrs;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
X
X	mem_free(rstrm->out_base, rstrm->sendsize);
X	mem_free(rstrm->in_base, rstrm->recvsize);
X	mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
X}
X
X
X/*
X * Exported routines to manage xdr records
X */
X
X/*
X * Before reading (deserializing from the stream, one should always call
X * this procedure to guarantee proper record alignment.
X */
Xbool_t
Xxdrrec_skiprecord(xdrs)
X	XDR *xdrs;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
X
X	while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
X		if (! skip_input_bytes(rstrm, rstrm->fbtbc))
X			return (FALSE);
X		rstrm->fbtbc = 0;
X		if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
X			return (FALSE);
X	}
X	rstrm->last_frag = FALSE;
X	return (TRUE);
X}
X
X/*
X * Look ahead fuction.
X * Returns TRUE iff there is no more input in the buffer 
X * after consuming the rest of the current record.
X */
Xbool_t
Xxdrrec_eof(xdrs)
X	XDR *xdrs;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
X
X	while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
X		if (! skip_input_bytes(rstrm, rstrm->fbtbc))
X			return (TRUE);
X		rstrm->fbtbc = 0;
X		if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
X			return (TRUE);
X	}
X	if (rstrm->in_finger == rstrm->in_boundry)
X		return (TRUE);
X	return (FALSE);
X}
X
X/*
X * The client must tell the package when an end-of-record has occurred.
X * The second paraemters tells whether the record should be flushed to the
X * (output) tcp stream.  (This let's the package support batched or
X * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
X */
Xbool_t
Xxdrrec_endofrecord(xdrs, sendnow)
X	XDR *xdrs;
X	bool_t sendnow;
X{
X	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
X	register u_long len;  /* fragment length */
X
X	if (sendnow || rstrm->frag_sent ||
X	    ((u_long)rstrm->out_finger + sizeof(u_long) >=
X	    (u_long)rstrm->out_boundry)) {
X		rstrm->frag_sent = FALSE;
X		return (flush_out(rstrm, TRUE));
X	}
X	len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
X	   sizeof(u_long);
X	*(rstrm->frag_header) = htonl(len | LAST_FRAG);
X	rstrm->frag_header = (u_long *)rstrm->out_finger;
X	rstrm->out_finger += sizeof(u_long);
X	return (TRUE);
X}
X
X
X/*
X * Internal useful routines
X */
Xstatic bool_t
Xflush_out(rstrm, eor)
X	register RECSTREAM *rstrm;
X	bool_t eor;
X{
X	register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
X	register u_long len = (u_long)(rstrm->out_finger) - 
X	    (u_long)(rstrm->frag_header) - sizeof(u_long);
X
X	*(rstrm->frag_header) = htonl(len | eormask);
X	len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
X	if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
X	    != (int)len)
X		return (FALSE);
X	rstrm->frag_header = (u_long *)rstrm->out_base;
X	rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
X	return (TRUE);
X}
X
Xstatic bool_t  /* knows nothing about records!  Only about input buffers */
Xfill_input_buf(rstrm)
X	register RECSTREAM *rstrm;
X{
X	register caddr_t where = rstrm->in_base;
X	register int len = rstrm->in_size;
X
X	if (((int)rstrm->in_boundry % 2) != 0) {
X		/* keep stream odd bytes aligned with memory odd bytes */
X		where++;
X		len--;
X	}
X	if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
X		return (FALSE);
X	rstrm->in_finger = where;
X	where += len;
X	rstrm->in_boundry = where;
X	return (TRUE);
X}
X
Xstatic bool_t  /* knows nothing about records!  Only about input buffers */
Xget_input_bytes(rstrm, addr, len)
X	register RECSTREAM *rstrm;
X	register caddr_t addr;
X	register int len;
X{
X	register int current;
X
X	while (len > 0) {
X		current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
X		if (current == 0) {
X			if (! fill_input_buf(rstrm))
X				return (FALSE);
X			continue;
X		}
X		current = (len < current) ? len : current;
X		bcopy(rstrm->in_finger, addr, current);
X		rstrm->in_finger += current;
X		addr += current;
X		len -= current;
X	}
X	return (TRUE);
X}
X
Xstatic bool_t  /* next two bytes of the input stream are treated as a header */
Xset_input_fragment(rstrm)
X	register RECSTREAM *rstrm;
X{
X	u_long header;
X
X	if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
X		return (FALSE);
X	header = ntohl(header);
X	rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
X	rstrm->fbtbc = header & (~LAST_FRAG);
X	return (TRUE);
X}
X
Xstatic bool_t  /* consumes input bytes; knows nothing about records! */
Xskip_input_bytes(rstrm, cnt)
X	register RECSTREAM *rstrm;
X	int cnt;
X{
X	register int current;
X
X	while (cnt > 0) {
X		current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
X		if (current == 0) {
X			if (! fill_input_buf(rstrm))
X				return (FALSE);
X			continue;
X		}
X		current = (cnt < current) ? cnt : current;
X		rstrm->in_finger += current;
X		cnt -= current;
X	}
X	return (TRUE);
X}
X
Xstatic u_int
Xfix_buf_size(s)
X	register u_int s;
X{
X
X	if (s < 100)
X		return (3998);
X	for (; (s % 4) != 2; --s);
X	return (s);
X}
SHAR_EOF
if test 15063 -ne "`wc -c < 'rpc/rpclib/xdr_rec.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/xdr_rec.c'" '(should have been 15063 characters)'
fi
chmod 444 'rpc/rpclib/xdr_rec.c'
fi
echo shar: "extracting 'rpc/rpclib/xdr_reference.c'" '(2812 characters)'
if test -f 'rpc/rpclib/xdr_reference.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/xdr_reference.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_reference.c'
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part.  Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X * 
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X * 
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X * 
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X * 
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X * 
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California  94043
X */
X#ifndef lint
Xstatic char sccsid[] = "@(#)xdr_reference.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr_reference.c, Generic XDR routines impelmentation.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * These are the "non-trivial" xdr primitives used to serialize and de-serialize
X * "pointers".  See xdr.h for more info on the interface to xdr.
X */
X
X#include "types.h"
X#include "xdr.h"
X#include <stdio.h>
X#define LASTUNSIGNED	((u_int)0-1)
X
Xchar *mem_alloc();
X
X/*
X * XDR an indirect pointer
X * xdr_reference is for recursively translating a structure that is
X * referenced by a pointer inside the structure that is currently being
X * translated.  pp references a pointer to storage. If *pp is null
X * the  necessary storage is allocated.
X * size is the sizeof the referneced structure.
X * proc is the routine to handle the referenced structure.
X */
Xbool_t
Xxdr_reference(xdrs, pp, size, proc)
X	register XDR *xdrs;
X	caddr_t *pp;		/* the pointer to work on */
X	u_int size;		/* size of the object pointed to */
X	xdrproc_t proc;		/* xdr routine to handle the object */
X{
X	register caddr_t loc = *pp;
X	register bool_t stat;
X
X	if (loc == NULL)
X		switch (xdrs->x_op) {
X		case XDR_FREE:
X			return (TRUE);
X
X		case XDR_DECODE:
X			*pp = loc = mem_alloc(size);
X			if (loc == NULL) {
X				fprintf(stderr,
X				    "xdr_reference: out of memory\n");
X				return (FALSE);
X			}
X			bzero(loc, (int)size);
X			break;
X	}
X
X	stat = (*proc)(xdrs, loc, LASTUNSIGNED);
X
X	if (xdrs->x_op == XDR_FREE) {
X		mem_free(loc, size);
X		*pp = NULL;
X	}
X	return (stat);
X}
SHAR_EOF
if test 2812 -ne "`wc -c < 'rpc/rpclib/xdr_reference.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/xdr_reference.c'" '(should have been 2812 characters)'
fi
chmod 444 'rpc/rpclib/xdr_reference.c'
fi
echo shar: "extracting 'rpc/rpclib/xdr_stdio.c'" '(4653 characters)'
if test -f 'rpc/rpclib/xdr_stdio.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/xdr_stdio.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_stdio.c'
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part.  Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X * 
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X * 
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X * 
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X * 
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X * 
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California  94043
X */
X#ifndef lint
Xstatic char sccsid[] = "@(#)xdr_stdio.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr_stdio.c, XDR implementation on standard i/o file.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * This set of routines implements a XDR on a stdio stream.
X * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
X * from the stream.
X */
X
X#include "types.h"
X#include <stdio.h>
X#include "xdr.h"
X
Xstatic bool_t	xdrstdio_getlong();
Xstatic bool_t	xdrstdio_putlong();
Xstatic bool_t	xdrstdio_getbytes();
Xstatic bool_t	xdrstdio_putbytes();
Xstatic u_int	xdrstdio_getpos();
Xstatic bool_t	xdrstdio_setpos();
Xstatic long *	xdrstdio_inline();
Xstatic void	xdrstdio_destroy();
X
X/*
X * Ops vector for stdio type XDR
X */
Xstatic struct xdr_ops	xdrstdio_ops = {
X	xdrstdio_getlong,	/* deseraialize a long int */
X	xdrstdio_putlong,	/* seraialize a long int */
X	xdrstdio_getbytes,	/* deserialize counted bytes */
X	xdrstdio_putbytes,	/* serialize counted bytes */
X	xdrstdio_getpos,	/* get offset in the stream */
X	xdrstdio_setpos,	/* set offset in the stream */
X	xdrstdio_inline,	/* prime stream for inline macros */
X	xdrstdio_destroy	/* destroy stream */
X};
X
X/*
X * Initialize a stdio xdr stream.
X * Sets the xdr stream handle xdrs for use on the stream file.
X * Operation flag is set to op.
X */
Xvoid
Xxdrstdio_create(xdrs, file, op)
X	register XDR *xdrs;
X	FILE *file;
X	enum xdr_op op;
X{
X
X	xdrs->x_op = op;
X	xdrs->x_ops = &xdrstdio_ops;
X	xdrs->x_private = (caddr_t)file;
X	xdrs->x_handy = 0;
X	xdrs->x_base = 0;
X}
X
X/*
X * Destroy a stdio xdr stream.
X * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
X */
Xstatic void
Xxdrstdio_destroy(xdrs)
X	register XDR *xdrs;
X{
X	(void)fflush((FILE *)xdrs->x_private);
X	/* xx should we close the file ?? */
X};
X
Xstatic bool_t
Xxdrstdio_getlong(xdrs, lp)
X	XDR *xdrs;
X	register long *lp;
X{
X
X	if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
X		return (FALSE);
X#ifndef mc68000
X	*lp = ntohl(*lp);
X#endif
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrstdio_putlong(xdrs, lp)
X	XDR *xdrs;
X	long *lp;
X{
X
X#ifndef mc68000
X	long mycopy = htonl(*lp);
X	lp = &mycopy;
X#endif
X	if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
X		return (FALSE);
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrstdio_getbytes(xdrs, addr, len)
X	XDR *xdrs;
X	caddr_t addr;
X	u_int len;
X{
X
X	if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
X		return (FALSE);
X	return (TRUE);
X}
X
Xstatic bool_t
Xxdrstdio_putbytes(xdrs, addr, len)
X	XDR *xdrs;
X	caddr_t addr;
X	u_int len;
X{
X
X	if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
X		return (FALSE);
X	return (TRUE);
X}
X
Xstatic u_int
Xxdrstdio_getpos(xdrs)
X	XDR *xdrs;
X{
X
X	return ((u_int) ftell((FILE *)xdrs->x_private));
X}
X
Xstatic bool_t
Xxdrstdio_setpos(xdrs, pos) 
X	XDR *xdrs;
X	u_int pos;
X{ 
X
X	return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
X		FALSE : TRUE);
X}
X
Xstatic long *
Xxdrstdio_inline(xdrs, len)
X	XDR *xdrs;
X	u_int len;
X{
X
X	/*
X	 * Must do some work to implement this: must insure
X	 * enough data in the underlying stdio buffer,
X	 * that the buffer is aligned so that we can indirect through a
X	 * long *, and stuff this pointer in xdrs->x_buf.  Doing
X	 * a fread or fwrite to a scratch buffer would defeat
X	 * most of the gains to be had here and require storage
X	 * management on this buffer, so we don't do this.
X	 */
X	return (NULL);
X}
SHAR_EOF
if test 4653 -ne "`wc -c < 'rpc/rpclib/xdr_stdio.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/xdr_stdio.c'" '(should have been 4653 characters)'
fi
chmod 444 'rpc/rpclib/xdr_stdio.c'
fi
echo shar: "extracting 'rpc/tools/portmap.8c'" '(1034 characters)'
if test -f 'rpc/tools/portmap.8c'
then
	echo shar: "will not over-write existing file 'rpc/tools/portmap.8c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/tools/portmap.8c'
X.\" @(#)portmap.8c 1.1 85/12/28 SMI;
X.TH PORTMAP 8C "1 February 1985"
X.SH NAME
Xportmap \- DARPA port to RPC program number mapper
X.SH SYNOPSIS
X.B /usr/etc/rpc.portmap
X.SH DESCRIPTION
X.IX  "portmap command"  ""  "\fLportmap\fP \(em DARPA to RPC mapper"
X.IX  "DARPA to RPC mapper"  ""  "DARPA to RPC mapper \(em \fLportmap\fP"
X.I Portmap
Xis a server that converts RPC program numbers
Xinto DARPA protocol port numbers.
XIt must be running in order to make RPC calls.
X.PP
XWhen an RPC server is started, it will tell
X.I portmap
Xwhat port number it is listening to,
Xand what RPC program numbers it is prepared to serve.
XWhen a client wishes to make an RPC call to a given program number,
Xit will first contact
X.I portmap
Xon the server machine to determine
Xthe port number where RPC packets should be sent.
X.PP
XNormally, standard RPC servers are started by
X.IR inetd (8c),
Xso
X.I portmap
Xmust be started before
X.I inetd
Xis invoked.
X.SH "SEE ALSO"
Xservers(5), rpcinfo(8), inetd(8)
X.SH BUGS
XIf
X.I portmap
Xcrashes, all servers must be restarted.
SHAR_EOF
if test 1034 -ne "`wc -c < 'rpc/tools/portmap.8c'`"
then
	echo shar: "error transmitting 'rpc/tools/portmap.8c'" '(should have been 1034 characters)'
fi
chmod 444 'rpc/tools/portmap.8c'
fi
echo shar: "extracting 'rpc/tools/portmap.c'" '(10290 characters)'
if test -f 'rpc/tools/portmap.c'
then
	echo shar: "will not over-write existing file 'rpc/tools/portmap.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/tools/portmap.c'
X#ifndef lint
Xstatic	char sccsid[] = "@(#)portmap.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * Copyright (c) 1984 by Sun Microsystems, Inc.
X */
X
X/*
X * portmap.c, Implements the program,version to port number mapping for
X * rpc.
X */
X
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part.  Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X * 
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X * 
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X * 
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X * 
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X * 
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California  94043
X */
X
X#include <rpc/rpc.h>
X#include <rpc/pmap_prot.h>
X#include <stdio.h>
X#include <netdb.h>
X#include <sys/socket.h>
X#include <sys/time.h>
X#include <sys/ioctl.h>
X
Xchar *malloc();
Xint reg_service();
Xstatic int debugging = 0;
X
Xmain()
X{
X	SVCXPRT *xprt;
X	int sock, pid, t;
X	struct sockaddr_in addr;
X	int len = sizeof(struct sockaddr_in);
X
X#ifndef DEBUG
X	pid = fork();
X	if (pid < 0) {
X		perror("portmap: fork");
X		exit(1);
X	}
X	if (pid != 0)
X		exit(0);
X	for (t = 0; t < 20; t++)
X		close(t);
X 	open("/", 0);
X 	dup2(0, 1);
X 	dup2(0, 2);
X 	t = open("/dev/tty", 2);
X 	if (t >= 0) {
X 		ioctl(t, TIOCNOTTY, (char *)0);
X 		close(t);
X 	}
X#endif
X	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
X		perror("portmap cannot create socket");
X		exit(1);
X	}
X
X	addr.sin_addr.S_un.S_addr = 0;
X	addr.sin_family = AF_INET;
X	addr.sin_port = htons(PMAPPORT);
X	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
X		perror("portmap cannot bind");
X		exit(1);
X	}
X
X	if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
X		fprintf(stderr, "couldn't do udp_create\n");
X		exit(1);
X	}
X
X	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
X		perror("portmap cannot create socket");
X		exit(1);
X	}
X	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
X		perror("portmap cannot bind");
X		exit(1);
X	}
X	if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))
X	    == (SVCXPRT *)NULL) {
X		fprintf(stderr, "couldn't do tcp_create\n");
X		exit(1);
X	}
X
X        (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
X	svc_run();
X	fprintf(stderr, "run_svc returned unexpectedly\n");
X	abort();
X}
X
Xstruct pmaplist *pmaplist;
X
Xstatic struct pmaplist *
Xfind_service(prog, vers, prot)
X	u_long prog;
X	u_long vers;
X{
X	register struct pmaplist *hit = NULL;
X	register struct pmaplist *pml;
X
X	for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
X		if ((pml->pml_map.pm_prog != prog) ||
X			(pml->pml_map.pm_prot != prot))
X			continue;
X		hit = pml;
X		if (pml->pml_map.pm_vers == vers)
X		    break;
X	}
X	return (hit);
X}
X
X/* 
X * 1 OK, 0 not
X */
Xreg_service(rqstp, xprt)
X	struct svc_req *rqstp;
X	SVCXPRT *xprt;
X{
X	struct pmap reg;
X	struct pmaplist *pml, *prevpml, *fnd;
X	int ans, port;
X	caddr_t t;
X	
X#ifdef DEBUG
X	fprintf(stderr, "server: about do a switch\n");
X#endif
X	switch (rqstp->rq_proc) {
X
X	case PMAPPROC_NULL:
X		/*
X		 * Null proc call
X		 */
X		if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) {
X			abort();
X		}
X		break;
X
X	case PMAPPROC_SET:
X		/*
X		 * Set a program,version to port mapping
X		 */
X		if (!svc_getargs(xprt, xdr_pmap, &reg))
X			svcerr_decode(xprt);
X		else {
X			/*
X			 * check to see if already used
X			 * find_service returns a hit even if
X			 * the versions don't match, so check for it
X			 */
X			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
X			if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
X				if (fnd->pml_map.pm_port == reg.pm_port) {
X					ans = 1;
X					goto done;
X				}
X				else {
X					ans = 0;
X					goto done;
X				}
X			} else {
X				/* 
X				 * add to END of list
X				 */
X				pml = (struct pmaplist *)
X				    malloc((u_int)sizeof(struct pmaplist));
X				pml->pml_map = reg;
X				pml->pml_next = 0;
X				if (pmaplist == 0) {
X					pmaplist = pml;
X				} else {
X					for (fnd= pmaplist; fnd->pml_next != 0;
X					    fnd = fnd->pml_next);
X					fnd->pml_next = pml;
X				}
X				ans = 1;
X			}
X		done:
X			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
X			    debugging) {
X				fprintf(stderr, "svc_sendreply\n");
X				abort();
X			}
X		}
X		break;
X
X	case PMAPPROC_UNSET:
X		/*
X		 * Remove a program,version to port mapping.
X		 */
X		if (!svc_getargs(xprt, xdr_pmap, &reg))
X			svcerr_decode(xprt);
X		else {
X			ans = 0;
X			for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
X				if ((pml->pml_map.pm_prog != reg.pm_prog) ||
X					(pml->pml_map.pm_vers != reg.pm_vers)) {
X					/* both pml & prevpml move forwards */
X					prevpml = pml;
X					pml = pml->pml_next;
X					continue;
X				}
X				/* found it; pml moves forward, prevpml stays */
X				ans = 1;
X				t = (caddr_t)pml;
X				pml = pml->pml_next;
X				if (prevpml == NULL)
X					pmaplist = pml;
X				else
X					prevpml->pml_next = pml;
X				free(t);
X			}
X			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
X			    debugging) {
X				fprintf(stderr, "svc_sendreply\n");
X				abort();
X			}
X		}
X		break;
X
X	case PMAPPROC_GETPORT:
X		/*
X		 * Lookup the mapping for a program,version and return its port
X		 */
X		if (!svc_getargs(xprt, xdr_pmap, &reg))
X			svcerr_decode(xprt);
X		else {
X			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
X			if (fnd)
X				port = fnd->pml_map.pm_port;
X			else
X				port = 0;
X			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&
X			    debugging) {
X				fprintf(stderr, "svc_sendreply\n");
X				abort();
X			}
X		}
X		break;
X
X	case PMAPPROC_DUMP:
X		/*
X		 * Return the current set of mapped program,version
X		 */
X		if (!svc_getargs(xprt, xdr_void, NULL))
X			svcerr_decode(xprt);
X		else {
X			if ((!svc_sendreply(xprt, xdr_pmaplist,
X			    (caddr_t)&pmaplist)) && debugging) {
X				fprintf(stderr, "svc_sendreply\n");
X				abort();
X			}
X		}
X		break;
X
X	case PMAPPROC_CALLIT:
X		/*
X		 * Calls a procedure on the local machine.  If the requested
X		 * procedure is not registered this procedure does not return
X		 * error information!!
X		 * This procedure is only supported on rpc/udp and calls via 
X		 * rpc/udp.  It passes null authentication parameters.
X		 */
X		callit(rqstp, xprt);
X		break;
X
X	default:
X		svcerr_noproc(xprt);
X		break;
X	}
X}
X
X
X/*
X * Stuff for the rmtcall service
X */
X#define ARGSIZE 9000
X
Xtypedef struct encap_parms {
X	u_long arglen;
X	char *args;
X};
X
Xstatic bool_t
Xxdr_encap_parms(xdrs, epp)
X	XDR *xdrs;
X	struct encap_parms *epp;
X{
X
X	return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
X}
X
Xtypedef struct rmtcallargs {
X	u_long	rmt_prog;
X	u_long	rmt_vers;
X	u_long	rmt_port;
X	u_long	rmt_proc;
X	struct encap_parms rmt_args;
X};
X
Xstatic bool_t
Xxdr_rmtcall_args(xdrs, cap)
X	register XDR *xdrs;
X	register struct rmtcallargs *cap;
X{
X
X	/* does not get a port number */
X	if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
X	    xdr_u_long(xdrs, &(cap->rmt_vers)) &&
X	    xdr_u_long(xdrs, &(cap->rmt_proc))) {
X		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
X	}
X	return (FALSE);
X}
X
Xstatic bool_t
Xxdr_rmtcall_result(xdrs, cap)
X	register XDR *xdrs;
X	register struct rmtcallargs *cap;
X{
X	if (xdr_u_long(xdrs, &(cap->rmt_port)))
X		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
X	return (FALSE);
X}
X
X/*
X * only worries about the struct encap_parms part of struct rmtcallargs.
X * The arglen must already be set!!
X */
Xstatic bool_t
Xxdr_opaque_parms(xdrs, cap)
X	XDR *xdrs;
X	struct rmtcallargs *cap;
X{
X
X	return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
X}
X
X/*
X * This routine finds and sets the length of incoming opaque paraters
X * and then calls xdr_opaque_parms.
X */
Xstatic bool_t
Xxdr_len_opaque_parms(xdrs, cap)
X	register XDR *xdrs;
X	struct rmtcallargs *cap;
X{
X	register u_int beginpos, lowpos, highpos, currpos, pos;
X
X	beginpos = lowpos = pos = xdr_getpos(xdrs);
X	highpos = lowpos + ARGSIZE;
X	while ((int)(highpos - lowpos) >= 0) {
X		currpos = (lowpos + highpos) / 2;
X		if (xdr_setpos(xdrs, currpos)) {
X			pos = currpos;
X			lowpos = currpos + 1;
X		} else {
X			highpos = currpos - 1;
X		}
X	}
X	xdr_setpos(xdrs, beginpos);
X	cap->rmt_args.arglen = pos - beginpos;
X	return (xdr_opaque_parms(xdrs, cap));
X}
X
X/*
X * Call a remote procedure service
X * This procedure is very quiet when things go wrong.
X * The proc is written to support broadcast rpc.  In the broadcast case,
X * a machine should shut-up instead of complain, less the requestor be
X * overrun with complaints at the expense of not hearing a valid reply ...
X */
Xstatic
Xcallit(rqstp, xprt)
X	struct svc_req *rqstp;
X	SVCXPRT *xprt;
X{
X	char buf[2000];
X	struct rmtcallargs a;
X	struct pmaplist *pml;
X	u_short port;
X	struct sockaddr_in me;
X	int socket = -1;
X	CLIENT *client;
X	struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
X	struct timeval timeout;
X
X	timeout.tv_sec = 5;
X	timeout.tv_usec = 0;
X	a.rmt_args.args = buf;
X	if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
X	    return;
X	if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
X	    return;
X	port = pml->pml_map.pm_port;
X	get_myaddress(&me);
X	me.sin_port = htons(port);
X	client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
X	if (client != (CLIENT *)NULL) {
X		if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
X			client->cl_auth = authunix_create(au->aup_machname,
X			   au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
X		}
X		a.rmt_port = (u_long)port;
X		if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
X		    xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
X			svc_sendreply(xprt, xdr_rmtcall_result, &a);
X		}
X		AUTH_DESTROY(client->cl_auth);
X		clnt_destroy(client);
X	}
X	(void)close(socket);
X}
SHAR_EOF
if test 10290 -ne "`wc -c < 'rpc/tools/portmap.c'`"
then
	echo shar: "error transmitting 'rpc/tools/portmap.c'" '(should have been 10290 characters)'
fi
chmod 444 'rpc/tools/portmap.c'
fi
exit 0
#	End of shell archive