[mod.sources] v06i089: Sun RPC Source

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

Submitted by: sun!ferne!marks (Mark Stein)
Mod.sources: Volume 6, Issue 89
Archive-name: rpc2/Part01

[  All I did was very that the shar files were complete. --r$  ]

Sun RPC source (part 1 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/README
#	rpc/Files
#	rpc/doc/README
#	rpc/doc/rpc.spec
#	rpc/doc/runoff
#	rpc/doc/runoff.troff
#	rpc/doc/sunhead.ms
#	rpc/tools/rpcinfo.8
#	rpc/tools/rpcinfo.c
#	rpc/toys/Makefile
#	rpc/toys/sort_prot.c
#	rpc/toys/sort_prot.h
#	rpc/toys/sort_service.c
#	rpc/toys/sortit.c
#	rpc/rpclib/Makefile
# This archive created: Mon Jul 14 16:54:49 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/README'" '(1555 characters)'
if test -f 'rpc/README'
then
	echo shar: "will not over-write existing file 'rpc/README'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/README'
XJuly 14, 1986
X
XThis directory contains the public domain Sun rpc/xdr code.  There
Xare several subdirectories:
X
X	doc	Rpc/xdr documentation in .ms format.  See doc/README
X		for more information.
X
X	rpclib	The rpc/xdr library source code.  At Sun, RPC is part
X		of the C library (libc.a).  This makefile will make a
X		library called rpclib.
X
X	tools	Two source files and their manual pages.
X
X		portmap.c is the source to /etc/portmap, the rpc
X		daemon which must be started by root before any other
X		rpc servers or clients.
X
X		rpcinfo.c dumps the information that portmap keeps.
X		At Sun, it lives in /usr/etc/rpcinfo.
X
X		Both source files assume the the rpc dot-h files
X		have been installed in /usr/include.
X
X	toys	Source to a toy sort service which can be used to test
X		out the rpc/xdr library.
X
X	rpcgen	The RPC protocol compiler.  See the README file.
X
X
XThe rpc/xdr library was built with a post-1.1 Sun release of the
Xcompiler.  Old compilers complain about valid C.  You can make old
Xcompilers happy by changing some voids to ints.  However, the fix to
Xthe 4.2 VAX compiler is as follows:
X
Xtrees.c:
X
Xremoved spurious type mismatch errors in expressions involving
Xpointers to void functions, e.g., void foo(){...} void (*f)() = foo;
X
X1250c1264,1266
X< 		else if( mt12 == 0 ) break;
X---
X> 		/* if right is TVOID and looks like a CALL, is not ok */
X> 		else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL))
X> 			break;
X
X
XNetwork Services Consulting
XMS 2-33
XSun Microsystems, Inc
X2550 Garcia Avenue
XMountain View, CA  94043
SHAR_EOF
if test 1555 -ne "`wc -c < 'rpc/README'`"
then
	echo shar: "error transmitting 'rpc/README'" '(should have been 1555 characters)'
fi
chmod 644 'rpc/README'
fi
echo shar: "extracting 'rpc/Files'" '(1688 characters)'
if test -f 'rpc/Files'
then
	echo shar: "will not over-write existing file 'rpc/Files'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/Files'
Xrpc/README
Xrpc/Files
X
Xrpc/doc/README
Xrpc/doc/rpc.spec
Xrpc/doc/rpc.prog.p1
Xrpc/doc/rpc.prog.p2
Xrpc/doc/xdr.spec.p2
Xrpc/doc/xdr.spec.p1
Xrpc/doc/runoff
Xrpc/doc/runoff.troff
Xrpc/doc/sunhead.ms
X
Xrpc/tools/rpcinfo.8
Xrpc/tools/rpcinfo.c
Xrpc/tools/portmap.8c
Xrpc/tools/portmap.c
X
Xrpc/toys/Makefile
Xrpc/toys/sort_prot.c
Xrpc/toys/sort_prot.h
Xrpc/toys/sort_service.c
Xrpc/toys/sortit.c
X
Xrpc/rpclib/Makefile
Xrpc/rpclib/profiled
Xrpc/rpclib/auth.h
Xrpc/rpclib/auth_unix.h
Xrpc/rpclib/clnt.h
Xrpc/rpclib/pmap_clnt.h
Xrpc/rpclib/pmap_prot.h
Xrpc/rpclib/rpc.h
Xrpc/rpclib/rpc_msg.h
Xrpc/rpclib/svc.h
Xrpc/rpclib/svc_auth.h
Xrpc/rpclib/types.h
Xrpc/rpclib/xdr.h
Xrpc/rpclib/auth_none.c
Xrpc/rpclib/auth_unix.c
Xrpc/rpclib/authunix_prot.c
Xrpc/rpclib/clnt_perror.c
Xrpc/rpclib/clnt_raw.c
Xrpc/rpclib/clnt_simple.c
Xrpc/rpclib/clnt_tcp.c
Xrpc/rpclib/clnt_udp.c
Xrpc/rpclib/pmap_clnt.c
Xrpc/rpclib/pmap_getmaps.c
Xrpc/rpclib/pmap_getport.c
Xrpc/rpclib/pmap_prot.c
Xrpc/rpclib/pmap_rmt.c
Xrpc/rpclib/rpc_prot.c
Xrpc/rpclib/svc.c
Xrpc/rpclib/svc_auth.c
Xrpc/rpclib/svc_auth_unix.c
Xrpc/rpclib/svc_raw.c
Xrpc/rpclib/svc_simple.c
Xrpc/rpclib/svc_tcp.c
Xrpc/rpclib/svc_udp.c
Xrpc/rpclib/xdr.c
Xrpc/rpclib/xdr_array.c
Xrpc/rpclib/xdr_float.c
Xrpc/rpclib/xdr_mem.c
Xrpc/rpclib/xdr_rec.c
Xrpc/rpclib/xdr_reference.c
Xrpc/rpclib/xdr_stdio.c
X
Xrpc/rpcgen/Makefile
Xrpc/rpcgen/README
Xrpc/rpcgen/rpc_cout.c
Xrpc/rpcgen/rpc_hout.c
Xrpc/rpcgen/rpc_main.c
Xrpc/rpcgen/rpc_parse.c
Xrpc/rpcgen/rpc_parse.h
Xrpc/rpcgen/rpc_scan.c
Xrpc/rpcgen/rpc_scan.h
Xrpc/rpcgen/rpc_svcout.c
Xrpc/rpcgen/rpc_util.c
Xrpc/rpcgen/rpc_util.h
Xrpc/rpcgen/rpcgen.1
Xrpc/rpcgen/xdr_update.c
X
Xrpc/rpcgen/test/Makefile
Xrpc/rpcgen/test/demo_clnt.c
Xrpc/rpcgen/test/demo_proc.c
Xrpc/rpcgen/test/demo_xdr.x
SHAR_EOF
if test 1688 -ne "`wc -c < 'rpc/Files'`"
then
	echo shar: "error transmitting 'rpc/Files'" '(should have been 1688 characters)'
fi
chmod 664 'rpc/Files'
fi
echo shar: "extracting 'rpc/doc/README'" '(341 characters)'
if test -f 'rpc/doc/README'
then
	echo shar: "will not over-write existing file 'rpc/doc/README'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/doc/README'
XThis directory contains three documents of interest:
X
X	rpc.prog: RPC Programming Guide
X	rpc.spec: RPC Protocol Specification
X	xdr.spec: XDR Specification
X
XFormatting procedures for nroff are in the shell script runoff.
XRunoff.troff uses troff, and assumes you have ditroff and pic.  Some
Xextenstions to -ms are in the macro file sunhead.ms.
SHAR_EOF
if test 341 -ne "`wc -c < 'rpc/doc/README'`"
then
	echo shar: "error transmitting 'rpc/doc/README'" '(should have been 341 characters)'
fi
chmod 444 'rpc/doc/README'
fi
echo shar: "extracting 'rpc/doc/rpc.spec'" '(23693 characters)'
if test -f 'rpc/doc/rpc.spec'
then
	echo shar: "will not over-write existing file 'rpc/doc/rpc.spec'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/doc/rpc.spec'
X.PL RIGHT
X.TL
XRemote Procedure Call
X.br
XProtocol Specification
X.bp
X.NH
XIntroduction
X.LP
XThis document specifies a message protocol used in implementing
XSun's Remote Procedure Call (RPC) package.
XThe message protocol is specified with the
XeXternal Data Representation (XDR) language.
X.LP
XThis document assumes that the reader is familiar with both RPC and XDR.
XIt does not attempt to justify RPC or its uses.
XAlso, the casual user of RPC does not need to be
Xfamiliar with the information in this document.
X.NH 2
XTerminology
X.LP
XThe document discusses servers, services,
Xprograms, procedures, clients and versions.
XA server is a machine where some number
Xof network services are implemented.
XA service is a collection of one or more remote programs.
XA remote program implements one or more remote procedures;
Xthe procedures, their parameters and results are documented
Xin the specific program's protocol specification.
XNetwork clients are pieces of software that initiate
Xremote procedure calls to services.
XA server may support more than one version of a remote program
Xin order to be forward compatible with changing protocols.
X.LP
XFor example, a network file service may be composed of two programs.
XOne program may deal with high level applications
Xsuch as file system access control and locking.
XThe other may deal with low-level file I/O,
Xand have procedures like ``read'' and ``write''.
XA client machine of the network file service would call
Xthe procedures associated with the two programs of the service
Xon behalf of some user on the client machine.
X.NH 2
XThe RPC Model
X.LP
XThe remote procedure call model is similar to
Xthe local procedure call model.
XIn the local case, the caller places arguments to a procedure
Xin some well-specified location (such as a result register).
XIt then transfers control to the procedure,
Xand eventually gains back control.
XAt that point, the results of the procedure
Xare extracted from the well-specified location,
Xand the caller continues execution.
X.LP
XThe remote procedure call is similar,
Xexcept that one thread of control winds through two processes \(em
Xone is the caller's process,
Xthe other is a server's process.
XThat is, the caller process sends a call message
Xto the server process and waits (blocks) for a reply message.
XThe call message contains the procedure's parameters,
Xamong other things.
XThe reply message contains the procedure's results,
Xamong other things.
XOnce the reply message is received,
Xthe results of the procedure are extracted,
Xand caller's execution is resumed.
X.LP
XOn the server side,
Xa process is dormant awaiting the arrival of a call message.
XWhen one arrives the server process extracts the procedure's parameters,
Xcomputes the results, sends a reply message,
Xand then awaits the next call message.
XNote that in this model,
Xonly one of the two processes is active at any given time.
XThat is, the RPC protocol does not explicitly support
Xmulti-threading of caller or server processes.
X.NH 2
XTransports and Semantics
X.LP
XThe RPC protocol is independent of transport protocols.
XThat is, RPC does not care how a message is passed
Xfrom one process to another.
XThe protocol only deals with
Xthe specification and interpretation of messages.
X.LP
XBecause of transport independence,
Xthe RPC protocol does not attach specific semantics
Xto the remote procedures or their execution.
XSome semantics can be inferred from
X(but should be explicitly specified by)
Xthe underlying transport protocol.
XFor example, RPC message passing using UDP/IP is unreliable.
XThus, if the caller retransmits call messages after short time-outs,
Xthe only thing he can infer from no reply message
Xis that the remote procedure was executed
Xzero or more times (and from a reply message, one or more times).
XOn the other hand, RPC message passing using TCP/IP is reliable.
XNo reply message means that the remote procedure was executed at most once,
Xwhereas a reply message means that the remote procedure was exactly once.
X(Note:
XAt Sun, RPC is currently implemented
Xon top of TCP/IP and UDP/IP transports.)
X.NH 2
XBinding and Rendezvous Independence
X.LP
XThe act of binding a client to a service is
X.I not
Xpart of the remote procedure call specification.
XThis important and necessary function
Xis left up to some higher level software.
X.LP
XImplementors should think of the RPC protocol as the
Xjump-subroutine instruction (``JSR'') of a network;
Xthe loader (binder) makes JSR useful,
Xand the loader itself uses JSR to accomplish its task.
XLikewise, the network makes RPC useful,
Xusing RPC to accomplish this task.
X.NH 2
XMessage Authentication
X.LP
XThe RPC protocol provides the fields necessary for a client to
Xidentify himself to a service and vice versa.
XSecurity and access control mechanisms
Xcan be built on top of the message authentication.
X.bp
X.NH
XRPC Protocol Requirements
X.LP
XThe RPC protocol must provide for the following:
X.IP 1.
XUnique specification of a procedure to be called.
X.IP 2.
XProvisions for matching response messages to request messages.
X.IP 3.
XProvisions for authenticating the caller to service and vice versa.
X.LP
XBesides these requirements,
Xfeatures that detect the following are worth supporting
Xbecause of protocol roll-over errors, implementation bugs,
Xuser error, and network administration:
X.IP 1.
XRPC protocol mismatches.
X.IP 2.
XRemote program protocol version mismatches.
X.IP 3.
XProtocol errors (such as misspecification of a procedure's parameters).
X.IP 4.
XReasons why remote authentication failed.
X.IP 5.
XAny other reasons why the desired procedure was not called.
X.LP
X.NH 2
XRemote Programs and Procedures
X.LP
XThe RPC call message has three unsigned fields:
Xremote program number,
Xremote program version number,
Xand remote procedure number.
XThe three fields uniquely identify the procedure to be called.
XProgram numbers are administered by some central authority (like Sun).
XOnce an implementor has a program
Xnumber, he can implement his remote program;
Xthe first implementation would
Xmost likely have the version number of 1.
XBecause most new protocols evolve into better,
Xstable and mature protocols,
Xa version field of the call message identifies which version
Xof the protocol the caller is using.
XVersion numbers make speaking old and new protocols
Xthrough the same server process possible.
X.LP
XThe procedure number identifies the procedure to be called.
XThese numbers are documented in
Xthe specific program's protocol specification.
XFor example, a file service's protocol specification
Xmay state that its procedure number 5 is
X.LW read
Xand procedure number 12 is
X.LW write .
X.LP
XJust as remote program protocols may change over several versions,
Xthe actual RPC message protocol could also change.
XTherefore, the call message also has the RPC version number in it;
Xthis field must be two (2).
X.LP
XThe reply message to a request message has enough information
Xto distinguish the following error conditions:
X.IP 1.
XThe remote implementation of RPC does speak protocol version 2.  The
Xlowest and highest supported RPC version numbers are returned.
X.IP 2.
XThe remote program is not available on the remote system.
X.IP 3.
XThe remote program does not support the requested version number.
XThe lowest and highest supported
Xremote program version numbers are returned.
X.IP 4.
XThe requested procedure number does not exist
X(this is usually a caller side protocol or programming error).
X.IP 5.
XThe parameters to the remote procedure
Xappear to be garbage from the server's point of view.
X(Again, this is caused by a disagreement about the
Xprotocol between client and service.)
X.NH 2
XAuthentication
X.LP
XProvisions for authentication of caller to service and vice versa are
Xprovided as a wart on the side of the RPC protocol.  The call message
Xhas two authentication fields, the credentials and verifier.
XThe reply message has one authentication field,
Xthe response verifier.
XThe RPC protocol specification defines all three fields
Xto be the following opaque type:
X.BS
X.LS
Xenum auth_flavor {
X	AUTH_NULL	= 0,
X	AUTH_UNIX	= 1,
X	AUTH_SHORT	= 2
X	/* and more to be defined */
X};
X.sp.5
Xstruct opaque_auth {
X	union switch (enum auth_flavor) {
X		default: string auth_body<400>;
X	};
X};
X.Lf
X.BE
XIn simple English, any
X.LW opaque_auth
Xstructure is an
X.LW auth_flavor
Xenumeration followed by a counted string,
Xwhose bytes are opaque to the RPC protocol implementation.
X.LP
XThe interpretation and semantics of the data contained
Xwithin the authentication fields is specified by individual,
Xindependent authentication protocol specifications.
XAppendix A defines three authentication protocols.
X.LP
XIf authentication parameters were rejected,
Xthe response message contains information stating
Xwhy they were rejected.
X.NH 2
XProgram Number Assignment
X.LP
XProgram numbers are given out in groups of 0x20000000 (536870912)
Xaccording to the following chart:
X.BS
X.LS
X       0 - 1fffffff	defined by Sun
X20000000 - 3fffffff	defined by user
X40000000 - 5fffffff	transient
X60000000 - 7fffffff	reserved
X80000000 - 9fffffff	reserved
Xa0000000 - bfffffff	reserved
Xc0000000 - dfffffff	reserved
Xe0000000 - ffffffff	reserved
X.Lf
X.BE
XThe first group is a range of numbers administered by Sun Microsystems,
Xand should be identical for all Sun customers.  The second range
Xis for applications peculiar to a particular customer.
XThis range is intended primarily for debugging new programs.
XWhen a customer develops an application that might be of general
Xinterest, that application should be given an assigned number
Xin the first range.  The third group is for applications that
Xgenerate program numbers dynamically.  The final groups
Xare reservered for future use, and should not be used.
X.NH 2
XOther Uses of the RPC Protocol
X.LP
XThe intended use of this protocol is for calling remote procedures.
XThat is, each call message is matched with a response message.
XHowever, the protocol itself is a message passing protocol
Xwith which other (non-RPC) protocols can be implemented.
XSun currently uses, or perhaps abuses,
Xthe RPC message protocol for the following two (non-RPC) protocols:
Xbatching (or pipelining) and broadcast RPC.
XThese two protocols are discussed but not defined below.
X.NH 3
XBatching
X.LP
XBatching allows a client to send an arbitrarily large sequence
Xof call messages to a server;
Xbatching uses reliable bytes stream protocols (like TCP/IP)
Xfor their transport.
XIn the case of batching, the client never waits for a reply
Xfrom the server and the server does not send replies to batch requests.
XA sequence of batch calls is usually terminated by a legitimate
XRPC in order to flush the pipeline (with positive acknowledgement).
X.NH 3
XBroadcast RPC
X.LP
XIn broadcast RPC based protocols,
Xthe client sends an a broadcast packet to
Xthe network and waits for numerous replies.
XBroadcast RPC uses unreliable, packet based protocols (like UDP/IP)
Xas their transports.
XServers that support broadcast protocols only respond
Xwhen the request is successfully processed,
Xand are silent in the face of errors.
X.de NE
X.br
X.ne 1i
X..
X.bp
X.NH
XThe RPC Message Protocol
X.LP
XThis section defines the RPC message protocol in the XDR data description
Xlanguage.  The message is defined in a top down style.
XNote: This is an XDR specification, not C code.
X.BS
X.LS no
Xenum msg_type {
X	CALL = 0,
X	REPLY = 1
X};
X.sp.5
X.NE
X/*
X * A reply to a call message can take on two forms:
X * the message was either accepted or rejected.
X */
Xenum reply_stat {
X	MSG_ACCEPTED = 0,
X	MSG_DENIED = 1
X};
X.sp.5
X.NE
X/*
X * Given that a call message was accepted, the following is
X * the status of an attempt to call a remote procedure.
X */
Xenum accept_stat {
X	SUCCESS = 0,	  /* RPC executed successfully */
X	PROG_UNAVAIL = 1, /* remote hasn't exported program */
X	PROG_MISMATCH= 2, /* remote can't support version # */
X	PROC_UNAVAIL = 3, /* program can't support procedure */
X	GARBAGE_ARGS = 4  /* procedure can't decode params */
X};
X.sp.5
X.NE
X/*
X * Reasons why a call message was rejected:
X */
Xenum reject_stat {
X	RPC_MISMATCH = 0, /* RPC version number != 2 */
X	AUTH_ERROR = 1    /* remote can't authenticate caller */
X};
X.sp.5
X.NE
X/*
X * Why authentication failed:
X */
Xenum auth_stat {
X	AUTH_BADCRED = 1,    /* bad credentials (seal broken) */
X	AUTH_REJECTEDCRED=2, /* client must begin new session */
X	AUTH_BADVERF = 3,    /* bad verifier (seal broken) */
X	AUTH_REJECTEDVERF=4, /* verifier expired or replayed */
X	AUTH_TOOWEAK = 5,    /* rejected for security reasons */
X};
X.sp.5
X.NE
X/*
X * The RPC message:
X * All messages start with a transaction identifier, xid,
X * followed by a two-armed discriminated union.  The union's
X * discriminant is a msg_type which switches to one of the
X * two types of the message.  The xid of a REPLY message
X * always matches that of the initiating CALL message.  NB:
X * The xid field is only used for clients matching reply
X * messages with call messages; the service side cannot
X * treat this id as any type of sequence number.
X */
Xstruct rpc_msg {
X	unsigned	xid;
X	union switch (enum msg_type) {
X		CALL:	struct call_body;
X		REPLY:	struct reply_body;
X	};
X};
X.sp.5
X.NE
X/*
X * Body of an RPC request call:
X * In version 2 of the RPC protocol specification, rpcvers
X * must be equal to 2.  The fields prog, vers, and proc
X * specify the remote program, its version number, and the
X * procedure within the remote program to be called.  After
X * these fields are two  authentication parameters: cred
X * (authentication credentials) and verf (authentication
X * verifier).  The two  authentication parameters are
X * followed by the parameters to the remote procedure,
X * which are specified by the specific program protocol.
X */
Xstruct call_body {
X	unsigned rpcvers;	/* must be equal to two (2) */
X	unsigned prog;
X	unsigned vers;
X	unsigned proc;
X	struct opaque_auth cred;
X	struct opaque_auth verf;
X	/* procedure specific parameters start here */
X};
X.sp.5
X.NE
X/*
X * Body of a reply to an RPC request.
X * The call message was either accepted or rejected.
X */
Xstruct reply_body {
X	union switch (enum reply_stat) {
X		MSG_ACCEPTED:	struct accepted_reply;
X		MSG_DENIED:	struct rejected_reply;
X	};
X};
X.sp.5
X.NE
X/*
X * Reply to an RPC request that was accepted by the server.
X * Note: there could be an error even though the reques
X * was accepted.  The first field is an authentication
X * verifier that the server generates in order to validate
X * itself to the caller.  It is followed by a union whose
X * discriminant is an enum accept_stat.  The SUCCESS arm
X * of the union is protocol specific.  The PROG_UNAVAIL,
X * PROC_UNAVAIL, and GARBAGE_ARGS arms of the union are
X * void.  The PROG_MISMATCH arm specifies the lowest and
X * highest version numbers of the remote program that are
X * supported by the server.
X */
Xstruct accepted_reply {
X	struct opaque_auth	verf;
X	union switch (enum accept_stat) {
X		SUCCESS: struct {
X			/*
X			 * procedure-specific results start here
X			 */
X		};
X		PROG_MISMATCH: struct {
X			unsigned low;
X			unsigned  high;
X		};
X		default: struct {
X			/*
X			 * void. Cases include PROG_UNAVAIL,
X			 * PROC_UNAVAIL, and GARBAGE_ARGS.
X			 */
X		};
X	};
X};
X.sp.5
X.NE
X/*
X * Reply to an RPC request that was rejected by the server.
X * The request can be rejected because of two reasons:
X * either the server is not running a compatible version of
X * the RPC protocol (RPC_MISMATCH), or the server refuses
X * to authenticate the caller (AUTH_ERROR).  In the case of
X * an RPC version mismatch, the server returns the lowest
X * and highest supported RPC version numbers.  In the case
X * of refused authentication, failure status is returned.
X */
Xstruct rejected_reply {
X	union switch (enum reject_stat) {
X		RPC_MISMATCH: struct {
X			unsigned low;
X			unsigned high;
X		};
X		AUTH_ERROR: enum auth_stat;
X	};
X};
X.Lf
X.BE
X.NH 2
XAuthentication Parameter Specification
X.LP
XAs previously stated, authentication parameters are opaque,
Xbut open-ended to the rest of the
XRPC protocol.  This section defines some ``flavors'' of authentication
Xwhich have been implemented at (and supported by) Sun.
X.NH 3
XNull Authentication
X.LP
XOften calls must be made where the caller does not know who he is and
Xthe server does not care who the caller is.  In this case, the auth_flavor value
X(the discriminant of the opaque_auth's union) of the
XRPC message's credentials, verifier, and response verifier is
X.LW AUTH_NULL
X(0).
XThe bytes of the auth_body string are undefined.
XIt is recommended that the string length be zero.
X.NH 3
XUNIX Authentication
X.LP
XThe caller of a remote procedure may wish to identify himself as he is
Xidentified on a
X.UX
Xsystem.
XThe value of the
X.LW credential 's
Xdiscriminant of
Xan RPC call message is
X.LW AUTH_UNIX
X(1).  The bytes of the
X.LW credential 's
Xstring encode the the following (XDR) structure:
X.BS
X.LS
Xstruct auth_unix {
X	unsigned	stamp;
X	string		machinename<255>;
X	unsigned	uid;
X	unsigned	gid;
X	unsigned	gids<10>;
X};
X.Lf
X.BE
XThe
X.LW stamp
Xis an arbitrary id which the caller machine may generate.
XThe
X.LW machinename
Xis the name of the caller's machine (like ``krypton'').
XThe
X.LW uid
Xis the caller's effective user id.
XThe
X.LW gid
Xis the callers effective group id.
XThe
X.LW gids
Xis a counted array of groups
Xwhich contain the caller as a member.
XThe
X.LW verifier
Xaccompanying the credentials should be of
X.LW AUTH_NULL
X(defined above).
X.LP
XThe value of the discriminate of the
X.LW "response verifier"
Xreceived in the reply message from the server may be
X.LW AUTH_NULL
Xor
X.LW AUTH_SHORT .
XIn the case of
X.LW AUTH_SHORT ,
Xthe bytes of the
X.LW "response verifier" 's
Xstring encode an
X.LW auth_opaque
Xstructure.
XThis new
X.LW auth_opaque
Xstructure may now be passed to the server
Xinstead of the original
X.LW AUTH_UNIX
Xflavor credentials.
XThe server keeps a cache which maps short hand
X.LW auth_opaque
Xstructures (passed back by way of a
X.LW AUTH_SHORT
Xstyle
X.LW "response verifier" )
Xto the original credentials of the caller.
XThe caller can save network bandwidth and server cpu cycles
Xby using the new credentials.
X.LP
XThe server may flush the short hand
X.LW auth_opaque
Xstructure at any time.
XIf this happens, the remote procedure call message
Xwill be rejected due to an authentication error.
XThe reason for the failure will be
X.LW AUTH_REJECTEDCRED .
XAt this point, the caller may wish to try the original
X.LW AUTH_UNIX
Xstyle of credentials.
X.NH 2
XRecord Marking Standard
X.LP
XWhen RPC messages are passed on top of a byte stream protocol
X(like TCP/IP), it is necessary, or at least desirable,
Xto delimit one message from another in order to detect
Xand possibly recover from user protocol errors.
XThis is called record marking (RM).
XSun uses this RM/TCP/IP transport for passing
XRPC messages on TCP streams.
XOne RPC message fits into one RM record.
X.LP
XA record is composed of one or more record fragments.
XA record fragment is a four-byte header followed by
X.I 0
Xto
X.I "2\s-2\u31\d\s+2\-1"
Xbytes of fragment data.
XThe bytes encode an unsigned binary number;
Xas with XDR integers, the byte order is from highest to lowest.
XThe number encodes two values \(em
Xa boolean which indicates whether the fragment is the last fragment
Xof the record (bit value 1 implies the fragment is the last fragment)
Xand a 31-bit unsigned binary value which is the length in bytes of the
Xfragment's data.
XThe boolean value is the highest-order bit of the header;
Xthe length is the 31 low-order bits.
X(Note that this record specification is
X.I not
Xin XDR standard form!)
X.bp
X.SH
X.NH 0
XAppendix A: Port Mapper Program Protocol
X.LP
XThe port mapper program maps RPC program and version numbers
Xto UDP/IP or TCP/IP port numbers.
XThis program makes dynamic binding of remote programs possible.
X.LP
XThis is desirable because the range of reserved port numbers is very small
Xand the number of potential remote programs is very large.  By running only
Xthe port mapper on a reserved port, the port numbers of other remote programs
Xcan be ascertained by querying the port mapper.
X.NH 2
XThe RPC Protocol
X.LP
XThe protocol is specified by the XDR description language.
X.LP
X.BS
X.LS
XPort Mapper RPC Program Number: 100000
X	Version Number: 1
X	Supported Transports:
X		UDP/IP on port 111
X		RM/TCP/IP on port 111
X.Lf
X.BE
X.NH 3
XTransport Protocol Numbers
X.BS
X.LS
X#define IPPROTO_TCP	6	/* protocol number for TCP/IP */
X#define IPPROTO_UDP	17	/* protocol number for UDP/IP */
X.Lf
X.BE
X.NH 3
XRPC Procedures
X.LP
XHere is a list of RPC procedures:
X.NE
X.NH 4
XDo Nothing
X.LP
XProcedure 0, Version 2.
X.BS
X.LS
X0. PMAPPROC_NULL () returns ()
X.Lf
X.BE
XThis procedure does no work.
XBy convention, procedure zero of any protocol
Xtakes no parameters and returns no results.
X.NE
X.NH 4
XSet a Mapping
X.LP
XProcedure 1, Version 2.
X.BS
X.LS
X1. PMAPPROC_SET (prog,vers,prot,port) returns (resp)
X	unsigned prog;
X	unsigned vers;
X	unsigned prot;
X	unsigned port;
X	boolean resp;
X.Lf
X.BE
XWhen a program first becomes available on a machine,
Xit registers itself with the port mapper program on the same machine.
XThe program passes its program number
X.LW prog ,
Xversion number
X.LW vers ,
Xtransport protocol number
X.LW prot ,
Xand the port
X.LW port
Xon which it awaits service request.
XThe procedure returns
X.LW resp ,
Xwhose value is
X.LW TRUE
Xif the procedure successfully established the mapping and
X.LW FALSE
Xotherwise.  The procedure refuses to establish a mapping
Xif one already exists for the tuple
X.LW [prog,vers,prot] .
X.NE
X.NH 4
XUnset a Mapping
X.LP
XProcedure 2, Version 2.
X.BS
X.LS
X2. PMAPPROC_UNSET (prog,vers,dummy1,dummy2) returns (resp)
X	unsigned prog;
X	unsigned vers;
X	unsigned dummy1;  /* value always ignored */
X	unsigned dummy2;  /* value always ignored */
X	boolean resp;
X.Lf
X.BE
XWhen a program becomes unavailable, it should
Xunregister itself with the port mapper program on the same machine.
XThe parameters and results have meanings identical to those of
X.LW PMAPPROC_SET .
X.NE
X.NH 4
XLook Up a Mapping
X.LP
XProcedure 3, Version 2.
X.BS
X.LS
X3. PMAPPROC_GETPORT (prog,vers,prot,dummy) returns (port)
X	unsigned prog;
X	unsigned vers;
X	unsigned prot;
X	unsigned dummy;	/* this value always ignored */
X	unsigned port;	/* zero means program not registered */
X.Lf
X.BE
XGiven a program number
X.LW prog ,
Xversion number
X.LW vers ,
Xand transport protocol number
X.LW prot ,
Xthis procedure returns the port number on which
Xthe program is awaiting call requests.
XA port value of zeros means the program has not been registered.
X.NE
X.NH 4
XDumping the Mappings
X.LP
XProcedure 4, Version 2.
X.BS
X.LS
X4. PMAPPROC_DUMP () returns (maplist)
X	struct maplist {
X		union switch (boolean) {
X			FALSE: struct { /* void, end of list */ };
X			TRUE: struct {
X				unsigned prog;
X				unsigned vers;
X				unsigned prot;
X				unsigned port;
X				struct maplist the_rest;
X			};
X		};
X	} maplist;
X.Lf
X.BE
XThis procedure enumerates all entries in the port mapper's database.
XThe procedure takes no parameters and returns a list of
Xprogram, version, protocol, and port values.
X.NE
X.NH 4
XIndirect Call Routine
X.LP
XProcedure 5, Version 2.
X.BS
X.LS
X5. PMAPPROC_CALLIT (prog,vers,proc,args) returns (port,res)
X	unsigned prog;
X	unsigned vers;
X	unsigned proc;
X	string args<>;
X	unsigned port;
X	string res<>;
X.Lf
X.BE
XThis procedure allows a caller to call another remote procedure
Xon the same machine without knowing the remote procedure's port number.
XIts intended use is for supporting broadcasts
Xto arbitrary remote programs via the well-known port mapper's port.
XThe parameters
X.LW prog ,
X.LW vers ,
X.LW proc ,
Xand the bytes of
X.LW args
Xare the program number, version number, procedure number,
Xand parameters of the remote procedure.
XNote:
X.IP 1.
XThis procedure only sends a response if the procedure was
Xsuccessfully executed and is silent (no response) otherwise.
X.IP 2.
XThe port mapper communicates with the remote program using UDP/IP only.
X.LP
XThe procedure returns the remote program's port number,
Xand the bytes of results are the results of the remote procedure.
SHAR_EOF
if test 23693 -ne "`wc -c < 'rpc/doc/rpc.spec'`"
then
	echo shar: "error transmitting 'rpc/doc/rpc.spec'" '(should have been 23693 characters)'
fi
chmod 444 'rpc/doc/rpc.spec'
fi
echo shar: "extracting 'rpc/doc/runoff'" '(353 characters)'
if test -f 'rpc/doc/runoff'
then
	echo shar: "will not over-write existing file 'rpc/doc/runoff'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/doc/runoff'
X#! /bin/sh 
X#
X# usage: runoff file
X# output goes to stdout
X#
X
XROFF=nroff
XTBL=tbl
XEQN=neqn
X
Xcase $1 in
X	rpc.prog)
X		$TBL sunhead.ms rpc.prog.p[12] | $ROFF -ms -rF1 
X		;;
X	xdr.spec)
X		$TBL sunhead.ms xdr.spec.p[12] | $EQN $dev | $ROFF -ms -rF1 
X		;;
X	rpc.spec)
X		$ROFF -ms -rF1 sunhead.ms rpc.spec 
X		;;
X	*)
X		echo Don\'t know how to runoff $1.
X		;;
Xesac
SHAR_EOF
if test 353 -ne "`wc -c < 'rpc/doc/runoff'`"
then
	echo shar: "error transmitting 'rpc/doc/runoff'" '(should have been 353 characters)'
fi
chmod 775 'rpc/doc/runoff'
fi
echo shar: "extracting 'rpc/doc/runoff.troff'" '(436 characters)'
if test -f 'rpc/doc/runoff.troff'
then
	echo shar: "will not over-write existing file 'rpc/doc/runoff.troff'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/doc/runoff.troff'
X#! /bin/sh 
X#
X# usage: runoff.troff file [-Tdevtype]
X#
X
XROFF=nice troff
XTBL=tbl
XEQN=eqn
XPIC=pic
X
Xcase $2 in
X	-Tlw)
X		dev=-Tlw
X		;;
X	*)
X		;;
Xesac
Xcase $1 in
X	rpc.prog)
X		$PIC -D $dev sunhead.ms rpc.prog.p[12] | $TBL | \
X			$ROFF $2 -ms -rF1 
X		;;
X	xdr.spec)
X		$TBL sunhead.ms xdr.spec.p[12] | $EQN $dev | $ROFF $2 -ms -rF1 
X		;;
X	rpc.spec)
X		$ROFF $2 -ms -rF1 sunhead.ms rpc.spec 
X		;;
X	*)
X		echo Don\'t know how to runoff $1.
X		;;
Xesac
SHAR_EOF
if test 436 -ne "`wc -c < 'rpc/doc/runoff.troff'`"
then
	echo shar: "error transmitting 'rpc/doc/runoff.troff'" '(should have been 436 characters)'
fi
chmod 775 'rpc/doc/runoff.troff'
fi
echo shar: "extracting 'rpc/doc/sunhead.ms'" '(1316 characters)'
if test -f 'rpc/doc/sunhead.ms'
then
	echo shar: "will not over-write existing file 'rpc/doc/sunhead.ms'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/doc/sunhead.ms'
X.\"
X.\" Header File for Sun Manuals
X.\" Use with -ms macros
X.\" Adapted from TIS course header
X.\" Sally Rutter, The Instruction Set
X.\" 19th November 1985
X.\"
X.nr PS 11
X.nr VS 14
X.ds Un \s-1UNIX\s0
X.\" define string Un = UNIX in smaller point size
X.fp 7 L
X.\" Put constant width font in position 7
X.fp 6 LB
X.\" Put bold constant width font in position 6
X.\" The next 2 definitions are for constant width displays
X.\" LS for display start and Lf for display finish
X.de LS
X.DS \\$1 \\$2 \\$3
X.nf
X.ft 7
X.ps 10
X.vs 12
X.nr Tw \w'a'*8
X.ta \\n(Twu,+\\n(Twu,+\\n(Twu,+\\n(Twu,+\\n(Twu,+\\n(Twu,+\\n(Twu
X..
X.de Lf
X.ft
X.fi
X.ps 11
X.vs 14
X.DE
X..
X.\" The next definition is for text in constant width font.
X.de LW
X.ie\\n(.$ .nr ;G \\n(.f
X.el.ft 7
X.if\\n(.$ .if !\\n(.$-2 \&\f7\\$1\fP\\$2
X.if\\n(.$-2 \{.ds }i
X.if\\n(.f2 .ds }i \^
X.ds}I \&\f7\\$1\fP\\$2\\*(}i
X'br\}
X.if\\n(.$-2 .if !\\n(.$-4 \\*(}I\f7\\$3\fP\\$4
X.if\\n(.$-4 .if !\\n(.$-6 \\*(}I\f7\\$3\fP\\$4\\*(}i\f7\\$5\fP\\$6
X.if\\n(.$ .ft \\n(;G
X..
X.\" The next definition ensures that there is at least
X.\" 0.5i left on the page when a sub-heading is called
X.rn SH Sh
X.de SH
X.br
X.ne 1.5i
X.Sh
X..
X.\" The next definition is simply a need macro
X.       \" NE - need space
X.de NE
X.br
X.ne 2i
X..
X.de Pb
X'bp
X..
X.wh -1i Pb
X.\" Need the definition of index (IX) from somewhere ...
X
SHAR_EOF
if test 1316 -ne "`wc -c < 'rpc/doc/sunhead.ms'`"
then
	echo shar: "error transmitting 'rpc/doc/sunhead.ms'" '(should have been 1316 characters)'
fi
chmod 444 'rpc/doc/sunhead.ms'
fi
echo shar: "extracting 'rpc/tools/rpcinfo.8'" '(1084 characters)'
if test -f 'rpc/tools/rpcinfo.8'
then
	echo shar: "will not over-write existing file 'rpc/tools/rpcinfo.8'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/tools/rpcinfo.8'
X.\" @(#)rpcinfo.8 1.1 85/12/28 SMI;
X.TH RPCINFO 8 "1 February 1985"
X.SH NAME
Xrpcinfo \- report RPC information
X.SH SYNOPSIS
X.B "rpcinfo \-p"
X[ host ]
X.br
X.B "rpcinfo \-u"
Xhost program-number
X[ version-number ]
X.br
X.B "rpcinfo \-t"
Xhost program-number
X[ version-number ]
X.SH DESCRIPTION
X.IX  "rpcinfo command"  ""  "\fLrpcinfo\fP \(em report RPC information"
X.I Rpcinfo
Xmakes an RPC call to an RPC server and reports what it finds.
X.SH OPTIONS
X.TP
X.B \-p
XProbe the portmapper on
X.IR host ,
Xand print a list of all registered RPC programs.
XIf 
X.I host
Xis not specified, it defaults to the value returned by
X.IR hostname (1).
X.TP
X.B \-u
XMake an RPC call to procedure 0 of
X.I program-number
Xusing UDP, and report whether a response was received.
X.TP
X.B \-t
XMake an RPC call to procedure 0 of
X.I program-number
Xusing TCP, and report whether a response was received.
X.LP
XThe
X.I program-number
Xargument can be either a name or a number.  If no version is given,
Xit defaults to 1.
X.SH FILES
X/etc/rpc	names for rpc program numbers
X.SH "SEE ALSO"
X.I "RPC Programming Guide,"
Xrpc(5), portmap(8)
SHAR_EOF
if test 1084 -ne "`wc -c < 'rpc/tools/rpcinfo.8'`"
then
	echo shar: "error transmitting 'rpc/tools/rpcinfo.8'" '(should have been 1084 characters)'
fi
chmod 444 'rpc/tools/rpcinfo.8'
fi
echo shar: "extracting 'rpc/tools/rpcinfo.c'" '(6047 characters)'
if test -f 'rpc/tools/rpcinfo.c'
then
	echo shar: "will not over-write existing file 'rpc/tools/rpcinfo.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/tools/rpcinfo.c'
X/*      rpcinfo.c     1.1     86/02/05     */
X
X/*
X * Copyright (C) 1984, Sun Microsystems, Inc.
X */
X
X/*
X * rpcinfo: ping a particular rpc program
X *     or dump the portmapper
X */
X
X/*
X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
X * unrestricted use provided that this legend is included on all tape
X * media and as a part of the software program in whole or part.  Users
X * may copy or modify Sun RPC without charge, but are not authorized
X * to license or distribute it to anyone else except as part of a product or
X * program developed by the user.
X * 
X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
X * 
X * Sun RPC is provided with no support and without any obligation on the
X * part of Sun Microsystems, Inc. to assist in its use, correction,
X * modification or enhancement.
X * 
X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
X * OR ANY PART THEREOF.
X * 
X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
X * or profits or other special, indirect and consequential damages, even if
X * Sun has been advised of the possibility of such damages.
X * 
X * Sun Microsystems, Inc.
X * 2550 Garcia Avenue
X * Mountain View, California  94043
X */
X
X#include <rpc/rpc.h>
X#include <stdio.h>
X#include <sys/socket.h>
X#include <sys/time.h>
X#include <netdb.h>
X#include <rpc/pmap_prot.h>
X#include <rpc/pmap_clnt.h>
X#include <ctype.h>
X
X#define MAXHOSTLEN 256
X
Xmain(argc, argv)
X	char **argv;
X{
X	if (argc < 2) {
X		usage();
X		exit(1);
X	}
X	if (argv[1][0] == '-') {
X		switch(argv[1][1]) {
X			case 't':
X				tcpping(argc-1, argv+1);
X				break;
X			case 'p':
X				pmapdump(argc-1, argv+1);
X				break;
X			case 'u':
X				udpping(argc-1, argv+1);
X				break;
X			default:
X				usage();
X				exit(1);
X				break;
X		}
X	}
X	else
X		usage();
X}
X		
Xudpping(argc, argv)
X	char **argv;
X{
X	int ans, prognum, vers;
X	struct rpcent *rpc;
X    
X	if (argc < 3 || argc > 4) {
X		usage();
X		exit(1);
X	}
X	if (isalpha(argv[2][0])) {
X		rpc = getrpcbyname(argv[2]);
X		if (rpc == NULL) {
X			fprintf(stderr, "%s is unknown name\n", argv[2]);
X			exit(1);
X		}
X		prognum = rpc->r_number;
X	}
X	else
X		prognum = atoi(argv[2]);
X	if (argc == 3)
X		vers = 1;
X	else
X		vers = atoi(argv[3]);
X	ans = callrpc(argv[1], prognum, vers, NULLPROC,
X	    xdr_void, 0, xdr_void, 0);
X	if (ans != 0) {
X		clnt_perrno(ans);
X		fprintf(stderr, "\n");
X		printf("program %d version %d is not available\n",
X		    prognum, vers);
X		exit(1);
X	}
X	else
X		printf("program %d version %d ready and waiting\n",
X		    prognum, vers);
X}
X
Xtcpping(argc, argv)
X	int argc;
X	char **argv;
X{
X	struct timeval to;
X	struct sockaddr_in addr;
X	enum clnt_stat rpc_stat;
X	CLIENT *client;
X	int prognum, vers;
X	int sock = -1;
X	struct hostent *hp;
X	struct rpcent *rpc;
X
X	if (argc < 3 || argc > 4) {
X		usage();
X		exit(1);
X	}
X	if (isalpha(argv[2][0])) {
X		rpc = getrpcbyname(argv[2]);
X		if (rpc == NULL) {
X			fprintf(stderr, "%s is unknown name\n", argv[2]);
X			exit(1);
X		}
X		prognum = rpc->r_number;
X	}
X	else
X		prognum = atoi(argv[2]);
X	if ((hp = gethostbyname(argv[1])) == NULL) {
X	    fprintf(stderr, "can't find %s\n", argv[1]);
X	    exit(1);
X	}
X	addr.sin_family = AF_INET;
X	addr.sin_port = 0;
X	addr.sin_addr.s_addr = *(int *)hp->h_addr;
X	if (argc == 3)
X		vers = 1;
X	else
X		vers = atoi(argv[3]);
X	if ((client = clnttcp_create(&addr, prognum,
X		vers, &sock, 0, 0)) == NULL) {
X			clnt_pcreateerror("");
X			printf("program %d version %d is not available\n",
X			    prognum, vers);
X			exit(1);
X		}
X	to.tv_usec = 0;
X	to.tv_sec = 10;
X	rpc_stat = clnt_call(client, 0, xdr_void, NULL, xdr_void, NULL, to);
X	if (rpc_stat != RPC_SUCCESS) {
X		clnt_perrno(rpc_stat);
X		fprintf(stderr, "\n");
X		printf("program %d version %d is not available\n",
X		    prognum, vers);
X		exit(1);
X	}
X	else
X		printf("program %d version %d ready and waiting\n",
X		    prognum, vers);
X}
X
Xpmapdump(argc, argv)
X	int argc;
X	char **argv;
X{
X	struct sockaddr_in server_addr;
X	struct hostent *hp;
X	struct pmaplist *head = NULL;
X	char hoststr[MAXHOSTLEN];
X	int socket = -1;
X	struct timeval minutetimeout;
X	char *hostnm;
X	register CLIENT *client;
X	enum clnt_stat rpc_stat;
X	struct rpcent *rpc;
X	
X	if (argc > 2) {
X		usage();
X		exit(1);
X	}
X	if (argc == 2) {
X		hostnm = argv[1];
X	} else {
X		gethostname(hoststr, sizeof(hoststr));
X		hostnm = hoststr;
X	}
X	if ((hp = gethostbyname(hostnm)) == NULL) {
X		fprintf(stderr, "cannot get addr for '%s'\n", hostnm);
X		exit(0);
X	}
X	bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length);
X	server_addr.sin_family = AF_INET;
X	minutetimeout.tv_sec = 60;
X	minutetimeout.tv_usec = 0;
X	server_addr.sin_port = htons(PMAPPORT);
X	if ((client = clnttcp_create(&server_addr, PMAPPROG,
X	    PMAPVERS, &socket, 50, 500)) == NULL) {
X		clnt_pcreateerror("rpcinfo: can't contact portmapper");
X		exit(1);
X	}
X	if ((rpc_stat = clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
X	    xdr_pmaplist, &head, minutetimeout)) != RPC_SUCCESS) {
X		fprintf(stderr, "rpcinfo: can't contact portmapper: ");
X		clnt_perrno(rpc_stat);
X		fprintf(stderr, "\n");
X		exit(1);
X	}
X	if (head == NULL) {
X		printf("No remote programs registered.\n");
X	} else {
X		printf("   program vers proto   port\n");
X		for (; head != NULL; head = head->pml_next) {
X			printf("%10ld%5ld",
X			    head->pml_map.pm_prog,
X			    head->pml_map.pm_vers);
X			if (head->pml_map.pm_prot == IPPROTO_UDP)
X				printf("%6s",  "udp");
X			else if (head->pml_map.pm_prot == IPPROTO_TCP)
X				printf("%6s", "tcp");
X			else
X				printf("%6ld",  head->pml_map.pm_prot);
X			printf("%7ld",  head->pml_map.pm_port);
X			rpc = getrpcbynumber(head->pml_map.pm_prog);
X			if (rpc)
X				printf("  %s\n", rpc->r_name);
X			else
X				printf("\n");
X		}
X	}
X}
X
Xusage()
X{
X	fprintf(stderr, "Usage: rpcinfo -u host prognum [versnum]\n");
X	fprintf(stderr, "       rpcinfo -t host prognum [versnum]\n");
X	fprintf(stderr, "       rpcinfo -p [host]\n");
X}
SHAR_EOF
if test 6047 -ne "`wc -c < 'rpc/tools/rpcinfo.c'`"
then
	echo shar: "error transmitting 'rpc/tools/rpcinfo.c'" '(should have been 6047 characters)'
fi
chmod 444 'rpc/tools/rpcinfo.c'
fi
echo shar: "extracting 'rpc/toys/Makefile'" '(250 characters)'
if test -f 'rpc/toys/Makefile'
then
	echo shar: "will not over-write existing file 'rpc/toys/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/toys/Makefile'
XCFLAGS= -O
X
Xall: sortit sort_service
X
Xsortit: sortit.o sort_prot.o
X	${CC} ${CFLAGS} sortit.o sort_prot.o -o sortit
X
Xsort_service: sort_service.o sort_prot.o
X	${CC} ${CFLAGS} sort_service.o sort_prot.o -o sort_service
X
X.c.o:
X	${CC} ${CFLAGS} -c $*.c
X
SHAR_EOF
if test 250 -ne "`wc -c < 'rpc/toys/Makefile'`"
then
	echo shar: "error transmitting 'rpc/toys/Makefile'" '(should have been 250 characters)'
fi
chmod 444 'rpc/toys/Makefile'
fi
echo shar: "extracting 'rpc/toys/sort_prot.c'" '(298 characters)'
if test -f 'rpc/toys/sort_prot.c'
then
	echo shar: "will not over-write existing file 'rpc/toys/sort_prot.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/toys/sort_prot.c'
X/*
X * sort_prot.c
X * Implements the protcol filter for the toy sort service.
X */
X
X#include <rpc/rpc.h>
X#include "sort_prot.h"
X
Xint
Xxdr_sortstrings(xdrs, ssp)
X	XDR *xdrs;
X	struct sortstrings *ssp;
X{
X
X	return (xdr_array(xdrs, &ssp->s, &ssp->ns, MAXSORTSIZE,
X	    sizeof (char *), xdr_wrapstring));
X}
SHAR_EOF
if test 298 -ne "`wc -c < 'rpc/toys/sort_prot.c'`"
then
	echo shar: "error transmitting 'rpc/toys/sort_prot.c'" '(should have been 298 characters)'
fi
chmod 444 'rpc/toys/sort_prot.c'
fi
echo shar: "extracting 'rpc/toys/sort_prot.h'" '(453 characters)'
if test -f 'rpc/toys/sort_prot.h'
then
	echo shar: "will not over-write existing file 'rpc/toys/sort_prot.h'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/toys/sort_prot.h'
X/*
X * Protocol for a sorting service.
X */
X
X#define SORTPROG	((long) 22855)
X#define SORTVERS	((long) 1)
X#define SORT		((long) 1)
X
X/*
X * The sort procedure receives an array of strings and returns an array
X * of strings.  This toy service handles a maximum of 64 strings.
X */
X#define MAXSORTSIZE	((long) 64)
X
Xstruct sortstrings {
X	long	ns;  /* number of strings in the array */
X	char	**s; /* pointer to the array of strings */
X};
X
Xint xdr_sortstrings();
X
SHAR_EOF
if test 453 -ne "`wc -c < 'rpc/toys/sort_prot.h'`"
then
	echo shar: "error transmitting 'rpc/toys/sort_prot.h'" '(should have been 453 characters)'
fi
chmod 444 'rpc/toys/sort_prot.h'
fi
echo shar: "extracting 'rpc/toys/sort_service.c'" '(557 characters)'
if test -f 'rpc/toys/sort_service.c'
then
	echo shar: "will not over-write existing file 'rpc/toys/sort_service.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/toys/sort_service.c'
X/*
X * sort_service.c
X * Implements the server side of the sort_service.
X */
X
X#include <rpc/rpc.h>
X#include "sort_prot.h"
X
Xstatic int
Xcomparestrings(sp1, sp2) 
X	char **sp1, **sp2;
X{
X
X	return (strcmp(*sp1, *sp2));
X}
X
Xstatic struct sortstrings *
Xsort(ssp)
X	struct sortstrings *ssp;
X{
X
X	qsort(ssp->s, ssp->ns, sizeof (char *), comparestrings);
X	return(ssp);
X}
X
Xmain()
X{
X
X	/* register the serive */
X	registerrpc(SORTPROG, SORTVERS, SORT,
X	    sort, xdr_sortstrings, xdr_sortstrings);
X
X	/* run the service forever */
X	svc_run();  /* never returns */
X	exit(1);
X}
X
SHAR_EOF
if test 557 -ne "`wc -c < 'rpc/toys/sort_service.c'`"
then
	echo shar: "error transmitting 'rpc/toys/sort_service.c'" '(should have been 557 characters)'
fi
chmod 444 'rpc/toys/sort_service.c'
fi
echo shar: "extracting 'rpc/toys/sortit.c'" '(622 characters)'
if test -f 'rpc/toys/sortit.c'
then
	echo shar: "will not over-write existing file 'rpc/toys/sortit.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/toys/sortit.c'
X/*
X * sortit.c
X * Client side application which sorts argc, argv.
X */
X#include <stdio.h>
X#include <rpc/rpc.h>
X#include "sort_prot.h"
X
Xmain(argc, argv)
X	int argc;
X	char **argv;
X{
X	char *machinename;
X	struct sortstrings args, res;
X	int i;
X
X	if (argc < 2) {
X		fprintf(stderr, "usage: %s machinename [s1 ...]\n", argv[0]);
X		exit(1);
X	}
X	machinename = argv[1];
X	args.ns = argc;
X	args.s = argv;
X	res.s = (char **)NULL;
X
X	callrpc(machinename, SORTPROG, SORTVERS, SORT,
X	    xdr_sortstrings, &args, xdr_sortstrings, &res);
X
X	for (i = 0; i < res.ns; i++) {
X		printf("%s\n", res.s[i]);
X	}
X
X	/* should free res here */
X	exit(0);
X}
X
SHAR_EOF
if test 622 -ne "`wc -c < 'rpc/toys/sortit.c'`"
then
	echo shar: "error transmitting 'rpc/toys/sortit.c'" '(should have been 622 characters)'
fi
chmod 444 'rpc/toys/sortit.c'
fi
echo shar: "extracting 'rpc/rpclib/Makefile'" '(3535 characters)'
if test -f 'rpc/rpclib/Makefile'
then
	echo shar: "will not over-write existing file 'rpc/rpclib/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/Makefile'
X#
X# 	Makefile	1.1	86/02/03
X#
XDESTDIR=
X
XSRC=	auth_none.c auth_unix.c authunix_prot.c \
X	clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c clnt_udp.c \
X	pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_rmt.c rpc_prot.c \
X	svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_simple.c \
X	svc_tcp.c svc_udp.c xdr.c xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c xdr_stdio.c
X
XOBJ=	auth_none.o auth_unix.o authunix_prot.o clnt_perror.o clnt_raw.o\
X	clnt_simple.o clnt_tcp.o clnt_udp.o \
X	pmap_clnt.o pmap_getmaps.o pmap_getport.o pmap_prot.o pmap_rmt.o rpc_prot.o \
X	svc.o svc_auth.o svc_auth_unix.o svc_raw.o svc_simple.o \
X	svc_tcp.o svc_udp.o xdr.o xdr_array.o xdr_float.o xdr_mem.o xdr_rec.o xdr_reference.o xdr_stdio.o
XINC=	auth.h auth_unix.h clnt.h pmap_clnt.h\
X	pmap_prot.h rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h
X
XCFLAGS= -O -A-R
X
X.c.o:
X	${CC} -p -c ${CFLAGS} $*.c
X	-ld -X -r $*.o
X	mv a.out profiled/$*.o
X	${CC} ${CFLAGS} -c $*.c
X	-ld -x -r $*.o
X	mv a.out $*.o
X
Xrpclib rpclib_p: ${OBJ}
X	@echo "building profiled rpclib"
X	@cd profiled; ar cru ../rpclib_p ${OBJ}
X	@echo "building normal rpclib"
X	@ar cru rpclib ${OBJ}
X
Xinstall:
X	-mkdir ${DESTDIR}/usr/include/rpc && \
X		chown bin ${DESTDIR}/usr/include/rpc && \
X		chmod 755 ${DESTDIR}/usr/include/rpc
X	-for i in *.h; do \
X		(install -c -m 644 $$i ${DESTDIR}/usr/include/rpc) done
X
Xtags: $(SRC) $(KSRC) $(INC)
X	ctags -tw $(SRC) $(KSRC) $(INC)
X
Xref: tags
X	sed 's,	/.*,,' tags | \
X	awk ' { printf("%-26s%-16s%s\n", $$1, $$2, $$3) }' > ref
X
Xlint:
X	lint -bnuvx $(SRC)
X
Xprint:
X	pr $(INC) $(SRC) $(KSRC) | lpr -Pvp
X
Xclean:
X	rm -f $(OBJ) rpclib rpclib_p linted made profiled/*.o
X
Xdepend:
X	@-grep '^#include' $(SRC) | grep -v '<' | grep -v '../' | \
X	sed 's/:[^"]*"\([^"]*\)".*/: \1/' | sed 's/\.[cs]:/.o:/' | \
X	awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
X		else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
X		       else rec = rec " " $$2 } } \
X	      END { print rec } ' >> makedep
X	@echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
X	@echo '$$r makedep' >>eddep
X	@echo 'w' >>eddep
X	@cp Makefile makefile.bak
X	@ed - Makefile < eddep
X	@rm eddep makedep makefile.bak
X
X
X
X# DO NOT DELETE THIS LINE
X
Xauth_none.o: types.h xdr.h auth.h
Xauth_unix.o: types.h xdr.h auth.h auth_unix.h
Xauthunix_prot.o: types.h xdr.h auth.h auth_unix.h
Xclnt_perror.o: types.h xdr.h auth.h clnt.h rpc_msg.h
Xclnt_raw.o: types.h xdr.h auth.h clnt.h rpc_msg.h
Xclnt_tcp.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_clnt.h
Xclnt_udp.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_clnt.h
Xpmap_clnt.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
Xpmap_getmaps.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
Xpmap_getport.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
Xpmap_prot.o: types.h xdr.h pmap_prot.h
Xpmap_rmt.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
Xrpc_prot.o: types.h xdr.h auth.h clnt.h rpc_msg.h
Xsvc.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h svc_auth.h pmap_clnt.h
Xsvc_auth.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h svc_auth.h
Xsvc_auth_unix.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h auth_unix.h
Xsvc_auth_unix.o: svc_auth.h
Xsvc_raw.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h
Xsvc_tcp.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h
Xsvc_udp.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h
Xxdr.o: types.h xdr.h
Xxdr_array.o: types.h xdr.h
Xxdr_float.o: types.h xdr.h
Xxdr_mem.o: types.h xdr.h
Xxdr_rec.o: types.h xdr.h
Xxdr_reference.o: types.h xdr.h
Xxdr_stdio.o: types.h xdr.h
SHAR_EOF
if test 3535 -ne "`wc -c < 'rpc/rpclib/Makefile'`"
then
	echo shar: "error transmitting 'rpc/rpclib/Makefile'" '(should have been 3535 characters)'
fi
chmod 444 'rpc/rpclib/Makefile'
fi
exit 0
#	End of shell archive