Subject: v06i096: Sun RPC Source (rpc2), Part08/11 Newsgroups: mod.sources Approved: rs@mirror.UUCP 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 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 X#include "types.h" X#include X#include 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 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 X#include X#include X#include X#include 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 X#include "types.h" X#include X#include X#include X#include 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 X#include "types.h" X#include X#include X#include 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 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 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