[mod.sources] v06i096: Sun RPC Source

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

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

[  I have not tried any of this code, just verified that it unpacks ok.  -r$ ]

Sun RPC source (part 8 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/svc_auth.c
#	rpc/rpclib/svc_auth_unix.c
#	rpc/rpclib/svc_raw.c
#	rpc/rpclib/svc_simple.c
#	rpc/rpclib/svc_tcp.c
#	rpc/rpclib/svc_udp.c
#	rpc/rpclib/xdr.c
#	rpc/rpclib/xdr_array.c
# This archive created: Mon Jul 14 16:55:34 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/svc_auth.c'" '(3678 characters)'
if test -f 'rpc/rpclib/svc_auth.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/svc_auth.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc_auth.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[] = "@(#)svc_auth.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * svc_auth.c, Server-side rpc authenticator interface.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X */
X
X#include "types.h"
X#include <netinet/in.h>
X#include "xdr.h"
X#include "auth.h"
X#include "clnt.h"
X#include "rpc_msg.h"
X#include "svc.h"
X#include "svc_auth.h"
X
X/*
X * svcauthsw is the bdevsw of server side authentication. 
X * 
X * Server side authenticators are called from authenticate by
X * using the client auth struct flavor field to index into svcauthsw.
X * The server auth flavors must implement a routine that looks  
X * like: 
X * 
X *	enum auth_stat 
X *	flavorx_auth(rqst, msg)
X *		register struct svc_req *rqst; 
X *		register struct rpc_msg *msg;
X *  
X */
X
Xenum auth_stat _svcauth_null();		/* no authentication */
Xenum auth_stat _svcauth_unix();		/* unix style (uid, gids) */
Xenum auth_stat _svcauth_short();	/* short hand unix style */
X
Xstatic struct {
X	enum auth_stat (*authenticator)();
X} svcauthsw[] = {
X	_svcauth_null,			/* AUTH_NULL */
X	_svcauth_unix,			/* AUTH_UNIX */
X	_svcauth_short			/* AUTH_SHORT */
X};
X#define	AUTH_MAX	2		/* HIGHEST AUTH NUMBER */
X
X
X/*
X * The call rpc message, msg has been obtained from the wire.  The msg contains
X * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
X * if the msg is successfully authenticated.  If AUTH_OK then the routine also
X * does the following things:
X * set rqst->rq_xprt->verf to the appropriate response verifier;
X * sets rqst->rq_client_cred to the "cooked" form of the credentials.
X *
X * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
X * its length is set appropriately.
X *
X * The caller still owns and is responsible for msg->u.cmb.cred and
X * msg->u.cmb.verf.  The authentication system retains ownership of
X * rqst->rq_client_cred, the cooked credentials.
X */
Xenum auth_stat
X_authenticate(rqst, msg)
X	register struct svc_req *rqst;
X	struct rpc_msg *msg;
X{
X	register int cred_flavor;
X
X	rqst->rq_cred = msg->rm_call.cb_cred;
X	rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
X	rqst->rq_xprt->xp_verf.oa_length = 0;
X	cred_flavor = rqst->rq_cred.oa_flavor;
X	if (cred_flavor <= AUTH_MAX) {
X		return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg));
X	}
X
X	return (AUTH_REJECTEDCRED);
X}
X
Xenum auth_stat
X_svcauth_null(/*rqst, msg*/)
X	/*struct svc_req *rqst;
X	struct rpc_msg *msg;*/
X{
X
X	return (AUTH_OK);
X}
SHAR_EOF
if test 3678 -ne "`wc -c < 'rpc/rpclib/svc_auth.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/svc_auth.c'" '(should have been 3678 characters)'
fi
chmod 444 'rpc/rpclib/svc_auth.c'
fi
echo shar: "extracting 'rpc/rpclib/svc_auth_unix.c'" '(4210 characters)'
if test -f 'rpc/rpclib/svc_auth_unix.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/svc_auth_unix.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc_auth_unix.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[] = "@(#)svc_auth_unix.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * svc_auth_unix.c
X * Handles UNIX flavor authentication parameters on the service side of rpc.
X * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
X * _svcauth_unix does full blown unix style uid,gid+gids auth,
X * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
X * Note: the shorthand has been gutted for efficiency.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include <sys/time.h>
X#include <netinet/in.h>
X#include "xdr.h"
X#include "auth.h"
X#include "clnt.h"
X#include "rpc_msg.h"
X#include "svc.h"
X#include "auth_unix.h"
X#include "svc_auth.h"
Xchar *mem_alloc();
X
X#define	RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
X		   * BYTES_PER_XDR_UNIT)
X
X/*
X * Unix longhand authenticator
X */
Xenum auth_stat
X_svcauth_unix(rqst, msg)
X	register struct svc_req *rqst;
X	register struct rpc_msg *msg;
X{
X	register enum auth_stat stat;
X	XDR xdrs;
X	register struct authunix_parms *aup;
X	register long *buf;
X	struct area {
X		struct authunix_parms area_aup;
X		char area_machname[MAX_MACHINE_NAME];
X		int area_gids[NGRPS];
X	} *area;
X	u_int auth_len;
X	int str_len, gid_len;
X	register int i;
X
X	area = (struct area *) rqst->rq_clntcred;
X	aup = &area->area_aup;
X	aup->aup_machname = area->area_machname;
X	aup->aup_gids = area->area_gids;
X	auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
X	xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
X	buf = XDR_INLINE(&xdrs, auth_len);
X	if (buf != NULL) {
X		aup->aup_time = IXDR_GET_LONG(buf);
X		str_len = IXDR_GET_U_LONG(buf);
X		bcopy(buf, aup->aup_machname, str_len);
X		aup->aup_machname[str_len] = 0;
X		str_len = RNDUP(str_len);
X		buf += str_len / sizeof (long);
X		aup->aup_uid = IXDR_GET_LONG(buf);
X		aup->aup_gid = IXDR_GET_LONG(buf);
X		gid_len = IXDR_GET_U_LONG(buf);
X		if (gid_len > NGRPS) {
X			stat = AUTH_BADCRED;
X			goto done;
X		}
X		aup->aup_len = gid_len;
X		for (i = 0; i < gid_len; i++) {
X			aup->aup_gids[i] = IXDR_GET_LONG(buf);
X		}
X		/*
X		 * five is the smallest unix credentials structure -
X		 * timestamp, hostname len (0), uid, gid, and gids len (0).
X		 */
X		if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
X			printf("bad auth_len gid %d str %d auth %d\n",
X			       gid_len, auth_len, auth_len);
X			stat = AUTH_BADCRED;
X			goto done;
X		}
X	} else if (! xdr_authunix_parms(&xdrs, aup)) {
X		xdrs.x_op = XDR_FREE;
X		(void)xdr_authunix_parms(&xdrs, aup);
X		stat = AUTH_BADCRED;
X		goto done;
X	}
X	rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
X	rqst->rq_xprt->xp_verf.oa_length = 0;
X	stat = AUTH_OK;
Xdone:
X	XDR_DESTROY(&xdrs);
X	return (stat);
X}
X
X
X/*
X * Shorthand unix authenticator
X * Looks up longhand in a cache.
X */
X/*ARGSUSED*/
Xenum auth_stat 
X_svcauth_short(rqst, msg)
X	struct svc_req *rqst;
X	struct rpc_msg *msg;
X{
X	return (AUTH_REJECTEDCRED);
X}
SHAR_EOF
if test 4210 -ne "`wc -c < 'rpc/rpclib/svc_auth_unix.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/svc_auth_unix.c'" '(should have been 4210 characters)'
fi
chmod 444 'rpc/rpclib/svc_auth_unix.c'
fi
echo shar: "extracting 'rpc/rpclib/svc_raw.c'" '(3569 characters)'
if test -f 'rpc/rpclib/svc_raw.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/svc_raw.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc_raw.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[] = "@(#)svc_raw.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * svc_raw.c,   This a toy for simple testing and timing.
X * Interface to create an rpc client and server in the same UNIX process.
X * This lets us similate rpc and get rpc (round trip) overhead, without
X * any interference from the kernal.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X */
X
X#include "types.h"
X#include <netinet/in.h>
X#include "xdr.h"
X#include "auth.h"
X#include "clnt.h"
X#include "rpc_msg.h"
X#include "svc.h"
X
X#define NULL ((caddr_t)0)
X
X/*
X * This is the "network" that we will be moving data over
X */
Xextern char _raw_buf[UDPMSGSIZE];
X
Xstatic bool_t		svcraw_recv();
Xstatic enum xprt_stat 	svcraw_stat();
Xstatic bool_t		svcraw_getargs();
Xstatic bool_t		svcraw_reply();
Xstatic bool_t		svcraw_freeargs();
Xstatic void		svcraw_destroy();
X
Xstatic struct xp_ops server_ops = {
X	svcraw_recv,
X	svcraw_stat,
X	svcraw_getargs,
X	svcraw_reply,
X	svcraw_freeargs,
X	svcraw_destroy
X};
X
Xstatic SVCXPRT server;
Xstatic XDR xdr_stream;
Xstatic char verf_body[MAX_AUTH_BYTES];
X
XSVCXPRT *
Xsvcraw_create()
X{
X
X	server.xp_sock = 0;
X	server.xp_port = 0;
X	server.xp_ops = &server_ops;
X	server.xp_verf.oa_base = verf_body;
X	xdrmem_create(&xdr_stream, _raw_buf, UDPMSGSIZE, XDR_FREE);
X	return (&server);
X}
X
Xstatic enum xprt_stat
Xsvcraw_stat()
X{
X
X	return (XPRT_IDLE);
X}
X
Xstatic bool_t
Xsvcraw_recv(xprt, msg)
X	SVCXPRT *xprt;
X	struct rpc_msg *msg;
X{
X	register XDR *xdrs = &xdr_stream;
X
X	xdrs->x_op = XDR_DECODE;
X	XDR_SETPOS(xdrs, 0);
X	if (! xdr_callmsg(xdrs, msg))
X	       return (FALSE);
X	return (TRUE);
X}
X
Xstatic bool_t
Xsvcraw_reply(xprt, msg)
X	SVCXPRT *xprt;
X	struct rpc_msg *msg;
X{
X	register XDR *xdrs = &xdr_stream;
X
X	xdrs->x_op = XDR_ENCODE;
X	XDR_SETPOS(xdrs, 0);
X	if (! xdr_replymsg(xdrs, msg))
X	       return (FALSE);
X	(void)XDR_GETPOS(xdrs);  /* called just for overhead */
X	return (TRUE);
X}
X
Xstatic bool_t
Xsvcraw_getargs(xprt, xdr_args, args_ptr)
X	SVCXPRT *xprt;
X	xdrproc_t xdr_args;
X	caddr_t args_ptr;
X{
X
X	return ((*xdr_args)(&xdr_stream, args_ptr));
X}
X
Xstatic bool_t
Xsvcraw_freeargs(xprt, xdr_args, args_ptr)
X	SVCXPRT *xprt;
X	xdrproc_t xdr_args;
X	caddr_t args_ptr;
X{ 
X	register XDR *xdrs = &xdr_stream;
X
X	xdrs->x_op = XDR_FREE;
X	return ((*xdr_args)(xdrs, args_ptr));
X} 
X
Xstatic void
Xsvcraw_destroy()
X{
X}
SHAR_EOF
if test 3569 -ne "`wc -c < 'rpc/rpclib/svc_raw.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/svc_raw.c'" '(should have been 3569 characters)'
fi
chmod 444 'rpc/rpclib/svc_raw.c'
fi
echo shar: "extracting 'rpc/rpclib/svc_simple.c'" '(3936 characters)'
if test -f 'rpc/rpclib/svc_simple.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/svc_simple.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc_simple.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[] = "@(#)svc_simple.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/* 
X * svc_simple.c
X * Simplified front end to rpc.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X */
X
X#include <stdio.h>
X#include <rpc/rpc.h>
X#include <sys/socket.h>
X#include <sys/time.h>
X#include <netdb.h>
X
Xstatic struct proglst {
X	char *(*p_progname)();
X	int  p_prognum;
X	int  p_procnum;
X	xdrproc_t p_inproc, p_outproc;
X	struct proglst *p_nxt;
X} *proglst;
Xint universal();
Xstatic SVCXPRT *transp;
Xstatic madetransp;
Xstruct proglst *pl;
X
Xregisterrpc(prognum, versnum, procnum, progname, inproc, outproc)
X	char *(*progname)();
X	xdrproc_t inproc, outproc;
X{
X	
X	if (procnum == NULLPROC) {
X		fprintf(stderr,
X		    "can't reassign procedure number %d\n", NULLPROC);
X		return (-1);
X	}
X	if (!madetransp) {
X		madetransp = 1;
X		transp = svcudp_create(RPC_ANYSOCK);
X		if (transp == NULL) {
X			fprintf(stderr, "couldn't create an rpc server\n");
X			return (-1);
X		}
X	}
X	pmap_unset(prognum, versnum);
X	if (!svc_register(transp, prognum, versnum, universal, IPPROTO_UDP)) {
X	    	fprintf(stderr, "couldn't register prog %d vers %d\n",
X		    prognum, versnum);
X		return (-1);
X	}
X	pl = (struct proglst *)malloc(sizeof(struct proglst));
X	if (pl == NULL) {
X		fprintf(stderr, "registerrpc: out of memory\n");
X		return (-1);
X	}
X	pl->p_progname = progname;
X	pl->p_prognum = prognum;
X	pl->p_procnum = procnum;
X	pl->p_inproc = inproc;
X	pl->p_outproc = outproc;
X	pl->p_nxt = proglst;
X	proglst = pl;
X	return (0);
X}
X
Xstatic
Xuniversal(rqstp, transp)
X	struct svc_req *rqstp;
X	SVCXPRT *transp;
X{
X	int prog, proc, i;
X	char *outdata;
X	char xdrbuf[UDPMSGSIZE];
X	struct proglst *pl;
X
X	/* 
X	 * enforce "procnum 0 is echo" convention
X	 */
X	if (rqstp->rq_proc == NULLPROC) {
X		if (svc_sendreply(transp, xdr_void, 0) == FALSE) {
X			fprintf(stderr, "xxx\n");
X			exit(1);
X		}
X		return;
X	}
X	prog = rqstp->rq_prog;
X	proc = rqstp->rq_proc;
X	for (pl = proglst; pl != NULL; pl = pl->p_nxt)
X		if (pl->p_prognum == prog && pl->p_procnum == proc) {
X			/* decode arguments into a CLEAN buffer */
X			bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */
X			if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
X				svcerr_decode(transp);
X				return;
X			}
X			outdata = (*(pl->p_progname))(xdrbuf);
X			if (outdata == NULL && pl->p_outproc != xdr_void)
X				/* there was an error */
X				return;
X			if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
X				fprintf(stderr,
X				    "trouble replying to prog %d\n",
X				    pl->p_prognum);
X				exit(1);
X			/* free the decoded arguments */
X			(void)svc_freeargs(transp, pl->p_inproc, xdrbuf);
X			}
X			return;
X		}
X	fprintf(stderr, "never registered prog %d\n", prog);
X	exit(1);
X}
X
SHAR_EOF
if test 3936 -ne "`wc -c < 'rpc/rpclib/svc_simple.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/svc_simple.c'" '(should have been 3936 characters)'
fi
chmod 444 'rpc/rpclib/svc_simple.c'
fi
echo shar: "extracting 'rpc/rpclib/svc_tcp.c'" '(9984 characters)'
if test -f 'rpc/rpclib/svc_tcp.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/svc_tcp.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc_tcp.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[] = "@(#)svc_tcp.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * svc_tcp.c, Server side for TCP/IP based RPC. 
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * Actually implements two flavors of transporter -
X * a tcp rendezvouser (a listner and connection establisher)
X * and a record/tcp stream.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include <netinet/in.h>
X#include <sys/socket.h>
X#include <sys/time.h>
X#include <errno.h>
X#include "xdr.h"
X#include "auth.h"
X#include "clnt.h"
X#include "rpc_msg.h"
X#include "svc.h"
Xchar *mem_alloc();
Xextern bool_t abort();
Xextern errno;
X
X/*
X * Ops vector for TCP/IP based rpc service handle
X */
Xstatic bool_t		svctcp_recv();
Xstatic enum xprt_stat	svctcp_stat();
Xstatic bool_t		svctcp_getargs();
Xstatic bool_t		svctcp_reply();
Xstatic bool_t		svctcp_freeargs();
Xstatic void		svctcp_destroy();
X
Xstatic struct xp_ops svctcp_op = {
X	svctcp_recv,
X	svctcp_stat,
X	svctcp_getargs,
X	svctcp_reply,
X	svctcp_freeargs,
X	svctcp_destroy
X};
X
X/*
X * Ops vector for TCP/IP rendezvous handler
X */
Xstatic bool_t		rendezvous_request();
Xstatic enum xprt_stat	rendezvous_stat();
X
Xstatic struct xp_ops svctcp_rendezvous_op = {
X	rendezvous_request,
X	rendezvous_stat,
X	abort,
X	abort,
X	abort,
X	svctcp_destroy
X};
X
Xstatic int readtcp(), writetcp();
Xstatic SVCXPRT *makefd_xprt();
X
Xstruct tcp_rendezvous { /* kept in xprt->xp_p1 */
X	u_int sendsize;
X	u_int recvsize;
X};
X
Xstruct tcp_conn {  /* kept in xprt->xp_p1 */
X	enum xprt_stat strm_stat;
X	u_long x_id;
X	XDR xdrs;
X	char verf_body[MAX_AUTH_BYTES];
X};
X
X/*
X * Usage:
X *	xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
X *
X * Creates, registers, and returns a (rpc) tcp based transporter.
X * Once *xprt is initialized, it is registered as a transporter
X * see (svc.h, xprt_register).  This routine returns
X * a NULL if a problem occurred.
X *
X * If sock<0 then a socket is created, else sock is used.
X * If the socket, sock is not bound to a port then svctcp_create
X * binds it to an arbitrary port.  The routine then starts a tcp
X * listener on the socket's associated port.  In any (successful) case,
X * xprt->xp_sock is the registered socket number and xprt->xp_port is the
X * associated port number.
X *
X * Since tcp streams do buffered io similar to stdio, the caller can specify
X * how big the send and receive buffers are via the second and third parms;
X * 0 => use the system default.
X */
XSVCXPRT *
Xsvctcp_create(sock, sendsize, recvsize)
X	register int sock;
X	u_int sendsize;
X	u_int recvsize;
X{
X	bool_t madesock = FALSE;
X	register SVCXPRT *xprt;
X	register struct tcp_rendezvous *r;
X	struct sockaddr_in addr;
X	int len = sizeof(struct sockaddr_in);
X
X	if (sock == RPC_ANYSOCK) {
X		if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
X			perror("svctcp_.c - udp socket creation problem");
X			return ((SVCXPRT *)NULL);
X		}
X		madesock = TRUE;
X	}
X	addr.sin_addr.s_addr = 0;
X	addr.sin_family = AF_INET;
X	addr.sin_port = 0;
X	(void)bind(sock, (struct sockaddr *)&addr, len);
X	if ((getsockname(sock, (caddr_t)&addr, &len) != 0)  ||
X	    (listen(sock, 2) != 0)) {
X		perror("svctcp_.c - cannot getsockname or listen");
X		if (madesock)
X		       (void)close(sock);
X		return ((SVCXPRT *)NULL);
X	}
X	r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
X	if (r == NULL) {
X		fprintf(stderr, "svctcp_create: out of memory\n");
X		return (NULL);
X	}
X	r->sendsize = sendsize;
X	r->recvsize = recvsize;
X	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
X	if (xprt == NULL) {
X		fprintf(stderr, "svctcp_create: out of memory\n");
X		return (NULL);
X	}
X	xprt->xp_p2 = NULL;
X	xprt->xp_p1 = (caddr_t)r;
X	xprt->xp_verf = _null_auth;
X	xprt->xp_ops = &svctcp_rendezvous_op;
X	xprt->xp_port = ntohs(addr.sin_port);
X	xprt->xp_sock = sock;
X	xprt_register(xprt);
X	return (xprt);
X}
X
X/*
X * Like svtcp_create(), except the routine takes any *open* UNIX file
X * descriptor as its first input.
X */
XSVCXPRT *
Xsvcfd_create(fd, sendsize, recvsize)
X	int fd;
X	u_int sendsize;
X	u_int recvsize;
X{
X
X	return (makefd_xprt(fd, sendsize, recvsize));
X}
X
Xstatic SVCXPRT *
Xmakefd_xprt(fd, sendsize, recvsize)
X	int fd;
X	u_int sendsize;
X	u_int recvsize;
X{
X	register SVCXPRT *xprt;
X	register struct tcp_conn *cd;
X 
X	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
X	if (xprt == (SVCXPRT *)NULL) {
X		fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
X		goto done;
X	}
X	cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
X	if (cd == (struct tcp_conn *)NULL) {
X		fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
X		mem_free(xprt, sizeof(SVCXPRT));
X		xprt = (SVCXPRT *)NULL;
X		goto done;
X	}
X	cd->strm_stat = XPRT_IDLE;
X	xdrrec_create(&(cd->xdrs), sendsize, recvsize,
X	    (caddr_t)xprt, readtcp, writetcp);
X	xprt->xp_p2 = NULL;
X	xprt->xp_p1 = (caddr_t)cd;
X	xprt->xp_verf.oa_base = cd->verf_body;
X	xprt->xp_addrlen = 0;
X	xprt->xp_ops = &svctcp_op;  /* truely deals with calls */
X	xprt->xp_port = 0;  /* this is a connection, not a rendezvouser */
X	xprt->xp_sock = fd;
X	xprt_register(xprt);
X    done:
X	return (xprt);
X}
X
Xstatic bool_t
Xrendezvous_request(xprt)
X	register SVCXPRT *xprt;
X{
X	int sock;
X	struct tcp_rendezvous *r;
X	struct sockaddr_in addr;
X	int len;
X
X	r = (struct tcp_rendezvous *)xprt->xp_p1;
X    again:
X	len = sizeof(struct sockaddr_in);
X	if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
X	    &len)) < 0) {
X		if (errno == EINTR)
X			goto again;
X	       return (FALSE);
X	}
X	/*
X	 * make a new transporter (re-uses xprt)
X	 */
X	xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
X	xprt->xp_raddr = addr;
X	xprt->xp_addrlen = len;
X	return (FALSE); /* there is never an rpc msg to be processed */
X}
X
Xstatic enum xprt_stat
Xrendezvous_stat()
X{
X
X	return (XPRT_IDLE);
X}
X
Xstatic void
Xsvctcp_destroy(xprt)
X	register SVCXPRT *xprt;
X{
X	register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
X
X	xprt_unregister(xprt);
X	(void)close(xprt->xp_sock);
X	if (xprt->xp_port != 0) {
X		/* a rendezvouser socket */
X		xprt->xp_port = 0;
X	} else {
X		/* an actual connection socket */
X		XDR_DESTROY(&(cd->xdrs));
X	}
X	mem_free((caddr_t)cd, sizeof(struct tcp_conn));
X	mem_free((caddr_t)xprt, sizeof(SVCXPRT));
X}
X
X/*
X * All read operations timeout after 35 seconds.
X * A timeout is fatal for the connection.
X */
Xstatic struct timeval wait_per_try = { 35, 0 };
X
X/*
X * reads data from the tcp conection.
X * any error is fatal and the connection is closed.
X * (And a read of zero bytes is a half closed stream => error.)
X */
Xstatic int
Xreadtcp(xprt, buf, len)
X	register SVCXPRT *xprt;
X	caddr_t buf;
X	register int len;
X{
X	register int sock = xprt->xp_sock;
X	register int mask = 1 << sock;
X	int readfds;
X
X	do {
X		readfds = mask;
X		if (select(32, &readfds, NULL, NULL, &wait_per_try) <= 0) {
X			if (errno == EINTR)
X				continue;
X			goto fatal_err;
X		}
X	} while (readfds != mask);
X	if ((len = read(sock, buf, len)) > 0)
X		return (len);
Xfatal_err:
X	((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
X	return (-1);
X}
X
X/*
X * writes data to the tcp connection.
X * Any error is fatal and the connection is closed.
X */
Xstatic int
Xwritetcp(xprt, buf, len)
X	register SVCXPRT *xprt;
X	caddr_t buf;
X	int len;
X{
X	register int i, cnt;
X
X	for (cnt = len; cnt > 0; cnt -= i, buf += i) {
X		if ((i = write(xprt->xp_sock, buf, cnt)) < 0) {
X			((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
X			    XPRT_DIED;
X			return (-1);
X		}
X	}
X	return (len);
X}
X
Xstatic enum xprt_stat
Xsvctcp_stat(xprt)
X	SVCXPRT *xprt;
X{
X	register struct tcp_conn *cd =
X	    (struct tcp_conn *)(xprt->xp_p1);
X
X	if (cd->strm_stat == XPRT_DIED)
X		return (XPRT_DIED);
X	if (! xdrrec_eof(&(cd->xdrs)))
X		return (XPRT_MOREREQS);
X	return (XPRT_IDLE);
X}
X
Xstatic bool_t
Xsvctcp_recv(xprt, msg)
X	SVCXPRT *xprt;
X	register struct rpc_msg *msg;
X{
X	register struct tcp_conn *cd =
X	    (struct tcp_conn *)(xprt->xp_p1);
X	register XDR *xdrs = &(cd->xdrs);
X
X	xdrs->x_op = XDR_DECODE;
X	(void)xdrrec_skiprecord(xdrs);
X	if (xdr_callmsg(xdrs, msg)) {
X		cd->x_id = msg->rm_xid;
X		return (TRUE);
X	}
X	return (FALSE);
X}
X
Xstatic bool_t
Xsvctcp_getargs(xprt, xdr_args, args_ptr)
X	SVCXPRT *xprt;
X	xdrproc_t xdr_args;
X	caddr_t args_ptr;
X{
X
X	return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
X}
X
Xstatic bool_t
Xsvctcp_freeargs(xprt, xdr_args, args_ptr)
X	SVCXPRT *xprt;
X	xdrproc_t xdr_args;
X	caddr_t args_ptr;
X{
X	register XDR *xdrs =
X	    &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
X
X	xdrs->x_op = XDR_FREE;
X	return ((*xdr_args)(xdrs, args_ptr));
X}
X
Xstatic bool_t
Xsvctcp_reply(xprt, msg)
X	SVCXPRT *xprt;
X	register struct rpc_msg *msg;
X{
X	register struct tcp_conn *cd =
X	    (struct tcp_conn *)(xprt->xp_p1);
X	register XDR *xdrs = &(cd->xdrs);
X	register bool_t stat;
X
X	xdrs->x_op = XDR_ENCODE;
X	msg->rm_xid = cd->x_id;
X	stat = xdr_replymsg(xdrs, msg);
X	(void)xdrrec_endofrecord(xdrs, TRUE);
X	return (stat);
X}
SHAR_EOF
if test 9984 -ne "`wc -c < 'rpc/rpclib/svc_tcp.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/svc_tcp.c'" '(should have been 9984 characters)'
fi
chmod 444 'rpc/rpclib/svc_tcp.c'
fi
echo shar: "extracting 'rpc/rpclib/svc_udp.c'" '(6578 characters)'
if test -f 'rpc/rpclib/svc_udp.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/svc_udp.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc_udp.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[] = "@(#)svc_udp.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * svc_udp.c,
X * Server side for UDP/IP based RPC.  (Does some caching in the hopes of
X * achieving execute-at-most-once semantics.)
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include <netinet/in.h>
X#include <sys/socket.h>
X#include <errno.h>
X#include "xdr.h"
X#include "auth.h"
X#include "clnt.h"
X#include "rpc_msg.h"
X#include "svc.h"
X
Xchar *mem_alloc();
X
X#define rpc_buffer(xprt) ((xprt)->xp_p1)
X#define MAX(a, b)     ((a > b) ? a : b)
X
Xstatic bool_t		svcudp_recv();
Xstatic bool_t		svcudp_reply();
Xstatic enum xprt_stat	svcudp_stat();
Xstatic bool_t		svcudp_getargs();
Xstatic bool_t		svcudp_freeargs();
Xstatic void		svcudp_destroy();
X
Xstatic struct xp_ops svcudp_op = {
X	svcudp_recv,
X	svcudp_stat,
X	svcudp_getargs,
X	svcudp_reply,
X	svcudp_freeargs,
X	svcudp_destroy
X};
X
Xextern int errno;
X
X/*
X * kept in xprt->xp_p2
X */
Xstruct svcudp_data {
X	u_int   su_iosz;	/* byte size of send.recv buffer */
X	u_long	su_xid;		/* transaction id */
X	XDR	su_xdrs;	/* XDR handle */
X	char	su_verfbody[MAX_AUTH_BYTES];	/* verifier body */
X};
X#define	su_data(xprt)	((struct svcudp_data *)(xprt->xp_p2))
X
X/*
X * Usage:
X *	xprt = svcudp_create(sock);
X *
X * If sock<0 then a socket is created, else sock is used.
X * If the socket, sock is not bound to a port then svcudp_create
X * binds it to an arbitrary port.  In any (successful) case,
X * xprt->xp_sock is the registered socket number and xprt->xp_port is the
X * associated port number.
X * Once *xprt is initialized, it is registered as a transporter;
X * see (svc.h, xprt_register).
X * The routines returns NULL if a problem occurred.
X */
XSVCXPRT *
Xsvcudp_bufcreate(sock, sendsz, recvsz)
X	register int sock;
X	u_int sendsz, recvsz;
X{
X	bool_t madesock = FALSE;
X	register SVCXPRT *xprt;
X	register struct svcudp_data *su;
X	struct sockaddr_in addr;
X	int len = sizeof(struct sockaddr_in);
X
X	if (sock == RPC_ANYSOCK) {
X		if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
X			perror("svcudp_create: socket creation problem");
X			return ((SVCXPRT *)NULL);
X		}
X		madesock = TRUE;
X	}
X	addr.sin_addr.s_addr = 0;
X	addr.sin_family = AF_INET;
X	addr.sin_port = 0;
X	(void)bind(sock, (struct sockaddr *)&addr, len);
X	if (getsockname(sock, (caddr_t)&addr, &len) != 0) {
X		perror("svcudp_create - cannot getsockname");
X		if (madesock)
X			(void)close(sock);
X		return ((SVCXPRT *)NULL);
X	}
X	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
X	if (xprt == NULL) {
X		fprintf(stderr, "svcudp_create: out of memory\n");
X		return (NULL);
X	}
X	su = (struct svcudp_data *)mem_alloc(sizeof(*su));
X	if (su == NULL) {
X		fprintf(stderr, "svcudp_create: out of memory\n");
X		return (NULL);
X	}
X	su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
X	if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
X		fprintf(stderr, "svcudp_create: out of memory\n");
X		return (NULL);
X	}
X	xdrmem_create(
X	    &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
X	xprt->xp_p2 = (caddr_t)su;
X	xprt->xp_verf.oa_base = su->su_verfbody;
X	xprt->xp_ops = &svcudp_op;
X	xprt->xp_port = ntohs(addr.sin_port);
X	xprt->xp_sock = sock;
X	xprt_register(xprt);
X	return (xprt);
X}
X
XSVCXPRT *
Xsvcudp_create(sock, sendsz, recvsz)
X	int sock;
X{
X
X	return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
X}
X 
Xstatic enum xprt_stat
Xsvcudp_stat(xprt)
X	SVCXPRT *xprt;
X{
X
X	return (XPRT_IDLE); 
X}
X
Xstatic bool_t
Xsvcudp_recv(xprt, msg)
X	register SVCXPRT *xprt;
X	struct rpc_msg *msg;
X{
X	register struct svcudp_data *su = su_data(xprt);
X	register XDR *xdrs = &(su->su_xdrs);
X	register int rlen;
X
X    again:
X	xprt->xp_addrlen = sizeof(struct sockaddr_in);
X	rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), su->su_iosz,
X	    0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
X	if (rlen == -1 && errno == EINTR)
X		goto again;
X	if (rlen < 4*sizeof(u_long))
X		return (FALSE);
X	xdrs->x_op = XDR_DECODE;
X	XDR_SETPOS(xdrs, 0);
X	if (! xdr_callmsg(xdrs, msg))
X		return (FALSE);
X	su->su_xid = msg->rm_xid;
X	return (TRUE);
X}
X
Xstatic bool_t
Xsvcudp_reply(xprt, msg)
X	register SVCXPRT *xprt; 
X	struct rpc_msg *msg; 
X{
X	register struct svcudp_data *su = su_data(xprt);
X	register XDR *xdrs = &(su->su_xdrs);
X	register int slen;
X	register bool_t stat = FALSE;
X
X	xdrs->x_op = XDR_ENCODE;
X	XDR_SETPOS(xdrs, 0);
X	msg->rm_xid = su->su_xid;
X	if (xdr_replymsg(xdrs, msg)) {
X		slen = (int)XDR_GETPOS(xdrs);
X		if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
X		    (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
X		    == slen)
X			stat = TRUE;
X	}
X	return (stat);
X}
X
Xstatic bool_t
Xsvcudp_getargs(xprt, xdr_args, args_ptr)
X	SVCXPRT *xprt;
X	xdrproc_t xdr_args;
X	caddr_t args_ptr;
X{
X
X	return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
X}
X
Xstatic bool_t
Xsvcudp_freeargs(xprt, xdr_args, args_ptr)
X	SVCXPRT *xprt;
X	xdrproc_t xdr_args;
X	caddr_t args_ptr;
X{
X	register XDR *xdrs = &(su_data(xprt)->su_xdrs);
X
X	xdrs->x_op = XDR_FREE;
X	return ((*xdr_args)(xdrs, args_ptr));
X}
X
Xstatic void
Xsvcudp_destroy(xprt)
X	register SVCXPRT *xprt;
X{
X	register struct svcudp_data *su = su_data(xprt);
X
X	xprt_unregister(xprt);
X	(void)close(xprt->xp_sock);
X	XDR_DESTROY(&(su->su_xdrs));
X	mem_free(rpc_buffer(xprt), su->su_iosz);
X	mem_free((caddr_t)su, sizeof(struct svcudp_data));
X	mem_free((caddr_t)xprt, sizeof(SVCXPRT));
X}
SHAR_EOF
if test 6578 -ne "`wc -c < 'rpc/rpclib/svc_udp.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/svc_udp.c'" '(should have been 6578 characters)'
fi
chmod 444 'rpc/rpclib/svc_udp.c'
fi
echo shar: "extracting 'rpc/rpclib/xdr.c'" '(10032 characters)'
if test -f 'rpc/rpclib/xdr.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/xdr.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr.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.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr.c, Generic XDR routines implementation.
X *
X * Copyright (C) 1984, Sun Microsystems, Inc.
X *
X * These are the "generic" xdr routines used to serialize and 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>
Xchar *malloc();
X
X/*
X * constants specific to the xdr "protocol"
X */
X#define XDR_FALSE	((long) 0)
X#define XDR_TRUE	((long) 1)
X#define LASTUNSIGNED	((u_int) 0-1)
X
X/*
X * for unit alignment
X */
Xstatic char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
X
X
X/*
X * XDR nothing
X */
Xbool_t
Xxdr_void(/* xdrs, addr */)
X	/* XDR *xdrs; */
X	/* caddr_t addr; */
X{
X
X	return (TRUE);
X}
X
X/*
X * XDR integers
X */
Xbool_t
Xxdr_int(xdrs, ip)
X	XDR *xdrs;
X	int *ip;
X{
X
X#ifdef lint
X	(void) (xdr_short(xdrs, (short *)ip));
X	return (xdr_long(xdrs, (long *)ip));
X#else
X	if (sizeof (int) == sizeof (long)) {
X		return (xdr_long(xdrs, (long *)ip));
X	} else {
X		return (xdr_short(xdrs, (short *)ip));
X	}
X#endif
X}
X
X/*
X * XDR unsigned integers
X */
Xbool_t
Xxdr_u_int(xdrs, up)
X	XDR *xdrs;
X	u_int *up;
X{
X
X#ifdef lint
X	(void) (xdr_short(xdrs, (short *)up));
X	return (xdr_u_long(xdrs, (u_long *)up));
X#else
X	if (sizeof (u_int) == sizeof (u_long)) {
X		return (xdr_u_long(xdrs, (u_long *)up));
X	} else {
X		return (xdr_short(xdrs, (short *)up));
X	}
X#endif
X}
X
X/*
X * XDR long integers
X * same as xdr_u_long - open coded to save a proc call!
X */
Xbool_t
Xxdr_long(xdrs, lp)
X	register XDR *xdrs;
X	long *lp;
X{
X
X	if (xdrs->x_op == XDR_ENCODE)
X		return (XDR_PUTLONG(xdrs, lp));
X
X	if (xdrs->x_op == XDR_DECODE)
X		return (XDR_GETLONG(xdrs, lp));
X
X	if (xdrs->x_op == XDR_FREE)
X		return (TRUE);
X
X	return (FALSE);
X}
X
X/*
X * XDR unsigned long integers
X * same as xdr_long - open coded to save a proc call!
X */
Xbool_t
Xxdr_u_long(xdrs, ulp)
X	register XDR *xdrs;
X	u_long *ulp;
X{
X
X	if (xdrs->x_op == XDR_DECODE)
X		return (XDR_GETLONG(xdrs, (long *)ulp));
X	if (xdrs->x_op == XDR_ENCODE)
X		return (XDR_PUTLONG(xdrs, (long *)ulp));
X	if (xdrs->x_op == XDR_FREE)
X		return (TRUE);
X	return (FALSE);
X}
X
X/*
X * XDR short integers
X */
Xbool_t
Xxdr_short(xdrs, sp)
X	register XDR *xdrs;
X	short *sp;
X{
X	long l;
X
X	switch (xdrs->x_op) {
X
X	case XDR_ENCODE:
X		l = (long) *sp;
X		return (XDR_PUTLONG(xdrs, &l));
X
X	case XDR_DECODE:
X		if (!XDR_GETLONG(xdrs, &l)) {
X			return (FALSE);
X		}
X		*sp = (short) l;
X		return (TRUE);
X
X	case XDR_FREE:
X		return (TRUE);
X	}
X	return (FALSE);
X}
X
X/*
X * XDR unsigned short integers
X */
Xbool_t
Xxdr_u_short(xdrs, usp)
X	register XDR *xdrs;
X	u_short *usp;
X{
X	u_long l;
X
X	switch (xdrs->x_op) {
X
X	case XDR_ENCODE:
X		l = (u_long) *usp;
X		return (XDR_PUTLONG(xdrs, &l));
X
X	case XDR_DECODE:
X		if (!XDR_GETLONG(xdrs, &l)) {
X			return (FALSE);
X		}
X		*usp = (u_short) l;
X		return (TRUE);
X
X	case XDR_FREE:
X		return (TRUE);
X	}
X	return (FALSE);
X}
X
X
X/*
X * XDR booleans
X */
Xbool_t
Xxdr_bool(xdrs, bp)
X	register XDR *xdrs;
X	bool_t *bp;
X{
X	long lb;
X
X	switch (xdrs->x_op) {
X
X	case XDR_ENCODE:
X		lb = *bp ? XDR_TRUE : XDR_FALSE;
X		return (XDR_PUTLONG(xdrs, &lb));
X
X	case XDR_DECODE:
X		if (!XDR_GETLONG(xdrs, &lb)) {
X			return (FALSE);
X		}
X		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
X		return (TRUE);
X
X	case XDR_FREE:
X		return (TRUE);
X	}
X	return (FALSE);
X}
X
X/*
X * XDR enumerations
X */
Xbool_t
Xxdr_enum(xdrs, ep)
X	XDR *xdrs;
X	enum_t *ep;
X{
X	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
X
X	/*
X	 * enums are treated as ints
X	 */
X#ifdef lint
X	(void) (xdr_short(xdrs, (short *)ep));
X	return (xdr_long(xdrs, (long *)ep));
X#else
X	if (sizeof (enum sizecheck) == sizeof (long)) {
X		return (xdr_long(xdrs, (long *)ep));
X	} else if (sizeof (enum sizecheck) == sizeof (short)) {
X		return (xdr_short(xdrs, (short *)ep));
X	} else {
X		return (FALSE);
X	}
X#endif
X}
X
X/*
X * XDR opaque data
X * Allows the specification of a fixed size sequence of opaque bytes.
X * cp points to the opaque object and cnt gives the byte length.
X */
Xbool_t
Xxdr_opaque(xdrs, cp, cnt)
X	register XDR *xdrs;
X	caddr_t cp;
X	register u_int cnt;
X{
X	register u_int rndup;
X	static crud[BYTES_PER_XDR_UNIT];
X
X	/*
X	 * if no data we are done
X	 */
X	if (cnt == 0)
X		return (TRUE);
X
X	/*
X	 * round byte count to full xdr units
X	 */
X	rndup = cnt % BYTES_PER_XDR_UNIT;
X	if (rndup > 0)
X		rndup = BYTES_PER_XDR_UNIT - rndup;
X
X	if (xdrs->x_op == XDR_DECODE) {
X		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
X			return (FALSE);
X		}
X		if (rndup == 0)
X			return (TRUE);
X		return (XDR_GETBYTES(xdrs, crud, rndup));
X	}
X
X	if (xdrs->x_op == XDR_ENCODE) {
X		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
X			return (FALSE);
X		}
X		if (rndup == 0)
X			return (TRUE);
X		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
X	}
X
X	if (xdrs->x_op == XDR_FREE) {
X		return (TRUE);
X	}
X
X	return (FALSE);
X}
X
X/*
X * XDR counted bytes
X * *cpp is a pointer to the bytes, *sizep is the count.
X * If *cpp is NULL maxsize bytes are allocated
X */
Xbool_t
Xxdr_bytes(xdrs, cpp, sizep, maxsize)
X	register XDR *xdrs;
X	char **cpp;
X	register u_int *sizep;
X	u_int maxsize;
X{
X	register char *sp = *cpp;  /* sp is the actual string pointer */
X	register u_int nodesize;
X
X	/*
X	 * first deal with the length since xdr bytes are counted
X	 */
X	if (! xdr_u_int(xdrs, sizep)) {
X		return (FALSE);
X	}
X	nodesize = *sizep;
X	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
X		return (FALSE);
X	}
X
X	/*
X	 * now deal with the actual bytes
X	 */
X	switch (xdrs->x_op) {
X
X	case XDR_DECODE:
X		if (sp == NULL) {
X			*cpp = sp = (char *)mem_alloc(nodesize);
X		}
X		if (sp == NULL) {
X			fprintf(stderr, "xdr_bytes: out of memory\n");
X			return (FALSE);
X		}
X		/* fall into ... */
X
X	case XDR_ENCODE:
X		return (xdr_opaque(xdrs, sp, nodesize));
X
X	case XDR_FREE:
X		if (sp != NULL) {
X			mem_free(sp, nodesize);
X			*cpp = NULL;
X		}
X		return (TRUE);
X	}
X	return (FALSE);
X}
X
X/*
X * XDR a descriminated union
X * Support routine for discriminated unions.
X * You create an array of xdrdiscrim structures, terminated with
X * an entry with a null procedure pointer.  The routine gets
X * the discriminant value and then searches the array of xdrdiscrims
X * looking for that value.  It calls the procedure given in the xdrdiscrim
X * to handle the discriminant.  If there is no specific routine a default
X * routine may be called.
X * If there is no specific or default routine an error is returned.
X */
Xbool_t
Xxdr_union(xdrs, dscmp, unp, choices, dfault)
X	register XDR *xdrs;
X	enum_t *dscmp;		/* enum to decide which arm to work on */
X	caddr_t unp;		/* the union itself */
X	struct xdr_discrim *choices;	/* [value, xdr proc] for each arm */
X	xdrproc_t dfault;	/* default xdr routine */
X{
X	register enum_t dscm;
X
X	/*
X	 * we deal with the discriminator;  it's an enum
X	 */
X	if (! xdr_enum(xdrs, dscmp)) {
X		return (FALSE);
X	}
X	dscm = *dscmp;
X
X	/*
X	 * search choices for a value that matches the discriminator.
X	 * if we find one, execute the xdr routine for that value.
X	 */
X	for (; choices->proc != NULL_xdrproc_t; choices++) {
X		if (choices->value == dscm)
X			return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
X	}
X
X	/*
X	 * no match - execute the default xdr routine if there is one
X	 */
X	return ((dfault == NULL_xdrproc_t) ? FALSE :
X	    (*dfault)(xdrs, unp, LASTUNSIGNED));
X}
X
X
X/*
X * Non-portable xdr primitives.
X * Care should be taken when moving these routines to new architectures.
X */
X
X
X/*
X * XDR null terminated ASCII strings
X * xdr_string deals with "C strings" - arrays of bytes that are
X * terminated by a NULL character.  The parameter cpp references a
X * pointer to storage; If the pointer is null, then the necessary
X * storage is allocated.  The last parameter is the max allowed length
X * of the string as specified by a protocol.
X */
Xbool_t
Xxdr_string(xdrs, cpp, maxsize)
X	register XDR *xdrs;
X	char **cpp;
X	u_int maxsize;
X{
X	register char *sp = *cpp;  /* sp is the actual string pointer */
X	u_int size;
X	u_int nodesize;
X
X	/*
X	 * first deal with the length since xdr strings are counted-strings
X	 */
X	if ((xdrs->x_op) != XDR_DECODE)
X		size = strlen(sp);
X	if (! xdr_u_int(xdrs, &size)) {
X		return (FALSE);
X	}
X	if (size > maxsize) {
X		return (FALSE);
X	}
X	nodesize = size + 1;
X
X	/*
X	 * now deal with the actual bytes
X	 */
X	switch (xdrs->x_op) {
X
X	case XDR_DECODE:
X		if (sp == NULL)
X			*cpp = sp = (char *)mem_alloc(nodesize);
X		if (sp == NULL) {
X			fprintf(stderr, "xdr_string: out of memory\n");
X			return (FALSE);
X		}
X		sp[size] = 0;
X		/* fall into ... */
X
X	case XDR_ENCODE:
X		return (xdr_opaque(xdrs, sp, size));
X
X	case XDR_FREE:
X		if (sp != NULL) {
X			mem_free(sp, nodesize);
X			*cpp = NULL;
X		}
X		return (TRUE);
X	}
X	return (FALSE);
X}
X
X/* 
X * Wrapper for xdr_string that can be called directly from 
X * routines like clnt_call
X */
Xbool_t
Xxdr_wrapstring(xdrs, cpp)
X	XDR *xdrs;
X	char **cpp;
X{
X	if (xdr_string(xdrs, cpp, BUFSIZ)) {
X		return(TRUE);
X	}
X	return(FALSE);
X}
SHAR_EOF
if test 10032 -ne "`wc -c < 'rpc/rpclib/xdr.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/xdr.c'" '(should have been 10032 characters)'
fi
chmod 444 'rpc/rpclib/xdr.c'
fi
echo shar: "extracting 'rpc/rpclib/xdr_array.c'" '(3497 characters)'
if test -f 'rpc/rpclib/xdr_array.c'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/xdr_array.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_array.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_array.c 1.1 86/02/03 Copyr 1984 Sun Micro";
X#endif
X
X/*
X * xdr_array.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 * arrays.  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>
Xchar *mem_alloc();
X#define LASTUNSIGNED	((u_int)0-1)
X
X
X/*
X * XDR an array of arbitrary elements
X * *addrp is a pointer to the array, *sizep is the number of elements.
X * If addrp is NULL (*sizep * elsize) bytes are allocated.
X * elsize is the size (in bytes) of each element, and elproc is the
X * xdr procedure to call to handle each element of the array.
X */
Xbool_t
Xxdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
X	register XDR *xdrs;
X	caddr_t *addrp;		/* array pointer */
X	u_int *sizep;		/* number of elements */
X	u_int maxsize;		/* max numberof elements */
X	u_int elsize;		/* size in bytes of each element */
X	xdrproc_t elproc;	/* xdr routine to handle each element */
X{
X	register u_int i;
X	register caddr_t target = *addrp;
X	register u_int c;  /* the actual element count */
X	register bool_t stat = TRUE;
X	register int nodesize;
X
X	/* like strings, arrays are really counted arrays */
X	if (! xdr_u_int(xdrs, sizep)) {
X		return (FALSE);
X	}
X	c = *sizep;
X	if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
X		return (FALSE);
X	}
X	nodesize = c * elsize;
X
X	/*
X	 * if we are deserializing, we may need to allocate an array.
X	 * We also save time by checking for a null array if we are freeing.
X	 */
X	if (target == NULL)
X		switch (xdrs->x_op) {
X		case XDR_DECODE:
X			if (c == 0)
X				return (TRUE);
X			*addrp = target = mem_alloc(nodesize);
X			if (target == NULL) {
X				fprintf(stderr, "xdr_array: out of memory\n");
X				return (FALSE);
X			}
X			bzero(target, (u_int)nodesize);
X			break;
X
X		case XDR_FREE:
X			return (TRUE);
X	}
X	
X	/*
X	 * now we xdr each element of array
X	 */
X	for (i = 0; (i < c) && stat; i++) {
X		stat = (*elproc)(xdrs, target, LASTUNSIGNED);
X		target += elsize;
X	}
X
X	/*
X	 * the array may need freeing
X	 */
X	if (xdrs->x_op == XDR_FREE) {
X		mem_free(*addrp, nodesize);
X		*addrp = NULL;
X	}
X	return (stat);
X}
SHAR_EOF
if test 3497 -ne "`wc -c < 'rpc/rpclib/xdr_array.c'`"
then
	echo shar: "error transmitting 'rpc/rpclib/xdr_array.c'" '(should have been 3497 characters)'
fi
chmod 444 'rpc/rpclib/xdr_array.c'
fi
exit 0
#	End of shell archive