From 411e387c27b183eb53c9563a8decfb02af73dfd0 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 25 Jun 2002 14:52:37 +0000 Subject: 2002-06-25 Joel Sherrill * Per PR233, moved librpc to exec. Ralf will patch after move. The patches associated with this PR are out of date. ./include/rpc/.cvsignore, ./include/rpc/Makefile.am, ./include/rpc/auth.h, ./include/rpc/auth_des.h, ./include/rpc/auth_unix.h, ./include/rpc/clnt.h, ./include/rpc/des.h, ./include/rpc/des_crypt.h, ./include/rpc/pmap_clnt.h, ./include/rpc/pmap_prot.h, ./include/rpc/pmap_rmt.h, ./include/rpc/rpc.h, ./include/rpc/rpc_com.h, ./include/rpc/rpc_msg.h, ./include/rpc/svc.h, ./include/rpc/svc_auth.h, ./include/rpc/types.h, ./include/rpc/xdr.h, ./include/.cvsignore, ./include/Makefile.am, ./include/rpcsvc/.cvsignore, ./include/rpcsvc/Makefile.am, ./include/rpcsvc/bootparam_prot.x, ./include/rpcsvc/crypt.x, ./include/rpcsvc/key_prot.x, ./include/rpcsvc/klm_prot.x, ./include/rpcsvc/mount.x, ./include/rpcsvc/nfs_prot.x, ./include/rpcsvc/nis.x, ./include/rpcsvc/nis_cache.x, ./include/rpcsvc/nis_callback.x, ./include/rpcsvc/nis_db.h, ./include/rpcsvc/nis_object.x, ./include/rpcsvc/nis_tags.h, ./include/rpcsvc/nislib.h, ./include/rpcsvc/nlm_prot.x, ./include/rpcsvc/pmap_prot.x, ./include/rpcsvc/rex.x, ./include/rpcsvc/rnusers.x, ./include/rpcsvc/rquota.x, ./include/rpcsvc/rstat.x, ./include/rpcsvc/rwall.x, ./include/rpcsvc/sm_inter.x, ./include/rpcsvc/spray.x, ./include/rpcsvc/yp.x, ./include/rpcsvc/yp_prot.h, ./include/rpcsvc/ypclnt.h, ./include/rpcsvc/yppasswd.x, ./include/rpcsvc/ypupdate_prot.x, ./include/rpcsvc/ypxfrd.x, ./.cvsignore, ./Makefile.am, ./README_RTEMS, ./configure.ac, ./src/rpc/PSD.doc/.cvsignore, ./src/rpc/PSD.doc/Makefile.am, ./src/rpc/PSD.doc/nfs.rfc.ms, ./src/rpc/PSD.doc/rpc.prog.ms, ./src/rpc/PSD.doc/rpc.rfc.ms, ./src/rpc/PSD.doc/rpcgen.ms, ./src/rpc/PSD.doc/xdr.nts.ms, ./src/rpc/PSD.doc/xdr.rfc.ms, ./src/rpc/.cvsignore, ./src/rpc/DISCLAIMER, ./src/rpc/Makefile.am, ./src/rpc/README, ./src/rpc/auth_des.c, ./src/rpc/auth_none.c, ./src/rpc/auth_time.c, ./src/rpc/auth_unix.c, ./src/rpc/authdes_prot.c, ./src/rpc/authunix_prot.c, ./src/rpc/bindresvport.3, ./src/rpc/bindresvport.c, ./src/rpc/clnt_generic.c, ./src/rpc/clnt_perror.c, ./src/rpc/clnt_raw.c, ./src/rpc/clnt_simple.c, ./src/rpc/clnt_tcp.c, ./src/rpc/clnt_udp.c, ./src/rpc/clnt_unix.c, ./src/rpc/crypt_client.c, ./src/rpc/des_crypt.3, ./src/rpc/des_crypt.c, ./src/rpc/des_soft.c, ./src/rpc/get_myaddress.c, ./src/rpc/getpublickey.c, ./src/rpc/getrpcent.3, ./src/rpc/getrpcent.c, ./src/rpc/getrpcport.3, ./src/rpc/getrpcport.c, ./src/rpc/key_call.c, ./src/rpc/key_prot_xdr.c, ./src/rpc/netname.c, ./src/rpc/netnamer.c, ./src/rpc/pmap_clnt.c, ./src/rpc/pmap_getmaps.c, ./src/rpc/pmap_getport.c, ./src/rpc/pmap_prot.c, ./src/rpc/pmap_prot2.c, ./src/rpc/pmap_rmt.c, ./src/rpc/publickey.3, ./src/rpc/publickey.5, ./src/rpc/rpc.3, ./src/rpc/rpc.5, ./src/rpc/rpc_callmsg.c, ./src/rpc/rpc_commondata.c, ./src/rpc/rpc_dtablesize.c, ./src/rpc/rpc_prot.c, ./src/rpc/rpc_secure.3, ./src/rpc/rpcdname.c, ./src/rpc/rstat.1, ./src/rpc/rstat_svc.8, ./src/rpc/rtems_portmapper.c, ./src/rpc/rtems_rpc.c, ./src/rpc/rtime.3, ./src/rpc/rtime.c, ./src/rpc/svc.c, ./src/rpc/svc_auth.c, ./src/rpc/svc_auth_des.c, ./src/rpc/svc_auth_unix.c, ./src/rpc/svc_raw.c, ./src/rpc/svc_run.c, ./src/rpc/svc_simple.c, ./src/rpc/svc_tcp.c, ./src/rpc/svc_udp.c, ./src/rpc/svc_unix.c, ./src/xdr/.cvsignore, ./src/xdr/Makefile.am, ./src/xdr/xdr.3, ./src/xdr/xdr.c, ./src/xdr/xdr_array.c, ./src/xdr/xdr_float.c, ./src/xdr/xdr_mem.c, ./src/xdr/xdr_rec.c, ./src/xdr/xdr_reference.c, ./src/xdr/xdr_sizeof.c, ./src/xdr/xdr_stdio.c, ./src/.cvsignore, ./src/Makefile.am: Moved to exec. --- c/src/librpc/src/rpc/.cvsignore | 2 - c/src/librpc/src/rpc/DISCLAIMER | 28 - c/src/librpc/src/rpc/Makefile.am | 57 - c/src/librpc/src/rpc/PSD.doc/.cvsignore | 2 - c/src/librpc/src/rpc/PSD.doc/Makefile.am | 7 - c/src/librpc/src/rpc/PSD.doc/nfs.rfc.ms | 1372 --------------- c/src/librpc/src/rpc/PSD.doc/rpc.prog.ms | 2684 ------------------------------ c/src/librpc/src/rpc/PSD.doc/rpc.rfc.ms | 1302 --------------- c/src/librpc/src/rpc/PSD.doc/rpcgen.ms | 1299 --------------- c/src/librpc/src/rpc/PSD.doc/xdr.nts.ms | 1966 ---------------------- c/src/librpc/src/rpc/PSD.doc/xdr.rfc.ms | 1058 ------------ c/src/librpc/src/rpc/README | 233 --- c/src/librpc/src/rpc/auth_des.c | 554 ------ c/src/librpc/src/rpc/auth_none.c | 136 -- c/src/librpc/src/rpc/auth_time.c | 503 ------ c/src/librpc/src/rpc/auth_unix.c | 349 ---- c/src/librpc/src/rpc/authdes_prot.c | 82 - c/src/librpc/src/rpc/authunix_prot.c | 68 - c/src/librpc/src/rpc/bindresvport.3 | 106 -- c/src/librpc/src/rpc/bindresvport.c | 147 -- c/src/librpc/src/rpc/clnt_generic.c | 141 -- c/src/librpc/src/rpc/clnt_perror.c | 254 --- c/src/librpc/src/rpc/clnt_raw.c | 243 --- c/src/librpc/src/rpc/clnt_simple.c | 123 -- c/src/librpc/src/rpc/clnt_tcp.c | 580 ------- c/src/librpc/src/rpc/clnt_udp.c | 567 ------- c/src/librpc/src/rpc/clnt_unix.c | 635 ------- c/src/librpc/src/rpc/crypt_client.c | 90 - c/src/librpc/src/rpc/des_crypt.3 | 130 -- c/src/librpc/src/rpc/des_crypt.c | 153 -- c/src/librpc/src/rpc/des_soft.c | 67 - c/src/librpc/src/rpc/get_myaddress.c | 112 -- c/src/librpc/src/rpc/getpublickey.c | 172 -- c/src/librpc/src/rpc/getrpcent.3 | 98 -- c/src/librpc/src/rpc/getrpcent.c | 303 ---- c/src/librpc/src/rpc/getrpcport.3 | 31 - c/src/librpc/src/rpc/getrpcport.c | 63 - c/src/librpc/src/rpc/key_call.c | 427 ----- c/src/librpc/src/rpc/key_prot_xdr.c | 166 -- c/src/librpc/src/rpc/netname.c | 136 -- c/src/librpc/src/rpc/netnamer.c | 326 ---- c/src/librpc/src/rpc/pmap_clnt.c | 149 -- c/src/librpc/src/rpc/pmap_getmaps.c | 86 - c/src/librpc/src/rpc/pmap_getport.c | 91 - c/src/librpc/src/rpc/pmap_prot.c | 59 - c/src/librpc/src/rpc/pmap_prot2.c | 118 -- c/src/librpc/src/rpc/pmap_rmt.c | 415 ----- c/src/librpc/src/rpc/publickey.3 | 47 - c/src/librpc/src/rpc/publickey.5 | 38 - c/src/librpc/src/rpc/rpc.3 | 1767 -------------------- c/src/librpc/src/rpc/rpc.5 | 35 - c/src/librpc/src/rpc/rpc_callmsg.c | 193 --- c/src/librpc/src/rpc/rpc_commondata.c | 41 - c/src/librpc/src/rpc/rpc_dtablesize.c | 61 - c/src/librpc/src/rpc/rpc_prot.c | 297 ---- c/src/librpc/src/rpc/rpc_secure.3 | 254 --- c/src/librpc/src/rpc/rpcdname.c | 78 - c/src/librpc/src/rpc/rstat.1 | 58 - c/src/librpc/src/rpc/rstat_svc.8 | 22 - c/src/librpc/src/rpc/rtems_portmapper.c | 488 ------ c/src/librpc/src/rpc/rtems_rpc.c | 56 - c/src/librpc/src/rpc/rtime.3 | 47 - c/src/librpc/src/rpc/rtime.c | 157 -- c/src/librpc/src/rpc/svc.c | 491 ------ c/src/librpc/src/rpc/svc_auth.c | 216 --- c/src/librpc/src/rpc/svc_auth_des.c | 531 ------ c/src/librpc/src/rpc/svc_auth_unix.c | 148 -- c/src/librpc/src/rpc/svc_raw.c | 169 -- c/src/librpc/src/rpc/svc_run.c | 83 - c/src/librpc/src/rpc/svc_simple.c | 151 -- c/src/librpc/src/rpc/svc_tcp.c | 481 ------ c/src/librpc/src/rpc/svc_udp.c | 480 ------ c/src/librpc/src/rpc/svc_unix.c | 527 ------ 73 files changed, 24606 deletions(-) delete mode 100644 c/src/librpc/src/rpc/.cvsignore delete mode 100644 c/src/librpc/src/rpc/DISCLAIMER delete mode 100644 c/src/librpc/src/rpc/Makefile.am delete mode 100644 c/src/librpc/src/rpc/PSD.doc/.cvsignore delete mode 100644 c/src/librpc/src/rpc/PSD.doc/Makefile.am delete mode 100644 c/src/librpc/src/rpc/PSD.doc/nfs.rfc.ms delete mode 100644 c/src/librpc/src/rpc/PSD.doc/rpc.prog.ms delete mode 100644 c/src/librpc/src/rpc/PSD.doc/rpc.rfc.ms delete mode 100644 c/src/librpc/src/rpc/PSD.doc/rpcgen.ms delete mode 100644 c/src/librpc/src/rpc/PSD.doc/xdr.nts.ms delete mode 100644 c/src/librpc/src/rpc/PSD.doc/xdr.rfc.ms delete mode 100644 c/src/librpc/src/rpc/README delete mode 100644 c/src/librpc/src/rpc/auth_des.c delete mode 100644 c/src/librpc/src/rpc/auth_none.c delete mode 100644 c/src/librpc/src/rpc/auth_time.c delete mode 100644 c/src/librpc/src/rpc/auth_unix.c delete mode 100644 c/src/librpc/src/rpc/authdes_prot.c delete mode 100644 c/src/librpc/src/rpc/authunix_prot.c delete mode 100644 c/src/librpc/src/rpc/bindresvport.3 delete mode 100644 c/src/librpc/src/rpc/bindresvport.c delete mode 100644 c/src/librpc/src/rpc/clnt_generic.c delete mode 100644 c/src/librpc/src/rpc/clnt_perror.c delete mode 100644 c/src/librpc/src/rpc/clnt_raw.c delete mode 100644 c/src/librpc/src/rpc/clnt_simple.c delete mode 100644 c/src/librpc/src/rpc/clnt_tcp.c delete mode 100644 c/src/librpc/src/rpc/clnt_udp.c delete mode 100644 c/src/librpc/src/rpc/clnt_unix.c delete mode 100644 c/src/librpc/src/rpc/crypt_client.c delete mode 100644 c/src/librpc/src/rpc/des_crypt.3 delete mode 100644 c/src/librpc/src/rpc/des_crypt.c delete mode 100644 c/src/librpc/src/rpc/des_soft.c delete mode 100644 c/src/librpc/src/rpc/get_myaddress.c delete mode 100644 c/src/librpc/src/rpc/getpublickey.c delete mode 100644 c/src/librpc/src/rpc/getrpcent.3 delete mode 100644 c/src/librpc/src/rpc/getrpcent.c delete mode 100644 c/src/librpc/src/rpc/getrpcport.3 delete mode 100644 c/src/librpc/src/rpc/getrpcport.c delete mode 100644 c/src/librpc/src/rpc/key_call.c delete mode 100644 c/src/librpc/src/rpc/key_prot_xdr.c delete mode 100644 c/src/librpc/src/rpc/netname.c delete mode 100644 c/src/librpc/src/rpc/netnamer.c delete mode 100644 c/src/librpc/src/rpc/pmap_clnt.c delete mode 100644 c/src/librpc/src/rpc/pmap_getmaps.c delete mode 100644 c/src/librpc/src/rpc/pmap_getport.c delete mode 100644 c/src/librpc/src/rpc/pmap_prot.c delete mode 100644 c/src/librpc/src/rpc/pmap_prot2.c delete mode 100644 c/src/librpc/src/rpc/pmap_rmt.c delete mode 100644 c/src/librpc/src/rpc/publickey.3 delete mode 100644 c/src/librpc/src/rpc/publickey.5 delete mode 100644 c/src/librpc/src/rpc/rpc.3 delete mode 100644 c/src/librpc/src/rpc/rpc.5 delete mode 100644 c/src/librpc/src/rpc/rpc_callmsg.c delete mode 100644 c/src/librpc/src/rpc/rpc_commondata.c delete mode 100644 c/src/librpc/src/rpc/rpc_dtablesize.c delete mode 100644 c/src/librpc/src/rpc/rpc_prot.c delete mode 100644 c/src/librpc/src/rpc/rpc_secure.3 delete mode 100644 c/src/librpc/src/rpc/rpcdname.c delete mode 100644 c/src/librpc/src/rpc/rstat.1 delete mode 100644 c/src/librpc/src/rpc/rstat_svc.8 delete mode 100644 c/src/librpc/src/rpc/rtems_portmapper.c delete mode 100644 c/src/librpc/src/rpc/rtems_rpc.c delete mode 100644 c/src/librpc/src/rpc/rtime.3 delete mode 100644 c/src/librpc/src/rpc/rtime.c delete mode 100644 c/src/librpc/src/rpc/svc.c delete mode 100644 c/src/librpc/src/rpc/svc_auth.c delete mode 100644 c/src/librpc/src/rpc/svc_auth_des.c delete mode 100644 c/src/librpc/src/rpc/svc_auth_unix.c delete mode 100644 c/src/librpc/src/rpc/svc_raw.c delete mode 100644 c/src/librpc/src/rpc/svc_run.c delete mode 100644 c/src/librpc/src/rpc/svc_simple.c delete mode 100644 c/src/librpc/src/rpc/svc_tcp.c delete mode 100644 c/src/librpc/src/rpc/svc_udp.c delete mode 100644 c/src/librpc/src/rpc/svc_unix.c (limited to 'c/src/librpc/src/rpc') diff --git a/c/src/librpc/src/rpc/.cvsignore b/c/src/librpc/src/rpc/.cvsignore deleted file mode 100644 index 282522db03..0000000000 --- a/c/src/librpc/src/rpc/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/c/src/librpc/src/rpc/DISCLAIMER b/c/src/librpc/src/rpc/DISCLAIMER deleted file mode 100644 index 1a66d5f4c9..0000000000 --- a/c/src/librpc/src/rpc/DISCLAIMER +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ diff --git a/c/src/librpc/src/rpc/Makefile.am b/c/src/librpc/src/rpc/Makefile.am deleted file mode 100644 index a3c2157658..0000000000 --- a/c/src/librpc/src/rpc/Makefile.am +++ /dev/null @@ -1,57 +0,0 @@ -## -## $Id$ -## - - -SUBDIRS = PSD.doc - -LIBNAME = librpc -LIB = $(ARCH)/$(LIBNAME).a - -C_FILES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ - clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \ - clnt_udp.c get_myaddress.c getrpcent.c getrpcport.c netname.c netnamer.c \ - pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_prot2.c \ - pmap_rmt.c rpc_callmsg.c rpc_commondata.c rpc_dtablesize.c rpc_prot.c \ - rpcdname.c rtime.c svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_run.c \ - svc_simple.c svc_tcp.c svc_udp.c rtems_portmapper.c rtems_rpc.c -UNUSED_C_FILES = auth_des.c auth_time.c authdes_prot.c clnt_unix.c \ - crypt_client.c des_crypt.c des_soft.c getpublickey.c key_call.c \ - key_prot_xdr.c svc_auth_des.c svc_unix.c - -C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) - -OBJS = $(C_O_FILES) - -include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg -include $(top_srcdir)/../../../automake/compile.am -include $(top_srcdir)/../../../automake/lib.am - -TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a - -# -# Add local stuff here using += -# - -AM_CPPFLAGS += '-D__P(x)=x' -D_RPC_read=read -D_RPC_write=write -D_RPC_close=close -D_RTEMS_RPC_INTERNAL_ - -$(LIB): $(OBJS) - $(make-library) - -$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB) - $(INSTALL_DATA) $< $@ - -noinst_MANS = bindresvport.3 getrpcent.3 publickey.3 rpc.3 rpc_secure.3 \ - rstat_svc.8 des_crypt.3 getrpcport.3 publickey.5 rpc.5 rstat.1 rtime.3 - -if HAS_NETWORKING -man_MANS = $(noinst_MANS) -all-local: $(ARCH) $(OBJS) $(TMPINSTALL_FILES) -endif - -.PRECIOUS: $(LIB) - -EXTRA_DIST = $(C_FILES) DISCLAIMER $(UNUSED_C_FILES) $(noinst_MANS) - -include $(top_srcdir)/../../../automake/subdirs.am -include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/librpc/src/rpc/PSD.doc/.cvsignore b/c/src/librpc/src/rpc/PSD.doc/.cvsignore deleted file mode 100644 index 282522db03..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/c/src/librpc/src/rpc/PSD.doc/Makefile.am b/c/src/librpc/src/rpc/PSD.doc/Makefile.am deleted file mode 100644 index 1cece8e061..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -## $Id$ - - -EXTRA_DIST = nfs.rfc.ms rpc.prog.ms rpc.rfc.ms rpcgen.ms xdr.nts.ms \ - xdr.rfc.ms - -include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/librpc/src/rpc/PSD.doc/nfs.rfc.ms b/c/src/librpc/src/rpc/PSD.doc/nfs.rfc.ms deleted file mode 100644 index 0c9a8995b5..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/nfs.rfc.ms +++ /dev/null @@ -1,1372 +0,0 @@ -.\" -.\" Must use -- tbl -- with this one -.\" -.\" @(#)nfs.rfc.ms 2.2 88/08/05 4.0 RPCSRC -.de BT -.if \\n%=1 .tl ''- % -'' -.. -.ND -.\" prevent excess underlining in nroff -.if n .fp 2 R -.OH 'Network File System: Version 2 Protocol Specification''Page %' -.EH 'Page %''Network File System: Version 2 Protocol Specification' -.if \\n%=1 .bp -.SH -\&Network File System: Version 2 Protocol Specification -.IX NFS "" "" "" PAGE MAJOR -.IX "Network File System" "" "" "" PAGE MAJOR -.IX NFS "version-2 protocol specification" -.IX "Network File System" "version-2 protocol specification" -.LP -.NH 0 -\&Status of this Standard -.LP -Note: This document specifies a protocol that Sun Microsystems, Inc., -and others are using. It specifies it in standard ARPA RFC form. -.NH 1 -\&Introduction -.IX NFS introduction -.LP -The Sun Network Filesystem (NFS) protocol provides transparent remote -access to shared filesystems over local area networks. The NFS -protocol is designed to be machine, operating system, network architecture, -and transport protocol independent. This independence is -achieved through the use of Remote Procedure Call (RPC) primitives -built on top of an External Data Representation (XDR). Implementations -exist for a variety of machines, from personal computers to -supercomputers. -.LP -The supporting mount protocol allows the server to hand out remote -access privileges to a restricted set of clients. It performs the -operating system-specific functions that allow, for example, to -attach remote directory trees to some local file system. -.NH 2 -\&Remote Procedure Call -.IX "Remote Procedure Call" -.LP -Sun's remote procedure call specification provides a procedure- -oriented interface to remote services. Each server supplies a -program that is a set of procedures. NFS is one such "program". -The combination of host address, program number, and procedure -number specifies one remote service procedure. RPC does not depend -on services provided by specific protocols, so it can be used with -any underlying transport protocol. See the -.I "Remote Procedure Calls: Protocol Specification" -chapter of this manual. -.NH 2 -\&External Data Representation -.IX "External Data Representation" -.LP -The External Data Representation (XDR) standard provides a common -way of representing a set of data types over a network. -The NFS -Protocol Specification is written using the RPC data description -language. -For more information, see the -.I " External Data Representation Standard: Protocol Specification." -Sun provides implementations of XDR and -RPC, but NFS does not require their use. Any software that -provides equivalent functionality can be used, and if the encoding -is exactly the same it can interoperate with other implementations -of NFS. -.NH 2 -\&Stateless Servers -.IX "stateless servers" -.IX servers stateless -.LP -The NFS protocol is stateless. That is, a server does not need to -maintain any extra state information about any of its clients in -order to function correctly. Stateless servers have a distinct -advantage over stateful servers in the event of a failure. With -stateless servers, a client need only retry a request until the -server responds; it does not even need to know that the server has -crashed, or the network temporarily went down. The client of a -stateful server, on the other hand, needs to either detect a server -crash and rebuild the server's state when it comes back up, or -cause client operations to fail. -.LP -This may not sound like an important issue, but it affects the -protocol in some unexpected ways. We feel that it is worth a bit -of extra complexity in the protocol to be able to write very simple -servers that do not require fancy crash recovery. -.LP -On the other hand, NFS deals with objects such as files and -directories that inherently have state -- what good would a file be -if it did not keep its contents intact? The goal is to not -introduce any extra state in the protocol itself. Another way to -simplify recovery is by making operations "idempotent" whenever -possible (so that they can potentially be repeated). -.NH 1 -\&NFS Protocol Definition -.IX NFS "protocol definition" -.IX NFS protocol -.LP -Servers have been known to change over time, and so can the -protocol that they use. So RPC provides a version number with each -RPC request. This RFC describes version two of the NFS protocol. -Even in the second version, there are various obsolete procedures -and parameters, which will be removed in later versions. An RFC -for version three of the NFS protocol is currently under -preparation. -.NH 2 -\&File System Model -.IX filesystem model -.LP -NFS assumes a file system that is hierarchical, with directories as -all but the bottom-level files. Each entry in a directory (file, -directory, device, etc.) has a string name. Different operating -systems may have restrictions on the depth of the tree or the names -used, as well as using different syntax to represent the "pathname", -which is the concatenation of all the "components" (directory and -file names) in the name. A "file system" is a tree on a single -server (usually a single disk or physical partition) with a specified -"root". Some operating systems provide a "mount" operation to make -all file systems appear as a single tree, while others maintain a -"forest" of file systems. Files are unstructured streams of -uninterpreted bytes. Version 3 of NFS uses a slightly more general -file system model. -.LP -NFS looks up one component of a pathname at a time. It may not be -obvious why it does not just take the whole pathname, traipse down -the directories, and return a file handle when it is done. There are -several good reasons not to do this. First, pathnames need -separators between the directory components, and different operating -systems use different separators. We could define a Network Standard -Pathname Representation, but then every pathname would have to be -parsed and converted at each end. Other issues are discussed in -\fINFS Implementation Issues\fP below. -.LP -Although files and directories are similar objects in many ways, -different procedures are used to read directories and files. This -provides a network standard format for representing directories. The -same argument as above could have been used to justify a procedure -that returns only one directory entry per call. The problem is -efficiency. Directories can contain many entries, and a remote call -to return each would be just too slow. -.NH 2 -\&RPC Information -.IX NFS "RPC information" -.IP \fIAuthentication\fP -The NFS service uses -.I AUTH_UNIX , -.I AUTH_DES , -or -.I AUTH_SHORT -style -authentication, except in the NULL procedure where -.I AUTH_NONE -is also allowed. -.IP "\fITransport Protocols\fP" -NFS currently is supported on UDP/IP only. -.IP "\fIPort Number\fP" -The NFS protocol currently uses the UDP port number 2049. This is -not an officially assigned port, so later versions of the protocol -use the \*QPortmapping\*U facility of RPC. -.NH 2 -\&Sizes of XDR Structures -.IX "XDR structure sizes" -.LP -These are the sizes, given in decimal bytes, of various XDR -structures used in the protocol: -.DS -/* \fIThe maximum number of bytes of data in a READ or WRITE request\fP */ -const MAXDATA = 8192; - -/* \fIThe maximum number of bytes in a pathname argument\fP */ -const MAXPATHLEN = 1024; - -/* \fIThe maximum number of bytes in a file name argument\fP */ -const MAXNAMLEN = 255; - -/* \fIThe size in bytes of the opaque "cookie" passed by READDIR\fP */ -const COOKIESIZE = 4; - -/* \fIThe size in bytes of the opaque file handle\fP */ -const FHSIZE = 32; -.DE -.NH 2 -\&Basic Data Types -.IX "NFS data types" -.IX NFS "basic data types" -.LP -The following XDR definitions are basic structures and types used -in other structures described further on. -.KS -.NH 3 -\&stat -.IX "NFS data types" stat "" \fIstat\fP -.DS -enum stat { - NFS_OK = 0, - NFSERR_PERM=1, - NFSERR_NOENT=2, - NFSERR_IO=5, - NFSERR_NXIO=6, - NFSERR_ACCES=13, - NFSERR_EXIST=17, - NFSERR_NODEV=19, - NFSERR_NOTDIR=20, - NFSERR_ISDIR=21, - NFSERR_FBIG=27, - NFSERR_NOSPC=28, - NFSERR_ROFS=30, - NFSERR_NAMETOOLONG=63, - NFSERR_NOTEMPTY=66, - NFSERR_DQUOT=69, - NFSERR_STALE=70, - NFSERR_WFLUSH=99 -}; -.DE -.KE -.LP -The -.I stat -type is returned with every procedure's results. A -value of -.I NFS_OK -indicates that the call completed successfully and -the results are valid. The other values indicate some kind of -error occurred on the server side during the servicing of the -procedure. The error values are derived from UNIX error numbers. -.IP \fBNFSERR_PERM\fP: -Not owner. The caller does not have correct ownership -to perform the requested operation. -.IP \fBNFSERR_NOENT\fP: -No such file or directory. The file or directory -specified does not exist. -.IP \fBNFSERR_IO\fP: -Some sort of hard error occurred when the operation was -in progress. This could be a disk error, for example. -.IP \fBNFSERR_NXIO\fP: -No such device or address. -.IP \fBNFSERR_ACCES\fP: -Permission denied. The caller does not have the -correct permission to perform the requested operation. -.IP \fBNFSERR_EXIST\fP: -File exists. The file specified already exists. -.IP \fBNFSERR_NODEV\fP: -No such device. -.IP \fBNFSERR_NOTDIR\fP: -Not a directory. The caller specified a -non-directory in a directory operation. -.IP \fBNFSERR_ISDIR\fP: -Is a directory. The caller specified a directory in -a non- directory operation. -.IP \fBNFSERR_FBIG\fP: -File too large. The operation caused a file to grow -beyond the server's limit. -.IP \fBNFSERR_NOSPC\fP: -No space left on device. The operation caused the -server's filesystem to reach its limit. -.IP \fBNFSERR_ROFS\fP: -Read-only filesystem. Write attempted on a read-only filesystem. -.IP \fBNFSERR_NAMETOOLONG\fP: -File name too long. The file name in an operation was too long. -.IP \fBNFSERR_NOTEMPTY\fP: -Directory not empty. Attempted to remove a -directory that was not empty. -.IP \fBNFSERR_DQUOT\fP: -Disk quota exceeded. The client's disk quota on the -server has been exceeded. -.IP \fBNFSERR_STALE\fP: -The "fhandle" given in the arguments was invalid. -That is, the file referred to by that file handle no longer exists, -or access to it has been revoked. -.IP \fBNFSERR_WFLUSH\fP: -The server's write cache used in the -.I WRITECACHE -call got flushed to disk. -.LP -.KS -.NH 3 -\&ftype -.IX "NFS data types" ftype "" \fIftype\fP -.DS -enum ftype { - NFNON = 0, - NFREG = 1, - NFDIR = 2, - NFBLK = 3, - NFCHR = 4, - NFLNK = 5 -}; -.DE -.KE -The enumeration -.I ftype -gives the type of a file. The type -.I NFNON -indicates a non-file, -.I NFREG -is a regular file, -.I NFDIR -is a directory, -.I NFBLK -is a block-special device, -.I NFCHR -is a character-special device, and -.I NFLNK -is a symbolic link. -.KS -.NH 3 -\&fhandle -.IX "NFS data types" fhandle "" \fIfhandle\fP -.DS -typedef opaque fhandle[FHSIZE]; -.DE -.KE -The -.I fhandle -is the file handle passed between the server and the client. -All file operations are done using file handles to refer to a file or -directory. The file handle can contain whatever information the server -needs to distinguish an individual file. -.KS -.NH 3 -\&timeval -.IX "NFS data types" timeval "" \fItimeval\fP -.DS -struct timeval { - unsigned int seconds; - unsigned int useconds; -}; -.DE -.KE -The -.I timeval -structure is the number of seconds and microseconds -since midnight January 1, 1970, Greenwich Mean Time. It is used to -pass time and date information. -.KS -.NH 3 -\&fattr -.IX "NFS data types" fattr "" \fIfattr\fP -.DS -struct fattr { - ftype type; - unsigned int mode; - unsigned int nlink; - unsigned int uid; - unsigned int gid; - unsigned int size; - unsigned int blocksize; - unsigned int rdev; - unsigned int blocks; - unsigned int fsid; - unsigned int fileid; - timeval atime; - timeval mtime; - timeval ctime; -}; -.DE -.KE -The -.I fattr -structure contains the attributes of a file; "type" is the type of -the file; "nlink" is the number of hard links to the file (the number -of different names for the same file); "uid" is the user -identification number of the owner of the file; "gid" is the group -identification number of the group of the file; "size" is the size in -bytes of the file; "blocksize" is the size in bytes of a block of the -file; "rdev" is the device number of the file if it is type -.I NFCHR -or -.I NFBLK ; -"blocks" is the number of blocks the file takes up on disk; "fsid" is -the file system identifier for the filesystem containing the file; -"fileid" is a number that uniquely identifies the file within its -filesystem; "atime" is the time when the file was last accessed for -either read or write; "mtime" is the time when the file data was last -modified (written); and "ctime" is the time when the status of the -file was last changed. Writing to the file also changes "ctime" if -the size of the file changes. -.LP -"mode" is the access mode encoded as a set of bits. Notice that the -file type is specified both in the mode bits and in the file type. -This is really a bug in the protocol and will be fixed in future -versions. The descriptions given below specify the bit positions -using octal numbers. -.TS -box tab (&) ; -cfI cfI -lfL l . -Bit&Description -_ -0040000&This is a directory; "type" field should be NFDIR. -0020000&This is a character special file; "type" field should be NFCHR. -0060000&This is a block special file; "type" field should be NFBLK. -0100000&This is a regular file; "type" field should be NFREG. -0120000&This is a symbolic link file; "type" field should be NFLNK. -0140000&This is a named socket; "type" field should be NFNON. -0004000&Set user id on execution. -0002000&Set group id on execution. -0001000&Save swapped text even after use. -0000400&Read permission for owner. -0000200&Write permission for owner. -0000100&Execute and search permission for owner. -0000040&Read permission for group. -0000020&Write permission for group. -0000010&Execute and search permission for group. -0000004&Read permission for others. -0000002&Write permission for others. -0000001&Execute and search permission for others. -.TE -.KS -Notes: -.IP -The bits are the same as the mode bits returned by the -.I stat(2) -system call in the UNIX system. The file type is specified both in -the mode bits and in the file type. This is fixed in future -versions. -.IP -The "rdev" field in the attributes structure is an operating system -specific device specifier. It will be removed and generalized in -the next revision of the protocol. -.KE -.LP -.KS -.NH 3 -\&sattr -.IX "NFS data types" sattr "" \fIsattr\fP -.DS -struct sattr { - unsigned int mode; - unsigned int uid; - unsigned int gid; - unsigned int size; - timeval atime; - timeval mtime; -}; -.DE -.KE -The -.I sattr -structure contains the file attributes which can be set -from the client. The fields are the same as for -.I fattr -above. A "size" of zero means the file should be truncated. -A value of -1 indicates a field that should be ignored. -.LP -.KS -.NH 3 -\&filename -.IX "NFS data types" filename "" \fIfilename\fP -.DS -typedef string filename; -.DE -.KE -The type -.I filename -is used for passing file names or pathname components. -.LP -.KS -.NH 3 -\&path -.IX "NFS data types" path "" \fIpath\fP -.DS -typedef string path; -.DE -.KE -The type -.I path -is a pathname. The server considers it as a string -with no internal structure, but to the client it is the name of a -node in a filesystem tree. -.LP -.KS -.NH 3 -\&attrstat -.IX "NFS data types" attrstat "" \fIattrstat\fP -.DS -union attrstat switch (stat status) { - case NFS_OK: - fattr attributes; - default: - void; -}; -.DE -.KE -The -.I attrstat -structure is a common procedure result. It contains -a "status" and, if the call succeeded, it also contains the -attributes of the file on which the operation was done. -.LP -.KS -.NH 3 -\&diropargs -.IX "NFS data types" diropargs "" \fIdiropargs\fP -.DS -struct diropargs { - fhandle dir; - filename name; -}; -.DE -.KE -The -.I diropargs -structure is used in directory operations. The -"fhandle" "dir" is the directory in which to find the file "name". -A directory operation is one in which the directory is affected. -.LP -.KS -.NH 3 -\&diropres -.IX "NFS data types" diropres "" \fIdiropres\fP -.DS -union diropres switch (stat status) { - case NFS_OK: - struct { - fhandle file; - fattr attributes; - } diropok; - default: - void; -}; -.DE -.KE -The results of a directory operation are returned in a -.I diropres -structure. If the call succeeded, a new file handle "file" and the -"attributes" associated with that file are returned along with the -"status". -.NH 2 -\&Server Procedures -.IX "NFS server procedures" "" "" "" PAGE MAJOR -.LP -The protocol definition is given as a set of procedures with -arguments and results defined using the RPC language. A brief -description of the function of each procedure should provide enough -information to allow implementation. -.LP -All of the procedures in the NFS protocol are assumed to be -synchronous. When a procedure returns to the client, the client -can assume that the operation has completed and any data associated -with the request is now on stable storage. For example, a client -.I WRITE -request may cause the server to update data blocks, -filesystem information blocks (such as indirect blocks), and file -attribute information (size and modify times). When the -.I WRITE -returns to the client, it can assume that the write is safe, even -in case of a server crash, and it can discard the data written. -This is a very important part of the statelessness of the server. -If the server waited to flush data from remote requests, the client -would have to save those requests so that it could resend them in -case of a server crash. -.ie t .DS -.el .DS L - -.ft I -/* -* Remote file service routines -*/ -.ft CW -program NFS_PROGRAM { - version NFS_VERSION { - void NFSPROC_NULL(void) = 0; - attrstat NFSPROC_GETATTR(fhandle) = 1; - attrstat NFSPROC_SETATTR(sattrargs) = 2; - void NFSPROC_ROOT(void) = 3; - diropres NFSPROC_LOOKUP(diropargs) = 4; - readlinkres NFSPROC_READLINK(fhandle) = 5; - readres NFSPROC_READ(readargs) = 6; - void NFSPROC_WRITECACHE(void) = 7; - attrstat NFSPROC_WRITE(writeargs) = 8; - diropres NFSPROC_CREATE(createargs) = 9; - stat NFSPROC_REMOVE(diropargs) = 10; - stat NFSPROC_RENAME(renameargs) = 11; - stat NFSPROC_LINK(linkargs) = 12; - stat NFSPROC_SYMLINK(symlinkargs) = 13; - diropres NFSPROC_MKDIR(createargs) = 14; - stat NFSPROC_RMDIR(diropargs) = 15; - readdirres NFSPROC_READDIR(readdirargs) = 16; - statfsres NFSPROC_STATFS(fhandle) = 17; - } = 2; -} = 100003; -.DE -.KS -.NH 3 -\&Do Nothing -.IX "NFS server procedures" NFSPROC_NULL() "" \fINFSPROC_NULL()\fP -.DS -void -NFSPROC_NULL(void) = 0; -.DE -.KE -This procedure does no work. It is made available in all RPC -services to allow server response testing and timing. -.KS -.NH 3 -\&Get File Attributes -.IX "NFS server procedures" NFSPROC_GETATTR() "" \fINFSPROC_GETATTR()\fP -.DS -attrstat -NFSPROC_GETATTR (fhandle) = 1; -.DE -.KE -If the reply status is -.I NFS_OK , -then the reply attributes contains -the attributes for the file given by the input fhandle. -.KS -.NH 3 -\&Set File Attributes -.IX "NFS server procedures" NFSPROC_SETATTR() "" \fINFSPROC_SETATTR()\fP -.DS -struct sattrargs { - fhandle file; - sattr attributes; - }; - -attrstat -NFSPROC_SETATTR (sattrargs) = 2; -.DE -.KE -The "attributes" argument contains fields which are either -1 or -are the new value for the attributes of "file". If the reply -status is -.I NFS_OK , -then the reply attributes have the attributes of -the file after the "SETATTR" operation has completed. -.LP -Note: The use of -1 to indicate an unused field in "attributes" is -changed in the next version of the protocol. -.KS -.NH 3 -\&Get Filesystem Root -.IX "NFS server procedures" NFSPROC_ROOT "" \fINFSPROC_ROOT\fP -.DS -void -NFSPROC_ROOT(void) = 3; -.DE -.KE -Obsolete. This procedure is no longer used because finding the -root file handle of a filesystem requires moving pathnames between -client and server. To do this right we would have to define a -network standard representation of pathnames. Instead, the -function of looking up the root file handle is done by the -.I MNTPROC_MNT() -procedure. (See the -.I "Mount Protocol Definition" -later in this chapter for details). -.KS -.NH 3 -\&Look Up File Name -.IX "NFS server procedures" NFSPROC_LOOKUP() "" \fINFSPROC_LOOKUP()\fP -.DS -diropres -NFSPROC_LOOKUP(diropargs) = 4; -.DE -.KE -If the reply "status" is -.I NFS_OK , -then the reply "file" and reply -"attributes" are the file handle and attributes for the file "name" -in the directory given by "dir" in the argument. -.KS -.NH 3 -\&Read From Symbolic Link -.IX "NFS server procedures" NFSPROC_READLINK() "" \fINFSPROC_READLINK()\fP -.DS -union readlinkres switch (stat status) { - case NFS_OK: - path data; - default: - void; -}; - -readlinkres -NFSPROC_READLINK(fhandle) = 5; -.DE -.KE -If "status" has the value -.I NFS_OK , -then the reply "data" is the data in -the symbolic link given by the file referred to by the fhandle argument. -.LP -Note: since NFS always parses pathnames on the client, the -pathname in a symbolic link may mean something different (or be -meaningless) on a different client or on the server if a different -pathname syntax is used. -.KS -.NH 3 -\&Read From File -.IX "NFS server procedures" NFSPROC_READ "" \fINFSPROC_READ\fP -.DS -struct readargs { - fhandle file; - unsigned offset; - unsigned count; - unsigned totalcount; -}; - -union readres switch (stat status) { - case NFS_OK: - fattr attributes; - opaque data; - default: - void; -}; - -readres -NFSPROC_READ(readargs) = 6; -.DE -.KE -Returns up to "count" bytes of "data" from the file given by -"file", starting at "offset" bytes from the beginning of the file. -The first byte of the file is at offset zero. The file attributes -after the read takes place are returned in "attributes". -.LP -Note: The argument "totalcount" is unused, and is removed in the -next protocol revision. -.KS -.NH 3 -\&Write to Cache -.IX "NFS server procedures" NFSPROC_WRITECACHE() "" \fINFSPROC_WRITECACHE()\fP -.DS -void -NFSPROC_WRITECACHE(void) = 7; -.DE -.KE -To be used in the next protocol revision. -.KS -.NH 3 -\&Write to File -.IX "NFS server procedures" NFSPROC_WRITE() "" \fINFSPROC_WRITE()\fP -.DS -struct writeargs { - fhandle file; - unsigned beginoffset; - unsigned offset; - unsigned totalcount; - opaque data; -}; - -attrstat -NFSPROC_WRITE(writeargs) = 8; -.DE -.KE -Writes "data" beginning "offset" bytes from the beginning of -"file". The first byte of the file is at offset zero. If the -reply "status" is NFS_OK, then the reply "attributes" contains the -attributes of the file after the write has completed. The write -operation is atomic. Data from this call to -.I WRITE -will not be mixed with data from another client's calls. -.LP -Note: The arguments "beginoffset" and "totalcount" are ignored and -are removed in the next protocol revision. -.KS -.NH 3 -\&Create File -.IX "NFS server procedures" NFSPROC_CREATE() "" \fINFSPROC_CREATE()\fP -.DS -struct createargs { - diropargs where; - sattr attributes; -}; - -diropres -NFSPROC_CREATE(createargs) = 9; -.DE -.KE -The file "name" is created in the directory given by "dir". The -initial attributes of the new file are given by "attributes". A -reply "status" of NFS_OK indicates that the file was created, and -reply "file" and reply "attributes" are its file handle and -attributes. Any other reply "status" means that the operation -failed and no file was created. -.LP -Note: This routine should pass an exclusive create flag, meaning -"create the file only if it is not already there". -.KS -.NH 3 -\&Remove File -.IX "NFS server procedures" NFSPROC_REMOVE() "" \fINFSPROC_REMOVE()\fP -.DS -stat -NFSPROC_REMOVE(diropargs) = 10; -.DE -.KE -The file "name" is removed from the directory given by "dir". A -reply of NFS_OK means the directory entry was removed. -.LP -Note: possibly non-idempotent operation. -.KS -.NH 3 -\&Rename File -.IX "NFS server procedures" NFSPROC_RENAME() "" \fINFSPROC_RENAME()\fP -.DS -struct renameargs { - diropargs from; - diropargs to; -}; - -stat -NFSPROC_RENAME(renameargs) = 11; -.DE -.KE -The existing file "from.name" in the directory given by "from.dir" -is renamed to "to.name" in the directory given by "to.dir". If the -reply is -.I NFS_OK , -the file was renamed. The -RENAME -operation is -atomic on the server; it cannot be interrupted in the middle. -.LP -Note: possibly non-idempotent operation. -.KS -.NH 3 -\&Create Link to File -.IX "NFS server procedures" NFSPROC_LINK() "" \fINFSPROC_LINK()\fP -.DS -struct linkargs { - fhandle from; - diropargs to; -}; - -stat -NFSPROC_LINK(linkargs) = 12; -.DE -.KE -Creates the file "to.name" in the directory given by "to.dir", -which is a hard link to the existing file given by "from". If the -return value is -.I NFS_OK , -a link was created. Any other return value -indicates an error, and the link was not created. -.LP -A hard link should have the property that changes to either of the -linked files are reflected in both files. When a hard link is made -to a file, the attributes for the file should have a value for -"nlink" that is one greater than the value before the link. -.LP -Note: possibly non-idempotent operation. -.KS -.NH 3 -\&Create Symbolic Link -.IX "NFS server procedures" NFSPROC_SYMLINK() "" \fINFSPROC_SYMLINK()\fP -.DS -struct symlinkargs { - diropargs from; - path to; - sattr attributes; -}; - -stat -NFSPROC_SYMLINK(symlinkargs) = 13; -.DE -.KE -Creates the file "from.name" with ftype -.I NFLNK -in the directory -given by "from.dir". The new file contains the pathname "to" and -has initial attributes given by "attributes". If the return value -is -.I NFS_OK , -a link was created. Any other return value indicates an -error, and the link was not created. -.LP -A symbolic link is a pointer to another file. The name given in -"to" is not interpreted by the server, only stored in the newly -created file. When the client references a file that is a symbolic -link, the contents of the symbolic link are normally transparently -reinterpreted as a pathname to substitute. A -.I READLINK -operation returns the data to the client for interpretation. -.LP -Note: On UNIX servers the attributes are never used, since -symbolic links always have mode 0777. -.KS -.NH 3 -\&Create Directory -.IX "NFS server procedures" NFSPROC_MKDIR() "" \fINFSPROC_MKDIR()\fP -.DS -diropres -NFSPROC_MKDIR (createargs) = 14; -.DE -.KE -The new directory "where.name" is created in the directory given by -"where.dir". The initial attributes of the new directory are given -by "attributes". A reply "status" of NFS_OK indicates that the new -directory was created, and reply "file" and reply "attributes" are -its file handle and attributes. Any other reply "status" means -that the operation failed and no directory was created. -.LP -Note: possibly non-idempotent operation. -.KS -.NH 3 -\&Remove Directory -.IX "NFS server procedures" NFSPROC_RMDIR() "" \fINFSPROC_RMDIR()\fP -.DS -stat -NFSPROC_RMDIR(diropargs) = 15; -.DE -.KE -The existing empty directory "name" in the directory given by "dir" -is removed. If the reply is -.I NFS_OK , -the directory was removed. -.LP -Note: possibly non-idempotent operation. -.KS -.NH 3 -\&Read From Directory -.IX "NFS server procedures" NFSPROC_READDIR() "" \fINFSPROC_READDIR()\fP -.DS -struct readdirargs { - fhandle dir; - nfscookie cookie; - unsigned count; -}; - -struct entry { - unsigned fileid; - filename name; - nfscookie cookie; - entry *nextentry; -}; - -union readdirres switch (stat status) { - case NFS_OK: - struct { - entry *entries; - bool eof; - } readdirok; - default: - void; -}; - -readdirres -NFSPROC_READDIR (readdirargs) = 16; -.DE -.KE -Returns a variable number of directory entries, with a total size -of up to "count" bytes, from the directory given by "dir". If the -returned value of "status" is -.I NFS_OK , -then it is followed by a -variable number of "entry"s. Each "entry" contains a "fileid" -which consists of a unique number to identify the file within a -filesystem, the "name" of the file, and a "cookie" which is an -opaque pointer to the next entry in the directory. The cookie is -used in the next -.I READDIR -call to get more entries starting at a -given point in the directory. The special cookie zero (all bits -zero) can be used to get the entries starting at the beginning of -the directory. The "fileid" field should be the same number as the -"fileid" in the the attributes of the file. (See the -.I "Basic Data Types" -section.) -The "eof" flag has a value of -.I TRUE -if there are no more entries in the directory. -.KS -.NH 3 -\&Get Filesystem Attributes -.IX "NFS server procedures" NFSPROC_STATFS() "" \fINFSPROC_STATFS()\fP -.DS -union statfsres (stat status) { - case NFS_OK: - struct { - unsigned tsize; - unsigned bsize; - unsigned blocks; - unsigned bfree; - unsigned bavail; - } info; - default: - void; -}; - -statfsres -NFSPROC_STATFS(fhandle) = 17; -.DE -.KE -If the reply "status" is -.I NFS_OK , -then the reply "info" gives the -attributes for the filesystem that contains file referred to by the -input fhandle. The attribute fields contain the following values: -.IP tsize: -The optimum transfer size of the server in bytes. This is -the number of bytes the server would like to have in the -data part of READ and WRITE requests. -.IP bsize: -The block size in bytes of the filesystem. -.IP blocks: -The total number of "bsize" blocks on the filesystem. -.IP bfree: -The number of free "bsize" blocks on the filesystem. -.IP bavail: -The number of "bsize" blocks available to non-privileged users. -.LP -Note: This call does not work well if a filesystem has variable -size blocks. -.NH 1 -\&NFS Implementation Issues -.IX NFS implementation -.LP -The NFS protocol is designed to be operating system independent, but -since this version was designed in a UNIX environment, many -operations have semantics similar to the operations of the UNIX file -system. This section discusses some of the implementation-specific -semantic issues. -.NH 2 -\&Server/Client Relationship -.IX NFS "server/client relationship" -.LP -The NFS protocol is designed to allow servers to be as simple and -general as possible. Sometimes the simplicity of the server can be a -problem, if the client wants to implement complicated filesystem -semantics. -.LP -For example, some operating systems allow removal of open files. A -process can open a file and, while it is open, remove it from the -directory. The file can be read and written as long as the process -keeps it open, even though the file has no name in the filesystem. -It is impossible for a stateless server to implement these semantics. -The client can do some tricks such as renaming the file on remove, -and only removing it on close. We believe that the server provides -enough functionality to implement most file system semantics on the -client. -.LP -Every NFS client can also potentially be a server, and remote and -local mounted filesystems can be freely intermixed. This leads to -some interesting problems when a client travels down the directory -tree of a remote filesystem and reaches the mount point on the server -for another remote filesystem. Allowing the server to follow the -second remote mount would require loop detection, server lookup, and -user revalidation. Instead, we decided not to let clients cross a -server's mount point. When a client does a LOOKUP on a directory on -which the server has mounted a filesystem, the client sees the -underlying directory instead of the mounted directory. A client can -do remote mounts that match the server's mount points to maintain the -server's view. -.LP -.NH 2 -\&Pathname Interpretation -.IX NFS "pathname interpretation" -.LP -There are a few complications to the rule that pathnames are always -parsed on the client. For example, symbolic links could have -different interpretations on different clients. Another common -problem for non-UNIX implementations is the special interpretation of -the pathname ".." to mean the parent of a given directory. The next -revision of the protocol uses an explicit flag to indicate the parent -instead. -.NH 2 -\&Permission Issues -.IX NFS "permission issues" -.LP -The NFS protocol, strictly speaking, does not define the permission -checking used by servers. However, it is expected that a server -will do normal operating system permission checking using -.I AUTH_UNIX -style authentication as the basis of its protection mechanism. The -server gets the client's effective "uid", effective "gid", and groups -on each call and uses them to check permission. There are various -problems with this method that can been resolved in interesting ways. -.LP -Using "uid" and "gid" implies that the client and server share the -same "uid" list. Every server and client pair must have the same -mapping from user to "uid" and from group to "gid". Since every -client can also be a server, this tends to imply that the whole -network shares the same "uid/gid" space. -.I AUTH_DES -(and the next -revision of the NFS protocol) uses string names instead of numbers, -but there are still complex problems to be solved. -.LP -Another problem arises due to the usually stateful open operation. -Most operating systems check permission at open time, and then check -that the file is open on each read and write request. With stateless -servers, the server has no idea that the file is open and must do -permission checking on each read and write call. On a local -filesystem, a user can open a file and then change the permissions so -that no one is allowed to touch it, but will still be able to write -to the file because it is open. On a remote filesystem, by contrast, -the write would fail. To get around this problem, the server's -permission checking algorithm should allow the owner of a file to -access it regardless of the permission setting. -.LP -A similar problem has to do with paging in from a file over the -network. The operating system usually checks for execute permission -before opening a file for demand paging, and then reads blocks from -the open file. The file may not have read permission, but after it -is opened it doesn't matter. An NFS server can not tell the -difference between a normal file read and a demand page-in read. To -make this work, the server allows reading of files if the "uid" given -in the call has execute or read permission on the file. -.LP -In most operating systems, a particular user (on the user ID zero) -has access to all files no matter what permission and ownership they -have. This "super-user" permission may not be allowed on the server, -since anyone who can become super-user on their workstation could -gain access to all remote files. The UNIX server by default maps -user id 0 to -2 before doing its access checking. This works except -for NFS root filesystems, where super-user access cannot be avoided. -.NH 2 -\&Setting RPC Parameters -.IX NFS "setting RPC parameters" -.LP -Various file system parameters and options should be set at mount -time. The mount protocol is described in the appendix below. For -example, "Soft" mounts as well as "Hard" mounts are usually both -provided. Soft mounted file systems return errors when RPC -operations fail (after a given number of optional retransmissions), -while hard mounted file systems continue to retransmit forever. -Clients and servers may need to keep caches of recent operations to -help avoid problems with non-idempotent operations. -.NH 1 -\&Mount Protocol Definition -.IX "mount protocol" "" "" "" PAGE MAJOR -.sp 1 -.NH 2 -\&Introduction -.IX "mount protocol" introduction -.LP -The mount protocol is separate from, but related to, the NFS -protocol. It provides operating system specific services to get the -NFS off the ground -- looking up server path names, validating user -identity, and checking access permissions. Clients use the mount -protocol to get the first file handle, which allows them entry into a -remote filesystem. -.LP -The mount protocol is kept separate from the NFS protocol to make it -easy to plug in new access checking and validation methods without -changing the NFS server protocol. -.LP -Notice that the protocol definition implies stateful servers because -the server maintains a list of client's mount requests. The mount -list information is not critical for the correct functioning of -either the client or the server. It is intended for advisory use -only, for example, to warn possible clients when a server is going -down. -.LP -Version one of the mount protocol is used with version two of the NFS -protocol. The only connecting point is the -.I fhandle -structure, which is the same for both protocols. -.NH 2 -\&RPC Information -.IX "mount protocol" "RPC information" -.IP \fIAuthentication\fP -The mount service uses -.I AUTH_UNIX -and -.I AUTH_DES -style authentication only. -.IP "\fITransport Protocols\fP" -The mount service is currently supported on UDP/IP only. -.IP "\fIPort Number\fP" -Consult the server's portmapper, described in the chapter -.I "Remote Procedure Calls: Protocol Specification", -to find the port number on which the mount service is registered. -.NH 2 -\&Sizes of XDR Structures -.IX "mount protocol" "XDR structure sizes" -.LP -These are the sizes, given in decimal bytes, of various XDR -structures used in the protocol: -.DS -/* \fIThe maximum number of bytes in a pathname argument\fP */ -const MNTPATHLEN = 1024; - -/* \fIThe maximum number of bytes in a name argument\fP */ -const MNTNAMLEN = 255; - -/* \fIThe size in bytes of the opaque file handle\fP */ -const FHSIZE = 32; -.DE -.NH 2 -\&Basic Data Types -.IX "mount protocol" "basic data types" -.IX "mount data types" -.LP -This section presents the data types used by the mount protocol. -In many cases they are similar to the types used in NFS. -.KS -.NH 3 -\&fhandle -.IX "mount data types" fhandle "" \fIfhandle\fP -.DS -typedef opaque fhandle[FHSIZE]; -.DE -.KE -The type -.I fhandle -is the file handle that the server passes to the -client. All file operations are done using file handles to refer -to a file or directory. The file handle can contain whatever -information the server needs to distinguish an individual file. -.LP -This is the same as the "fhandle" XDR definition in version 2 of -the NFS protocol; see -.I "Basic Data Types" -in the definition of the NFS protocol, above. -.KS -.NH 3 -\&fhstatus -.IX "mount data types" fhstatus "" \fIfhstatus\fP -.DS -union fhstatus switch (unsigned status) { - case 0: - fhandle directory; - default: - void; -}; -.DE -.KE -The type -.I fhstatus -is a union. If a "status" of zero is returned, -the call completed successfully, and a file handle for the -"directory" follows. A non-zero status indicates some sort of -error. In this case the status is a UNIX error number. -.KS -.NH 3 -\&dirpath -.IX "mount data types" dirpath "" \fIdirpath\fP -.DS -typedef string dirpath; -.DE -.KE -The type -.I dirpath -is a server pathname of a directory. -.KS -.NH 3 -\&name -.IX "mount data types" name "" \fIname\fP -.DS -typedef string name; -.DE -.KE -The type -.I name -is an arbitrary string used for various names. -.NH 2 -\&Server Procedures -.IX "mount server procedures" -.LP -The following sections define the RPC procedures supplied by a -mount server. -.ie t .DS -.el .DS L -.ft I -/* -* Protocol description for the mount program -*/ -.ft CW - -program MOUNTPROG { -.ft I -/* -* Version 1 of the mount protocol used with -* version 2 of the NFS protocol. -*/ -.ft CW - version MOUNTVERS { - void MOUNTPROC_NULL(void) = 0; - fhstatus MOUNTPROC_MNT(dirpath) = 1; - mountlist MOUNTPROC_DUMP(void) = 2; - void MOUNTPROC_UMNT(dirpath) = 3; - void MOUNTPROC_UMNTALL(void) = 4; - exportlist MOUNTPROC_EXPORT(void) = 5; - } = 1; -} = 100005; -.DE -.KS -.NH 3 -\&Do Nothing -.IX "mount server procedures" MNTPROC_NULL() "" \fIMNTPROC_NULL()\fP -.DS -void -MNTPROC_NULL(void) = 0; -.DE -.KE -This procedure does no work. It is made available in all RPC -services to allow server response testing and timing. -.KS -.NH 3 -\&Add Mount Entry -.IX "mount server procedures" MNTPROC_MNT() "" \fIMNTPROC_MNT()\fP -.DS -fhstatus -MNTPROC_MNT(dirpath) = 1; -.DE -.KE -If the reply "status" is 0, then the reply "directory" contains the -file handle for the directory "dirname". This file handle may be -used in the NFS protocol. This procedure also adds a new entry to -the mount list for this client mounting "dirname". -.KS -.NH 3 -\&Return Mount Entries -.IX "mount server procedures" MNTPROC_DUMP() "" \fIMNTPROC_DUMP()\fP -.DS -struct *mountlist { - name hostname; - dirpath directory; - mountlist nextentry; -}; - -mountlist -MNTPROC_DUMP(void) = 2; -.DE -.KE -Returns the list of remote mounted filesystems. The "mountlist" -contains one entry for each "hostname" and "directory" pair. -.KS -.NH 3 -\&Remove Mount Entry -.IX "mount server procedures" MNTPROC_UMNT() "" \fIMNTPROC_UMNT()\fP -.DS -void -MNTPROC_UMNT(dirpath) = 3; -.DE -.KE -Removes the mount list entry for the input "dirpath". -.KS -.NH 3 -\&Remove All Mount Entries -.IX "mount server procedures" MNTPROC_UMNTALL() "" \fIMNTPROC_UMNTALL()\fP -.DS -void -MNTPROC_UMNTALL(void) = 4; -.DE -.KE -Removes all of the mount list entries for this client. -.KS -.NH 3 -\&Return Export List -.IX "mount server procedures" MNTPROC_EXPORT() "" \fIMNTPROC_EXPORT()\fP -.DS -struct *groups { - name grname; - groups grnext; -}; - -struct *exportlist { - dirpath filesys; - groups groups; - exportlist next; -}; - -exportlist -MNTPROC_EXPORT(void) = 5; -.DE -.KE -Returns a variable number of export list entries. Each entry -contains a filesystem name and a list of groups that are allowed to -import it. The filesystem name is in "filesys", and the group name -is in the list "groups". -.LP -Note: The exportlist should contain -more information about the status of the filesystem, such as a -read-only flag. diff --git a/c/src/librpc/src/rpc/PSD.doc/rpc.prog.ms b/c/src/librpc/src/rpc/PSD.doc/rpc.prog.ms deleted file mode 100644 index 3b02447fe8..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/rpc.prog.ms +++ /dev/null @@ -1,2684 +0,0 @@ -.\" -.\" Must use -- tbl and pic -- with this one -.\" -.\" @(#)rpc.prog.ms 2.3 88/08/11 4.0 RPCSRC -.de BT -.if \\n%=1 .tl ''- % -'' -.. -.IX "Network Programming" "" "" "" PAGE MAJOR -.nr OF 0 -.ND -.\" prevent excess underlining in nroff -.if n .fp 2 R -.OH 'Remote Procedure Call Programming Guide''Page %' -.EH 'Page %''Remote Procedure Call Programming Guide' -.SH -\&Remote Procedure Call Programming Guide -.nr OF 1 -.IX "RPC Programming Guide" -.LP -This document assumes a working knowledge of network theory. It is -intended for programmers who wish to write network applications using -remote procedure calls (explained below), and who want to understand -the RPC mechanisms usually hidden by the -.I rpcgen(1) -protocol compiler. -.I rpcgen -is described in detail in the previous chapter, the -.I "\fBrpcgen\fP \fIProgramming Guide\fP". -.SH -Note: -.I -.IX rpcgen "" \fIrpcgen\fP -Before attempting to write a network application, or to convert an -existing non-network application to run over the network, you may want to -understand the material in this chapter. However, for most applications, -you can circumvent the need to cope with the details presented here by using -.I rpcgen . -The -.I "Generating XDR Routines" -section of that chapter contains the complete source for a working RPC -service\(ema remote directory listing service which uses -.I rpcgen -to generate XDR routines as well as client and server stubs. -.LP -.LP -What are remote procedure calls? Simply put, they are the high-level -communications paradigm used in the operating system. -RPC presumes the existence of -low-level networking mechanisms (such as TCP/IP and UDP/IP), and upon them -it implements a logical client to server communications system designed -specifically for the support of network applications. With RPC, the client -makes a procedure call to send a data packet to the server. When the -packet arrives, the server calls a dispatch routine, performs whatever -service is requested, sends back the reply, and the procedure call returns -to the client. -.NH 0 -\&Layers of RPC -.IX "layers of RPC" -.IX "RPC" "layers" -.LP -The RPC interface can be seen as being divided into three layers.\** -.FS -For a complete specification of the routines in the remote procedure -call Library, see the -.I rpc(3N) -manual page. -.FE -.LP -.I "The Highest Layer:" -.IX RPC "The Highest Layer" -The highest layer is totally transparent to the operating system, -machine and network upon which is is run. It's probably best to -think of this level as a way of -.I using -RPC, rather than as -a \fIpart of\fP RPC proper. Programmers who write RPC routines -should (almost) always make this layer available to others by way -of a simple C front end that entirely hides the networking. -.LP -To illustrate, at this level a program can simply make a call to -.I rnusers (), -a C routine which returns the number of users on a remote machine. -The user is not explicitly aware of using RPC \(em they simply -call a procedure, just as they would call -.I malloc() . -.LP -.I "The Middle Layer:" -.IX RPC "The Middle Layer" -The middle layer is really \*QRPC proper.\*U Here, the user doesn't -need to consider details about sockets, the UNIX system, or other low-level -implementation mechanisms. They simply make remote procedure calls -to routines on other machines. The selling point here is simplicity. -It's this layer that allows RPC to pass the \*Qhello world\*U test \(em -simple things should be simple. The middle-layer routines are used -for most applications. -.LP -RPC calls are made with the system routines -.I registerrpc() -.I callrpc() -and -.I svc_run (). -The first two of these are the most fundamental: -.I registerrpc() -obtains a unique system-wide procedure-identification number, and -.I callrpc() -actually executes a remote procedure call. At the middle level, a -call to -.I rnusers() -is implemented by way of these two routines. -.LP -The middle layer is unfortunately rarely used in serious programming -due to its inflexibility (simplicity). It does not allow timeout -specifications or the choice of transport. It allows no UNIX -process control or flexibility in case of errors. It doesn't support -multiple kinds of call authentication. The programmer rarely needs -all these kinds of control, but one or two of them is often necessary. -.LP -.I "The Lowest Layer:" -.IX RPC "The Lowest Layer" -The lowest layer does allow these details to be controlled by the -programmer, and for that reason it is often necessary. Programs -written at this level are also most efficient, but this is rarely a -real issue \(em since RPC clients and servers rarely generate -heavy network loads. -.LP -Although this document only discusses the interface to C, -remote procedure calls can be made from any language. -Even though this document discusses RPC -when it is used to communicate -between processes on different machines, -it works just as well for communication -between different processes on the same machine. -.br -.KS -.NH 2 -\&The RPC Paradigm -.IX RPC paradigm -.LP -Here is a diagram of the RPC paradigm: -.LP -\fBFigure 1-1\fI Network Communication with the Remote Reocedure Call\fR -.LP -.PS -L1: arrow down 1i "client " rjust "program " rjust -L2: line right 1.5i "\fIcallrpc\fP" "function" -move up 1.5i; line dotted down 6i; move up 4.5i -arrow right 1i -L3: arrow down 1i "invoke " rjust "service " rjust -L4: arrow right 1.5i "call" "service" -L5: arrow down 1i " service" ljust " executes" ljust -L6: arrow left 1.5i "\fIreturn\fP" "answer" -L7: arrow down 1i "request " rjust "completed " rjust -L8: line left 1i -arrow left 1.5i "\fIreturn\fP" "reply" -L9: arrow down 1i "program " rjust "continues " rjust -line dashed down from L2 to L9 -line dashed down from L4 to L7 -line dashed up 1i from L3 "service " rjust "daemon " rjust -arrow dashed down 1i from L8 -move right 1i from L3 -box invis "Machine B" -move left 1.2i from L2; move down -box invis "Machine A" -.PE -.KE -.KS -.NH 1 -\&Higher Layers of RPC -.NH 2 -\&Highest Layer -.IX "highest layer of RPC" -.IX RPC "highest layer" -.LP -Imagine you're writing a program that needs to know -how many users are logged into a remote machine. -You can do this by calling the RPC library routine -.I rnusers() -as illustrated below: -.ie t .DS -.el .DS L -.ft CW -#include - -main(argc, argv) - int argc; - char **argv; -{ - int num; - - if (argc != 2) { - fprintf(stderr, "usage: rnusers hostname\en"); - exit(1); - } - if ((num = rnusers(argv[1])) < 0) { - fprintf(stderr, "error: rnusers\en"); - exit(-1); - } - printf("%d users on %s\en", num, argv[1]); - exit(0); -} -.DE -.KE -RPC library routines such as -.I rnusers() -are in the RPC services library -.I librpcsvc.a -Thus, the program above should be compiled with -.DS -.ft CW -% cc \fIprogram.c -lrpcsvc\fP -.DE -.I rnusers (), -like the other RPC library routines, is documented in section 3R -of the -.I "System Interface Manual for the Sun Workstation" , -the same section which documents the standard Sun RPC services. -.IX "RPC Services" -See the -.I intro(3R) -manual page for an explanation of the documentation strategy -for these services and their RPC protocols. -.LP -Here are some of the RPC service library routines available to the -C programmer: -.LP -\fBTable 3-3\fI RPC Service Library Routines\RP -.TS -box tab (&) ; -cfI cfI -lfL l . -Routine&Description -_ -.sp.5 -rnusers&Return number of users on remote machine -rusers&Return information about users on remote machine -havedisk&Determine if remote machine has disk -rstats&Get performance data from remote kernel -rwall&Write to specified remote machines -yppasswd&Update user password in Yellow Pages -.TE -.LP -Other RPC services \(em for example -.I ether() -.I mount -.I rquota() -and -.I spray -\(em are not available to the C programmer as library routines. -They do, however, -have RPC program numbers so they can be invoked with -.I callrpc() -which will be discussed in the next section. Most of them also -have compilable -.I rpcgen(1) -protocol description files. (The -.I rpcgen -protocol compiler radically simplifies the process of developing -network applications. -See the \fBrpcgen\fI Programming Guide\fR -for detailed information about -.I rpcgen -and -.I rpcgen -protocol description files). -.KS -.NH 2 -\&Intermediate Layer -.IX "intermediate layer of RPC" -.IX "RPC" "intermediate layer" -.LP -The simplest interface, which explicitly makes RPC calls, uses the -functions -.I callrpc() -and -.I registerrpc() -Using this method, the number of remote users can be gotten as follows: -.ie t .DS -.el .DS L -#include -#include -#include -#include - -main(argc, argv) - int argc; - char **argv; -{ - unsigned long nusers; - int stat; - - if (argc != 2) { - fprintf(stderr, "usage: nusers hostname\en"); - exit(-1); - } - if (stat = callrpc(argv[1], - RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, - xdr_void, 0, xdr_u_long, &nusers) != 0) { - clnt_perrno(stat); - exit(1); - } - printf("%d users on %s\en", nusers, argv[1]); - exit(0); -} -.DE -.KE -Each RPC procedure is uniquely defined by a program number, -version number, and procedure number. The program number -specifies a group of related remote procedures, each of -which has a different procedure number. Each program also -has a version number, so when a minor change is made to a -remote service (adding a new procedure, for example), a new -program number doesn't have to be assigned. When you want -to call a procedure to find the number of remote users, you -look up the appropriate program, version and procedure numbers -in a manual, just as you look up the name of a memory allocator -when you want to allocate memory. -.LP -The simplest way of making remote procedure calls is with the the RPC -library routine -.I callrpc() -It has eight parameters. The first is the name of the remote server -machine. The next three parameters are the program, version, and procedure -numbers\(emtogether they identify the procedure to be called. -The fifth and sixth parameters are an XDR filter and an argument to -be encoded and passed to the remote procedure. -The final two parameters are a filter for decoding the results -returned by the remote procedure and a pointer to the place where -the procedure's results are to be stored. Multiple arguments and -results are handled by embedding them in structures. If -.I callrpc() -completes successfully, it returns zero; else it returns a nonzero -value. The return codes (of type -.IX "enum clnt_stat (in RPC programming)" "" "\fIenum clnt_stat\fP (in RPC programming)" -cast into an integer) are found in -.I . -.LP -Since data types may be represented differently on different machines, -.I callrpc() -needs both the type of the RPC argument, as well as -a pointer to the argument itself (and similarly for the result). For -.I RUSERSPROC_NUM , -the return value is an -.I "unsigned long" -so -.I callrpc() -has -.I xdr_u_long() -as its first return parameter, which says -that the result is of type -.I "unsigned long" -and -.I &nusers -as its second return parameter, -which is a pointer to where the long result will be placed. Since -.I RUSERSPROC_NUM -takes no argument, the argument parameter of -.I callrpc() -is -.I xdr_void (). -.LP -After trying several times to deliver a message, if -.I callrpc() -gets no answer, it returns with an error code. -The delivery mechanism is UDP, -which stands for User Datagram Protocol. -Methods for adjusting the number of retries -or for using a different protocol require you to use the lower -layer of the RPC library, discussed later in this document. -The remote server procedure -corresponding to the above might look like this: -.ie t .DS -.el .DS L -.ft CW -.ft CW -char * -nuser(indata) - char *indata; -{ - unsigned long nusers; - -.ft I - /* - * Code here to compute the number of users - * and place result in variable \fInusers\fP. - */ -.ft CW - return((char *)&nusers); -} -.DE -.LP -It takes one argument, which is a pointer to the input -of the remote procedure call (ignored in our example), -and it returns a pointer to the result. -In the current version of C, -character pointers are the generic pointers, -so both the input argument and the return value are cast to -.I "char *" . -.LP -Normally, a server registers all of the RPC calls it plans -to handle, and then goes into an infinite loop waiting to service requests. -In this example, there is only a single procedure -to register, so the main body of the server would look like this: -.ie t .DS -.el .DS L -.ft CW -#include -#include -#include -#include - -char *nuser(); - -main() -{ - registerrpc(RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, - nuser, xdr_void, xdr_u_long); - svc_run(); /* \fINever returns\fP */ - fprintf(stderr, "Error: svc_run returned!\en"); - exit(1); -} -.DE -.LP -The -.I registerrpc() -routine registers a C procedure as corresponding to a -given RPC procedure number. The first three parameters, -.I RUSERPROG , -.I RUSERSVERS , -and -.I RUSERSPROC_NUM -are the program, version, and procedure numbers -of the remote procedure to be registered; -.I nuser() -is the name of the local procedure that implements the remote -procedure; and -.I xdr_void() -and -.I xdr_u_long() -are the XDR filters for the remote procedure's arguments and -results, respectively. (Multiple arguments or multiple results -are passed as structures). -.LP -Only the UDP transport mechanism can use -.I registerrpc() -thus, it is always safe in conjunction with calls generated by -.I callrpc() . -.SH -.IX "UDP 8K warning" -Warning: the UDP transport mechanism can only deal with -arguments and results less than 8K bytes in length. -.LP -.LP -After registering the local procedure, the server program's -main procedure calls -.I svc_run (), -the RPC library's remote procedure dispatcher. It is this -function that calls the remote procedures in response to RPC -call messages. Note that the dispatcher takes care of decoding -remote procedure arguments and encoding results, using the XDR -filters specified when the remote procedure was registered. -.NH 2 -\&Assigning Program Numbers -.IX "program number assignment" -.IX "assigning program numbers" -.LP -Program numbers are assigned in groups of -.I 0x20000000 -according to the following chart: -.DS -.ft CW - 0x0 - 0x1fffffff \fRDefined by Sun\fP -0x20000000 - 0x3fffffff \fRDefined by user\fP -0x40000000 - 0x5fffffff \fRTransient\fP -0x60000000 - 0x7fffffff \fRReserved\fP -0x80000000 - 0x9fffffff \fRReserved\fP -0xa0000000 - 0xbfffffff \fRReserved\fP -0xc0000000 - 0xdfffffff \fRReserved\fP -0xe0000000 - 0xffffffff \fRReserved\fP -.ft R -.DE -Sun Microsystems administers the first group of numbers, which -should be identical for all Sun customers. If a customer -develops an application that might be of general interest, that -application should be given an assigned number in the first -range. The second group of numbers is reserved for specific -customer applications. This range is intended primarily for -debugging new programs. The third group is reserved for -applications that generate program numbers dynamically. The -final groups are reserved for future use, and should not be -used. -.LP -To register a protocol specification, send a request by network -mail to -.I rpc@sun -or write to: -.DS -RPC Administrator -Sun Microsystems -2550 Garcia Ave. -Mountain View, CA 94043 -.DE -Please include a compilable -.I rpcgen -\*Q.x\*U file describing your protocol. -You will be given a unique program number in return. -.IX RPC administration -.IX administration "of RPC" -.LP -The RPC program numbers and protocol specifications -of standard Sun RPC services can be -found in the include files in -.I "/usr/include/rpcsvc" . -These services, however, constitute only a small subset -of those which have been registered. The complete list of -registered programs, as of the time when this manual was -printed, is: -.LP -\fBTable 3-2\fI RPC Registered Programs\fR -.TS H -box tab (&) ; -lfBI lfBI lfBI -lfL lfL lfI . -RPC Number&Program&Description -_ -.TH -.sp.5 -100000&PMAPPROG&portmapper -100001&RSTATPROG&remote stats -100002&RUSERSPROG&remote users -100003&NFSPROG&nfs -100004&YPPROG&Yellow Pages -100005&MOUNTPROG&mount demon -100006&DBXPROG&remote dbx -100007&YPBINDPROG&yp binder -100008&WALLPROG&shutdown msg -100009&YPPASSWDPROG&yppasswd server -100010ÐERSTATPROGðer stats -100011&RQUOTAPROG&disk quotas -100012&SPRAYPROG&spray packets -100013&IBM3270PROG&3270 mapper -100014&IBMRJEPROG&RJE mapper -100015&SELNSVCPROG&selection service -100016&RDATABASEPROG&remote database access -100017&REXECPROG&remote execution -100018&ALICEPROG&Alice Office Automation -100019&SCHEDPROG&scheduling service -100020&LOCKPROG&local lock manager -100021&NETLOCKPROG&network lock manager -100022&X25PROG&x.25 inr protocol -100023&STATMON1PROG&status monitor 1 -100024&STATMON2PROG&status monitor 2 -100025&SELNLIBPROG&selection library -100026&BOOTPARAMPROG&boot parameters service -100027&MAZEPROG&mazewars game -100028&YPUPDATEPROG&yp update -100029&KEYSERVEPROG&key server -100030&SECURECMDPROG&secure login -100031&NETFWDIPROG&nfs net forwarder init -100032&NETFWDTPROG&nfs net forwarder trans -100033&SUNLINKMAP_PROG&sunlink MAP -100034&NETMONPROG&network monitor -100035&DBASEPROG&lightweight database -100036&PWDAUTHPROG&password authorization -100037&TFSPROG&translucent file svc -100038&NSEPROG&nse server -100039&NSE_ACTIVATE_PROG&nse activate daemon -.sp .2i -150001&PCNFSDPROG&pc passwd authorization -.sp .2i -200000&PYRAMIDLOCKINGPROG&Pyramid-locking -200001&PYRAMIDSYS5&Pyramid-sys5 -200002&CADDS_IMAGE&CV cadds_image -.sp .2i -300001&ADT_RFLOCKPROG&ADT file locking -.TE -.NH 2 -\&Passing Arbitrary Data Types -.IX "arbitrary data types" -.LP -In the previous example, the RPC call passes a single -.I "unsigned long" -RPC can handle arbitrary data structures, regardless of -different machines' byte orders or structure layout conventions, -by always converting them to a network standard called -.I "External Data Representation" -(XDR) before -sending them over the wire. -The process of converting from a particular machine representation -to XDR format is called -.I serializing , -and the reverse process is called -.I deserializing . -The type field parameters of -.I callrpc() -and -.I registerrpc() -can be a built-in procedure like -.I xdr_u_long() -in the previous example, or a user supplied one. -XDR has these built-in type routines: -.IX RPC "built-in routines" -.DS -.ft CW -xdr_int() xdr_u_int() xdr_enum() -xdr_long() xdr_u_long() xdr_bool() -xdr_short() xdr_u_short() xdr_wrapstring() -xdr_char() xdr_u_char() -.DE -Note that the routine -.I xdr_string() -exists, but cannot be used with -.I callrpc() -and -.I registerrpc (), -which only pass two parameters to their XDR routines. -.I xdr_wrapstring() -has only two parameters, and is thus OK. It calls -.I xdr_string (). -.LP -As an example of a user-defined type routine, -if you wanted to send the structure -.DS -.ft CW -struct simple { - int a; - short b; -} simple; -.DE -then you would call -.I callrpc() -as -.DS -.ft CW -callrpc(hostname, PROGNUM, VERSNUM, PROCNUM, - xdr_simple, &simple ...); -.DE -where -.I xdr_simple() -is written as: -.ie t .DS -.el .DS L -.ft CW -#include - -xdr_simple(xdrsp, simplep) - XDR *xdrsp; - struct simple *simplep; -{ - if (!xdr_int(xdrsp, &simplep->a)) - return (0); - if (!xdr_short(xdrsp, &simplep->b)) - return (0); - return (1); -} -.DE -.LP -An XDR routine returns nonzero (true in the sense of C) if it -completes successfully, and zero otherwise. -A complete description of XDR is in the -.I "XDR Protocol Specification" -section of this manual, only few implementation examples are -given here. -.LP -In addition to the built-in primitives, -there are also the prefabricated building blocks: -.DS -.ft CW -xdr_array() xdr_bytes() xdr_reference() -xdr_vector() xdr_union() xdr_pointer() -xdr_string() xdr_opaque() -.DE -To send a variable array of integers, -you might package them up as a structure like this -.DS -.ft CW -struct varintarr { - int *data; - int arrlnth; -} arr; -.DE -and make an RPC call such as -.DS -.ft CW -callrpc(hostname, PROGNUM, VERSNUM, PROCNUM, - xdr_varintarr, &arr...); -.DE -with -.I xdr_varintarr() -defined as: -.ie t .DS -.el .DS L -.ft CW -xdr_varintarr(xdrsp, arrp) - XDR *xdrsp; - struct varintarr *arrp; -{ - return (xdr_array(xdrsp, &arrp->data, &arrp->arrlnth, - MAXLEN, sizeof(int), xdr_int)); -} -.DE -This routine takes as parameters the XDR handle, -a pointer to the array, a pointer to the size of the array, -the maximum allowable array size, -the size of each array element, -and an XDR routine for handling each array element. -.KS -.LP -If the size of the array is known in advance, one can use -.I xdr_vector (), -which serializes fixed-length arrays. -.ie t .DS -.el .DS L -.ft CW -int intarr[SIZE]; - -xdr_intarr(xdrsp, intarr) - XDR *xdrsp; - int intarr[]; -{ - int i; - - return (xdr_vector(xdrsp, intarr, SIZE, sizeof(int), - xdr_int)); -} -.DE -.KE -.LP -XDR always converts quantities to 4-byte multiples when serializing. -Thus, if either of the examples above involved characters -instead of integers, each character would occupy 32 bits. -That is the reason for the XDR routine -.I xdr_bytes() -which is like -.I xdr_array() -except that it packs characters; -.I xdr_bytes() -has four parameters, similar to the first four parameters of -.I xdr_array (). -For null-terminated strings, there is also the -.I xdr_string() -routine, which is the same as -.I xdr_bytes() -without the length parameter. -On serializing it gets the string length from -.I strlen (), -and on deserializing it creates a null-terminated string. -.LP -Here is a final example that calls the previously written -.I xdr_simple() -as well as the built-in functions -.I xdr_string() -and -.I xdr_reference (), -which chases pointers: -.ie t .DS -.el .DS L -.ft CW -struct finalexample { - char *string; - struct simple *simplep; -} finalexample; - -xdr_finalexample(xdrsp, finalp) - XDR *xdrsp; - struct finalexample *finalp; -{ - - if (!xdr_string(xdrsp, &finalp->string, MAXSTRLEN)) - return (0); - if (!xdr_reference(xdrsp, &finalp->simplep, - sizeof(struct simple), xdr_simple); - return (0); - return (1); -} -.DE -Note that we could as easily call -.I xdr_simple() -here instead of -.I xdr_reference (). -.NH 1 -\&Lowest Layer of RPC -.IX "lowest layer of RPC" -.IX "RPC" "lowest layer" -.LP -In the examples given so far, -RPC takes care of many details automatically for you. -In this section, we'll show you how you can change the defaults -by using lower layers of the RPC library. -It is assumed that you are familiar with sockets -and the system calls for dealing with them. -.LP -There are several occasions when you may need to use lower layers of -RPC. First, you may need to use TCP, since the higher layer uses UDP, -which restricts RPC calls to 8K bytes of data. Using TCP permits calls -to send long streams of data. -For an example, see the -.I TCP -section below. Second, you may want to allocate and free memory -while serializing or deserializing with XDR routines. -There is no call at the higher level to let -you free memory explicitly. -For more explanation, see the -.I "Memory Allocation with XDR" -section below. -Third, you may need to perform authentication -on either the client or server side, by supplying -credentials or verifying them. -See the explanation in the -.I Authentication -section below. -.NH 2 -\&More on the Server Side -.IX RPC "server side" -.LP -The server for the -.I nusers() -program shown below does the same thing as the one using -.I registerrpc() -above, but is written using a lower layer of the RPC package: -.ie t .DS -.el .DS L -.ft CW -#include -#include -#include -#include - -main() -{ - SVCXPRT *transp; - int nuser(); - - transp = svcudp_create(RPC_ANYSOCK); - if (transp == NULL){ - fprintf(stderr, "can't create an RPC server\en"); - exit(1); - } - pmap_unset(RUSERSPROG, RUSERSVERS); - if (!svc_register(transp, RUSERSPROG, RUSERSVERS, - nuser, IPPROTO_UDP)) { - fprintf(stderr, "can't register RUSER service\en"); - exit(1); - } - svc_run(); /* \fINever returns\fP */ - fprintf(stderr, "should never reach this point\en"); -} - -nuser(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; -{ - unsigned long nusers; - - switch (rqstp->rq_proc) { - case NULLPROC: - if (!svc_sendreply(transp, xdr_void, 0)) - fprintf(stderr, "can't reply to RPC call\en"); - return; - case RUSERSPROC_NUM: -.ft I - /* - * Code here to compute the number of users - * and assign it to the variable \fInusers\fP - */ -.ft CW - if (!svc_sendreply(transp, xdr_u_long, &nusers)) - fprintf(stderr, "can't reply to RPC call\en"); - return; - default: - svcerr_noproc(transp); - return; - } -} -.DE -.LP -First, the server gets a transport handle, which is used -for receiving and replying to RPC messages. -.I registerrpc() -uses -.I svcudp_create() -to get a UDP handle. -If you require a more reliable protocol, call -.I svctcp_create() -instead. -If the argument to -.I svcudp_create() -is -.I RPC_ANYSOCK -the RPC library creates a socket -on which to receive and reply to RPC calls. Otherwise, -.I svcudp_create() -expects its argument to be a valid socket number. -If you specify your own socket, it can be bound or unbound. -If it is bound to a port by the user, the port numbers of -.I svcudp_create() -and -.I clnttcp_create() -(the low-level client routine) must match. -.LP -If the user specifies the -.I RPC_ANYSOCK -argument, the RPC library routines will open sockets. -Otherwise they will expect the user to do so. The routines -.I svcudp_create() -and -.I clntudp_create() -will cause the RPC library routines to -.I bind() -their socket if it is not bound already. -.LP -A service may choose to register its port number with the -local portmapper service. This is done is done by specifying -a non-zero protocol number in -.I svc_register (). -Incidently, a client can discover the server's port number by -consulting the portmapper on their server's machine. This can -be done automatically by specifying a zero port number in -.I clntudp_create() -or -.I clnttcp_create (). -.LP -After creating an -.I SVCXPRT , -the next step is to call -.I pmap_unset() -so that if the -.I nusers() -server crashed earlier, -any previous trace of it is erased before restarting. -More precisely, -.I pmap_unset() -erases the entry for -.I RUSERSPROG -from the port mapper's tables. -.LP -Finally, we associate the program number for -.I nusers() -with the procedure -.I nuser (). -The final argument to -.I svc_register() -is normally the protocol being used, -which, in this case, is -.I IPPROTO_UDP -Notice that unlike -.I registerrpc (), -there are no XDR routines involved -in the registration process. -Also, registration is done on the program, -rather than procedure, level. -.LP -The user routine -.I nuser() -must call and dispatch the appropriate XDR routines -based on the procedure number. -Note that -two things are handled by -.I nuser() -that -.I registerrpc() -handles automatically. -The first is that procedure -.I NULLPROC -(currently zero) returns with no results. -This can be used as a simple test -for detecting if a remote program is running. -Second, there is a check for invalid procedure numbers. -If one is detected, -.I svcerr_noproc() -is called to handle the error. -.KS -.LP -The user service routine serializes the results and returns -them to the RPC caller via -.I svc_sendreply() -Its first parameter is the -.I SVCXPRT -handle, the second is the XDR routine, -and the third is a pointer to the data to be returned. -Not illustrated above is how a server -handles an RPC program that receives data. -As an example, we can add a procedure -.I RUSERSPROC_BOOL -which has an argument -.I nusers (), -and returns -.I TRUE -or -.I FALSE -depending on whether there are nusers logged on. -It would look like this: -.ie t .DS -.el .DS L -.ft CW -case RUSERSPROC_BOOL: { - int bool; - unsigned nuserquery; - - if (!svc_getargs(transp, xdr_u_int, &nuserquery) { - svcerr_decode(transp); - return; - } -.ft I - /* - * Code to set \fInusers\fP = number of users - */ -.ft CW - if (nuserquery == nusers) - bool = TRUE; - else - bool = FALSE; - if (!svc_sendreply(transp, xdr_bool, &bool)) { - fprintf(stderr, "can't reply to RPC call\en"); - return (1); - } - return; -} -.DE -.KE -.LP -The relevant routine is -.I svc_getargs() -which takes an -.I SVCXPRT -handle, the XDR routine, -and a pointer to where the input is to be placed as arguments. -.NH 2 -\&Memory Allocation with XDR -.IX "memory allocation with XDR" -.IX XDR "memory allocation" -.LP -XDR routines not only do input and output, -they also do memory allocation. -This is why the second parameter of -.I xdr_array() -is a pointer to an array, rather than the array itself. -If it is -.I NULL , -then -.I xdr_array() -allocates space for the array and returns a pointer to it, -putting the size of the array in the third argument. -As an example, consider the following XDR routine -.I xdr_chararr1() -which deals with a fixed array of bytes with length -.I SIZE . -.ie t .DS -.el .DS L -.ft CW -xdr_chararr1(xdrsp, chararr) - XDR *xdrsp; - char chararr[]; -{ - char *p; - int len; - - p = chararr; - len = SIZE; - return (xdr_bytes(xdrsp, &p, &len, SIZE)); -} -.DE -If space has already been allocated in -.I chararr , -it can be called from a server like this: -.ie t .DS -.el .DS L -.ft CW -char chararr[SIZE]; - -svc_getargs(transp, xdr_chararr1, chararr); -.DE -If you want XDR to do the allocation, -you would have to rewrite this routine in the following way: -.ie t .DS -.el .DS L -.ft CW -xdr_chararr2(xdrsp, chararrp) - XDR *xdrsp; - char **chararrp; -{ - int len; - - len = SIZE; - return (xdr_bytes(xdrsp, charrarrp, &len, SIZE)); -} -.DE -Then the RPC call might look like this: -.ie t .DS -.el .DS L -.ft CW -char *arrptr; - -arrptr = NULL; -svc_getargs(transp, xdr_chararr2, &arrptr); -.ft I -/* - * Use the result here - */ -.ft CW -svc_freeargs(transp, xdr_chararr2, &arrptr); -.DE -Note that, after being used, the character array can be freed with -.I svc_freeargs() -.I svc_freeargs() -will not attempt to free any memory if the variable indicating it -is NULL. For example, in the the routine -.I xdr_finalexample (), -given earlier, if -.I finalp->string -was NULL, then it would not be freed. The same is true for -.I finalp->simplep . -.LP -To summarize, each XDR routine is responsible -for serializing, deserializing, and freeing memory. -When an XDR routine is called from -.I callrpc() -the serializing part is used. -When called from -.I svc_getargs() -the deserializer is used. -And when called from -.I svc_freeargs() -the memory deallocator is used. When building simple examples like those -in this section, a user doesn't have to worry -about the three modes. -See the -.I "External Data Representation: Sun Technical Notes" -for examples of more sophisticated XDR routines that determine -which of the three modes they are in and adjust their behavior accordingly. -.KS -.NH 2 -\&The Calling Side -.IX RPC "calling side" -.LP -When you use -.I callrpc() -you have no control over the RPC delivery -mechanism or the socket used to transport the data. -To illustrate the layer of RPC that lets you adjust these -parameters, consider the following code to call the -.I nusers -service: -.ie t .DS -.el .DS L -.ft CW -.vs 11 -#include -#include -#include -#include -#include -#include -#include - -main(argc, argv) - int argc; - char **argv; -{ - struct hostent *hp; - struct timeval pertry_timeout, total_timeout; - struct sockaddr_in server_addr; - int sock = RPC_ANYSOCK; - register CLIENT *client; - enum clnt_stat clnt_stat; - unsigned long nusers; - - if (argc != 2) { - fprintf(stderr, "usage: nusers hostname\en"); - exit(-1); - } - if ((hp = gethostbyname(argv[1])) == NULL) { - fprintf(stderr, "can't get addr for %s\en",argv[1]); - exit(-1); - } - pertry_timeout.tv_sec = 3; - pertry_timeout.tv_usec = 0; - bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, - hp->h_length); - server_addr.sin_family = AF_INET; - server_addr.sin_port = 0; - if ((client = clntudp_create(&server_addr, RUSERSPROG, - RUSERSVERS, pertry_timeout, &sock)) == NULL) { - clnt_pcreateerror("clntudp_create"); - exit(-1); - } - total_timeout.tv_sec = 20; - total_timeout.tv_usec = 0; - clnt_stat = clnt_call(client, RUSERSPROC_NUM, xdr_void, - 0, xdr_u_long, &nusers, total_timeout); - if (clnt_stat != RPC_SUCCESS) { - clnt_perror(client, "rpc"); - exit(-1); - } - clnt_destroy(client); - close(sock); - exit(0); -} -.vs -.DE -.KE -The low-level version of -.I callrpc() -is -.I clnt_call() -which takes a -.I CLIENT -pointer rather than a host name. The parameters to -.I clnt_call() -are a -.I CLIENT -pointer, the procedure number, -the XDR routine for serializing the argument, -a pointer to the argument, -the XDR routine for deserializing the return value, -a pointer to where the return value will be placed, -and the time in seconds to wait for a reply. -.LP -The -.I CLIENT -pointer is encoded with the transport mechanism. -.I callrpc() -uses UDP, thus it calls -.I clntudp_create() -to get a -.I CLIENT -pointer. To get TCP (Transmission Control Protocol), you would use -.I clnttcp_create() . -.LP -The parameters to -.I clntudp_create() -are the server address, the program number, the version number, -a timeout value (between tries), and a pointer to a socket. -The final argument to -.I clnt_call() -is the total time to wait for a response. -Thus, the number of tries is the -.I clnt_call() -timeout divided by the -.I clntudp_create() -timeout. -.LP -Note that the -.I clnt_destroy() -call -always deallocates the space associated with the -.I CLIENT -handle. It closes the socket associated with the -.I CLIENT -handle, however, only if the RPC library opened it. It the -socket was opened by the user, it stays open. This makes it -possible, in cases where there are multiple client handles -using the same socket, to destroy one handle without closing -the socket that other handles are using. -.LP -To make a stream connection, the call to -.I clntudp_create() -is replaced with a call to -.I clnttcp_create() . -.DS -.ft CW -clnttcp_create(&server_addr, prognum, versnum, &sock, - inputsize, outputsize); -.DE -There is no timeout argument; instead, the receive and send buffer -sizes must be specified. When the -.I clnttcp_create() -call is made, a TCP connection is established. -All RPC calls using that -.I CLIENT -handle would use this connection. -The server side of an RPC call using TCP has -.I svcudp_create() -replaced by -.I svctcp_create() . -.DS -.ft CW -transp = svctcp_create(RPC_ANYSOCK, 0, 0); -.DE -The last two arguments to -.I svctcp_create() -are send and receive sizes respectively. If `0' is specified for -either of these, the system chooses a reasonable default. -.KS -.NH 1 -\&Other RPC Features -.IX "RPC" "miscellaneous features" -.IX "miscellaneous RPC features" -.LP -This section discusses some other aspects of RPC -that are occasionally useful. -.NH 2 -\&Select on the Server Side -.IX RPC select() RPC \fIselect()\fP -.IX select() "" \fIselect()\fP "on the server side" -.LP -Suppose a process is processing RPC requests -while performing some other activity. -If the other activity involves periodically updating a data structure, -the process can set an alarm signal before calling -.I svc_run() -But if the other activity -involves waiting on a a file descriptor, the -.I svc_run() -call won't work. -The code for -.I svc_run() -is as follows: -.ie t .DS -.el .DS L -.ft CW -.vs 11 -void -svc_run() -{ - fd_set readfds; - int dtbsz = getdtablesize(); - - for (;;) { - readfds = svc_fds; - switch (select(dtbsz, &readfds, NULL,NULL,NULL)) { - - case -1: - if (errno == EINTR) - continue; - perror("select"); - return; - case 0: - break; - default: - svc_getreqset(&readfds); - } - } -} -.vs -.DE -.KE -.LP -You can bypass -.I svc_run() -and call -.I svc_getreqset() -yourself. -All you need to know are the file descriptors -of the socket(s) associated with the programs you are waiting on. -Thus you can have your own -.I select() -.IX select() "" \fIselect()\fP -that waits on both the RPC socket, -and your own descriptors. Note that -.I svc_fds() -is a bit mask of all the file descriptors that RPC is using for -services. It can change everytime that -.I any -RPC library routine is called, because descriptors are constantly -being opened and closed, for example for TCP connections. -.NH 2 -\&Broadcast RPC -.IX "broadcast RPC" -.IX RPC "broadcast" -.LP -The -.I portmapper -is a daemon that converts RPC program numbers -into DARPA protocol port numbers; see the -.I portmap -man page. You can't do broadcast RPC without the portmapper. -Here are the main differences between -broadcast RPC and normal RPC calls: -.IP 1. -Normal RPC expects one answer, whereas -broadcast RPC expects many answers -(one or more answer from each responding machine). -.IP 2. -Broadcast RPC can only be supported by packet-oriented (connectionless) -transport protocols like UPD/IP. -.IP 3. -The implementation of broadcast RPC -treats all unsuccessful responses as garbage by filtering them out. -Thus, if there is a version mismatch between the -broadcaster and a remote service, -the user of broadcast RPC never knows. -.IP 4. -All broadcast messages are sent to the portmap port. -Thus, only services that register themselves with their portmapper -are accessible via the broadcast RPC mechanism. -.IP 5. -Broadcast requests are limited in size to the MTU (Maximum Transfer -Unit) of the local network. For Ethernet, the MTU is 1500 bytes. -.KS -.NH 3 -\&Broadcast RPC Synopsis -.IX "broadcast RPC" synopsis -.IX "RPC" "broadcast synopsis" -.ie t .DS -.el .DS L -.ft CW -#include - . . . -enum clnt_stat clnt_stat; - . . . -clnt_stat = clnt_broadcast(prognum, versnum, procnum, - inproc, in, outproc, out, eachresult) - u_long prognum; /* \fIprogram number\fP */ - u_long versnum; /* \fIversion number\fP */ - u_long procnum; /* \fIprocedure number\fP */ - xdrproc_t inproc; /* \fIxdr routine for args\fP */ - caddr_t in; /* \fIpointer to args\fP */ - xdrproc_t outproc; /* \fIxdr routine for results\fP */ - caddr_t out; /* \fIpointer to results\fP */ - bool_t (*eachresult)();/* \fIcall with each result gotten\fP */ -.DE -.KE -The procedure -.I eachresult() -is called each time a valid result is obtained. -It returns a boolean that indicates -whether or not the user wants more responses. -.ie t .DS -.el .DS L -.ft CW -bool_t done; - . . . -done = eachresult(resultsp, raddr) - caddr_t resultsp; - struct sockaddr_in *raddr; /* \fIAddr of responding machine\fP */ -.DE -If -.I done -is -.I TRUE , -then broadcasting stops and -.I clnt_broadcast() -returns successfully. -Otherwise, the routine waits for another response. -The request is rebroadcast -after a few seconds of waiting. -If no responses come back, -the routine returns with -.I RPC_TIMEDOUT . -.NH 2 -\&Batching -.IX "batching" -.IX RPC "batching" -.LP -The RPC architecture is designed so that clients send a call message, -and wait for servers to reply that the call succeeded. -This implies that clients do not compute -while servers are processing a call. -This is inefficient if the client does not want or need -an acknowledgement for every message sent. -It is possible for clients to continue computing -while waiting for a response, -using RPC batch facilities. -.LP -RPC messages can be placed in a \*Qpipeline\*U of calls -to a desired server; this is called batching. -Batching assumes that: -1) each RPC call in the pipeline requires no response from the server, -and the server does not send a response message; and -2) the pipeline of calls is transported on a reliable -byte stream transport such as TCP/IP. -Since the server does not respond to every call, -the client can generate new calls in parallel -with the server executing previous calls. -Furthermore, the TCP/IP implementation can buffer up -many call messages, and send them to the server in one -.I write() -system call. This overlapped execution -greatly decreases the interprocess communication overhead of -the client and server processes, -and the total elapsed time of a series of calls. -.LP -Since the batched calls are buffered, -the client should eventually do a nonbatched call -in order to flush the pipeline. -.LP -A contrived example of batching follows. -Assume a string rendering service (like a window system) -has two similar calls: one renders a string and returns void results, -while the other renders a string and remains silent. -The service (using the TCP/IP transport) may look like: -.ie t .DS -.el .DS L -.ft CW -#include -#include -#include - -void windowdispatch(); - -main() -{ - SVCXPRT *transp; - - transp = svctcp_create(RPC_ANYSOCK, 0, 0); - if (transp == NULL){ - fprintf(stderr, "can't create an RPC server\en"); - exit(1); - } - pmap_unset(WINDOWPROG, WINDOWVERS); - if (!svc_register(transp, WINDOWPROG, WINDOWVERS, - windowdispatch, IPPROTO_TCP)) { - fprintf(stderr, "can't register WINDOW service\en"); - exit(1); - } - svc_run(); /* \fINever returns\fP */ - fprintf(stderr, "should never reach this point\en"); -} - -void -windowdispatch(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; -{ - char *s = NULL; - - switch (rqstp->rq_proc) { - case NULLPROC: - if (!svc_sendreply(transp, xdr_void, 0)) - fprintf(stderr, "can't reply to RPC call\en"); - return; - case RENDERSTRING: - if (!svc_getargs(transp, xdr_wrapstring, &s)) { - fprintf(stderr, "can't decode arguments\en"); -.ft I - /* - * Tell caller he screwed up - */ -.ft CW - svcerr_decode(transp); - break; - } -.ft I - /* - * Code here to render the string \fIs\fP - */ -.ft CW - if (!svc_sendreply(transp, xdr_void, NULL)) - fprintf(stderr, "can't reply to RPC call\en"); - break; - case RENDERSTRING_BATCHED: - if (!svc_getargs(transp, xdr_wrapstring, &s)) { - fprintf(stderr, "can't decode arguments\en"); -.ft I - /* - * We are silent in the face of protocol errors - */ -.ft CW - break; - } -.ft I - /* - * Code here to render string s, but send no reply! - */ -.ft CW - break; - default: - svcerr_noproc(transp); - return; - } -.ft I - /* - * Now free string allocated while decoding arguments - */ -.ft CW - svc_freeargs(transp, xdr_wrapstring, &s); -} -.DE -Of course the service could have one procedure -that takes the string and a boolean -to indicate whether or not the procedure should respond. -.LP -In order for a client to take advantage of batching, -the client must perform RPC calls on a TCP-based transport -and the actual calls must have the following attributes: -1) the result's XDR routine must be zero -.I NULL ), -and 2) the RPC call's timeout must be zero. -.KS -.LP -Here is an example of a client that uses batching to render a -bunch of strings; the batching is flushed when the client gets -a null string (EOF): -.ie t .DS -.el .DS L -.ft CW -.vs 11 -#include -#include -#include -#include -#include -#include - -main(argc, argv) - int argc; - char **argv; -{ - struct hostent *hp; - struct timeval pertry_timeout, total_timeout; - struct sockaddr_in server_addr; - int sock = RPC_ANYSOCK; - register CLIENT *client; - enum clnt_stat clnt_stat; - char buf[1000], *s = buf; - - if ((client = clnttcp_create(&server_addr, - WINDOWPROG, WINDOWVERS, &sock, 0, 0)) == NULL) { - perror("clnttcp_create"); - exit(-1); - } - total_timeout.tv_sec = 0; - total_timeout.tv_usec = 0; - while (scanf("%s", s) != EOF) { - clnt_stat = clnt_call(client, RENDERSTRING_BATCHED, - xdr_wrapstring, &s, NULL, NULL, total_timeout); - if (clnt_stat != RPC_SUCCESS) { - clnt_perror(client, "batched rpc"); - exit(-1); - } - } - - /* \fINow flush the pipeline\fP */ - - total_timeout.tv_sec = 20; - clnt_stat = clnt_call(client, NULLPROC, xdr_void, NULL, - xdr_void, NULL, total_timeout); - if (clnt_stat != RPC_SUCCESS) { - clnt_perror(client, "rpc"); - exit(-1); - } - clnt_destroy(client); - exit(0); -} -.vs -.DE -.KE -Since the server sends no message, -the clients cannot be notified of any of the failures that may occur. -Therefore, clients are on their own when it comes to handling errors. -.LP -The above example was completed to render -all of the (2000) lines in the file -.I /etc/termcap . -The rendering service did nothing but throw the lines away. -The example was run in the following four configurations: -1) machine to itself, regular RPC; -2) machine to itself, batched RPC; -3) machine to another, regular RPC; and -4) machine to another, batched RPC. -The results are as follows: -1) 50 seconds; -2) 16 seconds; -3) 52 seconds; -4) 10 seconds. -Running -.I fscanf() -on -.I /etc/termcap -only requires six seconds. -These timings show the advantage of protocols -that allow for overlapped execution, -though these protocols are often hard to design. -.NH 2 -\&Authentication -.IX "authentication" -.IX "RPC" "authentication" -.LP -In the examples presented so far, -the caller never identified itself to the server, -and the server never required an ID from the caller. -Clearly, some network services, such as a network filesystem, -require stronger security than what has been presented so far. -.LP -In reality, every RPC call is authenticated by -the RPC package on the server, and similarly, -the RPC client package generates and sends authentication parameters. -Just as different transports (TCP/IP or UDP/IP) -can be used when creating RPC clients and servers, -different forms of authentication can be associated with RPC clients; -the default authentication type used as a default is type -.I none . -.LP -The authentication subsystem of the RPC package is open ended. -That is, numerous types of authentication are easy to support. -.NH 3 -\&UNIX Authentication -.IX "UNIX Authentication" -.IP "\fIThe Client Side\fP" -.LP -When a caller creates a new RPC client handle as in: -.DS -.ft CW -clnt = clntudp_create(address, prognum, versnum, - wait, sockp) -.DE -the appropriate transport instance defaults -the associate authentication handle to be -.DS -.ft CW -clnt->cl_auth = authnone_create(); -.DE -The RPC client can choose to use -.I UNIX -style authentication by setting -.I clnt\->cl_auth -after creating the RPC client handle: -.DS -.ft CW -clnt->cl_auth = authunix_create_default(); -.DE -This causes each RPC call associated with -.I clnt -to carry with it the following authentication credentials structure: -.ie t .DS -.el .DS L -.ft I -/* - * UNIX style credentials. - */ -.ft CW -struct authunix_parms { - u_long aup_time; /* \fIcredentials creation time\fP */ - char *aup_machname; /* \fIhost name where client is\fP */ - int aup_uid; /* \fIclient's UNIX effective uid\fP */ - int aup_gid; /* \fIclient's current group id\fP */ - u_int aup_len; /* \fIelement length of aup_gids\fP */ - int *aup_gids; /* \fIarray of groups user is in\fP */ -}; -.DE -These fields are set by -.I authunix_create_default() -by invoking the appropriate system calls. -Since the RPC user created this new style of authentication, -the user is responsible for destroying it with: -.DS -.ft CW -auth_destroy(clnt->cl_auth); -.DE -This should be done in all cases, to conserve memory. -.sp -.IP "\fIThe Server Side\fP" -.LP -Service implementors have a harder time dealing with authentication issues -since the RPC package passes the service dispatch routine a request -that has an arbitrary authentication style associated with it. -Consider the fields of a request handle passed to a service dispatch routine: -.ie t .DS -.el .DS L -.ft I -/* - * An RPC Service request - */ -.ft CW -struct svc_req { - u_long rq_prog; /* \fIservice program number\fP */ - u_long rq_vers; /* \fIservice protocol vers num\fP */ - u_long rq_proc; /* \fIdesired procedure number\fP */ - struct opaque_auth rq_cred; /* \fIraw credentials from wire\fP */ - caddr_t rq_clntcred; /* \fIcredentials (read only)\fP */ -}; -.DE -The -.I rq_cred -is mostly opaque, except for one field of interest: -the style or flavor of authentication credentials: -.ie t .DS -.el .DS L -.ft I -/* - * Authentication info. Mostly opaque to the programmer. - */ -.ft CW -struct opaque_auth { - enum_t oa_flavor; /* \fIstyle of credentials\fP */ - caddr_t oa_base; /* \fIaddress of more auth stuff\fP */ - u_int oa_length; /* \fInot to exceed \fIMAX_AUTH_BYTES */ -}; -.DE -.IX RPC guarantees -The RPC package guarantees the following -to the service dispatch routine: -.IP 1. -That the request's -.I rq_cred -is well formed. Thus the service implementor may inspect the request's -.I rq_cred.oa_flavor -to determine which style of authentication the caller used. -The service implementor may also wish to inspect the other fields of -.I rq_cred -if the style is not one of the styles supported by the RPC package. -.IP 2. -That the request's -.I rq_clntcred -field is either -.I NULL -or points to a well formed structure -that corresponds to a supported style of authentication credentials. -Remember that only -.I unix -style is currently supported, so (currently) -.I rq_clntcred -could be cast to a pointer to an -.I authunix_parms -structure. If -.I rq_clntcred -is -.I NULL , -the service implementor may wish to inspect the other (opaque) fields of -.I rq_cred -in case the service knows about a new type of authentication -that the RPC package does not know about. -.LP -Our remote users service example can be extended so that -it computes results for all users except UID 16: -.ie t .DS -.el .DS L -.ft CW -.vs 11 -nuser(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; -{ - struct authunix_parms *unix_cred; - int uid; - unsigned long nusers; - -.ft I - /* - * we don't care about authentication for null proc - */ -.ft CW - if (rqstp->rq_proc == NULLPROC) { - if (!svc_sendreply(transp, xdr_void, 0)) { - fprintf(stderr, "can't reply to RPC call\en"); - return (1); - } - return; - } -.ft I - /* - * now get the uid - */ -.ft CW - switch (rqstp->rq_cred.oa_flavor) { - case AUTH_UNIX: - unix_cred = - (struct authunix_parms *)rqstp->rq_clntcred; - uid = unix_cred->aup_uid; - break; - case AUTH_NULL: - default: - svcerr_weakauth(transp); - return; - } - switch (rqstp->rq_proc) { - case RUSERSPROC_NUM: -.ft I - /* - * make sure caller is allowed to call this proc - */ -.ft CW - if (uid == 16) { - svcerr_systemerr(transp); - return; - } -.ft I - /* - * Code here to compute the number of users - * and assign it to the variable \fInusers\fP - */ -.ft CW - if (!svc_sendreply(transp, xdr_u_long, &nusers)) { - fprintf(stderr, "can't reply to RPC call\en"); - return (1); - } - return; - default: - svcerr_noproc(transp); - return; - } -} -.vs -.DE -A few things should be noted here. -First, it is customary not to check -the authentication parameters associated with the -.I NULLPROC -(procedure number zero). -Second, if the authentication parameter's type is not suitable -for your service, you should call -.I svcerr_weakauth() . -And finally, the service protocol itself should return status -for access denied; in the case of our example, the protocol -does not have such a status, so we call the service primitive -.I svcerr_systemerr() -instead. -.LP -The last point underscores the relation between -the RPC authentication package and the services; -RPC deals only with -.I authentication -and not with individual services' -.I "access control" . -The services themselves must implement their own access control policies -and reflect these policies as return statuses in their protocols. -.NH 2 -\&DES Authentication -.IX RPC DES -.IX RPC authentication -.LP -UNIX authentication is quite easy to defeat. Instead of using -.I authunix_create_default (), -one can call -.I authunix_create() -and then modify the RPC authentication handle it returns by filling in -whatever user ID and hostname they wish the server to think they have. -DES authentication is thus recommended for people who want more security -than UNIX authentication offers. -.LP -The details of the DES authentication protocol are complicated and -are not explained here. -See -.I "Remote Procedure Calls: Protocol Specification" -for the details. -.LP -In order for DES authentication to work, the -.I keyserv(8c) -daemon must be running on both the server and client machines. The -users on these machines need public keys assigned by the network -administrator in the -.I publickey(5) -database. And, they need to have decrypted their secret keys -using their login password. This automatically happens when one -logs in using -.I login(1) , -or can be done manually using -.I keylogin(1) . -The -.I "Network Services" -chapter -./" XXX -explains more how to setup secure networking. -.sp -.IP "\fIClient Side\fP" -.LP -If a client wishes to use DES authentication, it must set its -authentication handle appropriately. Here is an example: -.DS -cl->cl_auth = - authdes_create(servername, 60, &server_addr, NULL); -.DE -The first argument is the network name or \*Qnetname\*U of the owner of -the server process. Typically, server processes are root processes -and their netname can be derived using the following call: -.DS -char servername[MAXNETNAMELEN]; - -host2netname(servername, rhostname, NULL); -.DE -Here, -.I rhostname -is the hostname of the machine the server process is running on. -.I host2netname() -fills in -.I servername -to contain this root process's netname. If the -server process was run by a regular user, one could use the call -.I user2netname() -instead. Here is an example for a server process with the same user -ID as the client: -.DS -char servername[MAXNETNAMELEN]; - -user2netname(servername, getuid(), NULL); -.DE -The last argument to both of these calls, -.I user2netname() -and -.I host2netname (), -is the name of the naming domain where the server is located. The -.I NULL -used here means \*Quse the local domain name.\*U -.LP -The second argument to -.I authdes_create() -is a lifetime for the credential. Here it is set to sixty -seconds. What that means is that the credential will expire 60 -seconds from now. If some mischievous user tries to reuse the -credential, the server RPC subsystem will recognize that it has -expired and not grant any requests. If the same mischievous user -tries to reuse the credential within the sixty second lifetime, -he will still be rejected because the server RPC subsystem -remembers which credentials it has already seen in the near past, -and will not grant requests to duplicates. -.LP -The third argument to -.I authdes_create() -is the address of the host to synchronize with. In order for DES -authentication to work, the server and client must agree upon the -time. Here we pass the address of the server itself, so the -client and server will both be using the same time: the server's -time. The argument can be -.I NULL , -which means \*Qdon't bother synchronizing.\*U You should only do this -if you are sure the client and server are already synchronized. -.LP -The final argument to -.I authdes_create() -is the address of a DES encryption key to use for encrypting -timestamps and data. If this argument is -.I NULL , -as it is in this example, a random key will be chosen. The client -may find out the encryption key being used by consulting the -.I ah_key -field of the authentication handle. -.sp -.IP "\fIServer Side\fP" -.LP -The server side is a lot simpler than the client side. Here is the -previous example rewritten to use -.I AUTH_DES -instead of -.I AUTH_UNIX : -.ie t .DS -.el .DS L -.ft CW -.vs 11 -#include -#include - . . . - . . . -nuser(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; -{ - struct authdes_cred *des_cred; - int uid; - int gid; - int gidlen; - int gidlist[10]; -.ft I - /* - * we don't care about authentication for null proc - */ -.ft CW - - if (rqstp->rq_proc == NULLPROC) { - /* \fIsame as before\fP */ - } - -.ft I - /* - * now get the uid - */ -.ft CW - switch (rqstp->rq_cred.oa_flavor) { - case AUTH_DES: - des_cred = - (struct authdes_cred *) rqstp->rq_clntcred; - if (! netname2user(des_cred->adc_fullname.name, - &uid, &gid, &gidlen, gidlist)) - { - fprintf(stderr, "unknown user: %s\n", - des_cred->adc_fullname.name); - svcerr_systemerr(transp); - return; - } - break; - case AUTH_NULL: - default: - svcerr_weakauth(transp); - return; - } - -.ft I - /* - * The rest is the same as before - */ -.ft CW -.vs -.DE -Note the use of the routine -.I netname2user (), -the inverse of -.I user2netname (): -it takes a network ID and converts to a unix ID. -.I netname2user () -also supplies the group IDs which we don't use in this example, -but which may be useful to other UNIX programs. -.NH 2 -\&Using Inetd -.IX inetd "" "using \fIinetd\fP" -.LP -An RPC server can be started from -.I inetd -The only difference from the usual code is that the service -creation routine should be called in the following form: -.ie t .DS -.el .DS L -.ft CW -transp = svcudp_create(0); /* \fIFor UDP\fP */ -transp = svctcp_create(0,0,0); /* \fIFor listener TCP sockets\fP */ -transp = svcfd_create(0,0,0); /* \fIFor connected TCP sockets\fP */ -.DE -since -.I inet -passes a socket as file descriptor 0. -Also, -.I svc_register() -should be called as -.ie t .DS -.el .DS L -.ft CW -svc_register(transp, PROGNUM, VERSNUM, service, 0); -.DE -with the final flag as 0, -since the program would already be registered by -.I inetd -Remember that if you want to exit -from the server process and return control to -.I inet -you need to explicitly exit, since -.I svc_run() -never returns. -.LP -The format of entries in -.I /etc/inetd.conf -for RPC services is in one of the following two forms: -.ie t .DS -.el .DS L -.ft CW -p_name/version dgram rpc/udp wait/nowait user server args -p_name/version stream rpc/tcp wait/nowait user server args -.DE -where -.I p_name -is the symbolic name of the program as it appears in -.I rpc(5) , -.I server -is the program implementing the server, -and -.I program -and -.I version -are the program and version numbers of the service. -For more information, see -.I inetd.conf(5) . -.LP -If the same program handles multiple versions, -then the version number can be a range, -as in this example: -.ie t .DS -.el .DS L -.ft CW -rstatd/1-2 dgram rpc/udp wait root /usr/etc/rpc.rstatd -.DE -.NH 1 -\&More Examples -.sp 1 -.NH 2 -\&Versions -.IX "versions" -.IX "RPC" "versions" -.LP -By convention, the first version number of program -.I PROG -is -.I PROGVERS_ORIG -and the most recent version is -.I PROGVERS -Suppose there is a new version of the -.I user -program that returns an -.I "unsigned short" -rather than a -.I long . -If we name this version -.I RUSERSVERS_SHORT -then a server that wants to support both versions -would do a double register. -.ie t .DS -.el .DS L -.ft CW -if (!svc_register(transp, RUSERSPROG, RUSERSVERS_ORIG, - nuser, IPPROTO_TCP)) { - fprintf(stderr, "can't register RUSER service\en"); - exit(1); -} -if (!svc_register(transp, RUSERSPROG, RUSERSVERS_SHORT, - nuser, IPPROTO_TCP)) { - fprintf(stderr, "can't register RUSER service\en"); - exit(1); -} -.DE -Both versions can be handled by the same C procedure: -.ie t .DS -.el .DS L -.ft CW -.vs 11 -nuser(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; -{ - unsigned long nusers; - unsigned short nusers2; - - switch (rqstp->rq_proc) { - case NULLPROC: - if (!svc_sendreply(transp, xdr_void, 0)) { - fprintf(stderr, "can't reply to RPC call\en"); - return (1); - } - return; - case RUSERSPROC_NUM: -.ft I - /* - * Code here to compute the number of users - * and assign it to the variable \fInusers\fP - */ -.ft CW - nusers2 = nusers; - switch (rqstp->rq_vers) { - case RUSERSVERS_ORIG: - if (!svc_sendreply(transp, xdr_u_long, - &nusers)) { - fprintf(stderr,"can't reply to RPC call\en"); - } - break; - case RUSERSVERS_SHORT: - if (!svc_sendreply(transp, xdr_u_short, - &nusers2)) { - fprintf(stderr,"can't reply to RPC call\en"); - } - break; - } - default: - svcerr_noproc(transp); - return; - } -} -.vs -.DE -.KS -.NH 2 -\&TCP -.IX "TCP" -.LP -Here is an example that is essentially -.I rcp. -The initiator of the RPC -.I snd -call takes its standard input and sends it to the server -.I rcv -which prints it on standard output. -The RPC call uses TCP. -This also illustrates an XDR procedure that behaves differently -on serialization than on deserialization. -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* - * The xdr routine: - * on decode, read from wire, write onto fp - * on encode, read from fp, write onto wire - */ -.ft CW -#include -#include - -xdr_rcp(xdrs, fp) - XDR *xdrs; - FILE *fp; -{ - unsigned long size; - char buf[BUFSIZ], *p; - - if (xdrs->x_op == XDR_FREE)/* nothing to free */ - return 1; - while (1) { - if (xdrs->x_op == XDR_ENCODE) { - if ((size = fread(buf, sizeof(char), BUFSIZ, - fp)) == 0 && ferror(fp)) { - fprintf(stderr, "can't fread\en"); - return (1); - } - } - p = buf; - if (!xdr_bytes(xdrs, &p, &size, BUFSIZ)) - return 0; - if (size == 0) - return 1; - if (xdrs->x_op == XDR_DECODE) { - if (fwrite(buf, sizeof(char), size, - fp) != size) { - fprintf(stderr, "can't fwrite\en"); - return (1); - } - } - } -} -.vs -.DE -.KE -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* - * The sender routines - */ -.ft CW -#include -#include -#include -#include -#include - -main(argc, argv) - int argc; - char **argv; -{ - int xdr_rcp(); - int err; - - if (argc < 2) { - fprintf(stderr, "usage: %s servername\en", argv[0]); - exit(-1); - } - if ((err = callrpctcp(argv[1], RCPPROG, RCPPROC, - RCPVERS, xdr_rcp, stdin, xdr_void, 0) != 0)) { - clnt_perrno(err); - fprintf(stderr, "can't make RPC call\en"); - exit(1); - } - exit(0); -} - -callrpctcp(host, prognum, procnum, versnum, - inproc, in, outproc, out) - char *host, *in, *out; - xdrproc_t inproc, outproc; -{ - struct sockaddr_in server_addr; - int socket = RPC_ANYSOCK; - enum clnt_stat clnt_stat; - struct hostent *hp; - register CLIENT *client; - struct timeval total_timeout; - - if ((hp = gethostbyname(host)) == NULL) { - fprintf(stderr, "can't get addr for '%s'\en", host); - return (-1); - } - bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, - hp->h_length); - server_addr.sin_family = AF_INET; - server_addr.sin_port = 0; - if ((client = clnttcp_create(&server_addr, prognum, - versnum, &socket, BUFSIZ, BUFSIZ)) == NULL) { - perror("rpctcp_create"); - return (-1); - } - total_timeout.tv_sec = 20; - total_timeout.tv_usec = 0; - clnt_stat = clnt_call(client, procnum, - inproc, in, outproc, out, total_timeout); - clnt_destroy(client); - return (int)clnt_stat; -} -.vs -.DE -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* - * The receiving routines - */ -.ft CW -#include -#include - -main() -{ - register SVCXPRT *transp; - int rcp_service(), xdr_rcp(); - - if ((transp = svctcp_create(RPC_ANYSOCK, - BUFSIZ, BUFSIZ)) == NULL) { - fprintf("svctcp_create: error\en"); - exit(1); - } - pmap_unset(RCPPROG, RCPVERS); - if (!svc_register(transp, - RCPPROG, RCPVERS, rcp_service, IPPROTO_TCP)) { - fprintf(stderr, "svc_register: error\en"); - exit(1); - } - svc_run(); /* \fInever returns\fP */ - fprintf(stderr, "svc_run should never return\en"); -} - -rcp_service(rqstp, transp) - register struct svc_req *rqstp; - register SVCXPRT *transp; -{ - switch (rqstp->rq_proc) { - case NULLPROC: - if (svc_sendreply(transp, xdr_void, 0) == 0) { - fprintf(stderr, "err: rcp_service"); - return (1); - } - return; - case RCPPROC_FP: - if (!svc_getargs(transp, xdr_rcp, stdout)) { - svcerr_decode(transp); - return; - } - if (!svc_sendreply(transp, xdr_void, 0)) { - fprintf(stderr, "can't reply\en"); - return; - } - return (0); - default: - svcerr_noproc(transp); - return; - } -} -.vs -.DE -.NH 2 -\&Callback Procedures -.IX RPC "callback procedures" -.LP -Occasionally, it is useful to have a server become a client, -and make an RPC call back to the process which is its client. -An example is remote debugging, -where the client is a window system program, -and the server is a debugger running on the remote machine. -Most of the time, -the user clicks a mouse button at the debugging window, -which converts this to a debugger command, -and then makes an RPC call to the server -(where the debugger is actually running), -telling it to execute that command. -However, when the debugger hits a breakpoint, the roles are reversed, -and the debugger wants to make an rpc call to the window program, -so that it can inform the user that a breakpoint has been reached. -.LP -In order to do an RPC callback, -you need a program number to make the RPC call on. -Since this will be a dynamically generated program number, -it should be in the transient range, -.I "0x40000000 - 0x5fffffff" . -The routine -.I gettransient() -returns a valid program number in the transient range, -and registers it with the portmapper. -It only talks to the portmapper running on the same machine as the -.I gettransient() -routine itself. The call to -.I pmap_set() -is a test and set operation, -in that it indivisibly tests whether a program number -has already been registered, -and if it has not, then reserves it. On return, the -.I sockp -argument will contain a socket that can be used -as the argument to an -.I svcudp_create() -or -.I svctcp_create() -call. -.ie t .DS -.el .DS L -.ft CW -.vs 11 -#include -#include -#include - -gettransient(proto, vers, sockp) - int proto, vers, *sockp; -{ - static int prognum = 0x40000000; - int s, len, socktype; - struct sockaddr_in addr; - - switch(proto) { - case IPPROTO_UDP: - socktype = SOCK_DGRAM; - break; - case IPPROTO_TCP: - socktype = SOCK_STREAM; - break; - default: - fprintf(stderr, "unknown protocol type\en"); - return 0; - } - if (*sockp == RPC_ANYSOCK) { - if ((s = socket(AF_INET, socktype, 0)) < 0) { - perror("socket"); - return (0); - } - *sockp = s; - } - else - s = *sockp; - addr.sin_addr.s_addr = 0; - addr.sin_family = AF_INET; - addr.sin_port = 0; - len = sizeof(addr); -.ft I - /* - * may be already bound, so don't check for error - */ -.ft CW - bind(s, &addr, len); - if (getsockname(s, &addr, &len)< 0) { - perror("getsockname"); - return (0); - } - while (!pmap_set(prognum++, vers, proto, - ntohs(addr.sin_port))) continue; - return (prognum-1); -} -.vs -.DE -.SH -Note: -.I -The call to -.I ntohs() -is necessary to ensure that the port number in -.I "addr.sin_port" , -which is in -.I network -byte order, is passed in -.I host -byte order (as -.I pmap_set() -expects). See the -.I byteorder(3N) -man page for more details on the conversion of network -addresses from network to host byte order. -.KS -.LP -The following pair of programs illustrate how to use the -.I gettransient() -routine. -The client makes an RPC call to the server, -passing it a transient program number. -Then the client waits around to receive a callback -from the server at that program number. -The server registers the program -.I EXAMPLEPROG -so that it can receive the RPC call -informing it of the callback program number. -Then at some random time (on receiving an -.I ALRM -signal in this example), it sends a callback RPC call, -using the program number it received earlier. -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* - * client - */ -.ft CW -#include -#include - -int callback(); -char hostname[256]; - -main() -{ - int x, ans, s; - SVCXPRT *xprt; - - gethostname(hostname, sizeof(hostname)); - s = RPC_ANYSOCK; - x = gettransient(IPPROTO_UDP, 1, &s); - fprintf(stderr, "client gets prognum %d\en", x); - if ((xprt = svcudp_create(s)) == NULL) { - fprintf(stderr, "rpc_server: svcudp_create\en"); - exit(1); - } -.ft I - /* protocol is 0 - gettransient does registering - */ -.ft CW - (void)svc_register(xprt, x, 1, callback, 0); - ans = callrpc(hostname, EXAMPLEPROG, EXAMPLEVERS, - EXAMPLEPROC_CALLBACK, xdr_int, &x, xdr_void, 0); - if ((enum clnt_stat) ans != RPC_SUCCESS) { - fprintf(stderr, "call: "); - clnt_perrno(ans); - fprintf(stderr, "\en"); - } - svc_run(); - fprintf(stderr, "Error: svc_run shouldn't return\en"); -} - -callback(rqstp, transp) - register struct svc_req *rqstp; - register SVCXPRT *transp; -{ - switch (rqstp->rq_proc) { - case 0: - if (!svc_sendreply(transp, xdr_void, 0)) { - fprintf(stderr, "err: exampleprog\en"); - return (1); - } - return (0); - case 1: - if (!svc_getargs(transp, xdr_void, 0)) { - svcerr_decode(transp); - return (1); - } - fprintf(stderr, "client got callback\en"); - if (!svc_sendreply(transp, xdr_void, 0)) { - fprintf(stderr, "err: exampleprog"); - return (1); - } - } -} -.vs -.DE -.KE -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* - * server - */ -.ft CW -#include -#include -#include - -char *getnewprog(); -char hostname[256]; -int docallback(); -int pnum; /* \fIprogram number for callback routine\fP */ - -main() -{ - gethostname(hostname, sizeof(hostname)); - registerrpc(EXAMPLEPROG, EXAMPLEVERS, - EXAMPLEPROC_CALLBACK, getnewprog, xdr_int, xdr_void); - fprintf(stderr, "server going into svc_run\en"); - signal(SIGALRM, docallback); - alarm(10); - svc_run(); - fprintf(stderr, "Error: svc_run shouldn't return\en"); -} - -char * -getnewprog(pnump) - char *pnump; -{ - pnum = *(int *)pnump; - return NULL; -} - -docallback() -{ - int ans; - - ans = callrpc(hostname, pnum, 1, 1, xdr_void, 0, - xdr_void, 0); - if (ans != 0) { - fprintf(stderr, "server: "); - clnt_perrno(ans); - fprintf(stderr, "\en"); - } -} -.vs -.DE diff --git a/c/src/librpc/src/rpc/PSD.doc/rpc.rfc.ms b/c/src/librpc/src/rpc/PSD.doc/rpc.rfc.ms deleted file mode 100644 index af9c2df2ed..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/rpc.rfc.ms +++ /dev/null @@ -1,1302 +0,0 @@ -.\" -.\" Must use -- tbl -- with this one -.\" -.\" @(#)rpc.rfc.ms 2.2 88/08/05 4.0 RPCSRC -.de BT -.if \\n%=1 .tl ''- % -'' -.. -.ND -.\" prevent excess underlining in nroff -.if n .fp 2 R -.OH 'Remote Procedure Calls: Protocol Specification''Page %' -.EH 'Page %''Remote Procedure Calls: Protocol Specification' -.if \\n%=1 .bp -.SH -\&Remote Procedure Calls: Protocol Specification -.LP -.NH 0 -\&Status of this Memo -.LP -Note: This chapter specifies a protocol that Sun Microsystems, Inc., -and others are using. -It has been designated RFC1050 by the ARPA Network -Information Center. -.LP -.NH 1 -\&Introduction -.LP -This chapter specifies a message protocol used in implementing -Sun's Remote Procedure Call (RPC) package. (The message protocol is -specified with the External Data Representation (XDR) language. -See the -.I "External Data Representation Standard: Protocol Specification" -for the details. Here, we assume that the reader is familiar -with XDR and do not attempt to justify it or its uses). The paper -by Birrell and Nelson [1] is recommended as an excellent background -to and justification of RPC. -.NH 2 -\&Terminology -.LP -This chapter discusses servers, services, programs, procedures, -clients, and versions. A server is a piece of software where network -services are implemented. A network service is a collection of one -or more remote programs. A remote program implements one or more -remote procedures; the procedures, their parameters, and results are -documented in the specific program's protocol specification (see the -\fIPort Mapper Program Protocol\fP\, below, for an example). Network -clients are pieces of software that initiate remote procedure calls -to services. A server may support more than one version of a remote -program in order to be forward compatible with changing protocols. -.LP -For example, a network file service may be composed of two programs. -One program may deal with high-level applications such as file system -access control and locking. The other may deal with low-level file -IO and have procedures like "read" and "write". A client machine of -the network file service would call the procedures associated with -the two programs of the service on behalf of some user on the client -machine. -.NH 2 -\&The RPC Model -.LP -The remote procedure call model is similar to the local procedure -call model. In the local case, the caller places arguments to a -procedure in some well-specified location (such as a result -register). It then transfers control to the procedure, and -eventually gains back control. At that point, the results of the -procedure are extracted from the well-specified location, and the -caller continues execution. -.LP -The remote procedure call is similar, in that one thread of control -logically winds through two processes\(emone is the caller's process, -the other is a server's process. That is, the caller process sends a -call message to the server process and waits (blocks) for a reply -message. The call message contains the procedure's parameters, among -other things. The reply message contains the procedure's results, -among other things. Once the reply message is received, the results -of the procedure are extracted, and caller's execution is resumed. -.LP -On the server side, a process is dormant awaiting the arrival of a -call message. When one arrives, the server process extracts the -procedure's parameters, computes the results, sends a reply message, -and then awaits the next call message. -.LP -Note that in this model, only one of the two processes is active at -any given time. However, this model is only given as an example. -The RPC protocol makes no restrictions on the concurrency model -implemented, and others are possible. For example, an implementation -may choose to have RPC calls be asynchronous, so that the client may -do useful work while waiting for the reply from the server. Another -possibility is to have the server create a task to process an -incoming request, so that the server can be free to receive other -requests. -.NH 2 -\&Transports and Semantics -.LP -The RPC protocol is independent of transport protocols. That is, RPC -does not care how a message is passed from one process to another. -The protocol deals only with specification and interpretation of -messages. -.LP -It is important to point out that RPC does not try to implement any -kind of reliability and that the application must be aware of the -type of transport protocol underneath RPC. If it knows it is running -on top of a reliable transport such as TCP/IP[6], then most of the -work is already done for it. On the other hand, if it is running on -top of an unreliable transport such as UDP/IP[7], it must implement -is own retransmission and time-out policy as the RPC layer does not -provide this service. -.LP -Because of transport independence, the RPC protocol does not attach -specific semantics to the remote procedures or their execution. -Semantics can be inferred from (but should be explicitly specified -by) the underlying transport protocol. For example, consider RPC -running on top of an unreliable transport such as UDP/IP. If an -application retransmits RPC messages after short time-outs, the only -thing it can infer if it receives no reply is that the procedure was -executed zero or more times. If it does receive a reply, then it can -infer that the procedure was executed at least once. -.LP -A server may wish to remember previously granted requests from a -client and not regrant them in order to insure some degree of -execute-at-most-once semantics. A server can do this by taking -advantage of the transaction ID that is packaged with every RPC -request. The main use of this transaction is by the client RPC layer -in matching replies to requests. However, a client application may -choose to reuse its previous transaction ID when retransmitting a -request. The server application, knowing this fact, may choose to -remember this ID after granting a request and not regrant requests -with the same ID in order to achieve some degree of -execute-at-most-once semantics. The server is not allowed to examine -this ID in any other way except as a test for equality. -.LP -On the other hand, if using a reliable transport such as TCP/IP, the -application can infer from a reply message that the procedure was -executed exactly once, but if it receives no reply message, it cannot -assume the remote procedure was not executed. Note that even if a -connection-oriented protocol like TCP is used, an application still -needs time-outs and reconnection to handle server crashes. -.LP -There are other possibilities for transports besides datagram- or -connection-oriented protocols. For example, a request-reply protocol -such as VMTP[2] is perhaps the most natural transport for RPC. -.SH -.I -NOTE: At Sun, RPC is currently implemented on top of both TCP/IP -and UDP/IP transports. -.LP -.NH 2 -\&Binding and Rendezvous Independence -.LP -The act of binding a client to a service is NOT part of the remote -procedure call specification. This important and necessary function -is left up to some higher-level software. (The software may use RPC -itself\(emsee the \fIPort Mapper Program Protocol\fP\, below). -.LP -Implementors should think of the RPC protocol as the jump-subroutine -instruction ("JSR") of a network; the loader (binder) makes JSR -useful, and the loader itself uses JSR to accomplish its task. -Likewise, the network makes RPC useful, using RPC to accomplish this -task. -.NH 2 -\&Authentication -.LP -The RPC protocol provides the fields necessary for a client to -identify itself to a service and vice-versa. Security and access -control mechanisms can be built on top of the message authentication. -Several different authentication protocols can be supported. A field -in the RPC header indicates which protocol is being used. More -information on specific authentication protocols can be found in the -\fIAuthentication Protocols\fP\, -below. -.KS -.NH 1 -\&RPC Protocol Requirements -.LP -The RPC protocol must provide for the following: -.IP 1. -Unique specification of a procedure to be called. -.IP 2. -Provisions for matching response messages to request messages. -.KE -.IP 3. -Provisions for authenticating the caller to service and vice-versa. -.LP -Besides these requirements, features that detect the following are -worth supporting because of protocol roll-over errors, implementation -bugs, user error, and network administration: -.IP 1. -RPC protocol mismatches. -.IP 2. -Remote program protocol version mismatches. -.IP 3. -Protocol errors (such as misspecification of a procedure's parameters). -.IP 4. -Reasons why remote authentication failed. -.IP 5. -Any other reasons why the desired procedure was not called. -.NH 2 -\&Programs and Procedures -.LP -The RPC call message has three unsigned fields: remote program -number, remote program version number, and remote procedure number. -The three fields uniquely identify the procedure to be called. -Program numbers are administered by some central authority (like -Sun). Once an implementor has a program number, he can implement his -remote program; the first implementation would most likely have the -version number of 1. Because most new protocols evolve into better, -stable, and mature protocols, a version field of the call message -identifies which version of the protocol the caller is using. -Version numbers make speaking old and new protocols through the same -server process possible. -.LP -The procedure number identifies the procedure to be called. These -numbers are documented in the specific program's protocol -specification. For example, a file service's protocol specification -may state that its procedure number 5 is "read" and procedure number -12 is "write". -.LP -Just as remote program protocols may change over several versions, -the actual RPC message protocol could also change. Therefore, the -call message also has in it the RPC version number, which is always -equal to two for the version of RPC described here. -.LP -The reply message to a request message has enough information to -distinguish the following error conditions: -.IP 1. -The remote implementation of RPC does speak protocol version 2. -The lowest and highest supported RPC version numbers are returned. -.IP 2. -The remote program is not available on the remote system. -.IP 3. -The remote program does not support the requested version number. -The lowest and highest supported remote program version numbers are -returned. -.IP 4. -The requested procedure number does not exist. (This is usually a -caller side protocol or programming error.) -.IP 5. -The parameters to the remote procedure appear to be garbage from the -server's point of view. (Again, this is usually caused by a -disagreement about the protocol between client and service.) -.NH 2 -\&Authentication -.LP -Provisions for authentication of caller to service and vice-versa are -provided as a part of the RPC protocol. The call message has two -authentication fields, the credentials and verifier. The reply -message has one authentication field, the response verifier. The RPC -protocol specification defines all three fields to be the following -opaque type: -.DS -.ft CW -.vs 11 -enum auth_flavor { - AUTH_NULL = 0, - AUTH_UNIX = 1, - AUTH_SHORT = 2, - AUTH_DES = 3 - /* \fIand more to be defined\fP */ -}; - -struct opaque_auth { - auth_flavor flavor; - opaque body<400>; -}; -.DE -.LP -In simple English, any -.I opaque_auth -structure is an -.I auth_flavor -enumeration followed by bytes which are opaque to the RPC protocol -implementation. -.LP -The interpretation and semantics of the data contained within the -authentication fields is specified by individual, independent -authentication protocol specifications. (See -\fIAuthentication Protocols\fP\, -below, for definitions of the various authentication protocols.) -.LP -If authentication parameters were rejected, the response message -contains information stating why they were rejected. -.NH 2 -\&Program Number Assignment -.LP -Program numbers are given out in groups of -.I 0x20000000 -(decimal 536870912) according to the following chart: -.TS -box tab (&) ; -lfI lfI -rfL cfI . -Program Numbers&Description -_ -.sp .5 -0 - 1fffffff&Defined by Sun -20000000 - 3fffffff&Defined by user -40000000 - 5fffffff&Transient -60000000 - 7fffffff&Reserved -80000000 - 9fffffff&Reserved -a0000000 - bfffffff&Reserved -c0000000 - dfffffff&Reserved -e0000000 - ffffffff&Reserved -.TE -.LP -The first group is a range of numbers administered by Sun -Microsystems and should be identical for all sites. The second range -is for applications peculiar to a particular site. This range is -intended primarily for debugging new programs. When a site develops -an application that might be of general interest, that application -should be given an assigned number in the first range. The third -group is for applications that generate program numbers dynamically. -The final groups are reserved for future use, and should not be used. -.NH 2 -\&Other Uses of the RPC Protocol -.LP -The intended use of this protocol is for calling remote procedures. -That is, each call message is matched with a response message. -However, the protocol itself is a message-passing protocol with which -other (non-RPC) protocols can be implemented. Sun currently uses, or -perhaps abuses, the RPC message protocol for the following two -(non-RPC) protocols: batching (or pipelining) and broadcast RPC. -These two protocols are discussed but not defined below. -.NH 3 -\&Batching -.LP -Batching allows a client to send an arbitrarily large sequence of -call messages to a server; batching typically uses reliable byte -stream protocols (like TCP/IP) for its transport. In the case of -batching, the client never waits for a reply from the server, and the -server does not send replies to batch requests. A sequence of batch -calls is usually terminated by a legitimate RPC in order to flush the -pipeline (with positive acknowledgement). -.NH 3 -\&Broadcast RPC -.LP -In broadcast RPC-based protocols, the client sends a broadcast packet -to the network and waits for numerous replies. Broadcast RPC uses -unreliable, packet-based protocols (like UDP/IP) as its transports. -Servers that support broadcast protocols only respond when the -request is successfully processed, and are silent in the face of -errors. Broadcast RPC uses the Port Mapper RPC service to achieve -its semantics. See the \fIPort Mapper Program Protocol\fP\, below, -for more information. -.KS -.NH 1 -\&The RPC Message Protocol -.LP -This section defines the RPC message protocol in the XDR data -description language. The message is defined in a top-down style. -.ie t .DS -.el .DS L -.ft CW -enum msg_type { - CALL = 0, - REPLY = 1 -}; - -.ft I -/* -* A reply to a call message can take on two forms: -* The message was either accepted or rejected. -*/ -.ft CW -enum reply_stat { - MSG_ACCEPTED = 0, - MSG_DENIED = 1 -}; - -.ft I -/* -* Given that a call message was accepted, the following is the -* status of an attempt to call a remote procedure. -*/ -.ft CW -enum accept_stat { - SUCCESS = 0, /* \fIRPC executed successfully \fP*/ - PROG_UNAVAIL = 1, /* \fIremote hasn't exported program \fP*/ - PROG_MISMATCH = 2, /* \fIremote can't support version # \fP*/ - PROC_UNAVAIL = 3, /* \fIprogram can't support procedure \fP*/ - GARBAGE_ARGS = 4 /* \fIprocedure can't decode params \fP*/ -}; -.DE -.ie t .DS -.el .DS L -.ft I -/* -* Reasons why a call message was rejected: -*/ -.ft CW -enum reject_stat { - RPC_MISMATCH = 0, /* \fIRPC version number != 2 \fP*/ - AUTH_ERROR = 1 /* \fIremote can't authenticate caller \fP*/ -}; - -.ft I -/* -* Why authentication failed: -*/ -.ft CW -enum auth_stat { - AUTH_BADCRED = 1, /* \fIbad credentials \fP*/ - AUTH_REJECTEDCRED = 2, /* \fIclient must begin new session \fP*/ - AUTH_BADVERF = 3, /* \fIbad verifier \fP*/ - AUTH_REJECTEDVERF = 4, /* \fIverifier expired or replayed \fP*/ - AUTH_TOOWEAK = 5 /* \fIrejected for security reasons \fP*/ -}; -.DE -.KE -.ie t .DS -.el .DS L -.ft I -/* -* The RPC message: -* All messages start with a transaction identifier, xid, -* followed by a two-armed discriminated union. The union's -* discriminant is a msg_type which switches to one of the two -* types of the message. The xid of a \fIREPLY\fP message always -* matches that of the initiating \fICALL\fP message. NB: The xid -* field is only used for clients matching reply messages with -* call messages or for servers detecting retransmissions; the -* service side cannot treat this id as any type of sequence -* number. -*/ -.ft CW -struct rpc_msg { - unsigned int xid; - union switch (msg_type mtype) { - case CALL: - call_body cbody; - case REPLY: - reply_body rbody; - } body; -}; -.DE -.ie t .DS -.el .DS L -.ft I -/* -* Body of an RPC request call: -* In version 2 of the RPC protocol specification, rpcvers must -* be equal to 2. The fields prog, vers, and proc specify the -* remote program, its version number, and the procedure within -* the remote program to be called. After these fields are two -* authentication parameters: cred (authentication credentials) -* and verf (authentication verifier). The two authentication -* parameters are followed by the parameters to the remote -* procedure, which are specified by the specific program -* protocol. -*/ -.ft CW -struct call_body { - unsigned int rpcvers; /* \fImust be equal to two (2) \fP*/ - unsigned int prog; - unsigned int vers; - unsigned int proc; - opaque_auth cred; - opaque_auth verf; - /* \fIprocedure specific parameters start here \fP*/ -}; -.DE -.ie t .DS -.el .DS L -.ft I -/* -* Body of a reply to an RPC request: -* The call message was either accepted or rejected. -*/ -.ft CW -union reply_body switch (reply_stat stat) { - case MSG_ACCEPTED: - accepted_reply areply; - case MSG_DENIED: - rejected_reply rreply; -} reply; -.DE -.ie t .DS -.el .DS L -.ft I -/* -* Reply to an RPC request that was accepted by the server: -* there could be an error even though the request was accepted. -* The first field is an authentication verifier that the server -* generates in order to validate itself to the caller. It is -* followed by a union whose discriminant is an enum -* accept_stat. The \fISUCCESS\fP arm of the union is protocol -* specific. The \fIPROG_UNAVAIL\fP, \fIPROC_UNAVAIL\fP, and \fIGARBAGE_ARGP\fP -* arms of the union are void. The \fIPROG_MISMATCH\fP arm specifies -* the lowest and highest version numbers of the remote program -* supported by the server. -*/ -.ft CW -struct accepted_reply { - opaque_auth verf; - union switch (accept_stat stat) { - case SUCCESS: - opaque results[0]; - /* \fIprocedure-specific results start here\fP */ - case PROG_MISMATCH: - struct { - unsigned int low; - unsigned int high; - } mismatch_info; - default: -.ft I - /* - * Void. Cases include \fIPROG_UNAVAIL, PROC_UNAVAIL\fP, - * and \fIGARBAGE_ARGS\fP. - */ -.ft CW - void; - } reply_data; -}; -.DE -.ie t .DS -.el .DS L -.ft I -/* -* Reply to an RPC request that was rejected by the server: -* The request can be rejected for two reasons: either the -* server is not running a compatible version of the RPC -* protocol (\fIRPC_MISMATCH\fP), or the server refuses to -* authenticate the caller (\fIAUTH_ERROR\fP). In case of an RPC -* version mismatch, the server returns the lowest and highest -* supported RPC version numbers. In case of refused -* authentication, failure status is returned. -*/ -.ft CW -union rejected_reply switch (reject_stat stat) { - case RPC_MISMATCH: - struct { - unsigned int low; - unsigned int high; - } mismatch_info; - case AUTH_ERROR: - auth_stat stat; -}; -.DE -.NH 1 -\&Authentication Protocols -.LP -As previously stated, authentication parameters are opaque, but -open-ended to the rest of the RPC protocol. This section defines -some "flavors" of authentication implemented at (and supported by) -Sun. Other sites are free to invent new authentication types, with -the same rules of flavor number assignment as there is for program -number assignment. -.NH 2 -\&Null Authentication -.LP -Often calls must be made where the caller does not know who he is or -the server does not care who the caller is. In this case, the flavor -value (the discriminant of the \fIopaque_auth\fP's union) of the RPC -message's credentials, verifier, and response verifier is -.I AUTH_NULL . -The bytes of the opaque_auth's body are undefined. -It is recommended that the opaque length be zero. -.NH 2 -\&UNIX Authentication -.LP -The caller of a remote procedure may wish to identify himself as he -is identified on a UNIX system. The value of the credential's -discriminant of an RPC call message is -.I AUTH_UNIX . -The bytes of -the credential's opaque body encode the following structure: -.DS -.ft CW -struct auth_unix { - unsigned int stamp; - string machinename<255>; - unsigned int uid; - unsigned int gid; - unsigned int gids<10>; -}; -.DE -The -.I stamp -is an arbitrary ID which the caller machine may -generate. The -.I machinename -is the name of the caller's machine (like "krypton"). The -.I uid -is the caller's effective user ID. The -.I gid -is the caller's effective group ID. The -.I gids -is a -counted array of groups which contain the caller as a member. The -verifier accompanying the credentials should be of -.I AUTH_NULL -(defined above). -.LP -The value of the discriminant of the response verifier received in -the reply message from the server may be -.I AUTH_NULL -or -.I AUTH_SHORT . -In the case of -.I AUTH_SHORT , -the bytes of the response verifier's string encode an opaque -structure. This new opaque structure may now be passed to the server -instead of the original -.I AUTH_UNIX -flavor credentials. The server keeps a cache which maps shorthand -opaque structures (passed back by way of an -.I AUTH_SHORT -style response verifier) to the original credentials of the caller. -The caller can save network bandwidth and server cpu cycles by using -the new credentials. -.LP -The server may flush the shorthand opaque structure at any time. If -this happens, the remote procedure call message will be rejected due -to an authentication error. The reason for the failure will be -.I AUTH_REJECTEDCRED . -At this point, the caller may wish to try the original -.I AUTH_UNIX -style of credentials. -.KS -.NH 2 -\&DES Authentication -.LP -UNIX authentication suffers from two major problems: -.IP 1. -The naming is too UNIX-system oriented. -.IP 2. -There is no verifier, so credentials can easily be faked. -.LP -DES authentication attempts to fix these two problems. -.KE -.NH 3 -\&Naming -.LP -The first problem is handled by addressing the caller by a simple -string of characters instead of by an operating system specific -integer. This string of characters is known as the "netname" or -network name of the caller. The server is not allowed to interpret -the contents of the caller's name in any other way except to -identify the caller. Thus, netnames should be unique for every -caller in the internet. -.LP -It is up to each operating system's implementation of DES -authentication to generate netnames for its users that insure this -uniqueness when they call upon remote servers. Operating systems -already know how to distinguish users local to their systems. It is -usually a simple matter to extend this mechanism to the network. -For example, a UNIX user at Sun with a user ID of 515 might be -assigned the following netname: "unix.515@sun.com". This netname -contains three items that serve to insure it is unique. Going -backwards, there is only one naming domain called "sun.com" in the -internet. Within this domain, there is only one UNIX user with -user ID 515. However, there may be another user on another -operating system, for example VMS, within the same naming domain -that, by coincidence, happens to have the same user ID. To insure -that these two users can be distinguished we add the operating -system name. So one user is "unix.515@sun.com" and the other is -"vms.515@sun.com". -.LP -The first field is actually a naming method rather than an -operating system name. It just happens that today there is almost -a one-to-one correspondence between naming methods and operating -systems. If the world could agree on a naming standard, the first -field could be the name of that standard, instead of an operating -system name. -.LP -.NH 3 -\&DES Authentication Verifiers -.LP -Unlike UNIX authentication, DES authentication does have a verifier -so the server can validate the client's credential (and -vice-versa). The contents of this verifier is primarily an -encrypted timestamp. The server can decrypt this timestamp, and if -it is close to what the real time is, then the client must have -encrypted it correctly. The only way the client could encrypt it -correctly is to know the "conversation key" of the RPC session. And -if the client knows the conversation key, then it must be the real -client. -.LP -The conversation key is a DES [5] key which the client generates -and notifies the server of in its first RPC call. The conversation -key is encrypted using a public key scheme in this first -transaction. The particular public key scheme used in DES -authentication is Diffie-Hellman [3] with 192-bit keys. The -details of this encryption method are described later. -.LP -The client and the server need the same notion of the current time -in order for all of this to work. If network time synchronization -cannot be guaranteed, then client can synchronize with the server -before beginning the conversation, perhaps by consulting the -Internet Time Server (TIME[4]). -.LP -The way a server determines if a client timestamp is valid is -somewhat complicated. For any other transaction but the first, the -server just checks for two things: -.IP 1. -the timestamp is greater than the one previously seen from the -same client. -.IP 2. -the timestamp has not expired. -.LP -A timestamp is expired if the server's time is later than the sum -of the client's timestamp plus what is known as the client's -"window". The "window" is a number the client passes (encrypted) -to the server in its first transaction. You can think of it as a -lifetime for the credential. -.LP -This explains everything but the first transaction. In the first -transaction, the server checks only that the timestamp has not -expired. If this was all that was done though, then it would be -quite easy for the client to send random data in place of the -timestamp with a fairly good chance of succeeding. As an added -check, the client sends an encrypted item in the first transaction -known as the "window verifier" which must be equal to the window -minus 1, or the server will reject the credential. -.LP -The client too must check the verifier returned from the server to -be sure it is legitimate. The server sends back to the client the -encrypted timestamp it received from the client, minus one second. -If the client gets anything different than this, it will reject it. -.LP -.NH 3 -\&Nicknames and Clock Synchronization -.LP -After the first transaction, the server's DES authentication -subsystem returns in its verifier to the client an integer -"nickname" which the client may use in its further transactions -instead of passing its netname, encrypted DES key and window every -time. The nickname is most likely an index into a table on the -server which stores for each client its netname, decrypted DES key -and window. -.LP -Though they originally were synchronized, the client's and server's -clocks can get out of sync again. When this happens the client RPC -subsystem most likely will get back -.I RPC_AUTHERROR -at which point it should resynchronize. -.LP -A client may still get the -.I RPC_AUTHERROR -error even though it is -synchronized with the server. The reason is that the server's -nickname table is a limited size, and it may flush entries whenever -it wants. A client should resend its original credential in this -case and the server will give it a new nickname. If a server -crashes, the entire nickname table gets flushed, and all clients -will have to resend their original credentials. -.KS -.NH 3 -\&DES Authentication Protocol (in XDR language) -.ie t .DS -.el .DS L -.ft I -/* -* There are two kinds of credentials: one in which the client uses -* its full network name, and one in which it uses its "nickname" -* (just an unsigned integer) given to it by the server. The -* client must use its fullname in its first transaction with the -* server, in which the server will return to the client its -* nickname. The client may use its nickname in all further -* transactions with the server. There is no requirement to use the -* nickname, but it is wise to use it for performance reasons. -*/ -.ft CW -enum authdes_namekind { - ADN_FULLNAME = 0, - ADN_NICKNAME = 1 -}; - -.ft I -/* -* A 64-bit block of encrypted DES data -*/ -.ft CW -typedef opaque des_block[8]; - -.ft I -/* -* Maximum length of a network user's name -*/ -.ft CW -const MAXNETNAMELEN = 255; - -.ft I -/* -* A fullname contains the network name of the client, an encrypted -* conversation key and the window. The window is actually a -* lifetime for the credential. If the time indicated in the -* verifier timestamp plus the window has past, then the server -* should expire the request and not grant it. To insure that -* requests are not replayed, the server should insist that -* timestamps are greater than the previous one seen, unless it is -* the first transaction. In the first transaction, the server -* checks instead that the window verifier is one less than the -* window. -*/ -.ft CW -struct authdes_fullname { -string name; /* \fIname of client \f(CW*/ -des_block key; /* \fIPK encrypted conversation key \f(CW*/ -unsigned int window; /* \fIencrypted window \f(CW*/ -}; - -.ft I -/* -* A credential is either a fullname or a nickname -*/ -.ft CW -union authdes_cred switch (authdes_namekind adc_namekind) { - case ADN_FULLNAME: - authdes_fullname adc_fullname; - case ADN_NICKNAME: - unsigned int adc_nickname; -}; - -.ft I -/* -* A timestamp encodes the time since midnight, January 1, 1970. -*/ -.ft CW -struct timestamp { - unsigned int seconds; /* \fIseconds \fP*/ - unsigned int useconds; /* \fIand microseconds \fP*/ -}; - -.ft I -/* -* Verifier: client variety -* The window verifier is only used in the first transaction. In -* conjunction with a fullname credential, these items are packed -* into the following structure before being encrypted: -* -* \f(CWstruct {\fP -* \f(CWadv_timestamp; \fP-- one DES block -* \f(CWadc_fullname.window; \fP-- one half DES block -* \f(CWadv_winverf; \fP-- one half DES block -* \f(CW}\fP -* This structure is encrypted using CBC mode encryption with an -* input vector of zero. All other encryptions of timestamps use -* ECB mode encryption. -*/ -.ft CW -struct authdes_verf_clnt { - timestamp adv_timestamp; /* \fIencrypted timestamp \fP*/ - unsigned int adv_winverf; /* \fIencrypted window verifier \fP*/ -}; - -.ft I -/* -* Verifier: server variety -* The server returns (encrypted) the same timestamp the client -* gave it minus one second. It also tells the client its nickname -* to be used in future transactions (unencrypted). -*/ -.ft CW -struct authdes_verf_svr { -timestamp adv_timeverf; /* \fIencrypted verifier \fP*/ -unsigned int adv_nickname; /* \fInew nickname for client \fP*/ -}; -.DE -.KE -.NH 3 -\&Diffie-Hellman Encryption -.LP -In this scheme, there are two constants, -.I BASE -and -.I MODULUS . -The -particular values Sun has chosen for these for the DES -authentication protocol are: -.ie t .DS -.el .DS L -.ft CW -const BASE = 3; -const MODULUS = - "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"; /* \fIhex \fP*/ -.DE -.ft R -The way this scheme works is best explained by an example. Suppose -there are two people "A" and "B" who want to send encrypted -messages to each other. So, A and B both generate "secret" keys at -random which they do not reveal to anyone. Let these keys be -represented as SK(A) and SK(B). They also publish in a public -directory their "public" keys. These keys are computed as follows: -.ie t .DS -.el .DS L -.ft CW -PK(A) = ( BASE ** SK(A) ) mod MODULUS -PK(B) = ( BASE ** SK(B) ) mod MODULUS -.DE -.ft R -The "**" notation is used here to represent exponentiation. Now, -both A and B can arrive at the "common" key between them, -represented here as CK(A, B), without revealing their secret keys. -.LP -A computes: -.ie t .DS -.el .DS L -.ft CW -CK(A, B) = ( PK(B) ** SK(A)) mod MODULUS -.DE -.ft R -while B computes: -.ie t .DS -.el .DS L -.ft CW -CK(A, B) = ( PK(A) ** SK(B)) mod MODULUS -.DE -.ft R -These two can be shown to be equivalent: -.ie t .DS -.el .DS L -.ft CW -(PK(B) ** SK(A)) mod MODULUS = (PK(A) ** SK(B)) mod MODULUS -.DE -.ft R -We drop the "mod MODULUS" parts and assume modulo arithmetic to -simplify things: -.ie t .DS -.el .DS L -.ft CW -PK(B) ** SK(A) = PK(A) ** SK(B) -.DE -.ft R -Then, replace PK(B) by what B computed earlier and likewise for -PK(A). -.ie t .DS -.el .DS L -.ft CW -((BASE ** SK(B)) ** SK(A) = (BASE ** SK(A)) ** SK(B) -.DE -.ft R -which leads to: -.ie t .DS -.el .DS L -.ft CW -BASE ** (SK(A) * SK(B)) = BASE ** (SK(A) * SK(B)) -.DE -.ft R -This common key CK(A, B) is not used to encrypt the timestamps used -in the protocol. Rather, it is used only to encrypt a conversation -key which is then used to encrypt the timestamps. The reason for -doing this is to use the common key as little as possible, for fear -that it could be broken. Breaking the conversation key is a far -less serious offense, since conversations are relatively -short-lived. -.LP -The conversation key is encrypted using 56-bit DES keys, yet the -common key is 192 bits. To reduce the number of bits, 56 bits are -selected from the common key as follows. The middle-most 8-bytes -are selected from the common key, and then parity is added to the -lower order bit of each byte, producing a 56-bit key with 8 bits of -parity. -.KS -.NH 1 -\&Record Marking Standard -.LP -When RPC messages are passed on top of a byte stream protocol (like -TCP/IP), it is necessary, or at least desirable, to delimit one -message from another in order to detect and possibly recover from -user protocol errors. This is called record marking (RM). Sun uses -this RM/TCP/IP transport for passing RPC messages on TCP streams. -One RPC message fits into one RM record. -.LP -A record is composed of one or more record fragments. A record -fragment is a four-byte header followed by 0 to (2**31) - 1 bytes of -fragment data. The bytes encode an unsigned binary number; as with -XDR integers, the byte order is from highest to lowest. The number -encodes two values\(ema boolean which indicates whether the fragment -is the last fragment of the record (bit value 1 implies the fragment -is the last fragment) and a 31-bit unsigned binary value which is the -length in bytes of the fragment's data. The boolean value is the -highest-order bit of the header; the length is the 31 low-order bits. -(Note that this record specification is NOT in XDR standard form!) -.KE -.KS -.NH 1 -\&The RPC Language -.LP -Just as there was a need to describe the XDR data-types in a formal -language, there is also need to describe the procedures that operate -on these XDR data-types in a formal language as well. We use the RPC -Language for this purpose. It is an extension to the XDR language. -The following example is used to describe the essence of the -language. -.NH 2 -\&An Example Service Described in the RPC Language -.LP -Here is an example of the specification of a simple ping program. -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* -* Simple ping program -*/ -.ft CW -program PING_PROG { - /* \fILatest and greatest version\fP */ - version PING_VERS_PINGBACK { - void - PINGPROC_NULL(void) = 0; - -.ft I - /* - * Ping the caller, return the round-trip time - * (in microseconds). Returns -1 if the operation - * timed out. - */ -.ft CW - int - PINGPROC_PINGBACK(void) = 1; -} = 2; - -.ft I -/* -* Original version -*/ -.ft CW -version PING_VERS_ORIG { - void - PINGPROC_NULL(void) = 0; - } = 1; -} = 1; - -const PING_VERS = 2; /* \fIlatest version \fP*/ -.vs -.DE -.KE -.LP -The first version described is -.I PING_VERS_PINGBACK -with two procedures, -.I PINGPROC_NULL -and -.I PINGPROC_PINGBACK . -.I PINGPROC_NULL -takes no arguments and returns no results, but it is useful for -computing round-trip times from the client to the server and back -again. By convention, procedure 0 of any RPC protocol should have -the same semantics, and never require any kind of authentication. -The second procedure is used for the client to have the server do a -reverse ping operation back to the client, and it returns the amount -of time (in microseconds) that the operation used. The next version, -.I PING_VERS_ORIG , -is the original version of the protocol -and it does not contain -.I PINGPROC_PINGBACK -procedure. It is useful -for compatibility with old client programs, and as this program -matures it may be dropped from the protocol entirely. -.KS -.NH 2 -\&The RPC Language Specification -.LP -The RPC language is identical to the XDR language, except for the -added definition of a -.I program-def -described below. -.DS -.ft CW -program-def: - "program" identifier "{" - version-def - version-def * - "}" "=" constant ";" - -version-def: - "version" identifier "{" - procedure-def - procedure-def * - "}" "=" constant ";" - -procedure-def: - type-specifier identifier "(" type-specifier ")" - "=" constant ";" -.DE -.KE -.NH 2 -\&Syntax Notes -.IP 1. -The following keywords are added and cannot be used as -identifiers: "program" and "version"; -.IP 2. -A version name cannot occur more than once within the scope of -a program definition. Nor can a version number occur more than once -within the scope of a program definition. -.IP 3. -A procedure name cannot occur more than once within the scope -of a version definition. Nor can a procedure number occur more than -once within the scope of version definition. -.IP 4. -Program identifiers are in the same name space as constant and -type identifiers. -.IP 5. -Only unsigned constants can be assigned to programs, versions -and procedures. -.NH 1 -\&Port Mapper Program Protocol -.LP -The port mapper program maps RPC program and version numbers to -transport-specific port numbers. This program makes dynamic binding -of remote programs possible. -.LP -This is desirable because the range of reserved port numbers is very -small and the number of potential remote programs is very large. By -running only the port mapper on a reserved port, the port numbers of -other remote programs can be ascertained by querying the port mapper. -.LP -The port mapper also aids in broadcast RPC. A given RPC program will -usually have different port number bindings on different machines, so -there is no way to directly broadcast to all of these programs. The -port mapper, however, does have a fixed port number. So, to -broadcast to a given program, the client actually sends its message -to the port mapper located at the broadcast address. Each port -mapper that picks up the broadcast then calls the local service -specified by the client. When the port mapper gets the reply from -the local service, it sends the reply on back to the client. -.KS -.NH 2 -\&Port Mapper Protocol Specification (in RPC Language) -.ie t .DS -.el .DS L -.ft CW -.vs 11 -const PMAP_PORT = 111; /* \fIportmapper port number \fP*/ - -.ft I -/* -* A mapping of (program, version, protocol) to port number -*/ -.ft CW -struct mapping { - unsigned int prog; - unsigned int vers; - unsigned int prot; - unsigned int port; -}; - -.ft I -/* -* Supported values for the "prot" field -*/ -.ft CW -const IPPROTO_TCP = 6; /* \fIprotocol number for TCP/IP \fP*/ -const IPPROTO_UDP = 17; /* \fIprotocol number for UDP/IP \fP*/ - -.ft I -/* -* A list of mappings -*/ -.ft CW -struct *pmaplist { - mapping map; - pmaplist next; -}; -.vs -.DE -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* -* Arguments to callit -*/ -.ft CW -struct call_args { - unsigned int prog; - unsigned int vers; - unsigned int proc; - opaque args<>; -}; - -.ft I -/* -* Results of callit -*/ -.ft CW -struct call_result { - unsigned int port; - opaque res<>; -}; -.vs -.DE -.KE -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* -* Port mapper procedures -*/ -.ft CW -program PMAP_PROG { - version PMAP_VERS { - void - PMAPPROC_NULL(void) = 0; - - bool - PMAPPROC_SET(mapping) = 1; - - bool - PMAPPROC_UNSET(mapping) = 2; - - unsigned int - PMAPPROC_GETPORT(mapping) = 3; - - pmaplist - PMAPPROC_DUMP(void) = 4; - - call_result - PMAPPROC_CALLIT(call_args) = 5; - } = 2; -} = 100000; -.vs -.DE -.NH 2 -\&Port Mapper Operation -.LP -The portmapper program currently supports two protocols (UDP/IP and -TCP/IP). The portmapper is contacted by talking to it on assigned -port number 111 (SUNRPC [8]) on either of these protocols. The -following is a description of each of the portmapper procedures: -.IP \fBPMAPPROC_NULL:\fP -This procedure does no work. By convention, procedure zero of any -protocol takes no parameters and returns no results. -.IP \fBPMAPPROC_SET:\fP -When a program first becomes available on a machine, it registers -itself with the port mapper program on the same machine. The program -passes its program number "prog", version number "vers", transport -protocol number "prot", and the port "port" on which it awaits -service request. The procedure returns a boolean response whose -value is -.I TRUE -if the procedure successfully established the mapping and -.I FALSE -otherwise. The procedure refuses to establish -a mapping if one already exists for the tuple "(prog, vers, prot)". -.IP \fBPMAPPROC_UNSET:\fP -When a program becomes unavailable, it should unregister itself with -the port mapper program on the same machine. The parameters and -results have meanings identical to those of -.I PMAPPROC_SET . -The protocol and port number fields of the argument are ignored. -.IP \fBPMAPPROC_GETPORT:\fP -Given a program number "prog", version number "vers", and transport -protocol number "prot", this procedure returns the port number on -which the program is awaiting call requests. A port value of zeros -means the program has not been registered. The "port" field of the -argument is ignored. -.IP \fBPMAPPROC_DUMP:\fP -This procedure enumerates all entries in the port mapper's database. -The procedure takes no parameters and returns a list of program, -version, protocol, and port values. -.IP \fBPMAPPROC_CALLIT:\fP -This procedure allows a caller to call another remote procedure on -the same machine without knowing the remote procedure's port number. -It is intended for supporting broadcasts to arbitrary remote programs -via the well-known port mapper's port. The parameters "prog", -"vers", "proc", and the bytes of "args" are the program number, -version number, procedure number, and parameters of the remote -procedure. -.LP -.B Note: -.RS -.IP 1. -This procedure only sends a response if the procedure was -successfully executed and is silent (no response) otherwise. -.IP 2. -The port mapper communicates with the remote program using UDP/IP -only. -.RE -.LP -The procedure returns the remote program's port number, and the bytes -of results are the results of the remote procedure. -.bp -.NH 1 -\&References -.LP -[1] Birrell, Andrew D. & Nelson, Bruce Jay; "Implementing Remote -Procedure Calls"; XEROX CSL-83-7, October 1983. -.LP -[2] Cheriton, D.; "VMTP: Versatile Message Transaction Protocol", -Preliminary Version 0.3; Stanford University, January 1987. -.LP -[3] Diffie & Hellman; "New Directions in Cryptography"; IEEE -Transactions on Information Theory IT-22, November 1976. -.LP -[4] Harrenstien, K.; "Time Server", RFC 738; Information Sciences -Institute, October 1977. -.LP -[5] National Bureau of Standards; "Data Encryption Standard"; Federal -Information Processing Standards Publication 46, January 1977. -.LP -[6] Postel, J.; "Transmission Control Protocol - DARPA Internet -Program Protocol Specification", RFC 793; Information Sciences -Institute, September 1981. -.LP -[7] Postel, J.; "User Datagram Protocol", RFC 768; Information Sciences -Institute, August 1980. -.LP -[8] Reynolds, J. & Postel, J.; "Assigned Numbers", RFC 923; Information -Sciences Institute, October 1984. diff --git a/c/src/librpc/src/rpc/PSD.doc/rpcgen.ms b/c/src/librpc/src/rpc/PSD.doc/rpcgen.ms deleted file mode 100644 index b4e50e5d6f..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/rpcgen.ms +++ /dev/null @@ -1,1299 +0,0 @@ -.\" -.\" Must use -- tbl -- for this one -.\" -.\" @(#)rpcgen.ms 2.2 88/08/04 4.0 RPCSRC -.de BT -.if \\n%=1 .tl ''- % -'' -.. -.ND -.\" prevent excess underlining in nroff -.if n .fp 2 R -.OH '\fBrpcgen\fP Programming Guide''Page %' -.EH 'Page %''\fBrpcgen\fP Programming Guide' -.if \\n%=1 .bp -.SH -\&\fBrpcgen\fP Programming Guide -.NH 0 -\&The \fBrpcgen\fP Protocol Compiler -.IX rpcgen "" \fIrpcgen\fP "" PAGE MAJOR -.LP -.IX RPC "" "" \fIrpcgen\fP -The details of programming applications to use Remote Procedure Calls -can be overwhelming. Perhaps most daunting is the writing of the XDR -routines necessary to convert procedure arguments and results into -their network format and vice-versa. -.LP -Fortunately, -.I rpcgen(1) -exists to help programmers write RPC applications simply and directly. -.I rpcgen -does most of the dirty work, allowing programmers to debug -the main features of their application, instead of requiring them to -spend most of their time debugging their network interface code. -.LP -.I rpcgen -is a compiler. It accepts a remote program interface definition written -in a language, called RPC Language, which is similar to C. It produces a C -language output which includes stub versions of the client routines, a -server skeleton, XDR filter routines for both parameters and results, and a -header file that contains common definitions. The client stubs interface -with the RPC library and effectively hide the network from their callers. -The server stub similarly hides the network from the server procedures that -are to be invoked by remote clients. -.I rpcgen 's -output files can be compiled and linked in the usual way. The developer -writes server procedures\(emin any language that observes Sun calling -conventions\(emand links them with the server skeleton produced by -.I rpcgen -to get an executable server program. To use a remote program, a programmer -writes an ordinary main program that makes local procedure calls to the -client stubs produced by -.I rpcgen . -Linking this program with -.I rpcgen 's -stubs creates an executable program. (At present the main program must be -written in C). -.I rpcgen -options can be used to suppress stub generation and to specify the transport -to be used by the server stub. -.LP -Like all compilers, -.I rpcgen -reduces development time -that would otherwise be spent coding and debugging low-level routines. -All compilers, including -.I rpcgen , -do this at a small cost in efficiency -and flexibility. However, many compilers allow escape hatches for -programmers to mix low-level code with high-level code. -.I rpcgen -is no exception. In speed-critical applications, hand-written routines -can be linked with the -.I rpcgen -output without any difficulty. Also, one may proceed by using -.I rpcgen -output as a starting point, and then rewriting it as necessary. -(If you need a discussion of RPC programming without -.I rpcgen , -see the -.I "Remote Procedure Call Programming Guide)\. -.NH 1 -\&Converting Local Procedures into Remote Procedures -.IX rpcgen "local procedures" \fIrpcgen\fP -.IX rpcgen "remote procedures" \fIrpcgen\fP -.LP -Assume an application that runs on a single machine, one which we want -to convert to run over the network. Here we will demonstrate such a -conversion by way of a simple example\(ema program that prints a -message to the console: -.ie t .DS -.el .DS L -.ft I -/* - * printmsg.c: print a message on the console - */ -.ft CW -#include - -main(argc, argv) - int argc; - char *argv[]; -{ - char *message; - - if (argc < 2) { - fprintf(stderr, "usage: %s \en", argv[0]); - exit(1); - } - message = argv[1]; - - if (!printmessage(message)) { - fprintf(stderr, "%s: couldn't print your message\en", - argv[0]); - exit(1); - } - printf("Message Delivered!\en"); - exit(0); -} -.ft I -/* - * Print a message to the console. - * Return a boolean indicating whether the message was actually printed. - */ -.ft CW -printmessage(msg) - char *msg; -{ - FILE *f; - - f = fopen("/dev/console", "w"); - if (f == NULL) { - return (0); - } - fprintf(f, "%s\en", msg); - fclose(f); - return(1); -} -.DE -.LP -And then, of course: -.ie t .DS -.el .DS L -.ft CW -example% \fBcc printmsg.c -o printmsg\fP -example% \fBprintmsg "Hello, there."\fP -Message delivered! -example% -.DE -.LP -If -.I printmessage() -was turned into a remote procedure, -then it could be called from anywhere in the network. -Ideally, one would just like to stick a keyword like -.I remote -in front of a -procedure to turn it into a remote procedure. Unfortunately, -we have to live within the constraints of the C language, since -it existed long before RPC did. But even without language -support, it's not very difficult to make a procedure remote. -.LP -In general, it's necessary to figure out what the types are for -all procedure inputs and outputs. In this case, we have a -procedure -.I printmessage() -which takes a string as input, and returns an integer -as output. Knowing this, we can write a protocol specification in RPC -language that describes the remote version of -.I printmessage (). -Here it is: -.ie t .DS -.el .DS L -.ft I -/* - * msg.x: Remote message printing protocol - */ -.ft CW - -program MESSAGEPROG { - version MESSAGEVERS { - int PRINTMESSAGE(string) = 1; - } = 1; -} = 99; -.DE -.LP -Remote procedures are part of remote programs, so we actually declared -an entire remote program here which contains the single procedure -.I PRINTMESSAGE . -This procedure was declared to be in version 1 of the -remote program. No null procedure (procedure 0) is necessary because -.I rpcgen -generates it automatically. -.LP -Notice that everything is declared with all capital letters. This is -not required, but is a good convention to follow. -.LP -Notice also that the argument type is \*Qstring\*U and not \*Qchar *\*U. This -is because a \*Qchar *\*U in C is ambiguous. Programmers usually intend it -to mean a null-terminated string of characters, but it could also -represent a pointer to a single character or a pointer to an array of -characters. In RPC language, a null-terminated string is -unambiguously called a \*Qstring\*U. -.LP -There are just two more things to write. First, there is the remote -procedure itself. Here's the definition of a remote procedure -to implement the -.I PRINTMESSAGE -procedure we declared above: -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* - * msg_proc.c: implementation of the remote procedure "printmessage" - */ -.ft CW - -#include -#include /* \fIalways needed\fP */ -#include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */ - -.ft I -/* - * Remote verson of "printmessage" - */ -.ft CW -int * -printmessage_1(msg) - char **msg; -{ - static int result; /* \fImust be static!\fP */ - FILE *f; - - f = fopen("/dev/console", "w"); - if (f == NULL) { - result = 0; - return (&result); - } - fprintf(f, "%s\en", *msg); - fclose(f); - result = 1; - return (&result); -} -.vs -.DE -.LP -Notice here that the declaration of the remote procedure -.I printmessage_1() -differs from that of the local procedure -.I printmessage() -in three ways: -.IP 1. -It takes a pointer to a string instead of a string itself. This -is true of all remote procedures: they always take pointers to their -arguments rather than the arguments themselves. -.IP 2. -It returns a pointer to an integer instead of an integer itself. This is -also generally true of remote procedures: they always return a pointer -to their results. -.IP 3. -It has an \*Q_1\*U appended to its name. In general, all remote -procedures called by -.I rpcgen -are named by the following rule: the name in the program definition -(here -.I PRINTMESSAGE ) -is converted to all -lower-case letters, an underbar (\*Q_\*U) is appended to it, and -finally the version number (here 1) is appended. -.LP -The last thing to do is declare the main client program that will call -the remote procedure. Here it is: -.ie t .DS -.el .DS L -.ft I -/* - * rprintmsg.c: remote version of "printmsg.c" - */ -.ft CW -#include -#include /* \fIalways needed\fP */ -#include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */ - -main(argc, argv) - int argc; - char *argv[]; -{ - CLIENT *cl; - int *result; - char *server; - char *message; - - if (argc < 3) { - fprintf(stderr, "usage: %s host message\en", argv[0]); - exit(1); - } - -.ft I - /* - * Save values of command line arguments - */ -.ft CW - server = argv[1]; - message = argv[2]; - -.ft I - /* - * Create client "handle" used for calling \fIMESSAGEPROG\fP on the - * server designated on the command line. We tell the RPC package - * to use the "tcp" protocol when contacting the server. - */ -.ft CW - cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp"); - if (cl == NULL) { -.ft I - /* - * Couldn't establish connection with server. - * Print error message and die. - */ -.ft CW - clnt_pcreateerror(server); - exit(1); - } - -.ft I - /* - * Call the remote procedure "printmessage" on the server - */ -.ft CW - result = printmessage_1(&message, cl); - if (result == NULL) { -.ft I - /* - * An error occurred while calling the server. - * Print error message and die. - */ -.ft CW - clnt_perror(cl, server); - exit(1); - } - -.ft I - /* - * Okay, we successfully called the remote procedure. - */ -.ft CW - if (*result == 0) { -.ft I - /* - * Server was unable to print our message. - * Print error message and die. - */ -.ft CW - fprintf(stderr, "%s: %s couldn't print your message\en", - argv[0], server); - exit(1); - } - -.ft I - /* - * The message got printed on the server's console - */ -.ft CW - printf("Message delivered to %s!\en", server); -} -.DE -There are two things to note here: -.IP 1. -.IX "client handle, used by rpcgen" "" "client handle, used by \fIrpcgen\fP" -First a client \*Qhandle\*U is created using the RPC library routine -.I clnt_create (). -This client handle will be passed to the stub routines -which call the remote procedure. -.IP 2. -The remote procedure -.I printmessage_1() -is called exactly the same way as it is declared in -.I msg_proc.c -except for the inserted client handle as the first argument. -.LP -Here's how to put all of the pieces together: -.ie t .DS -.el .DS L -.ft CW -example% \fBrpcgen msg.x\fP -example% \fBcc rprintmsg.c msg_clnt.c -o rprintmsg\fP -example% \fBcc msg_proc.c msg_svc.c -o msg_server\fP -.DE -Two programs were compiled here: the client program -.I rprintmsg -and the server program -.I msg_server . -Before doing this though, -.I rpcgen -was used to fill in the missing pieces. -.LP -Here is what -.I rpcgen -did with the input file -.I msg.x : -.IP 1. -It created a header file called -.I msg.h -that contained -.I #define 's -for -.I MESSAGEPROG , -.I MESSAGEVERS -and -.I PRINTMESSAGE -for use in the other modules. -.IP 2. -It created client \*Qstub\*U routines in the -.I msg_clnt.c -file. In this case there is only one, the -.I printmessage_1() -that was referred to from the -.I printmsg -client program. The name of the output file for -client stub routines is always formed in this way: if the name of the -input file is -.I FOO.x , -the client stubs output file is called -.I FOO_clnt.c . -.IP 3. -It created the server program which calls -.I printmessage_1() -in -.I msg_proc.c . -This server program is named -.I msg_svc.c . -The rule for naming the server output file is similar to the -previous one: for an input file called -.I FOO.x , -the output server file is named -.I FOO_svc.c . -.LP -Now we're ready to have some fun. First, copy the server to a -remote machine and run it. For this example, the -machine is called \*Qmoon\*U. Server processes are run in the -background, because they never exit. -.ie t .DS -.el .DS L -.ft CW -moon% \fBmsg_server &\fP -.DE -Then on our local machine (\*Qsun\*U) we can print a message on \*Qmoon\*Us -console. -.ie t .DS -.el .DS L -.ft CW -sun% \fBprintmsg moon "Hello, moon."\fP -.DE -The message will get printed to \*Qmoon\*Us console. You can print a -message on anybody's console (including your own) with this program if -you are able to copy the server to their machine and run it. -.NH 1 -\&Generating XDR Routines -.IX RPC "generating XDR routines" -.LP -The previous example only demonstrated the automatic generation of -client and server RPC code. -.I rpcgen -may also be used to generate XDR routines, that is, the routines -necessary to convert local data -structures into network format and vice-versa. This example presents -a complete RPC service\(ema remote directory listing service, which uses -.I rpcgen -not only to generate stub routines, but also to generate the XDR -routines. Here is the protocol description file: -.ie t .DS -.el .DS L -.ft I -/* - * dir.x: Remote directory listing protocol - */ -.ft CW -const MAXNAMELEN = 255; /* \fImaximum length of a directory entry\fP */ - -typedef string nametype; /* \fIa directory entry\fP */ - -typedef struct namenode *namelist; /* \fIa link in the listing\fP */ - -.ft I -/* - * A node in the directory listing - */ -.ft CW -struct namenode { - nametype name; /* \fIname of directory entry\fP */ - namelist next; /* \fInext entry\fP */ -}; - -.ft I -/* - * The result of a READDIR operation. - */ -.ft CW -union readdir_res switch (int errno) { -case 0: - namelist list; /* \fIno error: return directory listing\fP */ -default: - void; /* \fIerror occurred: nothing else to return\fP */ -}; - -.ft I -/* - * The directory program definition - */ -.ft CW -program DIRPROG { - version DIRVERS { - readdir_res - READDIR(nametype) = 1; - } = 1; -} = 76; -.DE -.SH -Note: -.I -Types (like -.I readdir_res -in the example above) can be defined using -the \*Qstruct\*U, \*Qunion\*U and \*Qenum\*U keywords, but those keywords -should not be used in subsequent declarations of variables of those types. -For example, if you define a union \*Qfoo\*U, you should declare using -only \*Qfoo\*U and not \*Qunion foo\*U. In fact, -.I rpcgen -compiles -RPC unions into C structures and it is an error to declare them using the -\*Qunion\*U keyword. -.LP -Running -.I rpcgen -on -.I dir.x -creates four output files. Three are the same as before: header file, -client stub routines and server skeleton. The fourth are the XDR routines -necessary for converting the data types we declared into XDR format and -vice-versa. These are output in the file -.I dir_xdr.c . -.LP -Here is the implementation of the -.I READDIR -procedure. -.ie t .DS -.el .DS L -.vs 11 -.ft I -/* - * dir_proc.c: remote readdir implementation - */ -.ft CW -#include -#include -#include "dir.h" - -extern int errno; -extern char *malloc(); -extern char *strdup(); - -readdir_res * -readdir_1(dirname) - nametype *dirname; -{ - DIR *dirp; - struct direct *d; - namelist nl; - namelist *nlp; - static readdir_res res; /* \fImust be static\fP! */ - -.ft I - /* - * Open directory - */ -.ft CW - dirp = opendir(*dirname); - if (dirp == NULL) { - res.errno = errno; - return (&res); - } - -.ft I - /* - * Free previous result - */ -.ft CW - xdr_free(xdr_readdir_res, &res); - -.ft I - /* - * Collect directory entries. - * Memory allocated here will be freed by \fIxdr_free\fP - * next time \fIreaddir_1\fP is called - */ -.ft CW - nlp = &res.readdir_res_u.list; - while (d = readdir(dirp)) { - nl = *nlp = (namenode *) malloc(sizeof(namenode)); - nl->name = strdup(d->d_name); - nlp = &nl->next; - } - *nlp = NULL; - -.ft I - /* - * Return the result - */ -.ft CW - res.errno = 0; - closedir(dirp); - return (&res); -} -.vs -.DE -Finally, there is the client side program to call the server: -.ie t .DS -.el .DS L -.ft I -/* - * rls.c: Remote directory listing client - */ -.ft CW -#include -#include /* \fIalways need this\fP */ -#include "dir.h" /* \fIwill be generated by rpcgen\fI */ - -extern int errno; - -main(argc, argv) - int argc; - char *argv[]; -{ - CLIENT *cl; - char *server; - char *dir; - readdir_res *result; - namelist nl; - - - if (argc != 3) { - fprintf(stderr, "usage: %s host directory\en", - argv[0]); - exit(1); - } - -.ft I - /* - * Remember what our command line arguments refer to - */ -.ft CW - server = argv[1]; - dir = argv[2]; - -.ft I - /* - * Create client "handle" used for calling \fIMESSAGEPROG\fP on the - * server designated on the command line. We tell the RPC package - * to use the "tcp" protocol when contacting the server. - */ -.ft CW - cl = clnt_create(server, DIRPROG, DIRVERS, "tcp"); - if (cl == NULL) { -.ft I - /* - * Couldn't establish connection with server. - * Print error message and die. - */ -.ft CW - clnt_pcreateerror(server); - exit(1); - } - -.ft I - /* - * Call the remote procedure \fIreaddir\fP on the server - */ -.ft CW - result = readdir_1(&dir, cl); - if (result == NULL) { -.ft I - /* - * An error occurred while calling the server. - * Print error message and die. - */ -.ft CW - clnt_perror(cl, server); - exit(1); - } - -.ft I - /* - * Okay, we successfully called the remote procedure. - */ -.ft CW - if (result->errno != 0) { -.ft I - /* - * A remote system error occurred. - * Print error message and die. - */ -.ft CW - errno = result->errno; - perror(dir); - exit(1); - } - -.ft I - /* - * Successfully got a directory listing. - * Print it out. - */ -.ft CW - for (nl = result->readdir_res_u.list; nl != NULL; - nl = nl->next) { - printf("%s\en", nl->name); - } - exit(0); -} -.DE -Compile everything, and run. -.DS -.ft CW -sun% \fBrpcgen dir.x\fP -sun% \fBcc rls.c dir_clnt.c dir_xdr.c -o rls\fP -sun% \fBcc dir_svc.c dir_proc.c dir_xdr.c -o dir_svc\fP - -sun% \fBdir_svc &\fP - -moon% \fBrls sun /usr/pub\fP -\&. -\&.. -ascii -eqnchar -greek -kbd -marg8 -tabclr -tabs -tabs4 -moon% -.DE -.LP -.IX "debugging with rpcgen" "" "debugging with \fIrpcgen\fP" -A final note about -.I rpcgen : -The client program and the server procedure can be tested together -as a single program by simply linking them with each other rather -than with the client and server stubs. The procedure calls will be -executed as ordinary local procedure calls and the program can be -debugged with a local debugger such as -.I dbx . -When the program is working, the client program can be linked to -the client stub produced by -.I rpcgen -and the server procedures can be linked to the server stub produced -by -.I rpcgen . -.SH -.I NOTE : -\fIIf you do this, you may want to comment out calls to RPC library -routines, and have client-side routines call server routines -directly.\fP -.LP -.NH 1 -\&The C-Preprocessor -.IX rpcgen "C-preprocessor" \fIrpcgen\fP -.LP -The C-preprocessor is run on all input files before they are -compiled, so all the preprocessor directives are legal within a \*Q.x\*U -file. Four symbols may be defined, depending upon which output file is -getting generated. The symbols are: -.TS -box tab (&); -lfI lfI -lfL l . -Symbol&Usage -_ -RPC_HDR&for header-file output -RPC_XDR&for XDR routine output -RPC_SVC&for server-skeleton output -RPC_CLNT&for client stub output -.TE -.LP -Also, -.I rpcgen -does a little preprocessing of its own. Any line that -begins with a percent sign is passed directly into the output file, -without any interpretation of the line. Here is a simple example that -demonstrates the preprocessing features. -.ie t .DS -.el .DS L -.ft I -/* - * time.x: Remote time protocol - */ -.ft CW -program TIMEPROG { - version TIMEVERS { - unsigned int TIMEGET(void) = 1; - } = 1; -} = 44; - -#ifdef RPC_SVC -%int * -%timeget_1() -%{ -% static int thetime; -% -% thetime = time(0); -% return (&thetime); -%} -#endif -.DE -The '%' feature is not generally recommended, as there is no guarantee -that the compiler will stick the output where you intended. -.NH 1 -\&\fBrpcgen\fP Programming Notes -.IX rpcgen "other operations" \fIrpcgen\fP -.sp -.NH 2 -\&Timeout Changes -.IX rpcgen "timeout changes" \fIrpcgen\fP -.LP -RPC sets a default timeout of 25 seconds for RPC calls when -.I clnt_create() -is used. This timeout may be changed using -.I clnt_control() -Here is a small code fragment to demonstrate use of -.I clnt_control (): -.ID -struct timeval tv; -CLIENT *cl; -.sp .5 -cl = clnt_create("somehost", SOMEPROG, SOMEVERS, "tcp"); -if (cl == NULL) { - exit(1); -} -tv.tv_sec = 60; /* \fIchange timeout to 1 minute\fP */ -tv.tv_usec = 0; -clnt_control(cl, CLSET_TIMEOUT, &tv); -.DE -.NH 2 -\&Handling Broadcast on the Server Side -.IX "broadcast RPC" -.IX rpcgen "broadcast RPC" \fIrpcgen\fP -.LP -When a procedure is known to be called via broadcast RPC, -it is usually wise for the server to not reply unless it can provide -some useful information to the client. This prevents the network -from getting flooded by useless replies. -.LP -To prevent the server from replying, a remote procedure can -return NULL as its result, and the server code generated by -.I rpcgen -will detect this and not send out a reply. -.LP -Here is an example of a procedure that replies only if it -thinks it is an NFS server: -.ID -void * -reply_if_nfsserver() -{ - char notnull; /* \fIjust here so we can use its address\fP */ -.sp .5 - if (access("/etc/exports", F_OK) < 0) { - return (NULL); /* \fIprevent RPC from replying\fP */ - } -.ft I - /* - * return non-null pointer so RPC will send out a reply - */ -.ft L - return ((void *)¬null); -} -.DE -Note that if procedure returns type \*Qvoid *\*U, they must return a non-NULL -pointer if they want RPC to reply for them. -.NH 2 -\&Other Information Passed to Server Procedures -.LP -Server procedures will often want to know more about an RPC call -than just its arguments. For example, getting authentication information -is important to procedures that want to implement some level of security. -This extra information is actually supplied to the server procedure as a -second argument. Here is an example to demonstrate its use. What we've -done here is rewrite the previous -.I printmessage_1() -procedure to only allow root users to print a message to the console. -.ID -int * -printmessage_1(msg, rq) - char **msg; - struct svc_req *rq; -{ - static in result; /* \fIMust be static\fP */ - FILE *f; - struct suthunix_parms *aup; -.sp .5 - aup = (struct authunix_parms *)rq->rq_clntcred; - if (aup->aup_uid != 0) { - result = 0; - return (&result); - } -.sp -.ft I - /* - * Same code as before. - */ -.ft L -} -.DE -.NH 1 -\&RPC Language -.IX RPCL -.IX rpcgen "RPC Language" \fIrpcgen\fP -.LP -RPC language is an extension of XDR language. The sole extension is -the addition of the -.I program -type. For a complete description of the XDR language syntax, see the -.I "External Data Representation Standard: Protocol Specification" -chapter. For a description of the RPC extensions to the XDR language, -see the -.I "Remote Procedure Calls: Protocol Specification" -chapter. -.LP -However, XDR language is so close to C that if you know C, you know most -of it already. We describe here the syntax of the RPC language, -showing a few examples along the way. We also show how the various -RPC and XDR type definitions get compiled into C type definitions in -the output header file. -.KS -.NH 2 -Definitions -\& -.IX rpcgen definitions \fIrpcgen\fP -.LP -An RPC language file consists of a series of definitions. -.DS L -.ft CW - definition-list: - definition ";" - definition ";" definition-list -.DE -.KE -It recognizes five types of definitions. -.DS L -.ft CW - definition: - enum-definition - struct-definition - union-definition - typedef-definition - const-definition - program-definition -.DE -.NH 2 -Structures -\& -.IX rpcgen structures \fIrpcgen\fP -.LP -An XDR struct is declared almost exactly like its C counterpart. It -looks like the following: -.DS L -.ft CW - struct-definition: - "struct" struct-ident "{" - declaration-list - "}" - - declaration-list: - declaration ";" - declaration ";" declaration-list -.DE -As an example, here is an XDR structure to a two-dimensional -coordinate, and the C structure that it gets compiled into in the -output header file. -.DS -.ft CW - struct coord { struct coord { - int x; --> int x; - int y; int y; - }; }; - typedef struct coord coord; -.DE -The output is identical to the input, except for the added -.I typedef -at the end of the output. This allows one to use \*Qcoord\*U instead of -\*Qstruct coord\*U when declaring items. -.NH 2 -Unions -\& -.IX rpcgen unions \fIrpcgen\fP -.LP -XDR unions are discriminated unions, and look quite different from C -unions. They are more analogous to Pascal variant records than they -are to C unions. -.DS L -.ft CW - union-definition: - "union" union-ident "switch" "(" declaration ")" "{" - case-list - "}" - - case-list: - "case" value ":" declaration ";" - "default" ":" declaration ";" - "case" value ":" declaration ";" case-list -.DE -Here is an example of a type that might be returned as the result of a -\*Qread data\*U operation. If there is no error, return a block of data. -Otherwise, don't return anything. -.DS L -.ft CW - union read_result switch (int errno) { - case 0: - opaque data[1024]; - default: - void; - }; -.DE -It gets compiled into the following: -.DS L -.ft CW - struct read_result { - int errno; - union { - char data[1024]; - } read_result_u; - }; - typedef struct read_result read_result; -.DE -Notice that the union component of the output struct has the name as -the type name, except for the trailing \*Q_u\*U. -.NH 2 -Enumerations -\& -.IX rpcgen enumerations \fIrpcgen\fP -.LP -XDR enumerations have the same syntax as C enumerations. -.DS L -.ft CW - enum-definition: - "enum" enum-ident "{" - enum-value-list - "}" - - enum-value-list: - enum-value - enum-value "," enum-value-list - - enum-value: - enum-value-ident - enum-value-ident "=" value -.DE -Here is a short example of an XDR enum, and the C enum that it gets -compiled into. -.DS L -.ft CW - enum colortype { enum colortype { - RED = 0, RED = 0, - GREEN = 1, --> GREEN = 1, - BLUE = 2 BLUE = 2, - }; }; - typedef enum colortype colortype; -.DE -.NH 2 -Typedef -\& -.IX rpcgen typedef \fIrpcgen\fP -.LP -XDR typedefs have the same syntax as C typedefs. -.DS L -.ft CW - typedef-definition: - "typedef" declaration -.DE -Here is an example that defines a -.I fname_type -used for declaring -file name strings that have a maximum length of 255 characters. -.DS L -.ft CW -typedef string fname_type<255>; --> typedef char *fname_type; -.DE -.NH 2 -Constants -\& -.IX rpcgen constants \fIrpcgen\fP -.LP -XDR constants symbolic constants that may be used wherever a -integer constant is used, for example, in array size specifications. -.DS L -.ft CW - const-definition: - "const" const-ident "=" integer -.DE -For example, the following defines a constant -.I DOZEN -equal to 12. -.DS L -.ft CW - const DOZEN = 12; --> #define DOZEN 12 -.DE -.NH 2 -Programs -\& -.IX rpcgen programs \fIrpcgen\fP -.LP -RPC programs are declared using the following syntax: -.DS L -.ft CW - program-definition: - "program" program-ident "{" - version-list - "}" "=" value - - version-list: - version ";" - version ";" version-list - - version: - "version" version-ident "{" - procedure-list - "}" "=" value - - procedure-list: - procedure ";" - procedure ";" procedure-list - - procedure: - type-ident procedure-ident "(" type-ident ")" "=" value -.DE -For example, here is the time protocol, revisited: -.ie t .DS -.el .DS L -.ft I -/* - * time.x: Get or set the time. Time is represented as number of seconds - * since 0:00, January 1, 1970. - */ -.ft CW -program TIMEPROG { - version TIMEVERS { - unsigned int TIMEGET(void) = 1; - void TIMESET(unsigned) = 2; - } = 1; -} = 44; -.DE -This file compiles into #defines in the output header file: -.ie t .DS -.el .DS L -.ft CW -#define TIMEPROG 44 -#define TIMEVERS 1 -#define TIMEGET 1 -#define TIMESET 2 -.DE -.NH 2 -Declarations -\& -.IX rpcgen declarations \fIrpcgen\fP -.LP -In XDR, there are only four kinds of declarations. -.DS L -.ft CW - declaration: - simple-declaration - fixed-array-declaration - variable-array-declaration - pointer-declaration -.DE -\fB1) Simple declarations\fP are just like simple C declarations. -.DS L -.ft CW - simple-declaration: - type-ident variable-ident -.DE -Example: -.DS L -.ft CW - colortype color; --> colortype color; -.DE -\fB2) Fixed-length Array Declarations\fP are just like C array declarations: -.DS L -.ft CW - fixed-array-declaration: - type-ident variable-ident "[" value "]" -.DE -Example: -.DS L -.ft CW - colortype palette[8]; --> colortype palette[8]; -.DE -\fB3) Variable-Length Array Declarations\fP have no explicit syntax -in C, so XDR invents its own using angle-brackets. -.DS L -.ft CW -variable-array-declaration: - type-ident variable-ident "<" value ">" - type-ident variable-ident "<" ">" -.DE -The maximum size is specified between the angle brackets. The size may -be omitted, indicating that the array may be of any size. -.DS L -.ft CW - int heights<12>; /* \fIat most 12 items\fP */ - int widths<>; /* \fIany number of items\fP */ -.DE -Since variable-length arrays have no explicit syntax in C, these -declarations are actually compiled into \*Qstruct\*Us. For example, the -\*Qheights\*U declaration gets compiled into the following struct: -.DS L -.ft CW - struct { - u_int heights_len; /* \fI# of items in array\fP */ - int *heights_val; /* \fIpointer to array\fP */ - } heights; -.DE -Note that the number of items in the array is stored in the \*Q_len\*U -component and the pointer to the array is stored in the \*Q_val\*U -component. The first part of each of these component's names is the -same as the name of the declared XDR variable. -.LP -\fB4) Pointer Declarations\fP are made in -XDR exactly as they are in C. You can't -really send pointers over the network, but you can use XDR pointers -for sending recursive data types such as lists and trees. The type is -actually called \*Qoptional-data\*U, not \*Qpointer\*U, in XDR language. -.DS L -.ft CW - pointer-declaration: - type-ident "*" variable-ident -.DE -Example: -.DS L -.ft CW - listitem *next; --> listitem *next; -.DE -.NH 2 -\&Special Cases -.IX rpcgen "special cases" \fIrpcgen\fP -.LP -There are a few exceptions to the rules described above. -.LP -.B Booleans: -C has no built-in boolean type. However, the RPC library does a -boolean type called -.I bool_t -that is either -.I TRUE -or -.I FALSE . -Things declared as type -.I bool -in XDR language are compiled into -.I bool_t -in the output header file. -.LP -Example: -.DS L -.ft CW - bool married; --> bool_t married; -.DE -.B Strings: -C has no built-in string type, but instead uses the null-terminated -\*Qchar *\*U convention. In XDR language, strings are declared using the -\*Qstring\*U keyword, and compiled into \*Qchar *\*Us in the output header -file. The maximum size contained in the angle brackets specifies the -maximum number of characters allowed in the strings (not counting the -.I NULL -character). The maximum size may be left off, indicating a string -of arbitrary length. -.LP -Examples: -.DS L -.ft CW - string name<32>; --> char *name; - string longname<>; --> char *longname; -.DE -.B "Opaque Data:" -Opaque data is used in RPC and XDR to describe untyped data, that is, -just sequences of arbitrary bytes. It may be declared either as a -fixed or variable length array. -.DS L -Examples: -.ft CW - opaque diskblock[512]; --> char diskblock[512]; - - opaque filedata<1024>; --> struct { - u_int filedata_len; - char *filedata_val; - } filedata; -.DE -.B Voids: -In a void declaration, the variable is not named. The declaration is -just \*Qvoid\*U and nothing else. Void declarations can only occur in two -places: union definitions and program definitions (as the argument or -result of a remote procedure). diff --git a/c/src/librpc/src/rpc/PSD.doc/xdr.nts.ms b/c/src/librpc/src/rpc/PSD.doc/xdr.nts.ms deleted file mode 100644 index 6c2d482dea..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/xdr.nts.ms +++ /dev/null @@ -1,1966 +0,0 @@ -.\" -.\" Must use -- eqn -- with this one -.\" -.\" @(#)xdr.nts.ms 2.2 88/08/05 4.0 RPCSRC -.EQ -delim $$ -.EN -.de BT -.if \\n%=1 .tl ''- % -'' -.. -.ND -.\" prevent excess underlining in nroff -.if n .fp 2 R -.OH 'External Data Representation: Sun Technical Notes''Page %' -.EH 'Page %''External Data Representation: Sun Technical Notes' -.if \\n%=1 .bp -.SH -\&External Data Representation: Sun Technical Notes -.IX XDR "Sun technical notes" -.LP -This chapter contains technical notes on Sun's implementation of the -External Data Representation (XDR) standard, a set of library routines -that allow a C programmer to describe arbitrary data structures in a -machinex-independent fashion. -For a formal specification of the XDR -standard, see the -.I "External Data Representation Standard: Protocol Specification". -XDR is the backbone of Sun's Remote Procedure Call package, in the -sense that data for remote procedure calls is transmitted using the -standard. XDR library routines should be used to transmit data -that is accessed (read or written) by more than one type of machine.\** -.FS -.IX XDR "system routines" -For a compete specification of the system External Data Representation -routines, see the -.I xdr(3N) -manual page. -.FE -.LP -This chapter contains a short tutorial overview of the XDR library -routines, a guide to accessing currently available XDR streams, and -information on defining new streams and data types. XDR was designed -to work across different languages, operating systems, and machine -architectures. Most users (particularly RPC users) will only need -the information in the -.I "Number Filters", -.I "Floating Point Filters", -and -.I "Enumeration Filters" -sections. -Programmers wishing to implement RPC and XDR on new machines -will be interested in the rest of the chapter, as well as the -.I "External Data Representaiton Standard: Protocol Specification", -which will be their primary reference. -.SH -Note: -.I -.I rpcgen -can be used to write XDR routines even in cases where no RPC calls are -being made. -.LP -On Sun systems, -C programs that want to use XDR routines -must include the file -.I , -which contains all the necessary interfaces to the XDR system. -Since the C library -.I libc.a -contains all the XDR routines, -compile as normal. -.DS -example% \fBcc\0\fIprogram\fP.c\fI -.DE -.ne 3i -.NH 0 -\&Justification -.IX XDR justification -.LP -Consider the following two programs, -.I writer : -.ie t .DS -.el .DS L -.ft CW -#include -.sp.5 -main() /* \fIwriter.c\fP */ -{ - long i; -.sp.5 - for (i = 0; i < 8; i++) { - if (fwrite((char *)&i, sizeof(i), 1, stdout) != 1) { - fprintf(stderr, "failed!\en"); - exit(1); - } - } - exit(0); -} -.DE -and -.I reader : -.ie t .DS -.el .DS L -.ft CW -#include -.sp.5 -main() /* \fIreader.c\fP */ -{ - long i, j; -.sp.5 - for (j = 0; j < 8; j++) { - if (fread((char *)&i, sizeof (i), 1, stdin) != 1) { - fprintf(stderr, "failed!\en"); - exit(1); - } - printf("%ld ", i); - } - printf("\en"); - exit(0); -} -.DE -The two programs appear to be portable, because (a) they pass -.I lint -checking, and (b) they exhibit the same behavior when executed -on two different hardware architectures, a Sun and a VAX. -.LP -Piping the output of the -.I writer -program to the -.I reader -program gives identical results on a Sun or a VAX. -.DS -.ft CW -sun% \fBwriter | reader\fP -0 1 2 3 4 5 6 7 -sun% - - -vax% \fBwriter | reader\fP -0 1 2 3 4 5 6 7 -vax% -.DE -With the advent of local area networks and 4.2BSD came the concept -of \*Qnetwork pipes\*U \(em a process produces data on one machine, -and a second process consumes data on another machine. -A network pipe can be constructed with -.I writer -and -.I reader . -Here are the results if the first produces data on a Sun, -and the second consumes data on a VAX. -.DS -.ft CW -sun% \fBwriter | rsh vax reader\fP -0 16777216 33554432 50331648 67108864 83886080 100663296 -117440512 -sun% -.DE -Identical results can be obtained by executing -.I writer -on the VAX and -.I reader -on the Sun. These results occur because the byte ordering -of long integers differs between the VAX and the Sun, -even though word size is the same. -Note that $16777216$ is $2 sup 24$ \(em -when four bytes are reversed, the 1 winds up in the 24th bit. -.LP -Whenever data is shared by two or more machine types, there is -a need for portable data. Programs can be made data-portable by -replacing the -.I read() -and -.I write() -calls with calls to an XDR library routine -.I xdr_long() , -a filter that knows the standard representation -of a long integer in its external form. -Here are the revised versions of -.I writer : -.ie t .DS -.el .DS L -.ft CW -#include -#include /* \fIxdr is a sub-library of rpc\fP */ -.sp.5 -main() /* \fIwriter.c\fP */ -{ - XDR xdrs; - long i; -.sp.5 - xdrstdio_create(&xdrs, stdout, XDR_ENCODE); - for (i = 0; i < 8; i++) { - if (!xdr_long(&xdrs, &i)) { - fprintf(stderr, "failed!\en"); - exit(1); - } - } - exit(0); -} -.DE -and -.I reader : -.ie t .DS -.el .DS L -.ft CW -#include -#include /* \fIxdr is a sub-library of rpc\fP */ -.sp.5 -main() /* \fIreader.c\fP */ -{ - XDR xdrs; - long i, j; -.sp.5 - xdrstdio_create(&xdrs, stdin, XDR_DECODE); - for (j = 0; j < 8; j++) { - if (!xdr_long(&xdrs, &i)) { - fprintf(stderr, "failed!\en"); - exit(1); - } - printf("%ld ", i); - } - printf("\en"); - exit(0); -} -.DE -The new programs were executed on a Sun, -on a VAX, and from a Sun to a VAX; -the results are shown below. -.DS -.ft CW -sun% \fBwriter | reader\fP -0 1 2 3 4 5 6 7 -sun% - -vax% \fBwriter | reader\fP -0 1 2 3 4 5 6 7 -vax% - -sun% \fBwriter | rsh vax reader\fP -0 1 2 3 4 5 6 7 -sun% -.DE -.SH -Note: -.I -.IX XDR "portable data" -Integers are just the tip of the portable-data iceberg. Arbitrary -data structures present portability problems, particularly with -respect to alignment and pointers. Alignment on word boundaries -may cause the size of a structure to vary from machine to machine. -And pointers, which are very convenient to use, have no meaning -outside the machine where they are defined. -.LP -.NH 1 -\&A Canonical Standard -.IX XDR "canonical standard" -.LP -XDR's approach to standardizing data representations is -.I canonical . -That is, XDR defines a single byte order (Big Endian), a single -floating-point representation (IEEE), and so on. Any program running on -any machine can use XDR to create portable data by translating its -local representation to the XDR standard representations; similarly, any -program running on any machine can read portable data by translating the -XDR standard representaions to its local equivalents. The single standard -completely decouples programs that create or send portable data from those -that use or receive portable data. The advent of a new machine or a new -language has no effect upon the community of existing portable data creators -and users. A new machine joins this community by being \*Qtaught\*U how to -convert the standard representations and its local representations; the -local representations of other machines are irrelevant. Conversely, to -existing programs running on other machines, the local representations of -the new machine are also irrelevant; such programs can immediately read -portable data produced by the new machine because such data conforms to the -canonical standards that they already understand. -.LP -There are strong precedents for XDR's canonical approach. For example, -TCP/IP, UDP/IP, XNS, Ethernet, and, indeed, all protocols below layer five -of the ISO model, are canonical protocols. The advantage of any canonical -approach is simplicity; in the case of XDR, a single set of conversion -routines is written once and is never touched again. The canonical approach -has a disadvantage, but it is unimportant in real-world data transfer -applications. Suppose two Little-Endian machines are transferring integers -according to the XDR standard. The sending machine converts the integers -from Little-Endian byte order to XDR (Big-Endian) byte order; the receiving -machine performs the reverse conversion. Because both machines observe the -same byte order, their conversions are unnecessary. The point, however, is -not necessity, but cost as compared to the alternative. -.LP -The time spent converting to and from a canonical representation is -insignificant, especially in networking applications. Most of the time -required to prepare a data structure for transfer is not spent in conversion -but in traversing the elements of the data structure. To transmit a tree, -for example, each leaf must be visited and each element in a leaf record must -be copied to a buffer and aligned there; storage for the leaf may have to be -deallocated as well. Similarly, to receive a tree, storage must be -allocated for each leaf, data must be moved from the buffer to the leaf and -properly aligned, and pointers must be constructed to link the leaves -together. Every machine pays the cost of traversing and copying data -structures whether or not conversion is required. In networking -applications, communications overhead\(emthe time required to move the data -down through the sender's protocol layers, across the network and up through -the receiver's protocol layers\(emdwarfs conversion overhead. -.NH 1 -\&The XDR Library -.IX "XDR" "library" -.LP -The XDR library not only solves data portability problems, it also -allows you to write and read arbitrary C constructs in a consistent, -specified, well-documented manner. Thus, it can make sense to use the -library even when the data is not shared among machines on a network. -.LP -The XDR library has filter routines for -strings (null-terminated arrays of bytes), -structures, unions, and arrays, to name a few. -Using more primitive routines, -you can write your own specific XDR routines -to describe arbitrary data structures, -including elements of arrays, arms of unions, -or objects pointed at from other structures. -The structures themselves may contain arrays of arbitrary elements, -or pointers to other structures. -.LP -Let's examine the two programs more closely. -There is a family of XDR stream creation routines -in which each member treats the stream of bits differently. -In our example, data is manipulated using standard I/O routines, -so we use -.I xdrstdio_create (). -.IX xdrstdio_create() "" "\fIxdrstdio_create()\fP" -The parameters to XDR stream creation routines -vary according to their function. -In our example, -.I xdrstdio_create() -takes a pointer to an XDR structure that it initializes, -a pointer to a -.I FILE -that the input or output is performed on, and the operation. -The operation may be -.I XDR_ENCODE -for serializing in the -.I writer -program, or -.I XDR_DECODE -for deserializing in the -.I reader -program. -.LP -Note: RPC users never need to create XDR streams; -the RPC system itself creates these streams, -which are then passed to the users. -.LP -The -.I xdr_long() -.IX xdr_long() "" "\fIxdr_long()\fP" -primitive is characteristic of most XDR library -primitives and all client XDR routines. -First, the routine returns -.I FALSE -(0) if it fails, and -.I TRUE -(1) if it succeeds. -Second, for each data type, -.I xxx , -there is an associated XDR routine of the form: -.DS -.ft CW -xdr_xxx(xdrs, xp) - XDR *xdrs; - xxx *xp; -{ -} -.DE -In our case, -.I xxx -is long, and the corresponding XDR routine is -a primitive, -.I xdr_long() . -The client could also define an arbitrary structure -.I xxx -in which case the client would also supply the routine -.I xdr_xxx (), -describing each field by calling XDR routines -of the appropriate type. -In all cases the first parameter, -.I xdrs -can be treated as an opaque handle, -and passed to the primitive routines. -.LP -XDR routines are direction independent; -that is, the same routines are called to serialize or deserialize data. -This feature is critical to software engineering of portable data. -The idea is to call the same routine for either operation \(em -this almost guarantees that serialized data can also be deserialized. -One routine is used by both producer and consumer of networked data. -This is implemented by always passing the address -of an object rather than the object itself \(em -only in the case of deserialization is the object modified. -This feature is not shown in our trivial example, -but its value becomes obvious when nontrivial data structures -are passed among machines. -If needed, the user can obtain the -direction of the XDR operation. -See the -.I "XDR Operation Directions" -section below for details. -.LP -Let's look at a slightly more complicated example. -Assume that a person's gross assets and liabilities -are to be exchanged among processes. -Also assume that these values are important enough -to warrant their own data type: -.ie t .DS -.el .DS L -.ft CW -struct gnumbers { - long g_assets; - long g_liabilities; -}; -.DE -The corresponding XDR routine describing this structure would be: -.ie t .DS -.el .DS L -.ft CW -bool_t /* \fITRUE is success, FALSE is failure\fP */ -xdr_gnumbers(xdrs, gp) - XDR *xdrs; - struct gnumbers *gp; -{ - if (xdr_long(xdrs, &gp->g_assets) && - xdr_long(xdrs, &gp->g_liabilities)) - return(TRUE); - return(FALSE); -} -.DE -Note that the parameter -.I xdrs -is never inspected or modified; -it is only passed on to the subcomponent routines. -It is imperative to inspect the return value of each XDR routine call, -and to give up immediately and return -.I FALSE -if the subroutine fails. -.LP -This example also shows that the type -.I bool_t -is declared as an integer whose only values are -.I TRUE -(1) and -.I FALSE -(0). This document uses the following definitions: -.ie t .DS -.el .DS L -.ft CW -#define bool_t int -#define TRUE 1 -#define FALSE 0 -.DE -.LP -Keeping these conventions in mind, -.I xdr_gnumbers() -can be rewritten as follows: -.ie t .DS -.el .DS L -.ft CW -xdr_gnumbers(xdrs, gp) - XDR *xdrs; - struct gnumbers *gp; -{ - return(xdr_long(xdrs, &gp->g_assets) && - xdr_long(xdrs, &gp->g_liabilities)); -} -.DE -This document uses both coding styles. -.NH 1 -\&XDR Library Primitives -.IX "library primitives for XDR" -.IX XDR "library primitives" -.LP -This section gives a synopsis of each XDR primitive. -It starts with basic data types and moves on to constructed data types. -Finally, XDR utilities are discussed. -The interface to these primitives -and utilities is defined in the include file -.I , -automatically included by -.I . -.NH 2 -\&Number Filters -.IX "XDR library" "number filters" -.LP -The XDR library provides primitives to translate between numbers -and their corresponding external representations. -Primitives cover the set of numbers in: -.DS -.ft CW -[signed, unsigned] * [short, int, long] -.DE -.ne 2i -Specifically, the eight primitives are: -.DS -.ft CW -bool_t xdr_char(xdrs, cp) - XDR *xdrs; - char *cp; -.sp.5 -bool_t xdr_u_char(xdrs, ucp) - XDR *xdrs; - unsigned char *ucp; -.sp.5 -bool_t xdr_int(xdrs, ip) - XDR *xdrs; - int *ip; -.sp.5 -bool_t xdr_u_int(xdrs, up) - XDR *xdrs; - unsigned *up; -.sp.5 -bool_t xdr_long(xdrs, lip) - XDR *xdrs; - long *lip; -.sp.5 -bool_t xdr_u_long(xdrs, lup) - XDR *xdrs; - u_long *lup; -.sp.5 -bool_t xdr_short(xdrs, sip) - XDR *xdrs; - short *sip; -.sp.5 -bool_t xdr_u_short(xdrs, sup) - XDR *xdrs; - u_short *sup; -.DE -The first parameter, -.I xdrs , -is an XDR stream handle. -The second parameter is the address of the number -that provides data to the stream or receives data from it. -All routines return -.I TRUE -if they complete successfully, and -.I FALSE -otherwise. -.NH 2 -\&Floating Point Filters -.IX "XDR library" "floating point filters" -.LP -The XDR library also provides primitive routines -for C's floating point types: -.DS -.ft CW -bool_t xdr_float(xdrs, fp) - XDR *xdrs; - float *fp; -.sp.5 -bool_t xdr_double(xdrs, dp) - XDR *xdrs; - double *dp; -.DE -The first parameter, -.I xdrs -is an XDR stream handle. -The second parameter is the address -of the floating point number that provides data to the stream -or receives data from it. -Both routines return -.I TRUE -if they complete successfully, and -.I FALSE -otherwise. -.LP -Note: Since the numbers are represented in IEEE floating point, -routines may fail when decoding a valid IEEE representation -into a machine-specific representation, or vice-versa. -.NH 2 -\&Enumeration Filters -.IX "XDR library" "enumeration filters" -.LP -The XDR library provides a primitive for generic enumerations. -The primitive assumes that a C -.I enum -has the same representation inside the machine as a C integer. -The boolean type is an important instance of the -.I enum . -The external representation of a boolean is always -.I TRUE -(1) or -.I FALSE -(0). -.DS -.ft CW -#define bool_t int -#define FALSE 0 -#define TRUE 1 -.sp.5 -#define enum_t int -.sp.5 -bool_t xdr_enum(xdrs, ep) - XDR *xdrs; - enum_t *ep; -.sp.5 -bool_t xdr_bool(xdrs, bp) - XDR *xdrs; - bool_t *bp; -.DE -The second parameters -.I ep -and -.I bp -are addresses of the associated type that provides data to, or -receives data from, the stream -.I xdrs . -.NH 2 -\&No Data -.IX "XDR library" "no data" -.LP -Occasionally, an XDR routine must be supplied to the RPC system, -even when no data is passed or required. -The library provides such a routine: -.DS -.ft CW -bool_t xdr_void(); /* \fIalways returns TRUE\fP */ -.DE -.NH 2 -\&Constructed Data Type Filters -.IX "XDR library" "constructed data type filters" -.LP -Constructed or compound data type primitives -require more parameters and perform more complicated functions -then the primitives discussed above. -This section includes primitives for -strings, arrays, unions, and pointers to structures. -.LP -Constructed data type primitives may use memory management. -In many cases, memory is allocated when deserializing data with -.I XDR_DECODE -Therefore, the XDR package must provide means to deallocate memory. -This is done by an XDR operation, -.I XDR_FREE -To review, the three XDR directional operations are -.I XDR_ENCODE , -.I XDR_DECODE -and -.I XDR_FREE . -.NH 3 -\&Strings -.IX "XDR library" "strings" -.LP -In C, a string is defined as a sequence of bytes -terminated by a null byte, -which is not considered when calculating string length. -However, when a string is passed or manipulated, -a pointer to it is employed. -Therefore, the XDR library defines a string to be a -.I "char *" -and not a sequence of characters. -The external representation of a string is drastically different -from its internal representation. -Externally, strings are represented as -sequences of ASCII characters, -while internally, they are represented with character pointers. -Conversion between the two representations -is accomplished with the routine -.I xdr_string (): -.IX xdr_string() "" \fIxdr_string()\fP -.DS -.ft CW -bool_t xdr_string(xdrs, sp, maxlength) - XDR *xdrs; - char **sp; - u_int maxlength; -.DE -The first parameter -.I xdrs -is the XDR stream handle. -The second parameter -.I sp -is a pointer to a string (type -.I "char **" . -The third parameter -.I maxlength -specifies the maximum number of bytes allowed during encoding or decoding. -its value is usually specified by a protocol. For example, a protocol -specification may say that a file name may be no longer than 255 characters. -.LP -The routine returns -.I FALSE -if the number of characters exceeds -.I maxlength , -and -.I TRUE -if it doesn't. -.SH -Keep -.I maxlength -small. If it is too big you can blow the heap, since -.I xdr_string() -will call -.I malloc() -for space. -.LP -The behavior of -.I xdr_string() -.IX xdr_string() "" \fIxdr_string()\fP -is similar to the behavior of other routines -discussed in this section. The direction -.I XDR_ENCODE -is easiest to understand. The parameter -.I sp -points to a string of a certain length; -if the string does not exceed -.I maxlength , -the bytes are serialized. -.LP -The effect of deserializing a string is subtle. -First the length of the incoming string is determined; -it must not exceed -.I maxlength . -Next -.I sp -is dereferenced; if the the value is -.I NULL , -then a string of the appropriate length is allocated and -.I *sp -is set to this string. -If the original value of -.I *sp -is non-null, then the XDR package assumes -that a target area has been allocated, -which can hold strings no longer than -.I maxlength . -In either case, the string is decoded into the target area. -The routine then appends a null character to the string. -.LP -In the -.I XDR_FREE -operation, the string is obtained by dereferencing -.I sp . -If the string is not -.I NULL , -it is freed and -.I *sp -is set to -.I NULL . -In this operation, -.I xdr_string() -ignores the -.I maxlength -parameter. -.NH 3 -\&Byte Arrays -.IX "XDR library" "byte arrays" -.LP -Often variable-length arrays of bytes are preferable to strings. -Byte arrays differ from strings in the following three ways: -1) the length of the array (the byte count) is explicitly -located in an unsigned integer, -2) the byte sequence is not terminated by a null character, and -3) the external representation of the bytes is the same as their -internal representation. -The primitive -.I xdr_bytes() -.IX xdr_bytes() "" \fIxdr_bytes()\fP -converts between the internal and external -representations of byte arrays: -.DS -.ft CW -bool_t xdr_bytes(xdrs, bpp, lp, maxlength) - XDR *xdrs; - char **bpp; - u_int *lp; - u_int maxlength; -.DE -The usage of the first, second and fourth parameters -are identical to the first, second and third parameters of -.I xdr_string (), -respectively. -The length of the byte area is obtained by dereferencing -.I lp -when serializing; -.I *lp -is set to the byte length when deserializing. -.NH 3 -\&Arrays -.IX "XDR library" "arrays" -.LP -The XDR library package provides a primitive -for handling arrays of arbitrary elements. -The -.I xdr_bytes() -routine treats a subset of generic arrays, -in which the size of array elements is known to be 1, -and the external description of each element is built-in. -The generic array primitive, -.I xdr_array() , -.IX xdr_array() "" \fIxdr_array()\fP -requires parameters identical to those of -.I xdr_bytes() -plus two more: -the size of array elements, -and an XDR routine to handle each of the elements. -This routine is called to encode or decode -each element of the array. -.DS -.ft CW -bool_t -xdr_array(xdrs, ap, lp, maxlength, elementsiz, xdr_element) - XDR *xdrs; - char **ap; - u_int *lp; - u_int maxlength; - u_int elementsiz; - bool_t (*xdr_element)(); -.DE -The parameter -.I ap -is the address of the pointer to the array. -If -.I *ap -is -.I NULL -when the array is being deserialized, -XDR allocates an array of the appropriate size and sets -.I *ap -to that array. -The element count of the array is obtained from -.I *lp -when the array is serialized; -.I *lp -is set to the array length when the array is deserialized. -The parameter -.I maxlength -is the maximum number of elements that the array is allowed to have; -.I elementsiz -is the byte size of each element of the array -(the C function -.I sizeof() -can be used to obtain this value). -The -.I xdr_element() -.IX xdr_element() "" \fIxdr_element()\fP -routine is called to serialize, deserialize, or free -each element of the array. -.br -.LP -Before defining more constructed data types, it is appropriate to -present three examples. -.LP -.I "Example A:" -.br -A user on a networked machine can be identified by -(a) the machine name, such as -.I krypton : -see the -.I gethostname -man page; (b) the user's UID: see the -.I geteuid -man page; and (c) the group numbers to which the user belongs: -see the -.I getgroups -man page. A structure with this information and its associated -XDR routine could be coded like this: -.ie t .DS -.el .DS L -.ft CW -struct netuser { - char *nu_machinename; - int nu_uid; - u_int nu_glen; - int *nu_gids; -}; -#define NLEN 255 /* \fImachine names < 256 chars\fP */ -#define NGRPS 20 /* \fIuser can't be in > 20 groups\fP */ -.sp.5 -bool_t -xdr_netuser(xdrs, nup) - XDR *xdrs; - struct netuser *nup; -{ - return(xdr_string(xdrs, &nup->nu_machinename, NLEN) && - xdr_int(xdrs, &nup->nu_uid) && - xdr_array(xdrs, &nup->nu_gids, &nup->nu_glen, - NGRPS, sizeof (int), xdr_int)); -} -.DE -.LP -.I "Example B:" -.br -A party of network users could be implemented -as an array of -.I netuser -structure. -The declaration and its associated XDR routines -are as follows: -.ie t .DS -.el .DS L -.ft CW -struct party { - u_int p_len; - struct netuser *p_nusers; -}; -#define PLEN 500 /* \fImax number of users in a party\fP */ -.sp.5 -bool_t -xdr_party(xdrs, pp) - XDR *xdrs; - struct party *pp; -{ - return(xdr_array(xdrs, &pp->p_nusers, &pp->p_len, PLEN, - sizeof (struct netuser), xdr_netuser)); -} -.DE -.LP -.I "Example C:" -.br -The well-known parameters to -.I main , -.I argc -and -.I argv -can be combined into a structure. -An array of these structures can make up a history of commands. -The declarations and XDR routines might look like: -.ie t .DS -.el .DS L -.ft CW -struct cmd { - u_int c_argc; - char **c_argv; -}; -#define ALEN 1000 /* \fIargs cannot be > 1000 chars\fP */ -#define NARGC 100 /* \fIcommands cannot have > 100 args\fP */ - -struct history { - u_int h_len; - struct cmd *h_cmds; -}; -#define NCMDS 75 /* \fIhistory is no more than 75 commands\fP */ - -bool_t -xdr_wrap_string(xdrs, sp) - XDR *xdrs; - char **sp; -{ - return(xdr_string(xdrs, sp, ALEN)); -} -.DE -.ie t .DS -.el .DS L -.ft CW -bool_t -xdr_cmd(xdrs, cp) - XDR *xdrs; - struct cmd *cp; -{ - return(xdr_array(xdrs, &cp->c_argv, &cp->c_argc, NARGC, - sizeof (char *), xdr_wrap_string)); -} -.DE -.ie t .DS -.el .DS L -.ft CW -bool_t -xdr_history(xdrs, hp) - XDR *xdrs; - struct history *hp; -{ - return(xdr_array(xdrs, &hp->h_cmds, &hp->h_len, NCMDS, - sizeof (struct cmd), xdr_cmd)); -} -.DE -The most confusing part of this example is that the routine -.I xdr_wrap_string() -is needed to package the -.I xdr_string() -routine, because the implementation of -.I xdr_array() -only passes two parameters to the array element description routine; -.I xdr_wrap_string() -supplies the third parameter to -.I xdr_string (). -.LP -By now the recursive nature of the XDR library should be obvious. -Let's continue with more constructed data types. -.NH 3 -\&Opaque Data -.IX "XDR library" "opaque data" -.LP -In some protocols, handles are passed from a server to client. -The client passes the handle back to the server at some later time. -Handles are never inspected by clients; -they are obtained and submitted. -That is to say, handles are opaque. -The -.I xdr_opaque() -.IX xdr_opaque() "" \fIxdr_opaque()\fP -primitive is used for describing fixed sized, opaque bytes. -.DS -.ft CW -bool_t xdr_opaque(xdrs, p, len) - XDR *xdrs; - char *p; - u_int len; -.DE -The parameter -.I p -is the location of the bytes; -.I len -is the number of bytes in the opaque object. -By definition, the actual data -contained in the opaque object are not machine portable. -.NH 3 -\&Fixed Sized Arrays -.IX "XDR library" "fixed sized arrays" -.LP -The XDR library provides a primitive, -.I xdr_vector (), -for fixed-length arrays. -.ie t .DS -.el .DS L -.ft CW -#define NLEN 255 /* \fImachine names must be < 256 chars\fP */ -#define NGRPS 20 /* \fIuser belongs to exactly 20 groups\fP */ -.sp.5 -struct netuser { - char *nu_machinename; - int nu_uid; - int nu_gids[NGRPS]; -}; -.sp.5 -bool_t -xdr_netuser(xdrs, nup) - XDR *xdrs; - struct netuser *nup; -{ - int i; -.sp.5 - if (!xdr_string(xdrs, &nup->nu_machinename, NLEN)) - return(FALSE); - if (!xdr_int(xdrs, &nup->nu_uid)) - return(FALSE); - if (!xdr_vector(xdrs, nup->nu_gids, NGRPS, sizeof(int), - xdr_int)) { - return(FALSE); - } - return(TRUE); -} -.DE -.NH 3 -\&Discriminated Unions -.IX "XDR library" "discriminated unions" -.LP -The XDR library supports discriminated unions. -A discriminated union is a C union and an -.I enum_t -value that selects an \*Qarm\*U of the union. -.DS -.ft CW -struct xdr_discrim { - enum_t value; - bool_t (*proc)(); -}; -.sp.5 -bool_t xdr_union(xdrs, dscmp, unp, arms, defaultarm) - XDR *xdrs; - enum_t *dscmp; - char *unp; - struct xdr_discrim *arms; - bool_t (*defaultarm)(); /* \fImay equal NULL\fP */ -.DE -First the routine translates the discriminant of the union located at -.I *dscmp . -The discriminant is always an -.I enum_t . -Next the union located at -.I *unp -is translated. -The parameter -.I arms -is a pointer to an array of -.I xdr_discrim -structures. -Each structure contains an ordered pair of -.I [value,proc] . -If the union's discriminant is equal to the associated -.I value , -then the -.I proc -is called to translate the union. -The end of the -.I xdr_discrim -structure array is denoted by a routine of value -.I NULL -(0). If the discriminant is not found in the -.I arms -array, then the -.I defaultarm -procedure is called if it is non-null; -otherwise the routine returns -.I FALSE . -.LP -.I "Example D:" -Suppose the type of a union may be integer, -character pointer (a string), or a -.I gnumbers -structure. -Also, assume the union and its current type -are declared in a structure. -The declaration is: -.ie t .DS -.el .DS L -.ft CW -enum utype { INTEGER=1, STRING=2, GNUMBERS=3 }; -.sp.5 -struct u_tag { - enum utype utype; /* \fIthe union's discriminant\fP */ - union { - int ival; - char *pval; - struct gnumbers gn; - } uval; -}; -.DE -The following constructs and XDR procedure (de)serialize -the discriminated union: -.ie t .DS -.el .DS L -.ft CW -struct xdr_discrim u_tag_arms[4] = { - { INTEGER, xdr_int }, - { GNUMBERS, xdr_gnumbers } - { STRING, xdr_wrap_string }, - { __dontcare__, NULL } - /* \fIalways terminate arms with a NULL xdr_proc\fP */ -} -.sp.5 -bool_t -xdr_u_tag(xdrs, utp) - XDR *xdrs; - struct u_tag *utp; -{ - return(xdr_union(xdrs, &utp->utype, &utp->uval, - u_tag_arms, NULL)); -} -.DE -The routine -.I xdr_gnumbers() -was presented above in -.I "The XDR Library" -section. -.I xdr_wrap_string() -was presented in example C. -The default -.I arm -parameter to -.I xdr_union() -(the last parameter) is -.I NULL -in this example. Therefore the value of the union's discriminant -may legally take on only values listed in the -.I u_tag_arms -array. This example also demonstrates that -the elements of the arm's array do not need to be sorted. -.LP -It is worth pointing out that the values of the discriminant -may be sparse, though in this example they are not. -It is always good -practice to assign explicitly integer values to each element of the -discriminant's type. -This practice both documents the external -representation of the discriminant and guarantees that different -C compilers emit identical discriminant values. -.LP -Exercise: Implement -.I xdr_union() -using the other primitives in this section. -.NH 3 -\&Pointers -.IX "XDR library" "pointers" -.LP -In C it is often convenient to put pointers -to another structure within a structure. -The -.I xdr_reference() -.IX xdr_reference() "" \fIxdr_reference()\fP -primitive makes it easy to serialize, deserialize, and free -these referenced structures. -.DS -.ft CW -bool_t xdr_reference(xdrs, pp, size, proc) - XDR *xdrs; - char **pp; - u_int ssize; - bool_t (*proc)(); -.DE -.LP -Parameter -.I pp -is the address of -the pointer to the structure; -parameter -.I ssize -is the size in bytes of the structure (use the C function -.I sizeof() -to obtain this value); and -.I proc -is the XDR routine that describes the structure. -When decoding data, storage is allocated if -.I *pp -is -.I NULL . -.LP -There is no need for a primitive -.I xdr_struct() -to describe structures within structures, -because pointers are always sufficient. -.LP -Exercise: Implement -.I xdr_reference() -using -.I xdr_array (). -Warning: -.I xdr_reference() -and -.I xdr_array() -are NOT interchangeable external representations of data. -.LP -.I "Example E:" -Suppose there is a structure containing a person's name -and a pointer to a -.I gnumbers -structure containing the person's gross assets and liabilities. -The construct is: -.DS -.ft CW -struct pgn { - char *name; - struct gnumbers *gnp; -}; -.DE -The corresponding XDR routine for this structure is: -.DS -.ft CW -bool_t -xdr_pgn(xdrs, pp) - XDR *xdrs; - struct pgn *pp; -{ - if (xdr_string(xdrs, &pp->name, NLEN) && - xdr_reference(xdrs, &pp->gnp, - sizeof(struct gnumbers), xdr_gnumbers)) - return(TRUE); - return(FALSE); -} -.DE -.IX "pointer semantics and XDR" -.I "Pointer Semantics and XDR" -.LP -In many applications, C programmers attach double meaning to -the values of a pointer. Typically the value -.I NULL -(or zero) means data is not needed, -yet some application-specific interpretation applies. -In essence, the C programmer is encoding -a discriminated union efficiently -by overloading the interpretation of the value of a pointer. -For instance, in example E a -.I NULL -pointer value for -.I gnp -could indicate that -the person's assets and liabilities are unknown. -That is, the pointer value encodes two things: -whether or not the data is known; -and if it is known, where it is located in memory. -Linked lists are an extreme example of the use -of application-specific pointer interpretation. -.LP -The primitive -.I xdr_reference() -.IX xdr_reference() "" \fIxdr_reference()\fP -cannot and does not attach any special -meaning to a null-value pointer during serialization. -That is, passing an address of a pointer whose value is -.I NULL -to -.I xdr_reference() -when serialing data will most likely cause a memory fault and, on the UNIX -system, a core dump. -.LP -.I xdr_pointer() -correctly handles -.I NULL -pointers. For more information about its use, see -the -.I "Linked Lists" -topics below. -.LP -.I Exercise: -After reading the section on -.I "Linked Lists" , -return here and extend example E so that -it can correctly deal with -.I NULL -pointer values. -.LP -.I Exercise: -Using the -.I xdr_union (), -.I xdr_reference() -and -.I xdr_void() -primitives, implement a generic pointer handling primitive -that implicitly deals with -.I NULL -pointers. That is, implement -.I xdr_pointer (). -.NH 2 -\&Non-filter Primitives -.IX "XDR" "non-filter primitives" -.LP -XDR streams can be manipulated with -the primitives discussed in this section. -.DS -.ft CW -u_int xdr_getpos(xdrs) - XDR *xdrs; -.sp.5 -bool_t xdr_setpos(xdrs, pos) - XDR *xdrs; - u_int pos; -.sp.5 -xdr_destroy(xdrs) - XDR *xdrs; -.DE -The routine -.I xdr_getpos() -.IX xdr_getpos() "" \fIxdr_getpos()\fP -returns an unsigned integer -that describes the current position in the data stream. -Warning: In some XDR streams, the returned value of -.I xdr_getpos() -is meaningless; -the routine returns a \-1 in this case -(though \-1 should be a legitimate value). -.LP -The routine -.I xdr_setpos() -.IX xdr_setpos() "" \fIxdr_setpos()\fP -sets a stream position to -.I pos . -Warning: In some XDR streams, setting a position is impossible; -in such cases, -.I xdr_setpos() -will return -.I FALSE . -This routine will also fail if the requested position is out-of-bounds. -The definition of bounds varies from stream to stream. -.LP -The -.I xdr_destroy() -.IX xdr_destroy() "" \fIxdr_destroy()\fP -primitive destroys the XDR stream. -Usage of the stream -after calling this routine is undefined. -.NH 2 -\&XDR Operation Directions -.IX XDR "operation directions" -.IX "direction of XDR operations" -.LP -At times you may wish to optimize XDR routines by taking -advantage of the direction of the operation \(em -.I XDR_ENCODE -.I XDR_DECODE -or -.I XDR_FREE -The value -.I xdrs->x_op -always contains the direction of the XDR operation. -Programmers are not encouraged to take advantage of this information. -Therefore, no example is presented here. However, an example in the -.I "Linked Lists" -topic below, demonstrates the usefulness of the -.I xdrs->x_op -field. -.NH 2 -\&XDR Stream Access -.IX "XDR" "stream access" -.LP -An XDR stream is obtained by calling the appropriate creation routine. -These creation routines take arguments that are tailored to the -specific properties of the stream. -.LP -Streams currently exist for (de)serialization of data to or from -standard I/O -.I FILE -streams, TCP/IP connections and UNIX files, and memory. -.NH 3 -\&Standard I/O Streams -.IX "XDR" "standard I/O streams" -.LP -XDR streams can be interfaced to standard I/O using the -.I xdrstdio_create() -.IX xdrstdio_create() "" \fIxdrstdio_create()\fP -routine as follows: -.DS -.ft CW -#include -#include /* \fIxdr streams part of rpc\fP */ -.sp.5 -void -xdrstdio_create(xdrs, fp, x_op) - XDR *xdrs; - FILE *fp; - enum xdr_op x_op; -.DE -The routine -.I xdrstdio_create() -initializes an XDR stream pointed to by -.I xdrs . -The XDR stream interfaces to the standard I/O library. -Parameter -.I fp -is an open file, and -.I x_op -is an XDR direction. -.NH 3 -\&Memory Streams -.IX "XDR" "memory streams" -.LP -Memory streams allow the streaming of data into or out of -a specified area of memory: -.DS -.ft CW -#include -.sp.5 -void -xdrmem_create(xdrs, addr, len, x_op) - XDR *xdrs; - char *addr; - u_int len; - enum xdr_op x_op; -.DE -The routine -.I xdrmem_create() -.IX xdrmem_create() "" \fIxdrmem_create()\fP -initializes an XDR stream in local memory. -The memory is pointed to by parameter -.I addr ; -parameter -.I len -is the length in bytes of the memory. -The parameters -.I xdrs -and -.I x_op -are identical to the corresponding parameters of -.I xdrstdio_create (). -Currently, the UDP/IP implementation of RPC uses -.I xdrmem_create (). -Complete call or result messages are built in memory before calling the -.I sendto() -system routine. -.NH 3 -\&Record (TCP/IP) Streams -.IX "XDR" "record (TCP/IP) streams" -.LP -A record stream is an XDR stream built on top of -a record marking standard that is built on top of the -UNIX file or 4.2 BSD connection interface. -.DS -.ft CW -#include /* \fIxdr streams part of rpc\fP */ -.sp.5 -xdrrec_create(xdrs, - sendsize, recvsize, iohandle, readproc, writeproc) - XDR *xdrs; - u_int sendsize, recvsize; - char *iohandle; - int (*readproc)(), (*writeproc)(); -.DE -The routine -.I xdrrec_create() -provides an XDR stream interface that allows for a bidirectional, -arbitrarily long sequence of records. -The contents of the records are meant to be data in XDR form. -The stream's primary use is for interfacing RPC to TCP connections. -However, it can be used to stream data into or out of normal -UNIX files. -.LP -The parameter -.I xdrs -is similar to the corresponding parameter described above. -The stream does its own data buffering similar to that of standard I/O. -The parameters -.I sendsize -and -.I recvsize -determine the size in bytes of the output and input buffers, respectively; -if their values are zero (0), then predetermined defaults are used. -When a buffer needs to be filled or flushed, the routine -.I readproc() -or -.I writeproc() -is called, respectively. -The usage and behavior of these -routines are similar to the UNIX system calls -.I read() -and -.I write (). -However, -the first parameter to each of these routines is the opaque parameter -.I iohandle . -The other two parameters -.I buf "" -and -.I nbytes ) -and the results -(byte count) are identical to the system routines. -If -.I xxx -is -.I readproc() -or -.I writeproc (), -then it has the following form: -.DS -.ft CW -.ft I -/* - * returns the actual number of bytes transferred. - * -1 is an error - */ -.ft CW -int -xxx(iohandle, buf, len) - char *iohandle; - char *buf; - int nbytes; -.DE -The XDR stream provides means for delimiting records in the byte stream. -The implementation details of delimiting records in a stream are -discussed in the -.I "Advanced Topics" -topic below. -The primitives that are specific to record streams are as follows: -.DS -.ft CW -bool_t -xdrrec_endofrecord(xdrs, flushnow) - XDR *xdrs; - bool_t flushnow; -.sp.5 -bool_t -xdrrec_skiprecord(xdrs) - XDR *xdrs; -.sp.5 -bool_t -xdrrec_eof(xdrs) - XDR *xdrs; -.DE -The routine -.I xdrrec_endofrecord() -.IX xdrrec_endofrecord() "" \fIxdrrec_endofrecord()\fP -causes the current outgoing data to be marked as a record. -If the parameter -.I flushnow -is -.I TRUE , -then the stream's -.I writeproc -will be called; otherwise, -.I writeproc -will be called when the output buffer has been filled. -.LP -The routine -.I xdrrec_skiprecord() -.IX xdrrec_skiprecord() "" \fIxdrrec_skiprecord()\fP -causes an input stream's position to be moved past -the current record boundary and onto the -beginning of the next record in the stream. -.LP -If there is no more data in the stream's input buffer, -then the routine -.I xdrrec_eof() -.IX xdrrec_eof() "" \fIxdrrec_eof()\fP -returns -.I TRUE . -That is not to say that there is no more data -in the underlying file descriptor. -.NH 2 -\&XDR Stream Implementation -.IX "XDR" "stream implementation" -.IX "stream implementation in XDR" -.LP -This section provides the abstract data types needed -to implement new instances of XDR streams. -.NH 3 -\&The XDR Object -.IX "XDR" "object" -.LP -The following structure defines the interface to an XDR stream: -.ie t .DS -.el .DS L -.ft CW -enum xdr_op { XDR_ENCODE=0, XDR_DECODE=1, XDR_FREE=2 }; -.sp.5 -typedef struct { - enum xdr_op x_op; /* \fIoperation; fast added param\fP */ - struct xdr_ops { - bool_t (*x_getlong)(); /* \fIget long from stream\fP */ - bool_t (*x_putlong)(); /* \fIput long to stream\fP */ - bool_t (*x_getbytes)(); /* \fIget bytes from stream\fP */ - bool_t (*x_putbytes)(); /* \fIput bytes to stream\fP */ - u_int (*x_getpostn)(); /* \fIreturn stream offset\fP */ - bool_t (*x_setpostn)(); /* \fIreposition offset\fP */ - caddr_t (*x_inline)(); /* \fIptr to buffered data\fP */ - VOID (*x_destroy)(); /* \fIfree private area\fP */ - } *x_ops; - caddr_t x_public; /* \fIusers' data\fP */ - caddr_t x_private; /* \fIpointer to private data\fP */ - caddr_t x_base; /* \fIprivate for position info\fP */ - int x_handy; /* \fIextra private word\fP */ -} XDR; -.DE -The -.I x_op -field is the current operation being performed on the stream. -This field is important to the XDR primitives, -but should not affect a stream's implementation. -That is, a stream's implementation should not depend -on this value. -The fields -.I x_private , -.I x_base , -and -.I x_handy -are private to the particular -stream's implementation. -The field -.I x_public -is for the XDR client and should never be used by -the XDR stream implementations or the XDR primitives. -.I x_getpostn() , -.I x_setpostn() -and -.I x_destroy() -are macros for accessing operations. The operation -.I x_inline() -takes two parameters: -an XDR *, and an unsigned integer, which is a byte count. -The routine returns a pointer to a piece of -the stream's internal buffer. -The caller can then use the buffer segment for any purpose. -From the stream's point of view, the bytes in the -buffer segment have been consumed or put. -The routine may return -.I NULL -if it cannot return a buffer segment of the requested size. -(The -.I x_inline() -routine is for cycle squeezers. -Use of the resulting buffer is not data-portable. -Users are encouraged not to use this feature.) -.LP -The operations -.I x_getbytes() -and -.I x_putbytes() -blindly get and put sequences of bytes -from or to the underlying stream; -they return -.I TRUE -if they are successful, and -.I FALSE -otherwise. The routines have identical parameters (replace -.I xxx ): -.DS -.ft CW -bool_t -xxxbytes(xdrs, buf, bytecount) - XDR *xdrs; - char *buf; - u_int bytecount; -.DE -The operations -.I x_getlong() -and -.I x_putlong() -receive and put -long numbers from and to the data stream. -It is the responsibility of these routines -to translate the numbers between the machine representation -and the (standard) external representation. -The UNIX primitives -.I htonl() -and -.I ntohl() -can be helpful in accomplishing this. -The higher-level XDR implementation assumes that -signed and unsigned long integers contain the same number of bits, -and that nonnegative integers -have the same bit representations as unsigned integers. -The routines return -.I TRUE -if they succeed, and -.I FALSE -otherwise. They have identical parameters: -.DS -.ft CW -bool_t -xxxlong(xdrs, lp) - XDR *xdrs; - long *lp; -.DE -Implementors of new XDR streams must make an XDR structure -(with new operation routines) available to clients, -using some kind of create routine. -.NH 1 -\&Advanced Topics -.IX XDR "advanced topics" -.LP -This section describes techniques for passing data structures that -are not covered in the preceding sections. Such structures include -linked lists (of arbitrary lengths). Unlike the simpler examples -covered in the earlier sections, the following examples are written -using both the XDR C library routines and the XDR data description -language. -The -.I "External Data Representation Standard: Protocol Specification" -describes this -language in complete detail. -.NH 2 -\&Linked Lists -.IX XDR "linked lists" -.LP -The last example in the -.I Pointers -topic earlier in this chapter -presented a C data structure and its associated XDR -routines for a individual's gross assets and liabilities. -The example is duplicated below: -.ie t .DS -.el .DS L -.ft CW -struct gnumbers { - long g_assets; - long g_liabilities; -}; -.sp.5 -bool_t -xdr_gnumbers(xdrs, gp) - XDR *xdrs; - struct gnumbers *gp; -{ - if (xdr_long(xdrs, &(gp->g_assets))) - return(xdr_long(xdrs, &(gp->g_liabilities))); - return(FALSE); -} -.DE -.LP -Now assume that we wish to implement a linked list of such information. -A data structure could be constructed as follows: -.ie t .DS -.el .DS L -.ft CW -struct gnumbers_node { - struct gnumbers gn_numbers; - struct gnumbers_node *gn_next; -}; -.sp .5 -typedef struct gnumbers_node *gnumbers_list; -.DE -.LP -The head of the linked list can be thought of as the data object; -that is, the head is not merely a convenient shorthand for a -structure. Similarly the -.I gn_next -field is used to indicate whether or not the object has terminated. -Unfortunately, if the object continues, the -.I gn_next -field is also the address of where it continues. The link addresses -carry no useful information when the object is serialized. -.LP -The XDR data description of this linked list is described by the -recursive declaration of -.I gnumbers_list : -.ie t .DS -.el .DS L -.ft CW -struct gnumbers { - int g_assets; - int g_liabilities; -}; -.sp .5 -struct gnumbers_node { - gnumbers gn_numbers; - gnumbers_node *gn_next; -}; -.DE -.LP -In this description, the boolean indicates whether there is more data -following it. If the boolean is -.I FALSE , -then it is the last data field of the structure. If it is -.I TRUE , -then it is followed by a gnumbers structure and (recursively) by a -.I gnumbers_list . -Note that the C declaration has no boolean explicitly declared in it -(though the -.I gn_next -field implicitly carries the information), while the XDR data -description has no pointer explicitly declared in it. -.LP -Hints for writing the XDR routines for a -.I gnumbers_list -follow easily from the XDR description above. Note how the primitive -.I xdr_pointer() -is used to implement the XDR union above. -.ie t .DS -.el .DS L -.ft CW -bool_t -xdr_gnumbers_node(xdrs, gn) - XDR *xdrs; - gnumbers_node *gn; -{ - return(xdr_gnumbers(xdrs, &gn->gn_numbers) && - xdr_gnumbers_list(xdrs, &gp->gn_next)); -} -.sp .5 -bool_t -xdr_gnumbers_list(xdrs, gnp) - XDR *xdrs; - gnumbers_list *gnp; -{ - return(xdr_pointer(xdrs, gnp, - sizeof(struct gnumbers_node), - xdr_gnumbers_node)); -} -.DE -.LP -The unfortunate side effect of XDR'ing a list with these routines -is that the C stack grows linearly with respect to the number of -node in the list. This is due to the recursion. The following -routine collapses the above two mutually recursive into a single, -non-recursive one. -.ie t .DS -.el .DS L -.ft CW -bool_t -xdr_gnumbers_list(xdrs, gnp) - XDR *xdrs; - gnumbers_list *gnp; -{ - bool_t more_data; - gnumbers_list *nextp; -.sp .5 - for (;;) { - more_data = (*gnp != NULL); - if (!xdr_bool(xdrs, &more_data)) { - return(FALSE); - } - if (! more_data) { - break; - } - if (xdrs->x_op == XDR_FREE) { - nextp = &(*gnp)->gn_next; - } - if (!xdr_reference(xdrs, gnp, - sizeof(struct gnumbers_node), xdr_gnumbers)) { - - return(FALSE); - } - gnp = (xdrs->x_op == XDR_FREE) ? - nextp : &(*gnp)->gn_next; - } - *gnp = NULL; - return(TRUE); -} -.DE -.LP -The first task is to find out whether there is more data or not, -so that this boolean information can be serialized. Notice that -this statement is unnecessary in the -.I XDR_DECODE -case, since the value of more_data is not known until we -deserialize it in the next statement. -.LP -The next statement XDR's the more_data field of the XDR union. -Then if there is truly no more data, we set this last pointer to -.I NULL -to indicate the end of the list, and return -.I TRUE -because we are done. Note that setting the pointer to -.I NULL -is only important in the -.I XDR_DECODE -case, since it is already -.I NULL -in the -.I XDR_ENCODE -and -XDR_FREE -cases. -.LP -Next, if the direction is -.I XDR_FREE , -the value of -.I nextp -is set to indicate the location of the next pointer in the list. -We do this now because we need to dereference gnp to find the -location of the next item in the list, and after the next -statement the storage pointed to by -.I gnp -will be freed up and no be longer valid. We can't do this for all -directions though, because in the -.I XDR_DECODE -direction the value of -.I gnp -won't be set until the next statement. -.LP -Next, we XDR the data in the node using the primitive -.I xdr_reference (). -.I xdr_reference() -is like -.I xdr_pointer() -which we used before, but it does not -send over the boolean indicating whether there is more data. -We use it instead of -.I xdr_pointer() -because we have already XDR'd this information ourselves. Notice -that the xdr routine passed is not the same type as an element -in the list. The routine passed is -.I xdr_gnumbers (), -for XDR'ing gnumbers, but each element in the list is actually of -type -.I gnumbers_node . -We don't pass -.I xdr_gnumbers_node() -because it is recursive, and instead use -.I xdr_gnumbers() -which XDR's all of the non-recursive part. Note that this trick -will work only if the -.I gn_numbers -field is the first item in each element, so that their addresses -are identical when passed to -.I xdr_reference (). -.LP -Finally, we update -.I gnp -to point to the next item in the list. If the direction is -.I XDR_FREE , -we set it to the previously saved value, otherwise we can -dereference -.I gnp -to get the proper value. Though harder to understand than the -recursive version, this non-recursive routine is far less likely -to blow the C stack. It will also run more efficiently since -a lot of procedure call overhead has been removed. Most lists -are small though (in the hundreds of items or less) and the -recursive version should be sufficient for them. -.EQ -delim off -.EN diff --git a/c/src/librpc/src/rpc/PSD.doc/xdr.rfc.ms b/c/src/librpc/src/rpc/PSD.doc/xdr.rfc.ms deleted file mode 100644 index d4baff5391..0000000000 --- a/c/src/librpc/src/rpc/PSD.doc/xdr.rfc.ms +++ /dev/null @@ -1,1058 +0,0 @@ -.\" -.\" Must use -- tbl -- with this one -.\" -.\" @(#)xdr.rfc.ms 2.2 88/08/05 4.0 RPCSRC -.de BT -.if \\n%=1 .tl ''- % -'' -.. -.ND -.\" prevent excess underlining in nroff -.if n .fp 2 R -.OH 'External Data Representation Standard''Page %' -.EH 'Page %''External Data Representation Standard' -.IX "External Data Representation" -.if \\n%=1 .bp -.SH -\&External Data Representation Standard: Protocol Specification -.IX XDR RFC -.IX XDR "protocol specification" -.LP -.NH 0 -\&Status of this Standard -.nr OF 1 -.IX XDR "RFC status" -.LP -Note: This chapter specifies a protocol that Sun Microsystems, Inc., and -others are using. It has been designated RFC1014 by the ARPA Network -Information Center. -.NH 1 -Introduction -\& -.LP -XDR is a standard for the description and encoding of data. It is -useful for transferring data between different computer -architectures, and has been used to communicate data between such -diverse machines as the Sun Workstation, VAX, IBM-PC, and Cray. -XDR fits into the ISO presentation layer, and is roughly analogous in -purpose to X.409, ISO Abstract Syntax Notation. The major difference -between these two is that XDR uses implicit typing, while X.409 uses -explicit typing. -.LP -XDR uses a language to describe data formats. The language can only -be used only to describe data; it is not a programming language. -This language allows one to describe intricate data formats in a -concise manner. The alternative of using graphical representations -(itself an informal language) quickly becomes incomprehensible when -faced with complexity. The XDR language itself is similar to the C -language [1], just as Courier [4] is similar to Mesa. Protocols such -as Sun RPC (Remote Procedure Call) and the NFS (Network File System) -use XDR to describe the format of their data. -.LP -The XDR standard makes the following assumption: that bytes (or -octets) are portable, where a byte is defined to be 8 bits of data. -A given hardware device should encode the bytes onto the various -media in such a way that other hardware devices may decode the bytes -without loss of meaning. For example, the Ethernet standard -suggests that bytes be encoded in "little-endian" style [2], or least -significant bit first. -.NH 2 -\&Basic Block Size -.IX XDR "basic block size" -.IX XDR "block size" -.LP -The representation of all items requires a multiple of four bytes (or -32 bits) of data. The bytes are numbered 0 through n-1. The bytes -are read or written to some byte stream such that byte m always -precedes byte m+1. If the n bytes needed to contain the data are not -a multiple of four, then the n bytes are followed by enough (0 to 3) -residual zero bytes, r, to make the total byte count a multiple of 4. -.LP -We include the familiar graphic box notation for illustration and -comparison. In most illustrations, each box (delimited by a plus -sign at the 4 corners and vertical bars and dashes) depicts a byte. -Ellipses (...) between boxes show zero or more additional bytes where -required. -.ie t .DS -.el .DS L -\fIA Block\fP - -\f(CW+--------+--------+...+--------+--------+...+--------+ -| byte 0 | byte 1 |...|byte n-1| 0 |...| 0 | -+--------+--------+...+--------+--------+...+--------+ -|<-----------n bytes---------->|<------r bytes------>| -|<-----------n+r (where (n+r) mod 4 = 0)>----------->|\fP - -.DE -.NH 1 -\&XDR Data Types -.IX XDR "data types" -.IX "XDR data types" -.LP -Each of the sections that follow describes a data type defined in the -XDR standard, shows how it is declared in the language, and includes -a graphic illustration of its encoding. -.LP -For each data type in the language we show a general paradigm -declaration. Note that angle brackets (< and >) denote -variable length sequences of data and square brackets ([ and ]) denote -fixed-length sequences of data. "n", "m" and "r" denote integers. -For the full language specification and more formal definitions of -terms such as "identifier" and "declaration", refer to -.I "The XDR Language Specification" , -below. -.LP -For some data types, more specific examples are included. -A more extensive example of a data description is in -.I "An Example of an XDR Data Description" -below. -.NH 2 -\&Integer -.IX XDR integer -.LP -An XDR signed integer is a 32-bit datum that encodes an integer in -the range [-2147483648,2147483647]. The integer is represented in -two's complement notation. The most and least significant bytes are -0 and 3, respectively. Integers are declared as follows: -.ie t .DS -.el .DS L -\fIInteger\fP - -\f(CW(MSB) (LSB) -+-------+-------+-------+-------+ -|byte 0 |byte 1 |byte 2 |byte 3 | -+-------+-------+-------+-------+ -<------------32 bits------------>\fP -.DE -.NH 2 -\&Unsigned Integer -.IX XDR "unsigned integer" -.IX XDR "integer, unsigned" -.LP -An XDR unsigned integer is a 32-bit datum that encodes a nonnegative -integer in the range [0,4294967295]. It is represented by an -unsigned binary number whose most and least significant bytes are 0 -and 3, respectively. An unsigned integer is declared as follows: -.ie t .DS -.el .DS L -\fIUnsigned Integer\fP - -\f(CW(MSB) (LSB) -+-------+-------+-------+-------+ -|byte 0 |byte 1 |byte 2 |byte 3 | -+-------+-------+-------+-------+ -<------------32 bits------------>\fP -.DE -.NH 2 -\&Enumeration -.IX XDR enumeration -.LP -Enumerations have the same representation as signed integers. -Enumerations are handy for describing subsets of the integers. -Enumerated data is declared as follows: -.ft CW -.DS -enum { name-identifier = constant, ... } identifier; -.DE -For example, the three colors red, yellow, and blue could be -described by an enumerated type: -.DS -.ft CW -enum { RED = 2, YELLOW = 3, BLUE = 5 } colors; -.DE -It is an error to encode as an enum any other integer than those that -have been given assignments in the enum declaration. -.NH 2 -\&Boolean -.IX XDR boolean -.LP -Booleans are important enough and occur frequently enough to warrant -their own explicit type in the standard. Booleans are declared as -follows: -.DS -.ft CW -bool identifier; -.DE -This is equivalent to: -.DS -.ft CW -enum { FALSE = 0, TRUE = 1 } identifier; -.DE -.NH 2 -\&Hyper Integer and Unsigned Hyper Integer -.IX XDR "hyper integer" -.IX XDR "integer, hyper" -.LP -The standard also defines 64-bit (8-byte) numbers called hyper -integer and unsigned hyper integer. Their representations are the -obvious extensions of integer and unsigned integer defined above. -They are represented in two's complement notation. The most and -least significant bytes are 0 and 7, respectively. Their -declarations: -.ie t .DS -.el .DS L -\fIHyper Integer\fP -\fIUnsigned Hyper Integer\fP - -\f(CW(MSB) (LSB) -+-------+-------+-------+-------+-------+-------+-------+-------+ -|byte 0 |byte 1 |byte 2 |byte 3 |byte 4 |byte 5 |byte 6 |byte 7 | -+-------+-------+-------+-------+-------+-------+-------+-------+ -<----------------------------64 bits---------------------------->\fP -.DE -.NH 2 -\&Floating-point -.IX XDR "integer, floating point" -.IX XDR "floating-point integer" -.LP -The standard defines the floating-point data type "float" (32 bits or -4 bytes). The encoding used is the IEEE standard for normalized -single-precision floating-point numbers [3]. The following three -fields describe the single-precision floating-point number: -.RS -.IP \fBS\fP: -The sign of the number. Values 0 and 1 represent positive and -negative, respectively. One bit. -.IP \fBE\fP: -The exponent of the number, base 2. 8 bits are devoted to this -field. The exponent is biased by 127. -.IP \fBF\fP: -The fractional part of the number's mantissa, base 2. 23 bits -are devoted to this field. -.RE -.LP -Therefore, the floating-point number is described by: -.DS -(-1)**S * 2**(E-Bias) * 1.F -.DE -It is declared as follows: -.ie t .DS -.el .DS L -\fISingle-Precision Floating-Point\fP - -\f(CW+-------+-------+-------+-------+ -|byte 0 |byte 1 |byte 2 |byte 3 | -S| E | F | -+-------+-------+-------+-------+ -1|<- 8 ->|<-------23 bits------>| -<------------32 bits------------>\fP -.DE -Just as the most and least significant bytes of a number are 0 and 3, -the most and least significant bits of a single-precision floating- -point number are 0 and 31. The beginning bit (and most significant -bit) offsets of S, E, and F are 0, 1, and 9, respectively. Note that -these numbers refer to the mathematical positions of the bits, and -NOT to their actual physical locations (which vary from medium to -medium). -.LP -The IEEE specifications should be consulted concerning the encoding -for signed zero, signed infinity (overflow), and denormalized numbers -(underflow) [3]. According to IEEE specifications, the "NaN" (not a -number) is system dependent and should not be used externally. -.NH 2 -\&Double-precision Floating-point -.IX XDR "integer, double-precision floating point" -.IX XDR "double-precision floating-point integer" -.LP -The standard defines the encoding for the double-precision floating- -point data type "double" (64 bits or 8 bytes). The encoding used is -the IEEE standard for normalized double-precision floating-point -numbers [3]. The standard encodes the following three fields, which -describe the double-precision floating-point number: -.RS -.IP \fBS\fP: -The sign of the number. Values 0 and 1 represent positive and -negative, respectively. One bit. -.IP \fBE\fP: -The exponent of the number, base 2. 11 bits are devoted to this -field. The exponent is biased by 1023. -.IP \fBF\fP: -The fractional part of the number's mantissa, base 2. 52 bits -are devoted to this field. -.RE -.LP -Therefore, the floating-point number is described by: -.DS -(-1)**S * 2**(E-Bias) * 1.F -.DE -It is declared as follows: -.ie t .DS -.el .DS L -\fIDouble-Precision Floating-Point\fP - -\f(CW+------+------+------+------+------+------+------+------+ -|byte 0|byte 1|byte 2|byte 3|byte 4|byte 5|byte 6|byte 7| -S| E | F | -+------+------+------+------+------+------+------+------+ -1|<--11-->|<-----------------52 bits------------------->| -<-----------------------64 bits------------------------->\fP -.DE -Just as the most and least significant bytes of a number are 0 and 3, -the most and least significant bits of a double-precision floating- -point number are 0 and 63. The beginning bit (and most significant -bit) offsets of S, E , and F are 0, 1, and 12, respectively. Note -that these numbers refer to the mathematical positions of the bits, -and NOT to their actual physical locations (which vary from medium to -medium). -.LP -The IEEE specifications should be consulted concerning the encoding -for signed zero, signed infinity (overflow), and denormalized numbers -(underflow) [3]. According to IEEE specifications, the "NaN" (not a -number) is system dependent and should not be used externally. -.NH 2 -\&Fixed-length Opaque Data -.IX XDR "fixed-length opaque data" -.IX XDR "opaque data, fixed length" -.LP -At times, fixed-length uninterpreted data needs to be passed among -machines. This data is called "opaque" and is declared as follows: -.DS -.ft CW -opaque identifier[n]; -.DE -where the constant n is the (static) number of bytes necessary to -contain the opaque data. If n is not a multiple of four, then the n -bytes are followed by enough (0 to 3) residual zero bytes, r, to make -the total byte count of the opaque object a multiple of four. -.ie t .DS -.el .DS L -\fIFixed-Length Opaque\fP - -\f(CW0 1 ... -+--------+--------+...+--------+--------+...+--------+ -| byte 0 | byte 1 |...|byte n-1| 0 |...| 0 | -+--------+--------+...+--------+--------+...+--------+ -|<-----------n bytes---------->|<------r bytes------>| -|<-----------n+r (where (n+r) mod 4 = 0)------------>|\fP -.DE -.NH 2 -\&Variable-length Opaque Data -.IX XDR "variable-length opaque data" -.IX XDR "opaque data, variable length" -.LP -The standard also provides for variable-length (counted) opaque data, -defined as a sequence of n (numbered 0 through n-1) arbitrary bytes -to be the number n encoded as an unsigned integer (as described -below), and followed by the n bytes of the sequence. -.LP -Byte m of the sequence always precedes byte m+1 of the sequence, and -byte 0 of the sequence always follows the sequence's length (count). -enough (0 to 3) residual zero bytes, r, to make the total byte count -a multiple of four. Variable-length opaque data is declared in the -following way: -.DS -.ft CW -opaque identifier; -.DE -or -.DS -.ft CW -opaque identifier<>; -.DE -The constant m denotes an upper bound of the number of bytes that the -sequence may contain. If m is not specified, as in the second -declaration, it is assumed to be (2**32) - 1, the maximum length. -The constant m would normally be found in a protocol specification. -For example, a filing protocol may state that the maximum data -transfer size is 8192 bytes, as follows: -.DS -.ft CW -opaque filedata<8192>; -.DE -This can be illustrated as follows: -.ie t .DS -.el .DS L -\fIVariable-Length Opaque\fP - -\f(CW0 1 2 3 4 5 ... -+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ -| length n |byte0|byte1|...| n-1 | 0 |...| 0 | -+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ -|<-------4 bytes------->|<------n bytes------>|<---r bytes--->| -|<----n+r (where (n+r) mod 4 = 0)---->|\fP -.DE -.LP -It is an error to encode a length greater than the maximum -described in the specification. -.NH 2 -\&String -.IX XDR string -.LP -The standard defines a string of n (numbered 0 through n-1) ASCII -bytes to be the number n encoded as an unsigned integer (as described -above), and followed by the n bytes of the string. Byte m of the -string always precedes byte m+1 of the string, and byte 0 of the -string always follows the string's length. If n is not a multiple of -four, then the n bytes are followed by enough (0 to 3) residual zero -bytes, r, to make the total byte count a multiple of four. Counted -byte strings are declared as follows: -.DS -.ft CW -string object; -.DE -or -.DS -.ft CW -string object<>; -.DE -The constant m denotes an upper bound of the number of bytes that a -string may contain. If m is not specified, as in the second -declaration, it is assumed to be (2**32) - 1, the maximum length. -The constant m would normally be found in a protocol specification. -For example, a filing protocol may state that a file name can be no -longer than 255 bytes, as follows: -.DS -.ft CW -string filename<255>; -.DE -Which can be illustrated as: -.ie t .DS -.el .DS L -\fIA String\fP - -\f(CW0 1 2 3 4 5 ... -+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ -| length n |byte0|byte1|...| n-1 | 0 |...| 0 | -+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ -|<-------4 bytes------->|<------n bytes------>|<---r bytes--->| -|<----n+r (where (n+r) mod 4 = 0)---->|\fP -.DE -.LP -It is an error to encode a length greater than the maximum -described in the specification. -.NH 2 -\&Fixed-length Array -.IX XDR "fixed-length array" -.IX XDR "array, fixed length" -.LP -Declarations for fixed-length arrays of homogeneous elements are in -the following form: -.DS -.ft CW -type-name identifier[n]; -.DE -Fixed-length arrays of elements numbered 0 through n-1 are encoded by -individually encoding the elements of the array in their natural -order, 0 through n-1. Each element's size is a multiple of four -bytes. Though all elements are of the same type, the elements may -have different sizes. For example, in a fixed-length array of -strings, all elements are of type "string", yet each element will -vary in its length. -.ie t .DS -.el .DS L -\fIFixed-Length Array\fP - -\f(CW+---+---+---+---+---+---+---+---+...+---+---+---+---+ -| element 0 | element 1 |...| element n-1 | -+---+---+---+---+---+---+---+---+...+---+---+---+---+ -|<--------------------n elements------------------->|\fP -.DE -.NH 2 -\&Variable-length Array -.IX XDR "variable-length array" -.IX XDR "array, variable length" -.LP -Counted arrays provide the ability to encode variable-length arrays -of homogeneous elements. The array is encoded as the element count n -(an unsigned integer) followed by the encoding of each of the array's -elements, starting with element 0 and progressing through element n- -1. The declaration for variable-length arrays follows this form: -.DS -.ft CW -type-name identifier; -.DE -or -.DS -.ft CW -type-name identifier<>; -.DE -The constant m specifies the maximum acceptable element count of an -array; if m is not specified, as in the second declaration, it is -assumed to be (2**32) - 1. -.ie t .DS -.el .DS L -\fICounted Array\fP - -\f(CW0 1 2 3 -+--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+ -| n | element 0 | element 1 |...|element n-1| -+--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+ -|<-4 bytes->|<--------------n elements------------->|\fP -.DE -It is an error to encode a value of n that is greater than the -maximum described in the specification. -.NH 2 -\&Structure -.IX XDR structure -.LP -Structures are declared as follows: -.DS -.ft CW -struct { - component-declaration-A; - component-declaration-B; - \&... -} identifier; -.DE -The components of the structure are encoded in the order of their -declaration in the structure. Each component's size is a multiple of -four bytes, though the components may be different sizes. -.ie t .DS -.el .DS L -\fIStructure\fP - -\f(CW+-------------+-------------+... -| component A | component B |... -+-------------+-------------+...\fP -.DE -.NH 2 -\&Discriminated Union -.IX XDR "discriminated union" -.IX XDR union discriminated -.LP -A discriminated union is a type composed of a discriminant followed -by a type selected from a set of prearranged types according to the -value of the discriminant. The type of discriminant is either "int", -"unsigned int", or an enumerated type, such as "bool". The component -types are called "arms" of the union, and are preceded by the value -of the discriminant which implies their encoding. Discriminated -unions are declared as follows: -.DS -.ft CW -union switch (discriminant-declaration) { - case discriminant-value-A: - arm-declaration-A; - case discriminant-value-B: - arm-declaration-B; - \&... - default: default-declaration; -} identifier; -.DE -Each "case" keyword is followed by a legal value of the discriminant. -The default arm is optional. If it is not specified, then a valid -encoding of the union cannot take on unspecified discriminant values. -The size of the implied arm is always a multiple of four bytes. -.LP -The discriminated union is encoded as its discriminant followed by -the encoding of the implied arm. -.ie t .DS -.el .DS L -\fIDiscriminated Union\fP - -\f(CW0 1 2 3 -+---+---+---+---+---+---+---+---+ -| discriminant | implied arm | -+---+---+---+---+---+---+---+---+ -|<---4 bytes--->|\fP -.DE -.NH 2 -\&Void -.IX XDR void -.LP -An XDR void is a 0-byte quantity. Voids are useful for describing -operations that take no data as input or no data as output. They are -also useful in unions, where some arms may contain data and others do -not. The declaration is simply as follows: -.DS -.ft CW -void; -.DE -Voids are illustrated as follows: -.ie t .DS -.el .DS L -\fIVoid\fP - -\f(CW ++ - || - ++ ---><-- 0 bytes\fP -.DE -.NH 2 -\&Constant -.IX XDR constant -.LP -The data declaration for a constant follows this form: -.DS -.ft CW -const name-identifier = n; -.DE -"const" is used to define a symbolic name for a constant; it does not -declare any data. The symbolic constant may be used anywhere a -regular constant may be used. For example, the following defines a -symbolic constant DOZEN, equal to 12. -.DS -.ft CW -const DOZEN = 12; -.DE -.NH 2 -\&Typedef -.IX XDR typedef -.LP -"typedef" does not declare any data either, but serves to define new -identifiers for declaring data. The syntax is: -.DS -.ft CW -typedef declaration; -.DE -The new type name is actually the variable name in the declaration -part of the typedef. For example, the following defines a new type -called "eggbox" using an existing type called "egg": -.DS -.ft CW -typedef egg eggbox[DOZEN]; -.DE -Variables declared using the new type name have the same type as the -new type name would have in the typedef, if it was considered a -variable. For example, the following two declarations are equivalent -in declaring the variable "fresheggs": -.DS -.ft CW -eggbox fresheggs; -egg fresheggs[DOZEN]; -.DE -When a typedef involves a struct, enum, or union definition, there is -another (preferred) syntax that may be used to define the same type. -In general, a typedef of the following form: -.DS -.ft CW -typedef <> identifier; -.DE -may be converted to the alternative form by removing the "typedef" -part and placing the identifier after the "struct", "union", or -"enum" keyword, instead of at the end. For example, here are the two -ways to define the type "bool": -.DS -.ft CW -typedef enum { /* \fIusing typedef\fP */ - FALSE = 0, - TRUE = 1 - } bool; - -enum bool { /* \fIpreferred alternative\fP */ - FALSE = 0, - TRUE = 1 - }; -.DE -The reason this syntax is preferred is one does not have to wait -until the end of a declaration to figure out the name of the new -type. -.NH 2 -\&Optional-data -.IX XDR "optional data" -.IX XDR "data, optional" -.LP -Optional-data is one kind of union that occurs so frequently that we -give it a special syntax of its own for declaring it. It is declared -as follows: -.DS -.ft CW -type-name *identifier; -.DE -This is equivalent to the following union: -.DS -.ft CW -union switch (bool opted) { - case TRUE: - type-name element; - case FALSE: - void; -} identifier; -.DE -It is also equivalent to the following variable-length array -declaration, since the boolean "opted" can be interpreted as the -length of the array: -.DS -.ft CW -type-name identifier<1>; -.DE -Optional-data is not so interesting in itself, but it is very useful -for describing recursive data-structures such as linked-lists and -trees. For example, the following defines a type "stringlist" that -encodes lists of arbitrary length strings: -.DS -.ft CW -struct *stringlist { - string item<>; - stringlist next; -}; -.DE -It could have been equivalently declared as the following union: -.DS -.ft CW -union stringlist switch (bool opted) { - case TRUE: - struct { - string item<>; - stringlist next; - } element; - case FALSE: - void; -}; -.DE -or as a variable-length array: -.DS -.ft CW -struct stringlist<1> { - string item<>; - stringlist next; -}; -.DE -Both of these declarations obscure the intention of the stringlist -type, so the optional-data declaration is preferred over both of -them. The optional-data type also has a close correlation to how -recursive data structures are represented in high-level languages -such as Pascal or C by use of pointers. In fact, the syntax is the -same as that of the C language for pointers. -.NH 2 -\&Areas for Future Enhancement -.IX XDR futures -.LP -The XDR standard lacks representations for bit fields and bitmaps, -since the standard is based on bytes. Also missing are packed (or -binary-coded) decimals. -.LP -The intent of the XDR standard was not to describe every kind of data -that people have ever sent or will ever want to send from machine to -machine. Rather, it only describes the most commonly used data-types -of high-level languages such as Pascal or C so that applications -written in these languages will be able to communicate easily over -some medium. -.LP -One could imagine extensions to XDR that would let it describe almost -any existing protocol, such as TCP. The minimum necessary for this -are support for different block sizes and byte-orders. The XDR -discussed here could then be considered the 4-byte big-endian member -of a larger XDR family. -.NH 1 -\&Discussion -.sp 2 -.NH 2 -\&Why a Language for Describing Data? -.IX XDR language -.LP -There are many advantages in using a data-description language such -as XDR versus using diagrams. Languages are more formal than -diagrams and lead to less ambiguous descriptions of data. -Languages are also easier to understand and allow one to think of -other issues instead of the low-level details of bit-encoding. -Also, there is a close analogy between the types of XDR and a -high-level language such as C or Pascal. This makes the -implementation of XDR encoding and decoding modules an easier task. -Finally, the language specification itself is an ASCII string that -can be passed from machine to machine to perform on-the-fly data -interpretation. -.NH 2 -\&Why Only one Byte-Order for an XDR Unit? -.IX XDR "byte order" -.LP -Supporting two byte-orderings requires a higher level protocol for -determining in which byte-order the data is encoded. Since XDR is -not a protocol, this can't be done. The advantage of this, though, -is that data in XDR format can be written to a magnetic tape, for -example, and any machine will be able to interpret it, since no -higher level protocol is necessary for determining the byte-order. -.NH 2 -\&Why does XDR use Big-Endian Byte-Order? -.LP -Yes, it is unfair, but having only one byte-order means you have to -be unfair to somebody. Many architectures, such as the Motorola -68000 and IBM 370, support the big-endian byte-order. -.NH 2 -\&Why is the XDR Unit Four Bytes Wide? -.LP -There is a tradeoff in choosing the XDR unit size. Choosing a small -size such as two makes the encoded data small, but causes alignment -problems for machines that aren't aligned on these boundaries. A -large size such as eight means the data will be aligned on virtually -every machine, but causes the encoded data to grow too big. We chose -four as a compromise. Four is big enough to support most -architectures efficiently, except for rare machines such as the -eight-byte aligned Cray. Four is also small enough to keep the -encoded data restricted to a reasonable size. -.NH 2 -\&Why must Variable-Length Data be Padded with Zeros? -.IX XDR "variable-length data" -.LP -It is desirable that the same data encode into the same thing on all -machines, so that encoded data can be meaningfully compared or -checksummed. Forcing the padded bytes to be zero ensures this. -.NH 2 -\&Why is there No Explicit Data-Typing? -.LP -Data-typing has a relatively high cost for what small advantages it -may have. One cost is the expansion of data due to the inserted type -fields. Another is the added cost of interpreting these type fields -and acting accordingly. And most protocols already know what type -they expect, so data-typing supplies only redundant information. -However, one can still get the benefits of data-typing using XDR. One -way is to encode two things: first a string which is the XDR data -description of the encoded data, and then the encoded data itself. -Another way is to assign a value to all the types in XDR, and then -define a universal type which takes this value as its discriminant -and for each value, describes the corresponding data type. -.NH 1 -\&The XDR Language Specification -.IX XDR language -.sp 1 -.NH 2 -\&Notational Conventions -.IX "XDR language" notation -.LP -This specification uses an extended Backus-Naur Form notation for -describing the XDR language. Here is a brief description of the -notation: -.IP 1. -The characters -.I | , -.I ( , -.I ) , -.I [ , -.I ] , -.I " , -and -.I * -are special. -.IP 2. -Terminal symbols are strings of any characters surrounded by -double quotes. -.IP 3. -Non-terminal symbols are strings of non-special characters. -.IP 4. -Alternative items are separated by a vertical bar ("\fI|\fP"). -.IP 5. -Optional items are enclosed in brackets. -.IP 6. -Items are grouped together by enclosing them in parentheses. -.IP 7. -A -.I * -following an item means 0 or more occurrences of that item. -.LP -For example, consider the following pattern: -.DS L -"a " "very" (", " " very")* [" cold " "and"] " rainy " ("day" | "night") -.DE -.LP -An infinite number of strings match this pattern. A few of them -are: -.DS -"a very rainy day" -"a very, very rainy day" -"a very cold and rainy day" -"a very, very, very cold and rainy night" -.DE -.NH 2 -\&Lexical Notes -.IP 1. -Comments begin with '/*' and terminate with '*/'. -.IP 2. -White space serves to separate items and is otherwise ignored. -.IP 3. -An identifier is a letter followed by an optional sequence of -letters, digits or underbar ('_'). The case of identifiers is -not ignored. -.IP 4. -A constant is a sequence of one or more decimal digits, -optionally preceded by a minus-sign ('-'). -.NH 2 -\&Syntax Information -.IX "XDR language" syntax -.DS -.ft CW -declaration: - type-specifier identifier - | type-specifier identifier "[" value "]" - | type-specifier identifier "<" [ value ] ">" - | "opaque" identifier "[" value "]" - | "opaque" identifier "<" [ value ] ">" - | "string" identifier "<" [ value ] ">" - | type-specifier "*" identifier - | "void" -.DE -.DS -.ft CW -value: - constant - | identifier - -type-specifier: - [ "unsigned" ] "int" - | [ "unsigned" ] "hyper" - | "float" - | "double" - | "bool" - | enum-type-spec - | struct-type-spec - | union-type-spec - | identifier -.DE -.DS -.ft CW -enum-type-spec: - "enum" enum-body - -enum-body: - "{" - ( identifier "=" value ) - ( "," identifier "=" value )* - "}" -.DE -.DS -.ft CW -struct-type-spec: - "struct" struct-body - -struct-body: - "{" - ( declaration ";" ) - ( declaration ";" )* - "}" -.DE -.DS -.ft CW -union-type-spec: - "union" union-body - -union-body: - "switch" "(" declaration ")" "{" - ( "case" value ":" declaration ";" ) - ( "case" value ":" declaration ";" )* - [ "default" ":" declaration ";" ] - "}" - -constant-def: - "const" identifier "=" constant ";" -.DE -.DS -.ft CW -type-def: - "typedef" declaration ";" - | "enum" identifier enum-body ";" - | "struct" identifier struct-body ";" - | "union" identifier union-body ";" - -definition: - type-def - | constant-def - -specification: - definition * -.DE -.NH 3 -\&Syntax Notes -.IX "XDR language" syntax -.LP -.IP 1. -The following are keywords and cannot be used as identifiers: -"bool", "case", "const", "default", "double", "enum", "float", -"hyper", "opaque", "string", "struct", "switch", "typedef", "union", -"unsigned" and "void". -.IP 2. -Only unsigned constants may be used as size specifications for -arrays. If an identifier is used, it must have been declared -previously as an unsigned constant in a "const" definition. -.IP 3. -Constant and type identifiers within the scope of a specification -are in the same name space and must be declared uniquely within this -scope. -.IP 4. -Similarly, variable names must be unique within the scope of -struct and union declarations. Nested struct and union declarations -create new scopes. -.IP 5. -The discriminant of a union must be of a type that evaluates to -an integer. That is, "int", "unsigned int", "bool", an enumerated -type or any typedefed type that evaluates to one of these is legal. -Also, the case values must be one of the legal values of the -discriminant. Finally, a case value may not be specified more than -once within the scope of a union declaration. -.NH 1 -\&An Example of an XDR Data Description -.LP -Here is a short XDR data description of a thing called a "file", -which might be used to transfer files from one machine to another. -.ie t .DS -.el .DS L -.ft CW - -const MAXUSERNAME = 32; /*\fI max length of a user name \fP*/ -const MAXFILELEN = 65535; /*\fI max length of a file \fP*/ -const MAXNAMELEN = 255; /*\fI max length of a file name \fP*/ - -.ft I -/* - * Types of files: - */ -.ft CW - -enum filekind { - TEXT = 0, /*\fI ascii data \fP*/ - DATA = 1, /*\fI raw data \fP*/ - EXEC = 2 /*\fI executable \fP*/ -}; - -.ft I -/* - * File information, per kind of file: - */ -.ft CW - -union filetype switch (filekind kind) { - case TEXT: - void; /*\fI no extra information \fP*/ - case DATA: - string creator; /*\fI data creator \fP*/ - case EXEC: - string interpretor; /*\fI program interpretor \fP*/ -}; - -.ft I -/* - * A complete file: - */ -.ft CW - -struct file { - string filename; /*\fI name of file \fP*/ - filetype type; /*\fI info about file \fP*/ - string owner; /*\fI owner of file \fP*/ - opaque data; /*\fI file data \fP*/ -}; -.DE -.LP -Suppose now that there is a user named "john" who wants to store -his lisp program "sillyprog" that contains just the data "(quit)". -His file would be encoded as follows: -.TS -box tab (&) ; -lfI lfI lfI lfI -rfL rfL rfL l . -Offset&Hex Bytes&ASCII&Description -_ -0&00 00 00 09&....&Length of filename = 9 -4&73 69 6c 6c&sill&Filename characters -8&79 70 72 6f&ypro& ... and more characters ... -12&67 00 00 00&g...& ... and 3 zero-bytes of fill -16&00 00 00 02&....&Filekind is EXEC = 2 -20&00 00 00 04&....&Length of interpretor = 4 -24&6c 69 73 70&lisp&Interpretor characters -28&00 00 00 04&....&Length of owner = 4 -32&6a 6f 68 6e&john&Owner characters -36&00 00 00 06&....&Length of file data = 6 -40&28 71 75 69&(qui&File data bytes ... -44&74 29 00 00&t)..& ... and 2 zero-bytes of fill -.TE -.NH 1 -\&References -.LP -[1] Brian W. Kernighan & Dennis M. Ritchie, "The C Programming -Language", Bell Laboratories, Murray Hill, New Jersey, 1978. -.LP -[2] Danny Cohen, "On Holy Wars and a Plea for Peace", IEEE Computer, -October 1981. -.LP -[3] "IEEE Standard for Binary Floating-Point Arithmetic", ANSI/IEEE -Standard 754-1985, Institute of Electrical and Electronics -Engineers, August 1985. -.LP -[4] "Courier: The Remote Procedure Call Protocol", XEROX -Corporation, XSIS 038112, December 1981. diff --git a/c/src/librpc/src/rpc/README b/c/src/librpc/src/rpc/README deleted file mode 100644 index ad9d70f990..0000000000 --- a/c/src/librpc/src/rpc/README +++ /dev/null @@ -1,233 +0,0 @@ -RPCSRC 4.0 7/11/89 - -This distribution contains Sun Microsystem's implementation of the -RPC and XDR protocols and is compatible with 4.2BSD and 4.3BSD. Also -included is complete documentation, utilities, RPC service -specification files, and demonstration services in the format used by -the RPC protocol compiler (rpcgen). See WHAT'S NEW below for -details. - -NOTE ABOUT SECURE RPC: - -This release of RPCSRC contains most of the code needed to implement -Secure RPC (see "DES Authentication" in the RPC Protocol Specification, -doc/rpc.rfc.ms). Due to legal considerations, we are unable to -distribute an implementation of DES, the Data Encryption Standard, which -Secure RPC requires. For this reason, all of the files, documentation, and -programs associated with Secure RPC have been placed into a separate -directory, secure_rpc. The RPC library contained in the main body of this -release *DOES NOT* support Secure RPC. See secure_rpc/README for more -details. (A DES library was posted in Volume 18 of comp.sources.unix.) - -If you wish to report bugs found in this release, send mail to: - -Portable ONC/NFS -Sun Microsystems, Inc -MS 12-33 -2550 Garcia Avenue -Mountain View, CA 94043 - -or send Email to nfsnet@sun.com (the Internet) or sun!nfsnet (Usenet). - -ROADMAP - -The directory hierarchy is as follows: - - demo/ Various demonstration services - demo/dir Remote directory lister - demo/msg Remote console message delivery service - demo/sort Remote sort service - - doc/ Documentation for RPC, XDR and NFS in "-ms" format. - - etc/ Utilities (rpcinfo and portmap). portmap must be - started by root before any other RPC network services are - used. SEE BELOW FOR BUGFIX TO 4.3BSD COMPILER. - - man/ Manual pages for RPC library, rpcgen, and utilities. - - rpc/ The RPC and XDR library. SEE BELOW - FOR BUGFIX TO 4.2BSD COMPILER. - - rpcgen/ The RPC Language compiler (for .x files) - - rpcsvc/ Service definition files for various services and the - server and client code for the Remote Status service. - - secure_rpc/ The files in this directory are used to build a version of - the RPC library with DES Authentication. See the README - file in that directory for more details. - -BUILD INSTRUCTIONS - -Makefiles can be found in all directories except for man. The -Makefile in the top directory will cause these others to be invoked -(except for in the doc, man and demo directories), in turn building the -entire release. - -WARNING! THE DEFAULT INSTALLATION PROCEDURES WILL INSTALL FILES -IN /usr/include, /usr/lib, /usr/bin and /etc. - -The master RPC include file, rpc/rpc.h, is used by all programs and -routines that use RPC. It includes other RPC and system include files -needed by the RPC system. PLEASE NOTE: If your system has NFS, it -may have been based on Sun's NFS Source. The include files installed -by this package may duplicate include files you will find on your NFS -system. The RPCSRC 4.0 include files are upwardly compatible to all -NFS Source include files as of the date of this distribution (not -including any new definitions or declarations added by your system -vendor). HOWEVER: Please read the comments towards the end of -rpc/rpc.h regarding rpc/netdb.h. You may need to uncomment the -inclusion of that file if the structures it defines are already -defined by your system's include files. - -After making any compiler fixes that are needed (see below), at -the top directory, type: - - make install - -For all installations, the Makefile macro DESTDIR is prepended to the -installation path. It is defined to be null in the Makefiles, so -installations are relative to root. (You will probably need root -privileges for installing the files under the default path.) To -install the files under some other tree (e.g., /usr/local), use the -command: - - make install DESTDIR=/usr/local - -This will place the include files in /usr/local/usr/include, the RPC -library in /usr/local/usr/lib, rpcgen in /usr/local/usr/bin, and the -utilities in /usr/local/etc. You'll have to edit the Makefiles or -install the files by hand if you want to do anything other than this -kind of relocation of the installation tree. - -The RPC library will be built and installed first. By default it is -installed in /usr/lib as "librpclib.a". The directory -/usr/include/rpc will also be created, and several header files will -be installed there. ALL RPC SERVICES INCLUDE THESE HEADER FILES. - -The programs in etc/ link in routines from librpclib.a. If you change -where it is installed, be sure to edit etc/'s Makefile to reflect this. -These programs are installed in /etc. PORTMAP MUST BE RUNNING ON -YOUR SYSTEM BEFORE YOU START ANY OTHER RPC SERVICE. - -rpcgen is installed in /usr/bin. This program is required to build -the demonstration services in demo and the rstat client and server in -rpcsvc/. - -The rpcsvc/ directory will install its files in the directory -/usr/include/rpcsvc. The Remote Status service (rstat_svc) will be -compiled and installed in /etc. If you wish to make this service -available, you should either start this service when needed or have -it started at boot time by invoking it in your /etc/rc.local script. -(Be sure that portmap is started first!) Sun has modified its -version of inetd to automatically start RPC services. (Use "make -LIB=" when building rstat on a Sun Workstation.) The Remote Status -client (rstat) will be installed in /usr/bin. This program queries -the rstat_svc on a remote host and prints a system status summary -similar to the one printed by "uptime". - -The documentation is not built during the "make install" command. -Typing "make" in the doc directory will cause all of the manuals to -be formatted using nroff into a single file. We have had a report -that certain "troff" equivalents have trouble processing the full -manual. If you have trouble, try building the manuals individually -(see the Makefile). - -The demonstration services in the demo directory are not built by the -top-level "make install" command. To build these, cd to the demo -directory and enter "make". The three services will be built. -RPCGEN MUST BE INSTALLED in a path that make can find. To run the -services, start the portmap program as root and invoke the service -(you probably will want to put it in the background). rpcinfo can be -used to check that the service succeeded in getting registered with -portmap, and to ping the service (see rpcinfo's man page). You can -then use the corresponding client program to exercise the service. -To build these services on a Sun workstation, you must prevent the -Makefile from trying to link the RPC library (as these routines are -already a part of Sun's libc). Use: "make LIB=". - -BUGFIX FOR 4.3BSD COMPILER - -The use of a 'void *' declaration for one of the arguments in -the reply_proc() procedure in etc/rpcinfo.c will trigger a bug -in the 4.3BSD compiler. The bug is fixed by the following change to -the compiler file mip/manifest.h: - -*** manifest.h.r1.1 Thu Apr 30 13:52:25 1987 ---- manifest.h.r1.2 Mon Nov 23 18:58:17 1987 -*************** -*** 21,27 **** - /* - * Bogus type values - */ -! #define TNULL PTR /* pointer to UNDEF */ - #define TVOID FTN /* function returning UNDEF (for void) */ - - /* ---- 21,27 ---- - /* - * Bogus type values - */ -! #define TNULL INCREF(MOETY) /* pointer to MOETY -- impossible type */ - #define TVOID FTN /* function returning UNDEF (for void) */ - - /* - -If you cannot fix your compiler, change the declaration in reply_proc() -from 'void *' to 'char *'. - -BUGFIX FOR 4.2BSD COMPILER - -Unpatched 4.2BSD compilers complain about valid C. You can make old -compilers happy by changing some voids to ints. However, the fix to -the 4.2 VAX compiler is as follows (to mip/trees.c): - -*** trees.c.r1.1 Mon May 11 13:47:58 1987 ---- trees.c.r1.2 Wed Jul 2 18:28:52 1986 -*************** -*** 1247,1253 **** - if(o==CAST && mt1==0)return(TYPL+TYMATCH); - if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH ); - else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN ); -! else if( mt12 == 0 ) break; - else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN ); - else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); - break; ---- 1261,1269 ---- - if(o==CAST && mt1==0)return(TYPL+TYMATCH); - if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH ); - else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN ); -! /* if right is TVOID and looks like a CALL, is not ok */ -! else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL)) -! break; - else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN ); - else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); - break; - -WHAT'S NEW IN THIS RELEASE: RPCSRC 4.0 - -The previous release was RPCSRC 3.9. As with all previous releases, -this release is based directly on files from Sun Microsystem's -implementation. - -Upgrade from RPCSRC 3.9 - -1) RPCSRC 4.0 upgrades RPCSRC 3.9. Improvements from SunOS 4.0 have - been integrated into this release. - -Secure RPC (in the secure_rpc/ directory) - -2) DES Authentication routines and programs are provided. -3) A new manual, "Secure NFS" is provided, which describes Secure RPC - and Secure NFS. -4) Skeleton routines and manual pages are provided which describe the - DES encryption procedures required by Secure RPC. HOWEVER, NO DES - ROUTINE IS PROVIDED. - -New Functionality - -5) rpcinfo can now be used to de-register services from the portmapper - which may have terminated abnormally. -6) A new client, rstat, is provided which queries the rstat_svc and - prints a status line similar to the one displayed by "uptime". diff --git a/c/src/librpc/src/rpc/auth_des.c b/c/src/librpc/src/rpc/auth_des.c deleted file mode 100644 index 87d55b67e7..0000000000 --- a/c/src/librpc/src/rpc/auth_des.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1988 by Sun Microsystems, Inc. - */ -/* - * auth_des.c, client-side implementation of DES authentication - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* XXX: just to get htonl() and ntohl() */ -#include -#undef NIS -#include - -#if defined(LIBC_SCCS) && !defined(lint) -/* from: static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; */ -static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/auth_des.c,v 1.3 1999/08/28 00:00:32 peter Exp $"; -#endif - -extern bool_t __rpc_get_time_offset __P(( struct timeval *, nis_server *, - char *, char **, struct sockaddr_in * )); -extern int rtime __P(( struct sockaddr_in *, struct timeval *, struct timeval *)); -extern bool_t xdr_authdes_cred __P(( XDR *, struct authdes_cred * )); -extern bool_t xdr_authdes_verf __P(( XDR *, struct authdes_verf * )); - -#define MILLION 1000000L -#define RTIME_TIMEOUT 5 /* seconds to wait for sync */ - -#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private -#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type)) -#define FREE(ptr, size) mem_free((char *)(ptr), (int) size) -#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) - -#define debug(msg) /*printf("%s\n", msg) */ - -/* - * DES authenticator operations vector - */ -static void authdes_nextverf(); -static bool_t authdes_marshal(); -static bool_t authdes_validate(); -static bool_t authdes_refresh(); -static void authdes_destroy(); -static struct auth_ops authdes_ops = { - authdes_nextverf, - authdes_marshal, - authdes_validate, - authdes_refresh, - authdes_destroy -}; -#ifdef foo -static bool_t synchronize __P(( struct sockaddr *, struct timeval *)); -#endif -/* - * This struct is pointed to by the ah_private field of an "AUTH *" - */ -struct ad_private { - char *ad_fullname; /* client's full name */ - u_int ad_fullnamelen; /* length of name, rounded up */ - char *ad_servername; /* server's full name */ - u_int ad_servernamelen; /* length of name, rounded up */ - u_int ad_window; /* client specified window */ - bool_t ad_dosync; /* synchronize? */ - struct sockaddr ad_syncaddr; /* remote host to synch with */ - char *ad_timehost; /* remote host to synch with */ - struct timeval ad_timediff; /* server's time - client's time */ - u_long ad_nickname; /* server's nickname for client */ - struct authdes_cred ad_cred; /* storage for credential */ - struct authdes_verf ad_verf; /* storage for verifier */ - struct timeval ad_timestamp; /* timestamp sent */ - des_block ad_xkey; /* encrypted conversation key */ - u_char ad_pkey[1024]; /* Server's actual public key */ - char *ad_netid; /* Timehost netid */ - char *ad_uaddr; /* Timehost uaddr */ - nis_server *ad_nis_srvr; /* NIS+ server struct */ -}; - - -/* - * Create the client des authentication object - */ -AUTH * -authdes_create(servername, window, syncaddr, ckey) - char *servername; /* network name of server */ - u_int window; /* time to live */ - struct sockaddr *syncaddr; /* optional addr of host to sync with */ - des_block *ckey; /* optional conversation key to use*/ -{ - - AUTH *auth; - struct ad_private *ad; - char namebuf[MAXNETNAMELEN+1]; - u_char pkey_data[1024]; - - if (!getpublickey(servername, pkey_data)) - return(NULL); - - /* - * Allocate everything now - */ - auth = ALLOC(AUTH); - ad = ALLOC(struct ad_private); - (void) getnetname(namebuf); - - ad->ad_fullnamelen = RNDUP(strlen(namebuf)); - ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); - - ad->ad_servernamelen = strlen(servername); - ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); - - if (auth == NULL || ad == NULL || ad->ad_fullname == NULL || - ad->ad_servername == NULL) { - debug("authdes_create: out of memory"); - goto failed; - } - - /* - * Set up private data - */ - bcopy(namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1); - bcopy(servername, ad->ad_servername, ad->ad_servernamelen + 1); - bcopy(pkey_data, ad->ad_pkey, strlen(pkey_data) + 1); - if (syncaddr != NULL) { - ad->ad_syncaddr = *syncaddr; - ad->ad_dosync = TRUE; - } else { - ad->ad_dosync = FALSE; - } - ad->ad_window = window; - if (ckey == NULL) { - if (key_gendes(&auth->ah_key) < 0) { - debug("authdes_create: unable to gen conversation key"); - return (NULL); - } - } else { - auth->ah_key = *ckey; - } - - /* - * Set up auth handle - */ - auth->ah_cred.oa_flavor = AUTH_DES; - auth->ah_verf.oa_flavor = AUTH_DES; - auth->ah_ops = &authdes_ops; - auth->ah_private = (caddr_t)ad; - - if (!authdes_refresh(auth)) { - goto failed; - } - return (auth); - -failed: - if (auth != NULL) - FREE(auth, sizeof(AUTH)); - if (ad != NULL) - FREE(ad, sizeof(struct ad_private)); - if (ad->ad_fullname != NULL) - FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); - if (ad->ad_servername != NULL) - FREE(ad->ad_servername, ad->ad_servernamelen + 1); - return (NULL); -} - -/* - * Slightly modified version of authdes_create which takes the public key - * of the server principal as an argument. This spares us a call to - * getpublickey() which in the nameserver context can cause a deadlock. - */ -AUTH * -authdes_pk_create(servername, pkey, window, timehost, ckey, srvr) - char *servername; /* network name of server */ - netobj *pkey; /* public key of server */ - u_int window; /* time to live */ - char *timehost; /* optional hostname to sync with */ - des_block *ckey; /* optional conversation key to use */ - nis_server *srvr; /* optional NIS+ server struct */ -{ - AUTH *auth; - struct ad_private *ad; - char namebuf[MAXNETNAMELEN+1]; - - /* - * Allocate everything now - */ - auth = ALLOC(AUTH); - if (auth == NULL) { - debug("authdes_pk_create: out of memory"); - return (NULL); - } - ad = ALLOC(struct ad_private); - if (ad == NULL) { - debug("authdes_pk_create: out of memory"); - goto failed; - } - ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */ - ad->ad_timehost = NULL; - ad->ad_netid = NULL; - ad->ad_uaddr = NULL; - ad->ad_nis_srvr = NULL; - ad->ad_timediff.tv_sec = 0; - ad->ad_timediff.tv_usec = 0; - memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len); - if (!getnetname(namebuf)) - goto failed; - ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf)); - ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); - ad->ad_servernamelen = strlen(servername); - ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); - - if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { - debug("authdes_pk_create: out of memory"); - goto failed; - } - if (timehost != NULL) { - ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); - if (ad->ad_timehost == NULL) { - debug("authdes_pk_create: out of memory"); - goto failed; - } - memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1); - ad->ad_dosync = TRUE; - } else if (srvr != NULL) { - ad->ad_nis_srvr = srvr; /* transient */ - ad->ad_dosync = TRUE; - } else { - ad->ad_dosync = FALSE; - } - memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); - memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1); - ad->ad_window = window; - if (ckey == NULL) { - if (key_gendes(&auth->ah_key) < 0) { - debug("authdes_pk_create: unable to gen conversation key"); - goto failed; - } - } else { - auth->ah_key = *ckey; - } - - /* - * Set up auth handle - */ - auth->ah_cred.oa_flavor = AUTH_DES; - auth->ah_verf.oa_flavor = AUTH_DES; - auth->ah_ops = &authdes_ops; - auth->ah_private = (caddr_t)ad; - - if (!authdes_refresh(auth)) { - goto failed; - } - ad->ad_nis_srvr = NULL; /* not needed any longer */ - return (auth); - -failed: - if (auth) - FREE(auth, sizeof (AUTH)); - if (ad) { - if (ad->ad_fullname) - FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); - if (ad->ad_servername) - FREE(ad->ad_servername, ad->ad_servernamelen + 1); - if (ad->ad_timehost) - FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); - if (ad->ad_netid) - free(ad->ad_netid); - if (ad->ad_uaddr) - free(ad->ad_uaddr); - FREE(ad, sizeof (struct ad_private)); - } - return (NULL); -} -/* - * Implement the five authentication operations - */ - - -/* - * 1. Next Verifier - */ -/*ARGSUSED*/ -static void -authdes_nextverf(auth) - AUTH *auth; -{ - /* what the heck am I supposed to do??? */ -} - - - -/* - * 2. Marshal - */ -static bool_t -authdes_marshal(auth, xdrs) - AUTH *auth; - XDR *xdrs; -{ - struct ad_private *ad = AUTH_PRIVATE(auth); - struct authdes_cred *cred = &ad->ad_cred; - struct authdes_verf *verf = &ad->ad_verf; - des_block cryptbuf[2]; - des_block ivec; - int status; - long len; - int32_t *ixdr; - - /* - * Figure out the "time", accounting for any time difference - * with the server if necessary. - */ - (void) gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL); - ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec; - ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec; - if (ad->ad_timestamp.tv_usec >= MILLION) { - ad->ad_timestamp.tv_usec -= MILLION; - ad->ad_timestamp.tv_sec += 1; - } - - /* - * XDR the timestamp and possibly some other things, then - * encrypt them. - */ - ixdr = (int32_t *)cryptbuf; - IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_sec); - IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_usec); - if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { - IXDR_PUT_U_LONG(ixdr, ad->ad_window); - IXDR_PUT_U_LONG(ixdr, ad->ad_window - 1); - ivec.key.high = ivec.key.low = 0; - status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf, - 2*sizeof(des_block), DES_ENCRYPT | DES_HW, (char *)&ivec); - } else { - status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf, - sizeof(des_block), DES_ENCRYPT | DES_HW); - } - if (DES_FAILED(status)) { - debug("authdes_marshal: DES encryption failure"); - return (FALSE); - } - ad->ad_verf.adv_xtimestamp = cryptbuf[0]; - if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { - ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high; - ad->ad_verf.adv_winverf = cryptbuf[1].key.low; - } else { - ad->ad_cred.adc_nickname = ad->ad_nickname; - ad->ad_verf.adv_winverf = 0; - } - - /* - * Serialize the credential and verifier into opaque - * authentication data. - */ - if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { - len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen); - } else { - len = (1 + 1)*BYTES_PER_XDR_UNIT; - } - - if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { - IXDR_PUT_LONG(ixdr, AUTH_DES); - IXDR_PUT_LONG(ixdr, len); - } else { - ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_cred.oa_flavor)); - ATTEMPT(xdr_putlong(xdrs, &len)); - } - ATTEMPT(xdr_authdes_cred(xdrs, cred)); - - len = (2 + 1)*BYTES_PER_XDR_UNIT; - if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { - IXDR_PUT_LONG(ixdr, AUTH_DES); - IXDR_PUT_LONG(ixdr, len); - } else { - ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_verf.oa_flavor)); - ATTEMPT(xdr_putlong(xdrs, &len)); - } - ATTEMPT(xdr_authdes_verf(xdrs, verf)); - return (TRUE); -} - - -/* - * 3. Validate - */ -static bool_t -authdes_validate(auth, rverf) - AUTH *auth; - struct opaque_auth *rverf; -{ - struct ad_private *ad = AUTH_PRIVATE(auth); - struct authdes_verf verf; - int status; - register u_long *ixdr; - - if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) { - return (FALSE); - } - ixdr = (u_long *)rverf->oa_base; - verf.adv_xtimestamp.key.high = (u_long)*ixdr++; - verf.adv_xtimestamp.key.low = (u_long)*ixdr++; - verf.adv_int_u = (u_long)*ixdr++; /* nickname not XDR'd ! */ - - /* - * Decrypt the timestamp - */ - status = ecb_crypt((char *)&auth->ah_key, (char *)&verf.adv_xtimestamp, - sizeof(des_block), DES_DECRYPT | DES_HW); - - if (DES_FAILED(status)) { - debug("authdes_validate: DES decryption failure"); - return (FALSE); - } - - /* - * xdr the decrypted timestamp - */ - ixdr = (u_long *)verf.adv_xtimestamp.c; - verf.adv_timestamp.tv_sec = IXDR_GET_LONG(ixdr) + 1; - verf.adv_timestamp.tv_usec = IXDR_GET_LONG(ixdr); - - /* - * validate - */ - if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, - sizeof(struct timeval)) != 0) { - debug("authdes_validate: verifier mismatch\n"); - return (FALSE); - } - - /* - * We have a nickname now, let's use it - */ - ad->ad_nickname = verf.adv_nickname; - ad->ad_cred.adc_namekind = ADN_NICKNAME; - return (TRUE); -} - -/* - * 4. Refresh - */ -static bool_t -authdes_refresh(auth) - AUTH *auth; -{ - struct ad_private *ad = AUTH_PRIVATE(auth); - struct authdes_cred *cred = &ad->ad_cred; - netobj pkey; - - if (ad->ad_dosync && -#ifdef old - !synchronize(&ad->ad_syncaddr, &ad->ad_timediff)) { -#else - !__rpc_get_time_offset(&ad->ad_timediff,ad->ad_nis_srvr, - ad->ad_timehost, &(ad->ad_uaddr), - (struct sockaddr_in *)&(ad->ad_syncaddr))) { -#endif - /* - * Hope the clocks are synced! - */ - ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0; - ad->ad_dosync = 0; - debug("authdes_refresh: unable to synchronize with server"); - } - ad->ad_xkey = auth->ah_key; - pkey.n_bytes = (char *)(ad->ad_pkey); - pkey.n_len = strlen((char *)ad->ad_pkey) + 1; - if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) { - debug("authdes_create: unable to encrypt conversation key"); - return (FALSE); - } - cred->adc_fullname.key = ad->ad_xkey; - cred->adc_namekind = ADN_FULLNAME; - cred->adc_fullname.name = ad->ad_fullname; - return (TRUE); -} - - -/* - * 5. Destroy - */ -static void -authdes_destroy(auth) - AUTH *auth; -{ - struct ad_private *ad = AUTH_PRIVATE(auth); - - FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); - FREE(ad->ad_servername, ad->ad_servernamelen + 1); - FREE(ad, sizeof(struct ad_private)); - FREE(auth, sizeof(AUTH)); -} - - -#ifdef old -/* - * Synchronize with the server at the given address, that is, - * adjust timep to reflect the delta between our clocks - */ -static bool_t -synchronize(syncaddr, timep) - struct sockaddr *syncaddr; - struct timeval *timep; -{ - struct timeval mytime; - struct timeval timeout; - - timeout.tv_sec = RTIME_TIMEOUT; - timeout.tv_usec = 0; - if (rtime((struct sockaddr_in *)syncaddr, timep, NULL /*&timeout*/) < 0) { - return (FALSE); - } - (void) gettimeofday(&mytime, (struct timezone *)NULL); - timep->tv_sec -= mytime.tv_sec; - if (mytime.tv_usec > timep->tv_usec) { - timep->tv_sec -= 1; - timep->tv_usec += MILLION; - } - timep->tv_usec -= mytime.tv_usec; - return (TRUE); -} -#endif diff --git a/c/src/librpc/src/rpc/auth_none.c b/c/src/librpc/src/rpc/auth_none.c deleted file mode 100644 index 9b08699ea8..0000000000 --- a/c/src/librpc/src/rpc/auth_none.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/auth_none.c,v 1.9 1999/08/28 00:00:32 peter Exp $"; -#endif - -/* - * auth_none.c - * Creates a client authentication handle for passing "null" - * credentials and verifiers to remote systems. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#define MAX_MARSHEL_SIZE 20 - -/* - * Authenticator operations routines - */ -static void authnone_verf(); -static void authnone_destroy(); -static bool_t authnone_marshal(); -static bool_t authnone_validate(); -static bool_t authnone_refresh(); - -static struct auth_ops ops = { - authnone_verf, - authnone_marshal, - authnone_validate, - authnone_refresh, - authnone_destroy -}; - -static struct authnone_private { - AUTH no_client; - char marshalled_client[MAX_MARSHEL_SIZE]; - u_int mcnt; -} *authnone_private; - -AUTH * -authnone_create() -{ - register struct authnone_private *ap = authnone_private; - XDR xdr_stream; - register XDR *xdrs; - - if (ap == 0) { - ap = (struct authnone_private *)calloc(1, sizeof (*ap)); - if (ap == 0) - return (0); - authnone_private = ap; - } - if (!ap->mcnt) { - ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth; - ap->no_client.ah_ops = &ops; - xdrs = &xdr_stream; - xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE, - XDR_ENCODE); - (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred); - (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf); - ap->mcnt = XDR_GETPOS(xdrs); - XDR_DESTROY(xdrs); - } - return (&ap->no_client); -} - -/*ARGSUSED*/ -static bool_t -authnone_marshal(client, xdrs) - AUTH *client; - XDR *xdrs; -{ - register struct authnone_private *ap = authnone_private; - - if (ap == 0) - return (0); - return ((*xdrs->x_ops->x_putbytes)(xdrs, - ap->marshalled_client, ap->mcnt)); -} - -static void -authnone_verf() -{ -} - -static bool_t -authnone_validate() -{ - - return (TRUE); -} - -static bool_t -authnone_refresh() -{ - - return (FALSE); -} - -static void -authnone_destroy() -{ -} diff --git a/c/src/librpc/src/rpc/auth_time.c b/c/src/librpc/src/rpc/auth_time.c deleted file mode 100644 index ab3277c4df..0000000000 --- a/c/src/librpc/src/rpc/auth_time.c +++ /dev/null @@ -1,503 +0,0 @@ -#pragma ident "@(#)auth_time.c 1.4 92/11/10 SMI" - -/* - * auth_time.c - * - * This module contains the private function __rpc_get_time_offset() - * which will return the difference in seconds between the local system's - * notion of time and a remote server's notion of time. This must be - * possible without calling any functions that may invoke the name - * service. (netdir_getbyxxx, getXbyY, etc). The function is used in the - * synchronize call of the authdes code to synchronize clocks between - * NIS+ clients and their servers. - * - * Note to minimize the amount of duplicate code, portions of the - * synchronize() function were folded into this code, and the synchronize - * call becomes simply a wrapper around this function. Further, if this - * function is called with a timehost it *DOES* recurse to the name - * server so don't use it in that mode if you are doing name service code. - * - * Copyright (c) 1992 Sun Microsystems Inc. - * All rights reserved. - * - * Side effects : - * When called a client handle to a RPCBIND process is created - * and destroyed. Two strings "netid" and "uaddr" are malloc'd - * and returned. The SIGALRM processing is modified only if - * needed to deal with TCP connections. - * - * NOTE: This code has had the crap beaten out it in order to convert - * it from TI-RPC back to TD-RPC for use on FreeBSD. - * - * $FreeBSD: src/lib/libc/rpc/auth_time.c,v 1.4 2000/01/27 23:06:35 jasone Exp $ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#undef NIS -#include - -/* - * FreeBSD currently uses RPC 4.0, which uses portmap rather than - * rpcbind. Consequently, we need to fake up these values here. - * Luckily, the RPCB_GETTIME procedure uses only base XDR data types - * so we don't need anything besides these magic numbers. - */ -#define RPCBPROG (u_long)100000 -#define RPCBVERS (u_long)3 -#define RPCBPROC_GETTIME (u_long)6 - -#ifdef TESTING -#define msg(x) printf("ERROR: %s\n", x) -/* #define msg(x) syslog(LOG_ERR, "%s", x) */ -#else -#define msg(x) -#endif - -static int saw_alarm = 0; - -static void -alarm_hndler(s) - int s; -{ - saw_alarm = 1; - return; -} - -/* - * The internet time server defines the epoch to be Jan 1, 1900 - * whereas UNIX defines it to be Jan 1, 1970. To adjust the result - * from internet time-service time, into UNIX time we subtract the - * following offset : - */ -#define NYEARS (1970 - 1900) -#define TOFFSET ((u_long)60*60*24*(365*NYEARS + (NYEARS/4))) - - -/* - * Stolen from rpc.nisd: - * Turn a 'universal address' into a struct sockaddr_in. - * Bletch. - */ -static int uaddr_to_sockaddr(uaddr, sin) -#ifdef foo - endpoint *endpt; -#endif - char *uaddr; - struct sockaddr_in *sin; -{ - unsigned char p_bytes[2]; - int i; - unsigned long a[6]; - - i = sscanf(uaddr, "%lu.%lu.%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], - &a[3], &a[4], &a[5]); - - if (i < 6) - return(1); - - for (i = 0; i < 4; i++) - sin->sin_addr.s_addr |= (a[i] & 0x000000FF) << (8 * i); - - p_bytes[0] = (unsigned char)a[4] & 0x000000FF; - p_bytes[1] = (unsigned char)a[5] & 0x000000FF; - - sin->sin_family = AF_INET; /* always */ - bcopy((char *)&p_bytes, (char *)&sin->sin_port, 2); - - return (0); -} - -/* - * free_eps() - * - * Free the strings that were strduped into the eps structure. - */ -static void -free_eps(eps, num) - endpoint eps[]; - int num; -{ - int i; - - for (i = 0; i < num; i++) { - free(eps[i].uaddr); - free(eps[i].proto); - free(eps[i].family); - } - return; -} - -/* - * get_server() - * - * This function constructs a nis_server structure description for the - * indicated hostname. - * - * NOTE: There is a chance we may end up recursing here due to the - * fact that gethostbyname() could do an NIS search. Ideally, the - * NIS+ server will call __rpc_get_time_offset() with the nis_server - * structure already populated. - */ -static nis_server * -get_server(sin, host, srv, eps, maxep) - struct sockaddr_in *sin; - char *host; /* name of the time host */ - nis_server *srv; /* nis_server struct to use. */ - endpoint eps[]; /* array of endpoints */ - int maxep; /* max array size */ -{ - char hname[256]; - int num_ep = 0, i; - struct hostent *he; - struct hostent dummy; - char *ptr[2]; - - if (host == NULL && sin == NULL) - return (NULL); - - if (sin == NULL) { - he = gethostbyname(host); - if (he == NULL) - return(NULL); - } else { - he = &dummy; - ptr[0] = (char *)&sin->sin_addr.s_addr; - ptr[1] = NULL; - dummy.h_addr_list = ptr; - } - - /* - * This is lame. We go around once for TCP, then again - * for UDP. - */ - for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep); - i++, num_ep++) { - struct in_addr *a; - - a = (struct in_addr *)he->h_addr_list[i]; - snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a)); - eps[num_ep].uaddr = strdup(hname); - eps[num_ep].family = strdup("inet"); - eps[num_ep].proto = strdup("tcp"); - } - - for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep); - i++, num_ep++) { - struct in_addr *a; - - a = (struct in_addr *)he->h_addr_list[i]; - snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a)); - eps[num_ep].uaddr = strdup(hname); - eps[num_ep].family = strdup("inet"); - eps[num_ep].proto = strdup("udp"); - } - - srv->name = (nis_name) host; - srv->ep.ep_len = num_ep; - srv->ep.ep_val = eps; - srv->key_type = NIS_PK_NONE; - srv->pkey.n_bytes = NULL; - srv->pkey.n_len = 0; - return (srv); -} - -/* - * __rpc_get_time_offset() - * - * This function uses a nis_server structure to contact the a remote - * machine (as named in that structure) and returns the offset in time - * between that machine and this one. This offset is returned in seconds - * and may be positive or negative. - * - * The first time through, a lot of fiddling is done with the netconfig - * stuff to find a suitable transport. The function is very aggressive - * about choosing UDP or at worst TCP if it can. This is because - * those transports support both the RCPBIND call and the internet - * time service. - * - * Once through, *uaddr is set to the universal address of - * the machine and *netid is set to the local netid for the transport - * that uaddr goes with. On the second call, the netconfig stuff - * is skipped and the uaddr/netid pair are used to fetch the netconfig - * structure and to then contact the machine for the time. - * - * td = "server" - "client" - */ -int -__rpc_get_time_offset(td, srv, thost, uaddr, netid) - struct timeval *td; /* Time difference */ - nis_server *srv; /* NIS Server description */ - char *thost; /* if no server, this is the timehost */ - char **uaddr; /* known universal address */ - struct sockaddr_in *netid; /* known network identifier */ -{ - CLIENT *clnt; /* Client handle */ - endpoint *ep, /* useful endpoints */ - *useep = NULL; /* endpoint of xp */ - char *useua = NULL; /* uaddr of selected xp */ - int epl, i; /* counters */ - enum clnt_stat status; /* result of clnt_call */ - u_long thetime, delta; - int needfree = 0; - struct timeval tv; - int time_valid; - int udp_ep = -1, tcp_ep = -1; - int a1, a2, a3, a4; - char ut[64], ipuaddr[64]; - endpoint teps[32]; - nis_server tsrv; - void (*oldsig)() = NULL; /* old alarm handler */ - struct sockaddr_in sin; - int s = RPC_ANYSOCK, len; - int type = 0; - - td->tv_sec = 0; - td->tv_usec = 0; - - /* - * First check to see if we need to find and address for this - * server. - */ - if (*uaddr == NULL) { - if ((srv != NULL) && (thost != NULL)) { - msg("both timehost and srv pointer used!"); - return (0); - } - if (! srv) { - srv = get_server(netid, thost, &tsrv, teps, 32); - if (srv == NULL) { - msg("unable to contruct server data."); - return (0); - } - needfree = 1; /* need to free data in endpoints */ - } - - ep = srv->ep.ep_val; - epl = srv->ep.ep_len; - - /* Identify the TCP and UDP endpoints */ - for (i = 0; - (i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) { - if (strcasecmp(ep[i].proto, "udp") == 0) - udp_ep = i; - if (strcasecmp(ep[i].proto, "tcp") == 0) - tcp_ep = i; - } - - /* Check to see if it is UDP or TCP */ - if (tcp_ep > -1) { - useep = &ep[tcp_ep]; - useua = ep[tcp_ep].uaddr; - type = SOCK_STREAM; - } else if (udp_ep > -1) { - useep = &ep[udp_ep]; - useua = ep[udp_ep].uaddr; - type = SOCK_DGRAM; - } - - if (useep == NULL) { - msg("no acceptable transport endpoints."); - if (needfree) - free_eps(teps, tsrv.ep.ep_len); - return (0); - } - } - - /* - * Create a sockaddr from the uaddr. - */ - if (*uaddr != NULL) - useua = *uaddr; - - /* Fixup test for NIS+ */ - sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4); - sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4); - useua = &ipuaddr[0]; - - bzero((char *)&sin, sizeof(sin)); - if (uaddr_to_sockaddr(useua, &sin)) { - msg("unable to translate uaddr to sockaddr."); - if (needfree) - free_eps(teps, tsrv.ep.ep_len); - return (0); - } - - /* - * Create the client handle to rpcbind. Note we always try - * version 3 since that is the earliest version that supports - * the RPCB_GETTIME call. Also it is the version that comes - * standard with SVR4. Since most everyone supports TCP/IP - * we could consider trying the rtime call first. - */ - clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0); - if (clnt == NULL) { - msg("unable to create client handle to rpcbind."); - if (needfree) - free_eps(teps, tsrv.ep.ep_len); - return (0); - } - - tv.tv_sec = 5; - tv.tv_usec = 0; - time_valid = 0; - status = clnt_call(clnt, RPCBPROC_GETTIME, xdr_void, NULL, - xdr_u_long, (char *)&thetime, tv); - /* - * The only error we check for is anything but success. In - * fact we could have seen PROGMISMATCH if talking to a 4.1 - * machine (pmap v2) or TIMEDOUT if the net was busy. - */ - if (status == RPC_SUCCESS) - time_valid = 1; - else { - int save; - - /* Blow away possible stale CLNT handle. */ - if (clnt != NULL) { - clnt_destroy(clnt); - clnt = NULL; - } - - /* - * Convert PMAP address into timeservice address - * We take advantage of the fact that we "know" what - * the universal address looks like for inet transports. - * - * We also know that the internet timeservice is always - * listening on port 37. - */ - sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4); - sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4); - - if (uaddr_to_sockaddr(ut, &sin)) { - msg("cannot convert timeservice uaddr to sockaddr."); - goto error; - } - - s = socket(AF_INET, type, 0); - if (s == -1) { - msg("unable to open fd to network."); - goto error; - } - - /* - * Now depending on whether or not we're talking to - * UDP we set a timeout or not. - */ - if (type == SOCK_DGRAM) { - struct timeval timeout = { 20, 0 }; - struct sockaddr_in from; - fd_set readfds; - int res; - - if (sendto(s, &thetime, sizeof(thetime), 0, - (struct sockaddr *)&sin, sizeof(sin)) == -1) { - msg("udp : sendto failed."); - goto error; - } - do { - FD_ZERO(&readfds); - FD_SET(s, &readfds); - res = select(_rpc_dtablesize(), &readfds, - (fd_set *)NULL, (fd_set *)NULL, &timeout); - } while (res < 0 && errno == EINTR); - if (res <= 0) - goto error; - len = sizeof(from); - res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0, - (struct sockaddr *)&from, &len); - if (res == -1) { - msg("recvfrom failed on udp transport."); - goto error; - } - time_valid = 1; - } else { - int res; - - oldsig = (void (*)())signal(SIGALRM, alarm_hndler); - saw_alarm = 0; /* global tracking the alarm */ - alarm(20); /* only wait 20 seconds */ - res = connect(s, (struct sockaddr *)&sin, sizeof(sin)); - if (res == -1) { - msg("failed to connect to tcp endpoint."); - goto error; - } - if (saw_alarm) { - msg("alarm caught it, must be unreachable."); - goto error; - } - res = _RPC_read(s, (char *)&thetime, sizeof(thetime)); - if (res != sizeof(thetime)) { - if (saw_alarm) - msg("timed out TCP call."); - else - msg("wrong size of results returned"); - - goto error; - } - time_valid = 1; - } - save = errno; - (void)_RPC_close(s); - errno = save; - s = RPC_ANYSOCK; - - if (time_valid) { - thetime = ntohl(thetime); - thetime = thetime - TOFFSET; /* adjust to UNIX time */ - } else - thetime = 0; - } - - gettimeofday(&tv, 0); - -error: - /* - * clean up our allocated data structures. - */ - - if (s != RPC_ANYSOCK) - (void)_RPC_close(s); - - if (clnt != NULL) - clnt_destroy(clnt); - - alarm(0); /* reset that alarm if its outstanding */ - if (oldsig) { - signal(SIGALRM, oldsig); - } - - /* - * note, don't free uaddr strings until after we've made a - * copy of them. - */ - if (time_valid) { - if (*uaddr == NULL) - *uaddr = strdup(useua); - - /* Round to the nearest second */ - tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0; - delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec : - tv.tv_sec - thetime; - td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta; - td->tv_usec = 0; - } else { - msg("unable to get the server's time."); - } - - if (needfree) - free_eps(teps, tsrv.ep.ep_len); - - return (time_valid); -} diff --git a/c/src/librpc/src/rpc/auth_unix.c b/c/src/librpc/src/rpc/auth_unix.c deleted file mode 100644 index 885c92a206..0000000000 --- a/c/src/librpc/src/rpc/auth_unix.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/auth_unix.c,v 1.12 1999/12/29 05:04:16 peter Exp $"; -#endif - -/* - * auth_unix.c, Implements UNIX style authentication parameters. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * The system is very weak. The client uses no encryption for it's - * credentials and only sends null verifiers. The server sends backs - * null verifiers or optionally a verifier that suggests a new short hand - * for the credentials. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * Unix authenticator operations vector - */ -static void authunix_nextverf(); -static bool_t authunix_marshal(); -static bool_t authunix_validate(); -static bool_t authunix_refresh(); -static void authunix_destroy(); - -static struct auth_ops auth_unix_ops = { - authunix_nextverf, - authunix_marshal, - authunix_validate, - authunix_refresh, - authunix_destroy -}; - -/* - * This struct is pointed to by the ah_private field of an auth_handle. - */ -struct audata { - struct opaque_auth au_origcred; /* original credentials */ - struct opaque_auth au_shcred; /* short hand cred */ - u_long au_shfaults; /* short hand cache faults */ - char au_marshed[MAX_AUTH_BYTES]; - u_int au_mpos; /* xdr pos at end of marshed */ -}; -#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) - -static void marshal_new_auth(); - -/* - * This goop is here because some servers refuse to accept a - * credential with more than some number (usually 8) supplementary - * groups. Blargh! - */ -static int authunix_maxgrouplist = 0; - -void -set_rpc_maxgrouplist(int num) -{ - authunix_maxgrouplist = num; -} - -/* - * Create a unix style authenticator. - * Returns an auth handle with the given stuff in it. - */ -AUTH * -authunix_create(machname, uid, gid, len, aup_gids) - char *machname; - int uid; - int gid; - register int len; - int *aup_gids; -{ - struct authunix_parms aup; - char mymem[MAX_AUTH_BYTES]; - struct timeval now; - XDR xdrs; - register AUTH *auth; - register struct audata *au; - - /* - * Allocate and set up auth handle - */ - auth = (AUTH *)mem_alloc(sizeof(*auth)); -#ifndef _KERNEL - if (auth == NULL) { - (void)fprintf(stderr, "authunix_create: out of memory\n"); - return (NULL); - } -#endif - au = (struct audata *)mem_alloc(sizeof(*au)); -#ifndef _KERNEL - if (au == NULL) { - (void)fprintf(stderr, "authunix_create: out of memory\n"); - return (NULL); - } -#endif - auth->ah_ops = &auth_unix_ops; - auth->ah_private = (caddr_t)au; - auth->ah_verf = au->au_shcred = _null_auth; - au->au_shfaults = 0; - - /* - * fill in param struct from the given params - */ - (void)gettimeofday(&now, (struct timezone *)0); - aup.aup_time = now.tv_sec; - aup.aup_machname = machname; - aup.aup_uid = uid; - aup.aup_gid = gid; - /* GW: continuation of max group list hack */ - if(authunix_maxgrouplist != 0) { - aup.aup_len = ((len < authunix_maxgrouplist) ? len - : authunix_maxgrouplist); - } else { - aup.aup_len = (u_int)len; - } - aup.aup_gids = aup_gids; - - /* - * Serialize the parameters into origcred - */ - xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); - if (! xdr_authunix_parms(&xdrs, &aup)) - abort(); - au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); - au->au_origcred.oa_flavor = AUTH_UNIX; -#ifdef _KERNEL - au->au_origcred.oa_base = mem_alloc((u_int) len); -#else - if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { - (void)fprintf(stderr, "authunix_create: out of memory\n"); - return (NULL); - } -#endif - memcpy(au->au_origcred.oa_base, mymem, (u_int)len); - - /* - * set auth handle to reflect new cred. - */ - auth->ah_cred = au->au_origcred; - marshal_new_auth(auth); - return (auth); -} - -/* - * Returns an auth handle with parameters determined by doing lots of - * syscalls. - */ -AUTH * -authunix_create_default() -{ - register int len; - char machname[MAX_MACHINE_NAME + 1]; - register int uid; - register int gid; - int gids[NGRPS]; - int i; - gid_t real_gids[NGROUPS]; - - if (gethostname(machname, MAX_MACHINE_NAME) == -1) - abort(); - machname[MAX_MACHINE_NAME] = 0; - uid = (int)geteuid(); - gid = (int)getegid(); - if ((len = getgroups(NGROUPS, real_gids)) < 0) - abort(); - if(len > NGRPS) len = NGRPS; /* GW: turn `gid_t's into `int's */ - for(i = 0; i < len; i++) { - gids[i] = (int)real_gids[i]; - } - return (authunix_create(machname, uid, gid, len, gids)); -} - -/* - * authunix operations - */ - -static void -authunix_nextverf(auth) - AUTH *auth; -{ - /* no action necessary */ -} - -static bool_t -authunix_marshal(auth, xdrs) - AUTH *auth; - XDR *xdrs; -{ - register struct audata *au = AUTH_PRIVATE(auth); - - return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); -} - -static bool_t -authunix_validate(auth, verf) - register AUTH *auth; - struct opaque_auth verf; -{ - register struct audata *au; - XDR xdrs; - - if (verf.oa_flavor == AUTH_SHORT) { - au = AUTH_PRIVATE(auth); - xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE); - - if (au->au_shcred.oa_base != NULL) { - mem_free(au->au_shcred.oa_base, - au->au_shcred.oa_length); - au->au_shcred.oa_base = NULL; - } - if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { - auth->ah_cred = au->au_shcred; - } else { - xdrs.x_op = XDR_FREE; - (void)xdr_opaque_auth(&xdrs, &au->au_shcred); - au->au_shcred.oa_base = NULL; - auth->ah_cred = au->au_origcred; - } - marshal_new_auth(auth); - } - return (TRUE); -} - -static bool_t -authunix_refresh(auth) - register AUTH *auth; -{ - register struct audata *au = AUTH_PRIVATE(auth); - struct authunix_parms aup; - struct timeval now; - XDR xdrs; - register int stat; - - if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { - /* there is no hope. Punt */ - return (FALSE); - } - au->au_shfaults ++; - - /* first deserialize the creds back into a struct authunix_parms */ - aup.aup_machname = NULL; - aup.aup_gids = (int *)NULL; - xdrmem_create(&xdrs, au->au_origcred.oa_base, - au->au_origcred.oa_length, XDR_DECODE); - stat = xdr_authunix_parms(&xdrs, &aup); - if (! stat) - goto done; - - /* update the time and serialize in place */ - (void)gettimeofday(&now, (struct timezone *)0); - aup.aup_time = now.tv_sec; - xdrs.x_op = XDR_ENCODE; - XDR_SETPOS(&xdrs, 0); - stat = xdr_authunix_parms(&xdrs, &aup); - if (! stat) - goto done; - auth->ah_cred = au->au_origcred; - marshal_new_auth(auth); -done: - /* free the struct authunix_parms created by deserializing */ - xdrs.x_op = XDR_FREE; - (void)xdr_authunix_parms(&xdrs, &aup); - XDR_DESTROY(&xdrs); - return (stat); -} - -static void -authunix_destroy(auth) - register AUTH *auth; -{ - register struct audata *au = AUTH_PRIVATE(auth); - - mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); - - if (au->au_shcred.oa_base != NULL) - mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); - - mem_free(auth->ah_private, sizeof(struct audata)); - - if (auth->ah_verf.oa_base != NULL) - mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); - - mem_free((caddr_t)auth, sizeof(*auth)); -} - -/* - * Marshals (pre-serializes) an auth struct. - * sets private data, au_marshed and au_mpos - */ -static void -marshal_new_auth(auth) - register AUTH *auth; -{ - XDR xdr_stream; - register XDR *xdrs = &xdr_stream; - register struct audata *au = AUTH_PRIVATE(auth); - - xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); - if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || - (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { - perror("auth_none.c - Fatal marshalling problem"); - } else { - au->au_mpos = XDR_GETPOS(xdrs); - } - XDR_DESTROY(xdrs); -} diff --git a/c/src/librpc/src/rpc/authdes_prot.c b/c/src/librpc/src/rpc/authdes_prot.c deleted file mode 100644 index 14679c00a9..0000000000 --- a/c/src/librpc/src/rpc/authdes_prot.c +++ /dev/null @@ -1,82 +0,0 @@ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88/02/08 SMI"; -#endif -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1988 by Sun Microsystems, Inc. - */ - -/* - * authdes_prot.c, XDR routines for DES authentication - */ - -#include -#include -#include -#include - -#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) - -bool_t -xdr_authdes_cred(xdrs, cred) - XDR *xdrs; - struct authdes_cred *cred; -{ - /* - * Unrolled xdr - */ - ATTEMPT(xdr_enum(xdrs, (enum_t *)&cred->adc_namekind)); - switch (cred->adc_namekind) { - case ADN_FULLNAME: - ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name, MAXNETNAMELEN)); - ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key, sizeof(des_block))); - ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window, sizeof(cred->adc_fullname.window))); - return (TRUE); - case ADN_NICKNAME: - ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname, sizeof(cred->adc_nickname))); - return (TRUE); - default: - return (FALSE); - } -} - - -bool_t -xdr_authdes_verf(xdrs, verf) - register XDR *xdrs; - register struct authdes_verf *verf; -{ - /* - * Unrolled xdr - */ - ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp, sizeof(des_block))); - ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u, sizeof(verf->adv_int_u))); - return (TRUE); -} diff --git a/c/src/librpc/src/rpc/authunix_prot.c b/c/src/librpc/src/rpc/authunix_prot.c deleted file mode 100644 index 022fac0686..0000000000 --- a/c/src/librpc/src/rpc/authunix_prot.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/authunix_prot.c,v 1.6 1999/08/28 00:00:33 peter Exp $"; -#endif - -/* - * authunix_prot.c - * XDR for UNIX style authentication parameters for RPC - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - - -#include -#include -#include -#include - -/* - * XDR for unix authentication parameters. - */ -bool_t -xdr_authunix_parms(xdrs, p) - register XDR *xdrs; - register struct authunix_parms *p; -{ - - if (xdr_u_long(xdrs, &(p->aup_time)) - && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) - && xdr_int(xdrs, &(p->aup_uid)) - && xdr_int(xdrs, &(p->aup_gid)) - && xdr_array(xdrs, (caddr_t *)&(p->aup_gids), - &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) { - return (TRUE); - } - return (FALSE); -} - diff --git a/c/src/librpc/src/rpc/bindresvport.3 b/c/src/librpc/src/rpc/bindresvport.3 deleted file mode 100644 index 02a079decc..0000000000 --- a/c/src/librpc/src/rpc/bindresvport.3 +++ /dev/null @@ -1,106 +0,0 @@ -.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI -.\" $FreeBSD: src/lib/libc/rpc/bindresvport.3,v 1.10 2000/01/27 02:55:01 bde Exp $ -.\" -.Dd January 27, 2000 -.Dt BINDRESVPORT 3 -.Os -.Sh NAME -.Nm bindresvport , -.Nm bindresvport_sa -.Ndbind a socket to a privileged IP port -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn bindresvport "int sd" "struct sockaddr_in *sin" -.Ft int -.Fn bindresvport_sa "int sd" "struct sockaddr *sa" -.Sh DESCRIPTION -.Fn bindresvport -and -.Fn bindresvport_sa -are used to bind a socket descriptor to a privileged -.Tn IP -port, that is, a -port number in the range 0-1023. -.Pp -Only root can bind to a privileged port; this call will fail for any -other users. -.Pp -When -.Va sin -is not null, -.Va sin->sin_family -must be initialized to the address family of the socket, passed by -.Va sd . -If the value of sin->sin_port is non-zero -.Fn bindresvport -will attempt to use that specific port. If it fails, it chooses another -privileged port automatically. -.Pp -It is legal to pass null pointer to -.Va sin . -In this case, the caller cannot get the port number -.Fn bindresvport -has picked. -.Pp -Function prototype of -.Fn bindresvport -is biased to -.Dv AF_INET -socket. -.Fn bindresvport_sa -acts exactly the same, with more neutral function prototype. -Note that both functions behave exactly the same, and -both support -.Dv AF_INET6 -sockets as well as -.Dv AF_INET -sockets. -.Sh RETURN VALUES -.Fn bindresvport -and -.Fn bindresvport_sa -return 0 if they are successful, otherwise \-1 is returned and -.Va errno -set to reflect the cause of the error. -.Sh ERRORS -The -.Fn bindresvport -and -.Fn bindresvport_sa -functions fail if: -.Bl -tag -width Er -.It Bq Er EBADF -.Fa sd -is not a valid descriptor. -.It Bq Er ENOTSOCK -.Fa sd -is not a socket. -.It Bq Er EADDRNOTAVAIL -The specified address is not available from the local machine. -.It Bq Er EADDRINUSE -The specified address is already in use. -.It Bq Er EINVAL -The socket is already bound to an address, -or the socket family and the family of specified address mismatch. -.It Bq Er EACCES -The requested address is protected, and the current user -has inadequate permission to access it. -.It Bq Er EFAULT -The -.Fa name -parameter is not in a valid part of the user -address space. -.It Bq Er ENOBUFS -Insufficient resources were available in the system -to perform the operation. -.It Bq Er EPFNOSUPPORT -The protocol family has not been configured into the -system, no implementation for it exists, -or address family did not match between arguments. -.El -.Sh "SEE ALSO" -.Xr bind 2 , -.Xr socket 2 , -.Xr rresvport 3 , -.Xr rresvport_af 3 diff --git a/c/src/librpc/src/rpc/bindresvport.c b/c/src/librpc/src/rpc/bindresvport.c deleted file mode 100644 index bb97570b88..0000000000 --- a/c/src/librpc/src/rpc/bindresvport.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/ -/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/ -/*from: OpenBSD: bindresvport.c,v 1.7 1996/07/30 16:25:47 downsj Exp */ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/bindresvport.c,v 1.12 2000/01/26 09:02:42 shin Exp $"; -#endif - -/* - * Copyright (c) 1987 by Sun Microsystems, Inc. - * - * Portions Copyright(C) 1996, Jason Downs. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include - -/* - * Bind a socket to a privileged port for whatever protocol. - */ -int -bindresvport_sa(sd, sa) - int sd; - struct sockaddr *sa; -{ - int old, error, af; - struct sockaddr myaddr; - struct sockaddr_in *sin; -#if (defined(AF_INET6) && defined(IPPROTO_IPV6)) - struct sockaddr_in6 *sin6; -#endif - int proto, portrange, portlow; - u_int16_t port; - int salen; - - if (sa == NULL) { - salen = sizeof(myaddr); - sa = (struct sockaddr *)&myaddr; - - if (getsockname(sd, sa, &salen) == -1) - return -1; /* errno is correctly set */ - - af = sa->sa_family; - memset(&myaddr, 0, salen); - } else - af = sa->sa_family; - - if (af == AF_INET) { - proto = IPPROTO_IP; - portrange = IP_PORTRANGE; - portlow = IP_PORTRANGE_LOW; - sin = (struct sockaddr_in *)sa; - salen = sizeof(struct sockaddr_in); - port = sin->sin_port; -#if (defined(AF_INET6) && defined(IPPROTO_IPV6)) - } else if (af == AF_INET6) { - proto = IPPROTO_IPV6; - portrange = IPV6_PORTRANGE; - portlow = IPV6_PORTRANGE_LOW; - sin6 = (struct sockaddr_in6 *)sa; - salen = sizeof(struct sockaddr_in6); - port = sin6->sin6_port; -#endif - } else { - errno = EPFNOSUPPORT; - return (-1); - } - sa->sa_family = af; - sa->sa_len = salen; - - if (port == 0) { - int oldlen = sizeof(old); - - error = getsockopt(sd, proto, portrange, &old, &oldlen); - if (error < 0) - return (error); - - error = setsockopt(sd, proto, portrange, &portlow, - sizeof(portlow)); - if (error < 0) - return (error); - } - - error = bind(sd, sa, salen); - - if (port == 0) { - int saved_errno = errno; - - if (error) { - if (setsockopt(sd, proto, portrange, &old, - sizeof(old)) < 0) - errno = saved_errno; - return (error); - } - - if (sa != (struct sockaddr *)&myaddr) { - /* Hmm, what did the kernel assign... */ - if (getsockname(sd, sa, &salen) < 0) - errno = saved_errno; - return (error); - } - } - return (error); -} - -/* - * Bind a socket to a privileged IP port - */ -int -bindresvport(sd, sin) - int sd; - struct sockaddr_in *sin; -{ - return bindresvport_sa(sd, (struct sockaddr *)sin); -} diff --git a/c/src/librpc/src/rpc/clnt_generic.c b/c/src/librpc/src/rpc/clnt_generic.c deleted file mode 100644 index d387fae4c0..0000000000 --- a/c/src/librpc/src/rpc/clnt_generic.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/ -/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_generic.c,v 1.9 1999/08/28 00:00:35 peter Exp $"; -#endif - -/* - * Copyright (C) 1987, Sun Microsystems, Inc. - */ -#include -#include -#include -#include -#include - -/* - * Generic client creation: takes (hostname, program-number, protocol) and - * returns client handle. Default options are set, which the user can - * change using the rpc equivalent of ioctl()'s. - */ -CLIENT * -clnt_create(hostname, prog, vers, proto) - char *hostname; - u_long prog; - u_long vers; - char *proto; -{ - struct hostent *h; - struct protoent *p; - struct sockaddr_in sin; -#ifndef __rtems__ - struct sockaddr_un sun; -#endif - int sock; - struct timeval tv; - CLIENT *client; - -#ifndef __rtems__ - if (!strcmp(proto, "unix")) { - bzero((char *)&sun, sizeof(sun)); - sun.sun_family = AF_UNIX; - strcpy(sun.sun_path, hostname); - sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) + - strlen(sun.sun_path) + 1; - sock = RPC_ANYSOCK; - client = clntunix_create(&sun, prog, vers, &sock, 0, 0); - if (client == NULL) - return(NULL); - tv.tv_sec = 25; - tv.tv_usec = 0; - clnt_control(client, CLSET_TIMEOUT, &tv); - return(client); - } -#endif - - h = gethostbyname(hostname); - if (h == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNHOST; - return (NULL); - } - if (h->h_addrtype != AF_INET) { - /* - * Only support INET for now - */ - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; - return (NULL); - } - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_family = h->h_addrtype; - sin.sin_port = 0; - memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length); - p = getprotobyname(proto); - if (p == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; - return (NULL); - } - sock = RPC_ANYSOCK; - switch (p->p_proto) { - case IPPROTO_UDP: - tv.tv_sec = 5; - tv.tv_usec = 0; - client = clntudp_create(&sin, prog, vers, tv, &sock); - if (client == NULL) { - return (NULL); - } -#if 0 /* XXX do we need this? */ - tv.tv_sec = 25; - tv.tv_usec = 0; - clnt_control(client, CLSET_TIMEOUT, &tv); -#endif - break; - case IPPROTO_TCP: - client = clnttcp_create(&sin, prog, vers, &sock, 0, 0); - if (client == NULL) { - return (NULL); - } -#if 0 /* XXX do we need this? */ - tv.tv_sec = 25; - tv.tv_usec = 0; - clnt_control(client, CLSET_TIMEOUT, &tv); -#endif - break; - default: - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; - return (NULL); - } - return (client); -} diff --git a/c/src/librpc/src/rpc/clnt_perror.c b/c/src/librpc/src/rpc/clnt_perror.c deleted file mode 100644 index 720583ba54..0000000000 --- a/c/src/librpc/src/rpc/clnt_perror.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_perror.c,v 1.11 1999/08/28 00:00:35 peter Exp $"; -#endif - -/* - * clnt_perror.c - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - */ -#include -#include -#include -#include -#include -#include -#include - -static char *auth_errmsg(); -#define CLNT_PERROR_BUFLEN 256 - -#define buf ((char *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->clnt_perror_buf) - -static char * -_buf() -{ - - if (buf == 0) - buf = (char *)malloc(CLNT_PERROR_BUFLEN); - return (buf); -} - -/* - * Print reply error info - */ -char * -clnt_sperror(rpch, s) - CLIENT *rpch; - char *s; -{ - struct rpc_err e; - char *err; - char *str = _buf(); - char *strstart = str; - - if (str == 0) - return (0); - CLNT_GETERR(rpch, &e); - - (void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status)); - str += strlen(str); - - switch (e.re_status) { - case RPC_SUCCESS: - case RPC_CANTENCODEARGS: - case RPC_CANTDECODERES: - case RPC_TIMEDOUT: - case RPC_PROGUNAVAIL: - case RPC_PROCUNAVAIL: - case RPC_CANTDECODEARGS: - case RPC_SYSTEMERROR: - case RPC_UNKNOWNHOST: - case RPC_UNKNOWNPROTO: - case RPC_PMAPFAILURE: - case RPC_PROGNOTREGISTERED: - case RPC_FAILED: - break; - - case RPC_CANTSEND: - case RPC_CANTRECV: - (void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart), - "; errno = %s\n", strerror(e.re_errno)); - break; - - case RPC_VERSMISMATCH: - (void) sprintf(str, - "; low version = %lu, high version = %lu\n", - (u_long)e.re_vers.low, (u_long)e.re_vers.high); - break; - - case RPC_AUTHERROR: - err = auth_errmsg(e.re_why); - (void) sprintf(str,"; why = "); - str += strlen(str); - if (err != NULL) { - (void) sprintf(str, "%s\n",err); - } else { - (void) sprintf(str, - "(unknown authentication error - %d)\n", - (int) e.re_why); - } - break; - - case RPC_PROGVERSMISMATCH: - (void) sprintf(str, - "; low version = %lu, high version = %lu\n", - (u_long)e.re_vers.low, (u_long)e.re_vers.high); - break; - - default: /* unknown */ - (void) sprintf(str, - "; s1 = %lu, s2 = %lu\n", - (long)e.re_lb.s1, (long)e.re_lb.s2); - break; - } - strstart[CLNT_PERROR_BUFLEN-2] = '\n'; - strstart[CLNT_PERROR_BUFLEN-1] = '\0'; - return(strstart) ; -} - -void -clnt_perror(rpch, s) - CLIENT *rpch; - char *s; -{ - (void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s)); -} - - -static const char *const rpc_errlist[] = { - "RPC: Success", /* 0 - RPC_SUCCESS */ - "RPC: Can't encode arguments", /* 1 - RPC_CANTENCODEARGS */ - "RPC: Can't decode result", /* 2 - RPC_CANTDECODERES */ - "RPC: Unable to send", /* 3 - RPC_CANTSEND */ - "RPC: Unable to receive", /* 4 - RPC_CANTRECV */ - "RPC: Timed out", /* 5 - RPC_TIMEDOUT */ - "RPC: Incompatible versions of RPC", /* 6 - RPC_VERSMISMATCH */ - "RPC: Authentication error", /* 7 - RPC_AUTHERROR */ - "RPC: Program unavailable", /* 8 - RPC_PROGUNAVAIL */ - "RPC: Program/version mismatch", /* 9 - RPC_PROGVERSMISMATCH */ - "RPC: Procedure unavailable", /* 10 - RPC_PROCUNAVAIL */ - "RPC: Server can't decode arguments", /* 11 - RPC_CANTDECODEARGS */ - "RPC: Remote system error", /* 12 - RPC_SYSTEMERROR */ - "RPC: Unknown host", /* 13 - RPC_UNKNOWNHOST */ - "RPC: Port mapper failure", /* 14 - RPC_PMAPFAILURE */ - "RPC: Program not registered", /* 15 - RPC_PROGNOTREGISTERED */ - "RPC: Failed (unspecified error)", /* 16 - RPC_FAILED */ - "RPC: Unknown protocol" /* 17 - RPC_UNKNOWNPROTO */ -}; - - -/* - * This interface for use by clntrpc - */ -char * -clnt_sperrno(stat) - enum clnt_stat stat; -{ - unsigned int errnum = stat; - - if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) - return (char *)rpc_errlist[errnum]; - - return ("RPC: (unknown error code)"); -} - -void -clnt_perrno(num) - enum clnt_stat num; -{ - (void) fprintf(stderr,"%s\n",clnt_sperrno(num)); -} - - -char * -clnt_spcreateerror(s) - char *s; -{ - char *str = _buf(); - - if (str == 0) - return(0); - switch (rpc_createerr.cf_stat) { - case RPC_PMAPFAILURE: - (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s, - clnt_sperrno(rpc_createerr.cf_stat), - clnt_sperrno(rpc_createerr.cf_error.re_status)); - break; - - case RPC_SYSTEMERROR: - (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s, - clnt_sperrno(rpc_createerr.cf_stat), - strerror(rpc_createerr.cf_error.re_errno)); - break; - default: - (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s, - clnt_sperrno(rpc_createerr.cf_stat)); - break; - } - str[CLNT_PERROR_BUFLEN-2] = '\n'; - str[CLNT_PERROR_BUFLEN-1] = '\0'; - return (str); -} - -void -clnt_pcreateerror(s) - char *s; -{ - (void) fprintf(stderr,"%s\n",clnt_spcreateerror(s)); -} - -static const char *const auth_errlist[] = { - "Authentication OK", /* 0 - AUTH_OK */ - "Invalid client credential", /* 1 - AUTH_BADCRED */ - "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */ - "Invalid client verifier", /* 3 - AUTH_BADVERF */ - "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */ - "Client credential too weak", /* 5 - AUTH_TOOWEAK */ - "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */ - "Failed (unspecified error)" /* 7 - AUTH_FAILED */ -}; - -static char * -auth_errmsg(stat) - enum auth_stat stat; -{ - unsigned int errnum = stat; - - if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0]))) - return (char *)auth_errlist[errnum]; - - return(NULL); -} diff --git a/c/src/librpc/src/rpc/clnt_raw.c b/c/src/librpc/src/rpc/clnt_raw.c deleted file mode 100644 index a343c49068..0000000000 --- a/c/src/librpc/src/rpc/clnt_raw.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_raw.c,v 1.10 1999/08/28 00:00:36 peter Exp $"; -#endif - -/* - * clnt_raw.c - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * Memory based rpc for simple testing and timing. - * Interface to create an rpc client and server in the same process. - * This lets us similate rpc and get round trip overhead, without - * any interference from the kernal. - */ - -#include -#include -#include - -#define MCALL_MSG_SIZE 24 - -/* - * This is the "network" we will be moving stuff over. - */ -struct clnt_raw_private { - CLIENT client_object; - XDR xdr_stream; - char _raw_buf[UDPMSGSIZE]; - char mashl_callmsg[MCALL_MSG_SIZE]; - u_int mcnt; -}; -#define clntraw_private ((struct clnt_raw_private *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->clnt_raw_private) - -static enum clnt_stat clntraw_call(); -static void clntraw_abort(); -static void clntraw_geterr(); -static bool_t clntraw_freeres(); -static bool_t clntraw_control(); -static void clntraw_destroy(); - -static struct clnt_ops client_ops = { - clntraw_call, - clntraw_abort, - clntraw_geterr, - clntraw_freeres, - clntraw_destroy, - clntraw_control -}; - -void svc_getreq(); - -/* - * Create a client handle for memory based rpc. - */ -CLIENT * -clntraw_create(prog, vers) - u_long prog; - u_long vers; -{ - register struct clnt_raw_private *clp = clntraw_private; - struct rpc_msg call_msg; - XDR *xdrs = &clp->xdr_stream; - CLIENT *client = &clp->client_object; - - if (clp == 0) { - clp = (struct clnt_raw_private *)calloc(1, sizeof (*clp)); - if (clp == 0) - return (0); - clntraw_private = clp; - } - /* - * pre-serialize the static part of the call msg and stash it away - */ - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = prog; - call_msg.rm_call.cb_vers = vers; - xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); - if (! xdr_callhdr(xdrs, &call_msg)) { - perror("clnt_raw.c - Fatal header serialization error."); - } - clp->mcnt = XDR_GETPOS(xdrs); - XDR_DESTROY(xdrs); - - /* - * Set xdrmem for client/server shared buffer - */ - xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); - - /* - * create client handle - */ - client->cl_ops = &client_ops; - client->cl_auth = authnone_create(); - return (client); -} - -static enum clnt_stat -clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) - CLIENT *h; - u_long proc; - xdrproc_t xargs; - caddr_t argsp; - xdrproc_t xresults; - caddr_t resultsp; - struct timeval timeout; -{ - register struct clnt_raw_private *clp = clntraw_private; - register XDR *xdrs = &clp->xdr_stream; - struct rpc_msg msg; - enum clnt_stat status; - struct rpc_err error; - - if (clp == 0) - return (RPC_FAILED); -call_again: - /* - * send request - */ - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, 0); - ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ; - if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) || - (! XDR_PUTLONG(xdrs, (long *)&proc)) || - (! AUTH_MARSHALL(h->cl_auth, xdrs)) || - (! (*xargs)(xdrs, argsp))) { - return (RPC_CANTENCODEARGS); - } - (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ - - /* - * We have to call server input routine here because this is - * all going on in one process. Yuk. - */ - svc_getreq(1); - - /* - * get results - */ - xdrs->x_op = XDR_DECODE; - XDR_SETPOS(xdrs, 0); - msg.acpted_rply.ar_verf = _null_auth; - msg.acpted_rply.ar_results.where = resultsp; - msg.acpted_rply.ar_results.proc = xresults; - if (! xdr_replymsg(xdrs, &msg)) - return (RPC_CANTDECODERES); - _seterr_reply(&msg, &error); - status = error.re_status; - - if (status == RPC_SUCCESS) { - if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { - status = RPC_AUTHERROR; - } - } /* end successful completion */ - else { - if (AUTH_REFRESH(h->cl_auth)) - goto call_again; - } /* end of unsuccessful completion */ - - if (status == RPC_SUCCESS) { - if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { - status = RPC_AUTHERROR; - } - if (msg.acpted_rply.ar_verf.oa_base != NULL) { - xdrs->x_op = XDR_FREE; - (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); - } - } - - return (status); -} - -static void -clntraw_geterr() -{ -} - - -static bool_t -clntraw_freeres(cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - caddr_t res_ptr; -{ - register struct clnt_raw_private *clp = clntraw_private; - register XDR *xdrs = &clp->xdr_stream; - bool_t rval; - - if (clp == 0) - { - rval = (bool_t) RPC_FAILED; - return (rval); - } - xdrs->x_op = XDR_FREE; - return ((*xdr_res)(xdrs, res_ptr)); -} - -static void -clntraw_abort() -{ -} - -static bool_t -clntraw_control() -{ - return (FALSE); -} - -static void -clntraw_destroy() -{ -} diff --git a/c/src/librpc/src/rpc/clnt_simple.c b/c/src/librpc/src/rpc/clnt_simple.c deleted file mode 100644 index cab68fda29..0000000000 --- a/c/src/librpc/src/rpc/clnt_simple.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_simple.c,v 1.12 2000/01/27 23:06:35 jasone Exp $"; -#endif - -/* - * clnt_simple.c - * Simplified front end to rpc. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct call_rpc_private { - CLIENT *client; - int socket; - int oldprognum, oldversnum, valid; - char *oldhost; -}; -#define callrpc_private ((struct call_rpc_private *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->call_rpc_private) - -int -callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) - char *host; - int prognum, versnum, procnum; - xdrproc_t inproc, outproc; - char *in, *out; -{ - register struct call_rpc_private *crp = callrpc_private; - struct sockaddr_in server_addr; - enum clnt_stat clnt_stat; - struct hostent *hp; - struct timeval timeout, tottimeout; - - if (crp == 0) { - crp = (struct call_rpc_private *)calloc(1, sizeof (*crp)); - if (crp == 0) - return (0); - callrpc_private = crp; - } - if (crp->oldhost == NULL) { - crp->oldhost = malloc(MAXHOSTNAMELEN); - crp->oldhost[0] = 0; - crp->socket = RPC_ANYSOCK; - } - if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum - && strcmp(crp->oldhost, host) == 0) { - /* reuse old client */ - } else { - crp->valid = 0; - if (crp->socket != -1) - (void)_RPC_close(crp->socket); - crp->socket = RPC_ANYSOCK; - if (crp->client) { - clnt_destroy(crp->client); - crp->client = NULL; - } - if ((hp = gethostbyname(host)) == NULL) - return ((int) RPC_UNKNOWNHOST); - timeout.tv_usec = 0; - timeout.tv_sec = 5; - memset(&server_addr, 0, sizeof(server_addr)); - memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length); - server_addr.sin_len = sizeof(struct sockaddr_in); - server_addr.sin_family = AF_INET; - server_addr.sin_port = 0; - if ((crp->client = clntudp_create(&server_addr, (u_long)prognum, - (u_long)versnum, timeout, &crp->socket)) == NULL) - return ((int) rpc_createerr.cf_stat); - crp->valid = 1; - crp->oldprognum = prognum; - crp->oldversnum = versnum; - (void) strcpy(crp->oldhost, host); - } - tottimeout.tv_sec = 25; - tottimeout.tv_usec = 0; - clnt_stat = clnt_call(crp->client, procnum, inproc, in, - outproc, out, tottimeout); - /* - * if call failed, empty cache - */ - if (clnt_stat != RPC_SUCCESS) - crp->valid = 0; - return ((int) clnt_stat); -} diff --git a/c/src/librpc/src/rpc/clnt_tcp.c b/c/src/librpc/src/rpc/clnt_tcp.c deleted file mode 100644 index 37c7a69fda..0000000000 --- a/c/src/librpc/src/rpc/clnt_tcp.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_tcp.c,v 1.14 2000/01/27 23:06:36 jasone Exp $"; -#endif - -/* - * clnt_tcp.c, Implements a TCP/IP based, client side RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * TCP based RPC supports 'batched calls'. - * A sequence of calls may be batched-up in a send buffer. The rpc call - * return immediately to the client even though the call was not necessarily - * sent. The batching occurs if the results' xdr routine is NULL (0) AND - * the rpc timeout value is zero (see clnt.h, rpc). - * - * Clients should NOT casually batch calls that in fact return results; that is, - * the server side should be aware that a call is batched and not produce any - * return message. Batched calls that produce many result messages can - * deadlock (netlock) the client and the server.... - * - * Now go hang yourself. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MCALL_MSG_SIZE 24 - -static int readtcp(); -static int writetcp(); - -static enum clnt_stat clnttcp_call(); -static void clnttcp_abort(); -static void clnttcp_geterr(); -static bool_t clnttcp_freeres(); -static bool_t clnttcp_control(); -static void clnttcp_destroy(); - -static struct clnt_ops tcp_ops = { - clnttcp_call, - clnttcp_abort, - clnttcp_geterr, - clnttcp_freeres, - clnttcp_destroy, - clnttcp_control -}; - -struct ct_data { - int ct_sock; - bool_t ct_closeit; - struct timeval ct_wait; - bool_t ct_waitset; /* wait set by clnt_control? */ - struct sockaddr_in ct_addr; - struct rpc_err ct_error; - char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ - u_int ct_mpos; /* pos after marshal */ - XDR ct_xdrs; -}; - -/* - * Create a client handle for a tcp/ip connection. - * If *sockp<0, *sockp is set to a newly created TCP socket and it is - * connected to raddr. If *sockp non-negative then - * raddr is ignored. The rpc/tcp package does buffering - * similar to stdio, so the client must pick send and receive buffer sizes,]; - * 0 => use the default. - * If raddr->sin_port is 0, then a binder on the remote machine is - * consulted for the right port number. - * NB: *sockp is copied into a private area. - * NB: It is the clients responsibility to close *sockp. - * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this - * something more useful. - */ -CLIENT * -clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) - struct sockaddr_in *raddr; - u_long prog; - u_long vers; - register int *sockp; - u_int sendsz; - u_int recvsz; -{ - CLIENT *h; - register struct ct_data *ct = NULL; - struct timeval now; - struct rpc_msg call_msg; - static u_int32_t disrupt; - - if (disrupt == 0) - disrupt = (u_int32_t)(long)raddr; - - h = (CLIENT *)mem_alloc(sizeof(*h)); - if (h == NULL) { - (void)fprintf(stderr, "clnttcp_create: out of memory\n"); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - ct = (struct ct_data *)mem_alloc(sizeof(*ct)); - if (ct == NULL) { - (void)fprintf(stderr, "clnttcp_create: out of memory\n"); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - - /* - * If no port number given ask the pmap for one - */ - if (raddr->sin_port == 0) { - u_short port; - if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) { - mem_free((caddr_t)ct, sizeof(struct ct_data)); - mem_free((caddr_t)h, sizeof(CLIENT)); - return ((CLIENT *)NULL); - } - raddr->sin_port = htons(port); - } - - /* - * If no socket given, open one - */ - if (*sockp < 0) { - *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - (void)bindresvport(*sockp, (struct sockaddr_in *)0); - if ((*sockp < 0) - || (connect(*sockp, (struct sockaddr *)raddr, - sizeof(*raddr)) < 0)) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - if (*sockp != -1) - (void)_RPC_close(*sockp); - goto fooy; - } - ct->ct_closeit = TRUE; - } else { - ct->ct_closeit = FALSE; - } - - /* - * Set up private data struct - */ - ct->ct_sock = *sockp; - ct->ct_wait.tv_usec = 0; - ct->ct_waitset = FALSE; - ct->ct_addr = *raddr; - - /* - * Initialize call message - */ - (void)gettimeofday(&now, (struct timezone *)0); - call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec; - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = prog; - call_msg.rm_call.cb_vers = vers; - - /* - * pre-serialize the static part of the call msg and stash it away - */ - xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, - XDR_ENCODE); - if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { - if (ct->ct_closeit) { - (void)_RPC_close(*sockp); - } - goto fooy; - } - ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); - XDR_DESTROY(&(ct->ct_xdrs)); - - /* - * Create a client handle which uses xdrrec for serialization - * and authnone for authentication. - */ - xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, - (caddr_t)ct, readtcp, writetcp); - h->cl_ops = &tcp_ops; - h->cl_private = (caddr_t) ct; - h->cl_auth = authnone_create(); - return (h); - -fooy: - /* - * Something goofed, free stuff and barf - */ - if (ct) - mem_free((caddr_t)ct, sizeof(struct ct_data)); - if (h) - mem_free((caddr_t)h, sizeof(CLIENT)); - return ((CLIENT *)NULL); -} - -static enum clnt_stat -clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) - register CLIENT *h; - u_long proc; - xdrproc_t xdr_args; - caddr_t args_ptr; - xdrproc_t xdr_results; - caddr_t results_ptr; - struct timeval timeout; -{ - register struct ct_data *ct = (struct ct_data *) h->cl_private; - register XDR *xdrs = &(ct->ct_xdrs); - struct rpc_msg reply_msg; - u_long x_id; - u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */ - register bool_t shipnow; - int refreshes = 2; - - if (!ct->ct_waitset) { - ct->ct_wait = timeout; - } - - shipnow = - (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 - && timeout.tv_usec == 0) ? FALSE : TRUE; - -call_again: - xdrs->x_op = XDR_ENCODE; - ct->ct_error.re_status = RPC_SUCCESS; - x_id = ntohl(--(*msg_x_id)); - if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) || - (! XDR_PUTLONG(xdrs, (long *)&proc)) || - (! AUTH_MARSHALL(h->cl_auth, xdrs)) || - (! (*xdr_args)(xdrs, args_ptr))) { - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTENCODEARGS; - (void)xdrrec_endofrecord(xdrs, TRUE); - return (ct->ct_error.re_status); - } - if (! xdrrec_endofrecord(xdrs, shipnow)) - return (ct->ct_error.re_status = RPC_CANTSEND); - if (! shipnow) - return (RPC_SUCCESS); - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { - return(ct->ct_error.re_status = RPC_TIMEDOUT); - } - - - /* - * Keep receiving until we get a valid transaction id - */ - xdrs->x_op = XDR_DECODE; - while (TRUE) { - reply_msg.acpted_rply.ar_verf = _null_auth; - reply_msg.acpted_rply.ar_results.where = NULL; - reply_msg.acpted_rply.ar_results.proc = xdr_void; - if (! xdrrec_skiprecord(xdrs)) - return (ct->ct_error.re_status); - /* now decode and validate the response header */ - if (! xdr_replymsg(xdrs, &reply_msg)) { - if (ct->ct_error.re_status == RPC_SUCCESS) - continue; - return (ct->ct_error.re_status); - } - if (reply_msg.rm_xid == x_id) - break; - } - - /* - * process header - */ - _seterr_reply(&reply_msg, &(ct->ct_error)); - if (ct->ct_error.re_status == RPC_SUCCESS) { - if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { - ct->ct_error.re_status = RPC_AUTHERROR; - ct->ct_error.re_why = AUTH_INVALIDRESP; - } else if (! (*xdr_results)(xdrs, results_ptr)) { - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTDECODERES; - } - /* free verifier ... */ - if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { - xdrs->x_op = XDR_FREE; - (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); - } - } /* end successful completion */ - else { - /* maybe our credentials need to be refreshed ... */ - if (refreshes-- && AUTH_REFRESH(h->cl_auth)) - goto call_again; - } /* end of unsuccessful completion */ - return (ct->ct_error.re_status); -} - -static void -clnttcp_geterr(h, errp) - CLIENT *h; - struct rpc_err *errp; -{ - register struct ct_data *ct = - (struct ct_data *) h->cl_private; - - *errp = ct->ct_error; -} - -static bool_t -clnttcp_freeres(cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - caddr_t res_ptr; -{ - register struct ct_data *ct = (struct ct_data *)cl->cl_private; - register XDR *xdrs = &(ct->ct_xdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_res)(xdrs, res_ptr)); -} - -static void -clnttcp_abort() -{ -} - - -static bool_t -clnttcp_control(cl, request, info) - CLIENT *cl; - int request; - char *info; -{ - register struct ct_data *ct = (struct ct_data *)cl->cl_private; - register struct timeval *tv; - int len; - - switch (request) { - case CLSET_FD_CLOSE: - ct->ct_closeit = TRUE; - break; - case CLSET_FD_NCLOSE: - ct->ct_closeit = FALSE; - break; - case CLSET_TIMEOUT: - if (info == NULL) - return(FALSE); - tv = (struct timeval *)info; - ct->ct_wait.tv_sec = tv->tv_sec; - ct->ct_wait.tv_usec = tv->tv_usec; - ct->ct_waitset = TRUE; - break; - case CLGET_TIMEOUT: - if (info == NULL) - return(FALSE); - *(struct timeval *)info = ct->ct_wait; - break; - case CLGET_SERVER_ADDR: - if (info == NULL) - return(FALSE); - *(struct sockaddr_in *)info = ct->ct_addr; - break; - case CLGET_FD: - if (info == NULL) - return(FALSE); - *(int *)info = ct->ct_sock; - break; - case CLGET_XID: - /* - * use the knowledge that xid is the - * first element in the call structure *. - * This will get the xid of the PREVIOUS call - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)ct->ct_mcall); - break; - case CLSET_XID: - /* This will set the xid of the NEXT call */ - if (info == NULL) - return(FALSE); - *(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1); - /* decrement by 1 as clnttcp_call() increments once */ - case CLGET_VERS: - /* - * This RELIES on the information that, in the call body, - * the version number field is the fifth field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + - 4 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_VERS: - if (info == NULL) - return(FALSE); - *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - case CLGET_PROG: - /* - * This RELIES on the information that, in the call body, - * the program number field is the field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + - 3 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_PROG: - if (info == NULL) - return(FALSE); - *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - case CLGET_LOCAL_ADDR: - len = sizeof(struct sockaddr); - if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0) - return(FALSE); - break; - case CLGET_RETRY_TIMEOUT: - case CLSET_RETRY_TIMEOUT: - case CLGET_SVC_ADDR: - case CLSET_SVC_ADDR: - case CLSET_PUSH_TIMOD: - case CLSET_POP_TIMOD: - default: - return (FALSE); - } - return (TRUE); -} - - -static void -clnttcp_destroy(h) - CLIENT *h; -{ - register struct ct_data *ct = - (struct ct_data *) h->cl_private; - - if (ct->ct_closeit) { - (void)_RPC_close(ct->ct_sock); - } - XDR_DESTROY(&(ct->ct_xdrs)); - mem_free((caddr_t)ct, sizeof(struct ct_data)); - mem_free((caddr_t)h, sizeof(CLIENT)); -} - -/* - * Interface between xdr serializer and tcp connection. - * Behaves like the system calls, read & write, but keeps some error state - * around for the rpc level. - */ -static int -readtcp(ct, buf, len) - register struct ct_data *ct; - caddr_t buf; - register int len; -{ - fd_set *fds, readfds; - struct timeval start, after, duration, delta, tmp, tv; - int r, save_errno; - - if (len == 0) - return (0); - - if (ct->ct_sock + 1 > FD_SETSIZE) { - int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask); - fds = (fd_set *)malloc(bytes); - if (fds == NULL) - return (-1); - memset(fds, 0, bytes); - } else { - fds = &readfds; - FD_ZERO(fds); - } - - gettimeofday(&start, NULL); - delta = ct->ct_wait; - while (TRUE) { - /* XXX we know the other bits are still clear */ - FD_SET(ct->ct_sock, fds); - tv = delta; /* in case select writes back */ - r = select(ct->ct_sock+1, fds, NULL, NULL, &tv); - save_errno = errno; - - gettimeofday(&after, NULL); - timersub(&start, &after, &duration); - timersub(&ct->ct_wait, &duration, &tmp); - delta = tmp; - if (delta.tv_sec < 0 || !timerisset(&delta)) - r = 0; - - switch (r) { - case 0: - if (fds != &readfds) - free(fds); - ct->ct_error.re_status = RPC_TIMEDOUT; - return (-1); - - case -1: - if (errno == EINTR) - continue; - if (fds != &readfds) - free(fds); - ct->ct_error.re_status = RPC_CANTRECV; - ct->ct_error.re_errno = save_errno; - return (-1); - } - break; - } - switch (len = _RPC_read(ct->ct_sock, buf, len)) { - - case 0: - /* premature eof */ - ct->ct_error.re_errno = ECONNRESET; - ct->ct_error.re_status = RPC_CANTRECV; - len = -1; /* it's really an error */ - break; - - case -1: - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTRECV; - break; - } - return (len); -} - -static int -writetcp(ct, buf, len) - struct ct_data *ct; - caddr_t buf; - int len; -{ - register int i, cnt; - - for (cnt = len; cnt > 0; cnt -= i, buf += i) { - if ((i = _RPC_write(ct->ct_sock, buf, cnt)) == -1) { - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTSEND; - return (-1); - } - } - return (len); -} diff --git a/c/src/librpc/src/rpc/clnt_udp.c b/c/src/librpc/src/rpc/clnt_udp.c deleted file mode 100644 index b9ead1c56a..0000000000 --- a/c/src/librpc/src/rpc/clnt_udp.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_udp.c,v 1.15 2000/01/27 23:06:36 jasone Exp $"; -#endif - -/* - * clnt_udp.c, Implements a UDP/IP based, client side RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * UDP bases client side rpc operations - */ -static enum clnt_stat clntudp_call(); -static void clntudp_abort(); -static void clntudp_geterr(); -static bool_t clntudp_freeres(); -static bool_t clntudp_control(); -static void clntudp_destroy(); - -static struct clnt_ops udp_ops = { - clntudp_call, - clntudp_abort, - clntudp_geterr, - clntudp_freeres, - clntudp_destroy, - clntudp_control -}; - -/* - * Private data kept per client handle - */ -struct cu_data { - int cu_sock; - bool_t cu_closeit; - struct sockaddr_in cu_raddr; - int cu_rlen; - struct timeval cu_wait; - struct timeval cu_total; - struct rpc_err cu_error; - XDR cu_outxdrs; - u_int cu_xdrpos; - u_int cu_sendsz; - char *cu_outbuf; - u_int cu_recvsz; - char cu_inbuf[1]; -}; - -/* - * Create a UDP based client handle. - * If *sockp<0, *sockp is set to a newly created UPD socket. - * If raddr->sin_port is 0 a binder on the remote machine - * is consulted for the correct port number. - * NB: It is the clients responsibility to close *sockp. - * NB: The rpch->cl_auth is initialized to null authentication. - * Caller may wish to set this something more useful. - * - * wait is the amount of time used between retransmitting a call if - * no response has been heard; retransmition occurs until the actual - * rpc call times out. - * - * sendsz and recvsz are the maximum allowable packet sizes that can be - * sent and received. - */ -CLIENT * -clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) - struct sockaddr_in *raddr; - u_long program; - u_long version; - struct timeval wait; - register int *sockp; - u_int sendsz; - u_int recvsz; -{ - CLIENT *cl; - register struct cu_data *cu = NULL; - struct timeval now; - struct rpc_msg call_msg; - static u_int32_t disrupt; - - if (disrupt == 0) - disrupt = (u_int32_t)(long)raddr; - - cl = (CLIENT *)mem_alloc(sizeof(CLIENT)); - if (cl == NULL) { - (void) fprintf(stderr, "clntudp_create: out of memory\n"); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - sendsz = ((sendsz + 3) / 4) * 4; - recvsz = ((recvsz + 3) / 4) * 4; - cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz); - if (cu == NULL) { - (void) fprintf(stderr, "clntudp_create: out of memory\n"); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - cu->cu_outbuf = &cu->cu_inbuf[recvsz]; - - (void)gettimeofday(&now, (struct timezone *)0); - if (raddr->sin_port == 0) { - u_short port; - if ((port = - pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) { - goto fooy; - } - raddr->sin_port = htons(port); - } - cl->cl_ops = &udp_ops; - cl->cl_private = (caddr_t)cu; - cu->cu_raddr = *raddr; - cu->cu_rlen = sizeof (cu->cu_raddr); - cu->cu_wait = wait; - cu->cu_total.tv_sec = -1; - cu->cu_total.tv_usec = -1; - cu->cu_sendsz = sendsz; - cu->cu_recvsz = recvsz; - call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec; - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = program; - call_msg.rm_call.cb_vers = version; - xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, - sendsz, XDR_ENCODE); - if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) { - goto fooy; - } - cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); - if (*sockp < 0) { - int dontblock = 1; - - *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (*sockp < 0) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - /* attempt to bind to priv port */ - (void)bindresvport(*sockp, (struct sockaddr_in *)0); - /* the sockets rpc controls are non-blocking */ - (void)ioctl(*sockp, FIONBIO, (char *) &dontblock); - cu->cu_closeit = TRUE; - } else { - cu->cu_closeit = FALSE; - } - cu->cu_sock = *sockp; - cl->cl_auth = authnone_create(); - return (cl); -fooy: - if (cu) - mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz); - if (cl) - mem_free((caddr_t)cl, sizeof(CLIENT)); - return ((CLIENT *)NULL); -} - -CLIENT * -clntudp_create(raddr, program, version, wait, sockp) - struct sockaddr_in *raddr; - u_long program; - u_long version; - struct timeval wait; - register int *sockp; -{ - - return(clntudp_bufcreate(raddr, program, version, wait, sockp, - UDPMSGSIZE, UDPMSGSIZE)); -} - -static enum clnt_stat -clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) - register CLIENT *cl; /* client handle */ - u_long proc; /* procedure number */ - xdrproc_t xargs; /* xdr routine for args */ - caddr_t argsp; /* pointer to args */ - xdrproc_t xresults; /* xdr routine for results */ - caddr_t resultsp; /* pointer to results */ - struct timeval utimeout; /* seconds to wait before giving up */ -{ - register struct cu_data *cu = (struct cu_data *)cl->cl_private; - register XDR *xdrs; - register int outlen; - register int inlen; - int fromlen; - fd_set *fds, readfds; - struct sockaddr_in from; - struct rpc_msg reply_msg; - XDR reply_xdrs; - struct timeval time_waited, start, after, tmp1, tmp2, tv; - bool_t ok; - int nrefreshes = 2; /* number of times to refresh cred */ - struct timeval timeout; - - if (cu->cu_total.tv_usec == -1) - timeout = utimeout; /* use supplied timeout */ - else - timeout = cu->cu_total; /* use default timeout */ - - if (cu->cu_sock + 1 > FD_SETSIZE) { - int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask); - fds = (fd_set *)malloc(bytes); - if (fds == NULL) - return (cu->cu_error.re_status = RPC_CANTSEND); - memset(fds, 0, bytes); - } else { - fds = &readfds; - FD_ZERO(fds); - } - - timerclear(&time_waited); - -call_again: - xdrs = &(cu->cu_outxdrs); - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, cu->cu_xdrpos); - /* - * the transaction is the first thing in the out buffer - */ - (*(u_short *)(cu->cu_outbuf))++; - if ((! XDR_PUTLONG(xdrs, (long *)&proc)) || - (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || - (! (*xargs)(xdrs, argsp))) { - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status = RPC_CANTENCODEARGS); - } - outlen = (int)XDR_GETPOS(xdrs); - -send_again: - if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0, - (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) { - cu->cu_error.re_errno = errno; - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status = RPC_CANTSEND); - } - - /* - * Hack to provide rpc-based message passing - */ - if (!timerisset(&timeout)) { - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status = RPC_TIMEDOUT); - } - /* - * sub-optimal code appears here because we have - * some clock time to spare while the packets are in flight. - * (We assume that this is actually only executed once.) - */ - reply_msg.acpted_rply.ar_verf = _null_auth; - reply_msg.acpted_rply.ar_results.where = resultsp; - reply_msg.acpted_rply.ar_results.proc = xresults; - - gettimeofday(&start, NULL); - for (;;) { - /* XXX we know the other bits are still clear */ - FD_SET(cu->cu_sock, fds); - tv = cu->cu_wait; - switch (select(cu->cu_sock+1, fds, NULL, NULL, &tv)) { - - case 0: - timeradd(&time_waited, &cu->cu_wait, &tmp1); - time_waited = tmp1; - if (timercmp(&time_waited, &timeout, <)) - goto send_again; - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status = RPC_TIMEDOUT); - - case -1: - if (errno == EINTR) { - gettimeofday(&after, NULL); - timersub(&after, &start, &tmp1); - timeradd(&time_waited, &tmp1, &tmp2); - time_waited = tmp2; - if (timercmp(&time_waited, &timeout, <)) - continue; - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status = RPC_TIMEDOUT); - } - cu->cu_error.re_errno = errno; - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status = RPC_CANTRECV); - } - - do { - fromlen = sizeof(struct sockaddr); - inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, - (int) cu->cu_recvsz, 0, - (struct sockaddr *)&from, &fromlen); - } while (inlen < 0 && errno == EINTR); - if (inlen < 0) { - if (errno == EWOULDBLOCK) - continue; - cu->cu_error.re_errno = errno; - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status = RPC_CANTRECV); - } - if (inlen < sizeof(u_int32_t)) - continue; - /* see if reply transaction id matches sent id */ - if (*((u_int32_t *)(cu->cu_inbuf)) != *((u_int32_t *)(cu->cu_outbuf))) - continue; - /* we now assume we have the proper reply */ - break; - } - - /* - * now decode and validate the response - */ - xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE); - ok = xdr_replymsg(&reply_xdrs, &reply_msg); - /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ - if (ok) { - _seterr_reply(&reply_msg, &(cu->cu_error)); - if (cu->cu_error.re_status == RPC_SUCCESS) { - if (! AUTH_VALIDATE(cl->cl_auth, - &reply_msg.acpted_rply.ar_verf)) { - cu->cu_error.re_status = RPC_AUTHERROR; - cu->cu_error.re_why = AUTH_INVALIDRESP; - } - if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { - xdrs->x_op = XDR_FREE; - (void)xdr_opaque_auth(xdrs, - &(reply_msg.acpted_rply.ar_verf)); - } - } /* end successful completion */ - else { - /* maybe our credentials need to be refreshed ... */ - if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) { - nrefreshes--; - goto call_again; - } - } /* end of unsuccessful completion */ - } /* end of valid reply message */ - else { - /* - * It's possible for xdr_replymsg() to fail partway - * through its attempt to decode the result from the - * server. If this happens, it will leave the reply - * structure partially populated with dynamically - * allocated memory. (This can happen if someone uses - * clntudp_bufcreate() to create a CLIENT handle and - * specifies a receive buffer size that is too small.) - * This memory must be free()ed to avoid a leak. - */ - int op = reply_xdrs.x_op; - reply_xdrs.x_op = XDR_FREE; - xdr_replymsg(&reply_xdrs, &reply_msg); - reply_xdrs.x_op = op; - cu->cu_error.re_status = RPC_CANTDECODERES; - } - if (fds != &readfds) - free(fds); - return (cu->cu_error.re_status); -} - -static void -clntudp_geterr(cl, errp) - CLIENT *cl; - struct rpc_err *errp; -{ - register struct cu_data *cu = (struct cu_data *)cl->cl_private; - - *errp = cu->cu_error; -} - - -static bool_t -clntudp_freeres(cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - caddr_t res_ptr; -{ - register struct cu_data *cu = (struct cu_data *)cl->cl_private; - register XDR *xdrs = &(cu->cu_outxdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_res)(xdrs, res_ptr)); -} - -static void -clntudp_abort(/*h*/) - /*CLIENT *h;*/ -{ -} - - -static bool_t -clntudp_control(cl, request, info) - CLIENT *cl; - int request; - char *info; -{ - register struct cu_data *cu = (struct cu_data *)cl->cl_private; - register struct timeval *tv; - int len; - - switch (request) { - case CLSET_FD_CLOSE: - cu->cu_closeit = TRUE; - break; - case CLSET_FD_NCLOSE: - cu->cu_closeit = FALSE; - break; - case CLSET_TIMEOUT: - if (info == NULL) - return(FALSE); - tv = (struct timeval *)info; - cu->cu_total.tv_sec = tv->tv_sec; - cu->cu_total.tv_usec = tv->tv_usec; - break; - case CLGET_TIMEOUT: - if (info == NULL) - return(FALSE); - *(struct timeval *)info = cu->cu_total; - break; - case CLSET_RETRY_TIMEOUT: - if (info == NULL) - return(FALSE); - tv = (struct timeval *)info; - cu->cu_wait.tv_sec = tv->tv_sec; - cu->cu_wait.tv_usec = tv->tv_usec; - break; - case CLGET_RETRY_TIMEOUT: - if (info == NULL) - return(FALSE); - *(struct timeval *)info = cu->cu_wait; - break; - case CLGET_SERVER_ADDR: - if (info == NULL) - return(FALSE); - *(struct sockaddr_in *)info = cu->cu_raddr; - break; - case CLGET_FD: - if (info == NULL) - return(FALSE); - *(int *)info = cu->cu_sock; - break; - case CLGET_XID: - /* - * use the knowledge that xid is the - * first element in the call structure *. - * This will get the xid of the PREVIOUS call - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf); - break; - case CLSET_XID: - /* This will set the xid of the NEXT call */ - if (info == NULL) - return(FALSE); - *(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1); - /* decrement by 1 as clntudp_call() increments once */ - case CLGET_VERS: - /* - * This RELIES on the information that, in the call body, - * the version number field is the fifth field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + - 4 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_VERS: - if (info == NULL) - return(FALSE); - *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - case CLGET_PROG: - /* - * This RELIES on the information that, in the call body, - * the program number field is the field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + - 3 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_PROG: - if (info == NULL) - return(FALSE); - *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - case CLGET_LOCAL_ADDR: - len = sizeof(struct sockaddr); - if (getsockname(cu->cu_sock, (struct sockaddr *)info, &len) <0) - return(FALSE); - break; - case CLGET_SVC_ADDR: - case CLSET_SVC_ADDR: - case CLSET_PUSH_TIMOD: - case CLSET_POP_TIMOD: - default: - return (FALSE); - } - return (TRUE); -} - -static void -clntudp_destroy(cl) - CLIENT *cl; -{ - register struct cu_data *cu = (struct cu_data *)cl->cl_private; - - if (cu->cu_closeit) { - (void)_RPC_close(cu->cu_sock); - } - XDR_DESTROY(&(cu->cu_outxdrs)); - mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); - mem_free((caddr_t)cl, sizeof(CLIENT)); -} diff --git a/c/src/librpc/src/rpc/clnt_unix.c b/c/src/librpc/src/rpc/clnt_unix.c deleted file mode 100644 index 0cfe988595..0000000000 --- a/c/src/librpc/src/rpc/clnt_unix.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)clnt_unix.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)clnt_unix.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_unix.c,v 1.5 2000/01/27 23:06:37 jasone Exp $"; -#endif - -/* - * clnt_unix.c, Implements a AF_UNIX based, client side RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * AF_UNIX based RPC supports 'batched calls'. - * A sequence of calls may be batched-up in a send buffer. The rpc call - * return immediately to the client even though the call was not necessarily - * sent. The batching occurs if the results' xdr routine is NULL (0) AND - * the rpc timeout value is zero (see clnt.h, rpc). - * - * Clients should NOT casually batch calls that in fact return results; that is, - * the server side should be aware that a call is batched and not produce any - * return message. Batched calls that produce many result messages can - * deadlock (netlock) the client and the server.... - * - * Now go hang yourself. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MCALL_MSG_SIZE 24 - -static int readunix(); -static int writeunix(); - -static enum clnt_stat clntunix_call(); -static void clntunix_abort(); -static void clntunix_geterr(); -static bool_t clntunix_freeres(); -static bool_t clntunix_control(); -static void clntunix_destroy(); - -static struct clnt_ops unix_ops = { - clntunix_call, - clntunix_abort, - clntunix_geterr, - clntunix_freeres, - clntunix_destroy, - clntunix_control -}; - -struct ct_data { - int ct_sock; - bool_t ct_closeit; - struct timeval ct_wait; - bool_t ct_waitset; /* wait set by clnt_control? */ - struct sockaddr_un ct_addr; - struct rpc_err ct_error; - char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ - u_int ct_mpos; /* pos after marshal */ - XDR ct_xdrs; -}; - -/* - * Create a client handle for a unix/ip connection. - * If *sockp<0, *sockp is set to a newly created TCP socket and it is - * connected to raddr. If *sockp non-negative then - * raddr is ignored. The rpc/unix package does buffering - * similar to stdio, so the client must pick send and receive buffer sizes,]; - * 0 => use the default. - * If raddr->sin_port is 0, then a binder on the remote machine is - * consulted for the right port number. - * NB: *sockp is copied into a private area. - * NB: It is the clients responsibility to close *sockp. - * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this - * something more useful. - */ -CLIENT * -clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz) - struct sockaddr_un *raddr; - u_long prog; - u_long vers; - register int *sockp; - u_int sendsz; - u_int recvsz; -{ - CLIENT *h; - register struct ct_data *ct = NULL; - struct timeval now; - struct rpc_msg call_msg; - static u_int32_t disrupt; - int len; - - if (disrupt == 0) - disrupt = (u_int32_t)(long)raddr; - - h = (CLIENT *)mem_alloc(sizeof(*h)); - if (h == NULL) { - (void)fprintf(stderr, "clntunix_create: out of memory\n"); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - ct = (struct ct_data *)mem_alloc(sizeof(*ct)); - if (ct == NULL) { - (void)fprintf(stderr, "clntunix_create: out of memory\n"); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto fooy; - } - - /* - * If no socket given, open one - */ - if (*sockp < 0) { - *sockp = socket(AF_UNIX, SOCK_STREAM, 0); - len = strlen(raddr->sun_path) + sizeof(raddr->sun_family) + - sizeof(raddr->sun_len) + 1; - raddr->sun_len = len; - if ((*sockp < 0) - || (connect(*sockp, (struct sockaddr *)raddr, len) < 0)) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - if (*sockp != -1) - (void)_RPC_close(*sockp); - goto fooy; - } - ct->ct_closeit = TRUE; - } else { - ct->ct_closeit = FALSE; - } - - /* - * Set up private data struct - */ - ct->ct_sock = *sockp; - ct->ct_wait.tv_usec = 0; - ct->ct_waitset = FALSE; - ct->ct_addr = *raddr; - - /* - * Initialize call message - */ - (void)gettimeofday(&now, (struct timezone *)0); - call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec; - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = prog; - call_msg.rm_call.cb_vers = vers; - - /* - * pre-serialize the static part of the call msg and stash it away - */ - xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, - XDR_ENCODE); - if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { - if (ct->ct_closeit) { - (void)_RPC_close(*sockp); - } - goto fooy; - } - ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); - XDR_DESTROY(&(ct->ct_xdrs)); - - /* - * Create a client handle which uses xdrrec for serialization - * and authnone for authentication. - */ - xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, - (caddr_t)ct, readunix, writeunix); - h->cl_ops = &unix_ops; - h->cl_private = (caddr_t) ct; - h->cl_auth = authnone_create(); - return (h); - -fooy: - /* - * Something goofed, free stuff and barf - */ - if (ct) - mem_free((caddr_t)ct, sizeof(struct ct_data)); - if (h) - mem_free((caddr_t)h, sizeof(CLIENT)); - return ((CLIENT *)NULL); -} - -static enum clnt_stat -clntunix_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) - register CLIENT *h; - u_long proc; - xdrproc_t xdr_args; - caddr_t args_ptr; - xdrproc_t xdr_results; - caddr_t results_ptr; - struct timeval timeout; -{ - register struct ct_data *ct = (struct ct_data *) h->cl_private; - register XDR *xdrs = &(ct->ct_xdrs); - struct rpc_msg reply_msg; - u_long x_id; - u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */ - register bool_t shipnow; - int refreshes = 2; - - if (!ct->ct_waitset) { - ct->ct_wait = timeout; - } - - shipnow = - (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 - && timeout.tv_usec == 0) ? FALSE : TRUE; - -call_again: - xdrs->x_op = XDR_ENCODE; - ct->ct_error.re_status = RPC_SUCCESS; - x_id = ntohl(--(*msg_x_id)); - if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) || - (! XDR_PUTLONG(xdrs, (long *)&proc)) || - (! AUTH_MARSHALL(h->cl_auth, xdrs)) || - (! (*xdr_args)(xdrs, args_ptr))) { - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTENCODEARGS; - (void)xdrrec_endofrecord(xdrs, TRUE); - return (ct->ct_error.re_status); - } - if (! xdrrec_endofrecord(xdrs, shipnow)) - return (ct->ct_error.re_status = RPC_CANTSEND); - if (! shipnow) - return (RPC_SUCCESS); - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { - return(ct->ct_error.re_status = RPC_TIMEDOUT); - } - - - /* - * Keep receiving until we get a valid transaction id - */ - xdrs->x_op = XDR_DECODE; - while (TRUE) { - reply_msg.acpted_rply.ar_verf = _null_auth; - reply_msg.acpted_rply.ar_results.where = NULL; - reply_msg.acpted_rply.ar_results.proc = xdr_void; - if (! xdrrec_skiprecord(xdrs)) - return (ct->ct_error.re_status); - /* now decode and validate the response header */ - if (! xdr_replymsg(xdrs, &reply_msg)) { - if (ct->ct_error.re_status == RPC_SUCCESS) - continue; - return (ct->ct_error.re_status); - } - if (reply_msg.rm_xid == x_id) - break; - } - - /* - * process header - */ - _seterr_reply(&reply_msg, &(ct->ct_error)); - if (ct->ct_error.re_status == RPC_SUCCESS) { - if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { - ct->ct_error.re_status = RPC_AUTHERROR; - ct->ct_error.re_why = AUTH_INVALIDRESP; - } else if (! (*xdr_results)(xdrs, results_ptr)) { - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTDECODERES; - } - /* free verifier ... */ - if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { - xdrs->x_op = XDR_FREE; - (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); - } - } /* end successful completion */ - else { - /* maybe our credentials need to be refreshed ... */ - if (refreshes-- && AUTH_REFRESH(h->cl_auth)) - goto call_again; - } /* end of unsuccessful completion */ - return (ct->ct_error.re_status); -} - -static void -clntunix_geterr(h, errp) - CLIENT *h; - struct rpc_err *errp; -{ - register struct ct_data *ct = - (struct ct_data *) h->cl_private; - - *errp = ct->ct_error; -} - -static bool_t -clntunix_freeres(cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - caddr_t res_ptr; -{ - register struct ct_data *ct = (struct ct_data *)cl->cl_private; - register XDR *xdrs = &(ct->ct_xdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_res)(xdrs, res_ptr)); -} - -static void -clntunix_abort() -{ -} - - -static bool_t -clntunix_control(cl, request, info) - CLIENT *cl; - int request; - char *info; -{ - register struct ct_data *ct = (struct ct_data *)cl->cl_private; - register struct timeval *tv; - int len; - - switch (request) { - case CLSET_FD_CLOSE: - ct->ct_closeit = TRUE; - break; - case CLSET_FD_NCLOSE: - ct->ct_closeit = FALSE; - break; - case CLSET_TIMEOUT: - if (info == NULL) - return(FALSE); - tv = (struct timeval *)info; - ct->ct_wait.tv_sec = tv->tv_sec; - ct->ct_wait.tv_usec = tv->tv_usec; - ct->ct_waitset = TRUE; - break; - case CLGET_TIMEOUT: - if (info == NULL) - return(FALSE); - *(struct timeval *)info = ct->ct_wait; - break; - case CLGET_SERVER_ADDR: - if (info == NULL) - return(FALSE); - *(struct sockaddr_un *)info = ct->ct_addr; - break; - case CLGET_FD: - if (info == NULL) - return(FALSE); - *(int *)info = ct->ct_sock; - break; - case CLGET_XID: - /* - * use the knowledge that xid is the - * first element in the call structure *. - * This will get the xid of the PREVIOUS call - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)ct->ct_mcall); - break; - case CLSET_XID: - /* This will set the xid of the NEXT call */ - if (info == NULL) - return(FALSE); - *(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1); - /* decrement by 1 as clntunix_call() increments once */ - case CLGET_VERS: - /* - * This RELIES on the information that, in the call body, - * the version number field is the fifth field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + - 4 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_VERS: - if (info == NULL) - return(FALSE); - *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - case CLGET_PROG: - /* - * This RELIES on the information that, in the call body, - * the program number field is the field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - if (info == NULL) - return(FALSE); - *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + - 3 * BYTES_PER_XDR_UNIT)); - break; - case CLSET_PROG: - if (info == NULL) - return(FALSE); - *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT) - = htonl(*(u_long *)info); - break; - case CLGET_LOCAL_ADDR: - len = sizeof(struct sockaddr); - if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0) - return(FALSE); - break; - case CLGET_RETRY_TIMEOUT: - case CLSET_RETRY_TIMEOUT: - case CLGET_SVC_ADDR: - case CLSET_SVC_ADDR: - case CLSET_PUSH_TIMOD: - case CLSET_POP_TIMOD: - default: - return (FALSE); - } - return (TRUE); -} - - -static void -clntunix_destroy(h) - CLIENT *h; -{ - register struct ct_data *ct = - (struct ct_data *) h->cl_private; - - if (ct->ct_closeit) { - (void)_RPC_close(ct->ct_sock); - } - XDR_DESTROY(&(ct->ct_xdrs)); - mem_free((caddr_t)ct, sizeof(struct ct_data)); - mem_free((caddr_t)h, sizeof(CLIENT)); -} - -/* - * read() and write() are replaced with recvmsg()/sendmsg() so that - * we can pass ancillary control data. In this case, the data constists - * of credential information which the kernel will fill in for us. - * XXX: This code is specific to FreeBSD and will not work on other - * platforms without the requisite kernel modifications. - */ -struct cmessage { - struct cmsghdr cmsg; - struct cmsgcred cmcred; -}; - -static int __msgread(sock, buf, cnt) - int sock; - void *buf; - size_t cnt; -{ - struct iovec iov[1]; - struct msghdr msg; - struct cmessage cm; - - bzero((char *)&cm, sizeof(cm)); - iov[0].iov_base = buf; - iov[0].iov_len = cnt; - - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = (caddr_t)&cm; - msg.msg_controllen = sizeof(struct cmessage); - msg.msg_flags = 0; - - return(recvmsg(sock, &msg, 0)); -} - -static int __msgwrite(sock, buf, cnt) - int sock; - void *buf; - size_t cnt; -{ - struct iovec iov[1]; - struct msghdr msg; - struct cmessage cm; - - bzero((char *)&cm, sizeof(cm)); - iov[0].iov_base = buf; - iov[0].iov_len = cnt; - - cm.cmsg.cmsg_type = SCM_CREDS; - cm.cmsg.cmsg_level = SOL_SOCKET; - cm.cmsg.cmsg_len = sizeof(struct cmessage); - - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = (caddr_t)&cm; - msg.msg_controllen = sizeof(struct cmessage); - msg.msg_flags = 0; - - return(sendmsg(sock, &msg, 0)); -} - -/* - * Interface between xdr serializer and unix connection. - * Behaves like the system calls, read & write, but keeps some error state - * around for the rpc level. - */ -static int -readunix(ct, buf, len) - register struct ct_data *ct; - caddr_t buf; - register int len; -{ - fd_set *fds, readfds; - struct timeval start, after, duration, delta, tmp, tv; - int r, save_errno; - - if (len == 0) - return (0); - - if (ct->ct_sock + 1 > FD_SETSIZE) { - int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask); - fds = (fd_set *)malloc(bytes); - if (fds == NULL) - return (-1); - memset(fds, 0, bytes); - } else { - fds = &readfds; - FD_ZERO(fds); - } - - gettimeofday(&start, NULL); - delta = ct->ct_wait; - while (TRUE) { - /* XXX we know the other bits are still clear */ - FD_SET(ct->ct_sock, fds); - tv = delta; /* in case select writes back */ - r = select(ct->ct_sock+1, fds, NULL, NULL, &tv); - save_errno = errno; - - gettimeofday(&after, NULL); - timersub(&start, &after, &duration); - timersub(&delta, &duration, &tmp); - delta = tmp; - if (delta.tv_sec < 0 || !timerisset(&delta)) - r = 0; - - switch (r) { - case 0: - if (fds != &readfds) - free(fds); - ct->ct_error.re_status = RPC_TIMEDOUT; - return (-1); - - case -1: - if (errno == EINTR) - continue; - if (fds != &readfds) - free(fds); - ct->ct_error.re_status = RPC_CANTRECV; - ct->ct_error.re_errno = save_errno; - return (-1); - } - break; - } - switch (len = __msgread(ct->ct_sock, buf, len)) { - - case 0: - /* premature eof */ - ct->ct_error.re_errno = ECONNRESET; - ct->ct_error.re_status = RPC_CANTRECV; - len = -1; /* it's really an error */ - break; - - case -1: - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTRECV; - break; - } - return (len); -} - -static int -writeunix(ct, buf, len) - struct ct_data *ct; - caddr_t buf; - int len; -{ - register int i, cnt; - - for (cnt = len; cnt > 0; cnt -= i, buf += i) { - if ((i = __msgwrite(ct->ct_sock, buf, cnt)) == -1) { - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTSEND; - return (-1); - } - } - return (len); -} diff --git a/c/src/librpc/src/rpc/crypt_client.c b/c/src/librpc/src/rpc/crypt_client.c deleted file mode 100644 index cb69470614..0000000000 --- a/c/src/librpc/src/rpc/crypt_client.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 1996 - * Bill Paul . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/lib/libc/rpc/crypt_client.c,v 1.4 1999/08/28 00:00:37 peter Exp $ - */ - -#include -#include -#include -#include -#include - -#ifndef lint -static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/crypt_client.c,v 1.4 1999/08/28 00:00:37 peter Exp $"; -#endif - -#ifndef KEYSERVSOCK -#define KEYSERVSOCK "/var/run/keyservsock" -#endif - -int -_des_crypt_call(buf, len, dparms) - char *buf; - int len; - struct desparams *dparms; -{ - CLIENT *clnt; - desresp *result_1; - desargs des_crypt_1_arg; - int stat; - - clnt = clnt_create(KEYSERVSOCK, CRYPT_PROG, CRYPT_VERS, "unix"); - if (clnt == (CLIENT *) NULL) { - return(DESERR_HWERROR); - } - - des_crypt_1_arg.desbuf.desbuf_len = len; - des_crypt_1_arg.desbuf.desbuf_val = buf; - des_crypt_1_arg.des_dir = dparms->des_dir; - des_crypt_1_arg.des_mode = dparms->des_mode; - bcopy(dparms->des_ivec, des_crypt_1_arg.des_ivec, 8); - bcopy(dparms->des_key, des_crypt_1_arg.des_key, 8); - - result_1 = des_crypt_1(&des_crypt_1_arg, clnt); - if (result_1 == (desresp *) NULL) { - clnt_destroy(clnt); - return(DESERR_HWERROR); - } - - stat = result_1->stat; - - if (result_1->stat == DESERR_NONE || - result_1->stat == DESERR_NOHWDEVICE) { - bcopy(result_1->desbuf.desbuf_val, buf, len); - bcopy(result_1->des_ivec, dparms->des_ivec, 8); - } - - clnt_freeres(clnt, xdr_desresp, (char *)result_1); - clnt_destroy(clnt); - - return(stat); -} diff --git a/c/src/librpc/src/rpc/des_crypt.3 b/c/src/librpc/src/rpc/des_crypt.3 deleted file mode 100644 index a92f577a56..0000000000 --- a/c/src/librpc/src/rpc/des_crypt.3 +++ /dev/null @@ -1,130 +0,0 @@ -.\" @(#)des_crypt.3 2.1 88/08/11 4.0 RPCSRC; from 1.16 88/03/02 SMI; -.\" $FreeBSD: src/lib/libc/rpc/des_crypt.3,v 1.4 2000/03/02 09:13:45 sheldonh Exp $ -.\" -.TH DES_CRYPT 3 "6 October 1987" -.SH NAME -des_crypt, ecb_crypt, cbc_crypt, des_setparity \- fast DES encryption -.SH SYNOPSIS -.nf -.B #include -.LP -.B int ecb_crypt(key, data, datalen, mode) -.B char *key; -.B char *data; -.B unsigned datalen; -.B unsigned mode; -.LP -.B int cbc_crypt(key, data, datalen, mode, ivec) -.B char *key; -.B char *data; -.B unsigned datalen; -.B unsigned mode; -.B char *ivec; -.LP -.B void des_setparity(key) -.B char *key; -.fi -.SH DESCRIPTION -.IX encryption cbc_crypt "" \fLcbc_crypt\fP -.IX "des encryption" cbc_crypt "DES encryption" \fLcbc_crypt\fP -.IX encryption des_setparity "" \fLdes_setparity\fP -.IX "des encryption" des_setparity "DES encryption" \fLdes_setparity\fP -.B ecb_crypt(\|) -and -.B cbc_crypt(\|) -implement the -.SM NBS -.SM DES -(Data Encryption Standard). -These routines are faster and more general purpose than -.BR crypt (3). -They also are able to utilize -.SM DES -hardware if it is available. -.B ecb_crypt(\|) -encrypts in -.SM ECB -(Electronic Code Book) -mode, which encrypts blocks of data independently. -.B cbc_crypt(\|) -encrypts in -.SM CBC -(Cipher Block Chaining) -mode, which chains together -successive blocks. -.SM CBC -mode protects against insertions, deletions and -substitutions of blocks. -Also, regularities in the clear text will -not appear in the cipher text. -.LP -Here is how to use these routines. The first parameter, -.IR key , -is the 8-byte encryption key with parity. -To set the key's parity, which for -.SM DES -is in the low bit of each byte, use -.IR des_setparity . -The second parameter, -.IR data , -contains the data to be encrypted or decrypted. -The -third parameter, -.IR datalen , -is the length in bytes of -.IR data , -which must be a multiple of 8. The fourth parameter, -.IR mode , -is formed by -.SM OR\s0'ing -together some things. For the encryption direction 'or' in either -.SM DES_ENCRYPT -or -.SM DES_DECRYPT\s0. -For software versus hardware -encryption, 'or' in either -.SM DES_HW -or -.SM DES_SW\s0. -If -.SM DES_HW -is specified, and there is no hardware, then the encryption is performed -in software and the routine returns -.SM DESERR_NOHWDEVICE\s0. -For -.IR cbc_crypt , -the parameter -.I ivec -is the the 8-byte initialization -vector for the chaining. It is updated to the next initialization -vector upon return. -.LP -.SH "SEE ALSO" -.BR des (1), -.BR crypt (3) -.SH DIAGNOSTICS -.PD 0 -.TP 20 -.SM DESERR_NONE -No error. -.TP -.SM DESERR_NOHWDEVICE -Encryption succeeded, but done in software instead of the requested hardware. -.TP -.SM DESERR_HWERR -An error occurred in the hardware or driver. -.TP -.SM DESERR_BADPARAM -Bad parameter to routine. -.PD -.LP -Given a result status -.IR stat , -the macro -.SM DES_FAILED\c -.BR ( stat ) -is false only for the first two statuses. -.SH RESTRICTIONS -These routines are not available in RPCSRC 4.0. -This information is provided to describe the DES interface expected by -Secure RPC. diff --git a/c/src/librpc/src/rpc/des_crypt.c b/c/src/librpc/src/rpc/des_crypt.c deleted file mode 100644 index d74ce9403a..0000000000 --- a/c/src/librpc/src/rpc/des_crypt.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * des_crypt.c, DES encryption library routines - * Copyright (C) 1986, Sun Microsystems, Inc. - */ - -#include -#include -#include - -#ifndef lint -/* from: static char sccsid[] = "@(#)des_crypt.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI"; */ -static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/des_crypt.c,v 1.3 1999/08/28 00:00:38 peter Exp $"; -#endif - -static int common_crypt __P(( char *, char *, register unsigned, unsigned, struct desparams * )); -int (*__des_crypt_LOCAL)() = 0; -extern _des_crypt_call __P(( char *, int, struct desparams * )); -/* - * Copy 8 bytes - */ -#define COPY8(src, dst) { \ - register char *a = (char *) dst; \ - register char *b = (char *) src; \ - *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ - *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ -} - -/* - * Copy multiple of 8 bytes - */ -#define DESCOPY(src, dst, len) { \ - register char *a = (char *) dst; \ - register char *b = (char *) src; \ - register int i; \ - for (i = (int) len; i > 0; i -= 8) { \ - *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ - *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ - } \ -} - -/* - * CBC mode encryption - */ -int -cbc_crypt(key, buf, len, mode, ivec) - char *key; - char *buf; - unsigned len; - unsigned mode; - char *ivec; -{ - int err; - struct desparams dp; - -#ifdef BROKEN_DES - dp.UDES.UDES_buf = buf; - dp.des_mode = ECB; -#else - dp.des_mode = CBC; -#endif - COPY8(ivec, dp.des_ivec); - err = common_crypt(key, buf, len, mode, &dp); - COPY8(dp.des_ivec, ivec); - return(err); -} - - -/* - * ECB mode encryption - */ -int -ecb_crypt(key, buf, len, mode) - char *key; - char *buf; - unsigned len; - unsigned mode; -{ - struct desparams dp; - -#ifdef BROKEN_DES - dp.UDES.UDES_buf = buf; - dp.des_mode = CBC; -#else - dp.des_mode = ECB; -#endif - return(common_crypt(key, buf, len, mode, &dp)); -} - - - -/* - * Common code to cbc_crypt() & ecb_crypt() - */ -static int -common_crypt(key, buf, len, mode, desp) - char *key; - char *buf; - register unsigned len; - unsigned mode; - register struct desparams *desp; -{ - register int desdev; - - if ((len % 8) != 0 || len > DES_MAXDATA) { - return(DESERR_BADPARAM); - } - desp->des_dir = - ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT; - - desdev = mode & DES_DEVMASK; - COPY8(key, desp->des_key); - /* - * software - */ - if (__des_crypt_LOCAL != NULL) { - if (!__des_crypt_LOCAL(buf, len, desp)) { - return (DESERR_HWERROR); - } - } else { - if (!_des_crypt_call(buf, len, desp)) { - return (DESERR_HWERROR); - } - } - return(desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE); -} diff --git a/c/src/librpc/src/rpc/des_soft.c b/c/src/librpc/src/rpc/des_soft.c deleted file mode 100644 index 01dd7f280b..0000000000 --- a/c/src/librpc/src/rpc/des_soft.c +++ /dev/null @@ -1,67 +0,0 @@ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)des_soft.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI"; -#endif -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Table giving odd parity in the low bit for ASCII characters - */ -static char partab[128] = { - 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, - 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e, - 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16, - 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f, - 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26, - 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f, - 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, - 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e, - 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, - 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f, - 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57, - 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e, - 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, - 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e, - 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76, - 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f, -}; - -/* - * Add odd parity to low bit of 8 byte key - */ -void -des_setparity(p) - char *p; -{ - int i; - - for (i = 0; i < 8; i++) { - *p = partab[*p & 0x7f]; - p++; - } -} diff --git a/c/src/librpc/src/rpc/get_myaddress.c b/c/src/librpc/src/rpc/get_myaddress.c deleted file mode 100644 index 8e951f559e..0000000000 --- a/c/src/librpc/src/rpc/get_myaddress.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/get_myaddress.c,v 1.17 2000/01/27 23:06:37 jasone Exp $"; -#endif - -/* - * get_myaddress.c - * - * Get client's IP address via ioctl. This avoids using the yellowpages. - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * don't use gethostbyname, which would invoke yellow pages - * - * Avoid loopback interfaces. We return information from a loopback - * interface only if there are no other possible interfaces. - */ -int -get_myaddress(addr) - struct sockaddr_in *addr; -{ - int s; - char buf[BUFSIZ]; - struct ifconf ifc; - struct ifreq ifreq, *ifr, *end; - int loopback = 0, gotit = 0; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - return(-1); - } - ifc.ifc_len = sizeof (buf); - ifc.ifc_buf = buf; - if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { - _RPC_close(s); - return(-1); - } -again: - ifr = ifc.ifc_req; - end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - - while (ifr < end) { - ifreq = *ifr; - if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { - _RPC_close(s); - return(-1); - } - if (((ifreq.ifr_flags & IFF_UP) && - ifr->ifr_addr.sa_family == AF_INET && - !(ifreq.ifr_flags & IFF_LOOPBACK)) || - (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK) - && (ifr->ifr_addr.sa_family == AF_INET) - && (ifreq.ifr_flags & IFF_UP))) { - *addr = *((struct sockaddr_in *)&ifr->ifr_addr); - addr->sin_port = htons(PMAPPORT); - gotit = 1; - break; - } - if (ifr->ifr_addr.sa_len) - ifr = (struct ifreq *) ((caddr_t) ifr + - ifr->ifr_addr.sa_len - - sizeof(struct sockaddr)); - ifr++; - } - if (gotit == 0 && loopback == 0) { - loopback = 1; - goto again; - } - (void)_RPC_close(s); - return (gotit ? 0 : -1); -} diff --git a/c/src/librpc/src/rpc/getpublickey.c b/c/src/librpc/src/rpc/getpublickey.c deleted file mode 100644 index e1c34d9b25..0000000000 --- a/c/src/librpc/src/rpc/getpublickey.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro"; -#endif - -/* - * publickey.c - * Copyright (C) 1986, Sun Microsystems, Inc. - */ - -/* - * Public key lookup routines - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define PKFILE "/etc/publickey" - -/* - * Hack to let ypserv/rpc.nisd use AUTH_DES. - */ -int (*__getpublickey_LOCAL)() = 0; - -/* - * Get somebody's public key - */ -int -__getpublickey_real(netname, publickey) - char *netname; - char *publickey; -{ - char lookup[3 * HEXKEYBYTES]; - char *p; - - if (publickey == NULL) - return (0); - if (!getpublicandprivatekey(netname, lookup)) - return (0); - p = strchr(lookup, ':'); - if (p == NULL) { - return (0); - } - *p = '\0'; - (void) strncpy(publickey, lookup, HEXKEYBYTES); - publickey[HEXKEYBYTES] = '\0'; - return (1); -} - -/* - * reads the file /etc/publickey looking for a + to optionally go to the - * yellow pages - */ - -int -getpublicandprivatekey(key, ret) - char *key; - char *ret; -{ - char buf[1024]; /* big enough */ - char *res; - FILE *fd; - char *mkey; - char *mval; - - fd = fopen(PKFILE, "r"); - if (fd == (FILE *) 0) - return (0); - for (;;) { - res = fgets(buf, 1024, fd); - if (res == 0) { - fclose(fd); - return (0); - } - if (res[0] == '#') - continue; - else if (res[0] == '+') { -#ifdef YP - char *PKMAP = "publickey.byname"; - char *lookup; - char *domain; - int err; - int len; - - err = yp_get_default_domain(&domain); - if (err) { - continue; - } - lookup = NULL; - err = yp_match(domain, PKMAP, key, strlen(key), &lookup, &len); - if (err) { -#ifdef DEBUG - fprintf(stderr, "match failed error %d\n", err); -#endif - continue; - } - lookup[len] = 0; - strcpy(ret, lookup); - fclose(fd); - free(lookup); - return (2); -#else /* YP */ -#ifdef DEBUG - fprintf(stderr, -"Bad record in %s '+' -- NIS not supported in this library copy\n", PKFILE); -#endif /* DEBUG */ - continue; -#endif /* YP */ - } else { - mkey = strtok(buf, "\t "); - if (mkey == NULL) { - fprintf(stderr, - "Bad record in %s -- %s", PKFILE, buf); - continue; - } - mval = strtok((char *)NULL, " \t#\n"); - if (mval == NULL) { - fprintf(stderr, - "Bad record in %s val problem - %s", PKFILE, buf); - continue; - } - if (strcmp(mkey, key) == 0) { - strcpy(ret, mval); - fclose(fd); - return (1); - } - } - } -} - -int getpublickey(netname, publickey) - char *netname; - char *publickey; -{ - if (__getpublickey_LOCAL != NULL) - return(__getpublickey_LOCAL(netname, publickey)); - else - return(__getpublickey_real(netname, publickey)); -} diff --git a/c/src/librpc/src/rpc/getrpcent.3 b/c/src/librpc/src/rpc/getrpcent.3 deleted file mode 100644 index 1e92e9d03d..0000000000 --- a/c/src/librpc/src/rpc/getrpcent.3 +++ /dev/null @@ -1,98 +0,0 @@ -.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI -.\" $FreeBSD: src/lib/libc/rpc/getrpcent.3,v 1.11 1999/08/28 00:00:39 peter Exp $ -.\" -.Dd December 14, 1987 -.Dt GETRPCENT 3 -.Os -.Sh NAME -.Nm getrpcent , -.Nm getrpcbyname , -.Nm getrpcbynumber , -.Nm endrpcent , -.Nm setrpcent -.Nd get RPC entry -.Sh SYNOPSIS -.Fd #include -.Ft struct rpcent * -.Fn getrpcent void -.Ft struct rpcent * -.Fn getrpcbyname "char *name" -.Ft struct rpcent * -.Fn getrpcbynumber "int number" -.Ft void -.Fn setrpcent "int stayopen" -.Ft void -.Fn endrpcent void -.Sh DESCRIPTION -The -.Fn getrpcent , -.Fn getrpcbyname , -and -.Fn getrpcbynumber -functions each return a pointer to an object with the -following structure -containing the broken-out -fields of a line in the rpc program number data base, -.Pa /etc/rpc . -.Bd -literal - -struct rpcent { - char *r_name; /* name of server for this rpc program */ - char **r_aliases; /* alias list */ - long r_number; /* rpc program number */ -}; -.Ed -.Pp -The members of this structure are: -.Bl -tag -width r_aliasesxxx -.It Fa r_name -The name of the server for this rpc program. -.It Fa r_aliases -A zero terminated list of alternate names for the rpc program. -.It Fa r_number -The rpc program number for this service. -.El -.Pp -The -.Fn getrpcent -function reads the next line of the file, opening the file if necessary. -The -.Nm getrpcent -function opens and rewinds the file. If the -.Fa stayopen -flag is non-zero, -the net data base will not be closed after each call to -.Fn getrpcent -(either directly, or indirectly through one of -the other -.Fn getrpcent -function family. -.Pp -.Fn endrpcent -closes the file. -.Pp -.Fn getrpcbyname -and -.Fn getrpcbynumber -sequentially search from the beginning -of the file until a matching rpc program name or -program number is found, or until end-of-file is encountered. -.Sh FILES -.Bl -tag -width /etc/rpc -compact -.It Pa /etc/rpc -.El -.Sh "SEE ALSO" -.Xr rpc 5 , -.Xr rpcinfo 8 , -.Xr ypserv 8 -.Sh DIAGNOSTICS -A -.Dv NULL -pointer is returned on -.Dv EOF -or error. -.Sh BUGS -All information -is contained in a static area -so it must be copied if it is -to be saved. diff --git a/c/src/librpc/src/rpc/getrpcent.c b/c/src/librpc/src/rpc/getrpcent.c deleted file mode 100644 index bdcf7172cb..0000000000 --- a/c/src/librpc/src/rpc/getrpcent.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * 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 or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/getrpcent.c,v 1.10 1999/08/28 00:00:39 peter Exp $"; -#endif - -/* - * Copyright (c) 1984 by Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#ifdef YP -#include -#include -#endif - -/* - * Internet version. - */ -struct rpcdata { - FILE *rpcf; - int stayopen; -#define MAXALIASES 35 - char *rpc_aliases[MAXALIASES]; - struct rpcent rpc; - char line[BUFSIZ+1]; -#ifdef YP - char *domain; - char *current; - int currentlen; -#endif -} *rpcdata; - -#ifdef YP -static int __yp_nomap = 0; -extern int _yp_check(char **); -#endif /* YP */ - -static struct rpcent *interpret(); -struct hostent *gethostent(); -char *inet_ntoa(); - -static char RPCDB[] = "/etc/rpc"; - -static struct rpcdata * -_rpcdata() -{ - register struct rpcdata *d = rpcdata; - - if (d == 0) { - d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); - rpcdata = d; - } - return (d); -} - -struct rpcent * -getrpcbynumber(number) - register int number; -{ - register struct rpcdata *d = _rpcdata(); - register struct rpcent *p; -#ifdef YP - int reason; - char adrstr[16]; -#endif - - if (d == 0) - return (0); -#ifdef YP - if (!__yp_nomap && _yp_check(&d->domain)) { - sprintf(adrstr, "%d", number); - reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr), - &d->current, &d->currentlen); - switch(reason) { - case 0: - break; - case YPERR_MAP: - __yp_nomap = 1; - goto no_yp; - break; - default: - return(0); - break; - } - d->current[d->currentlen] = '\0'; - p = interpret(d->current, d->currentlen); - (void) free(d->current); - return p; - } -no_yp: -#endif /* YP */ - setrpcent(0); - while ((p = getrpcent())) { - if (p->r_number == number) - break; - } - endrpcent(); - return (p); -} - -struct rpcent * -getrpcbyname(name) - char *name; -{ - struct rpcent *rpc = NULL; - char **rp; - - setrpcent(0); - while ((rpc = getrpcent())) { - if (strcmp(rpc->r_name, name) == 0) - goto done; - for (rp = rpc->r_aliases; *rp != NULL; rp++) { - if (strcmp(*rp, name) == 0) - goto done; - } - } -done: - endrpcent(); - return (rpc); -} - -void -setrpcent(f) - int f; -{ - register struct rpcdata *d = _rpcdata(); - - if (d == 0) - return; -#ifdef YP - if (!__yp_nomap && _yp_check(NULL)) { - if (d->current) - free(d->current); - d->current = NULL; - d->currentlen = 0; - return; - } - __yp_nomap = 0; -#endif /* YP */ - if (d->rpcf == NULL) - d->rpcf = fopen(RPCDB, "r"); - else - rewind(d->rpcf); - d->stayopen |= f; -} - -void -endrpcent() -{ - register struct rpcdata *d = _rpcdata(); - - if (d == 0) - return; -#ifdef YP - if (!__yp_nomap && _yp_check(NULL)) { - if (d->current && !d->stayopen) - free(d->current); - d->current = NULL; - d->currentlen = 0; - return; - } - __yp_nomap = 0; -#endif /* YP */ - if (d->rpcf && !d->stayopen) { - fclose(d->rpcf); - d->rpcf = NULL; - } -} - -struct rpcent * -getrpcent() -{ - register struct rpcdata *d = _rpcdata(); -#ifdef YP - struct rpcent *hp; - int reason; - char *val = NULL; - int vallen; -#endif - - if (d == 0) - return(NULL); -#ifdef YP - if (!__yp_nomap && _yp_check(&d->domain)) { - if (d->current == NULL && d->currentlen == 0) { - reason = yp_first(d->domain, "rpc.bynumber", - &d->current, &d->currentlen, - &val, &vallen); - } else { - reason = yp_next(d->domain, "rpc.bynumber", - d->current, d->currentlen, - &d->current, &d->currentlen, - &val, &vallen); - } - switch(reason) { - case 0: - break; - case YPERR_MAP: - __yp_nomap = 1; - goto no_yp; - break; - default: - return(0); - break; - } - val[vallen] = '\0'; - hp = interpret(val, vallen); - (void) free(val); - return hp; - } -no_yp: -#endif /* YP */ - if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) - return (NULL); - /* -1 so there is room to append a \n below */ - if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL) - return (NULL); - return (interpret(d->line, strlen(d->line))); -} - -static struct rpcent * -interpret(val, len) - char *val; - int len; -{ - register struct rpcdata *d = _rpcdata(); - char *p; - register char *cp, **q; - - if (d == 0) - return (0); - (void) strncpy(d->line, val, BUFSIZ); - d->line[BUFSIZ] = '\0'; - p = d->line; - p[len] = '\n'; - if (*p == '#') - return (getrpcent()); - cp = strpbrk(p, "#\n"); - if (cp == NULL) - return (getrpcent()); - *cp = '\0'; - cp = strpbrk(p, " \t"); - if (cp == NULL) - return (getrpcent()); - *cp++ = '\0'; - /* THIS STUFF IS INTERNET SPECIFIC */ - d->rpc.r_name = d->line; - while (*cp == ' ' || *cp == '\t') - cp++; - d->rpc.r_number = atoi(cp); - q = d->rpc.r_aliases = d->rpc_aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - if (q < &(d->rpc_aliases[MAXALIASES - 1])) - *q++ = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - } - *q = NULL; - return (&d->rpc); -} - diff --git a/c/src/librpc/src/rpc/getrpcport.3 b/c/src/librpc/src/rpc/getrpcport.3 deleted file mode 100644 index 0e9175ec12..0000000000 --- a/c/src/librpc/src/rpc/getrpcport.3 +++ /dev/null @@ -1,31 +0,0 @@ -.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI -.\" $FreeBSD: src/lib/libc/rpc/getrpcport.3,v 1.6 1999/08/28 00:00:40 peter Exp $ -.\" -.Dd October 6, 1987 -.Dt GETRPCPORT 3 -.Os -.Sh NAME -.Nm getrpcport -.Nd get RPC port number -.Sh SYNOPSIS -.Ft int -.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto" -.Sh DESCRIPTION -.Fn getrpcport -returns the port number for version -.Fa versnum -of the RPC program -.Fa prognum -running on -.Fa host -and using protocol -.Fa proto . -It returns 0 if it cannot contact the portmapper, or if -.Fa prognum -is not registered. If -.Fa prognum -is registered but not with version -.Fa versnum , -it will still return a port number (for some version of the program) -indicating that the program is indeed registered. -The version mismatch will be detected upon the first call to the service. diff --git a/c/src/librpc/src/rpc/getrpcport.c b/c/src/librpc/src/rpc/getrpcport.c deleted file mode 100644 index 8d17615c66..0000000000 --- a/c/src/librpc/src/rpc/getrpcport.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/ -/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/getrpcport.c,v 1.10 1999/08/28 00:00:40 peter Exp $"; -#endif - -/* - * Copyright (c) 1985 by Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include - -int -getrpcport(host, prognum, versnum, proto) - char *host; - int prognum, versnum, proto; -{ - struct sockaddr_in addr; - struct hostent *hp; - - if ((hp = gethostbyname(host)) == NULL) - return (0); - memset(&addr, 0, sizeof(addr)); - addr.sin_len = sizeof(struct sockaddr_in); - addr.sin_family = AF_INET; - addr.sin_port = 0; - memcpy((char *)&addr.sin_addr, hp->h_addr, hp->h_length); - return (pmap_getport(&addr, prognum, versnum, proto)); -} diff --git a/c/src/librpc/src/rpc/key_call.c b/c/src/librpc/src/rpc/key_call.c deleted file mode 100644 index 98df0d1f95..0000000000 --- a/c/src/librpc/src/rpc/key_call.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986-1991 by Sun Microsystems Inc. - * - * $FreeBSD: src/lib/libc/rpc/key_call.c,v 1.3 2000/01/27 23:06:39 jasone Exp $ - */ - -#ident "@(#)key_call.c 1.25 94/04/24 SMI" - -/* - * key_call.c, Interface to keyserver - * - * setsecretkey(key) - set your secret key - * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent - * decryptsessionkey(agent, deskey) - decrypt ditto - * gendeskey(deskey) - generate a secure des key - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define KEY_TIMEOUT 5 /* per-try timeout in seconds */ -#define KEY_NRETRY 12 /* number of retries */ - -#ifdef DEBUG -#define debug(msg) (void) fprintf(stderr, "%s\n", msg); -#else -#define debug(msg) -#endif /* DEBUG */ - -/* - * Hack to allow the keyserver to use AUTH_DES (for authenticated - * NIS+ calls, for example). The only functions that get called - * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. - * - * The approach is to have the keyserver fill in pointers to local - * implementations of these functions, and to call those in key_call(). - */ - -cryptkeyres *(*__key_encryptsession_pk_LOCAL)() = 0; -cryptkeyres *(*__key_decryptsession_pk_LOCAL)() = 0; -des_block *(*__key_gendes_LOCAL)() = 0; - -static int key_call __P(( u_long, xdrproc_t, char *, xdrproc_t, char * )); - -int -key_setsecret(secretkey) - const char *secretkey; -{ - keystatus status; - - if (!key_call((u_long) KEY_SET, xdr_keybuf, (char *) secretkey, - xdr_keystatus, (char *)&status)) { - return (-1); - } - if (status != KEY_SUCCESS) { - debug("set status is nonzero"); - return (-1); - } - return (0); -} - - -/* key_secretkey_is_set() returns 1 if the keyserver has a secret key - * stored for the caller's effective uid; it returns 0 otherwise - * - * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't - * be using it, because it allows them to get the user's secret key. - */ - -int -key_secretkey_is_set(void) -{ - struct key_netstres kres; - - memset((void*)&kres, 0, sizeof (kres)); - if (key_call((u_long) KEY_NET_GET, xdr_void, (char *)NULL, - xdr_key_netstres, (char *) &kres) && - (kres.status == KEY_SUCCESS) && - (kres.key_netstres_u.knet.st_priv_key[0] != 0)) { - /* avoid leaving secret key in memory */ - memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES); - return (1); - } - return (0); -} - -int -key_encryptsession_pk(remotename, remotekey, deskey) - char *remotename; - netobj *remotekey; - des_block *deskey; -{ - cryptkeyarg2 arg; - cryptkeyres res; - - arg.remotename = remotename; - arg.remotekey = *remotekey; - arg.deskey = *deskey; - if (!key_call((u_long)KEY_ENCRYPT_PK, xdr_cryptkeyarg2, (char *)&arg, - xdr_cryptkeyres, (char *)&res)) { - return (-1); - } - if (res.status != KEY_SUCCESS) { - debug("encrypt status is nonzero"); - return (-1); - } - *deskey = res.cryptkeyres_u.deskey; - return (0); -} - -int -key_decryptsession_pk(remotename, remotekey, deskey) - char *remotename; - netobj *remotekey; - des_block *deskey; -{ - cryptkeyarg2 arg; - cryptkeyres res; - - arg.remotename = remotename; - arg.remotekey = *remotekey; - arg.deskey = *deskey; - if (!key_call((u_long)KEY_DECRYPT_PK, xdr_cryptkeyarg2, (char *)&arg, - xdr_cryptkeyres, (char *)&res)) { - return (-1); - } - if (res.status != KEY_SUCCESS) { - debug("decrypt status is nonzero"); - return (-1); - } - *deskey = res.cryptkeyres_u.deskey; - return (0); -} - -int -key_encryptsession(remotename, deskey) - const char *remotename; - des_block *deskey; -{ - cryptkeyarg arg; - cryptkeyres res; - - arg.remotename = (char *) remotename; - arg.deskey = *deskey; - if (!key_call((u_long)KEY_ENCRYPT, xdr_cryptkeyarg, (char *)&arg, - xdr_cryptkeyres, (char *)&res)) { - return (-1); - } - if (res.status != KEY_SUCCESS) { - debug("encrypt status is nonzero"); - return (-1); - } - *deskey = res.cryptkeyres_u.deskey; - return (0); -} - -int -key_decryptsession(remotename, deskey) - const char *remotename; - des_block *deskey; -{ - cryptkeyarg arg; - cryptkeyres res; - - arg.remotename = (char *) remotename; - arg.deskey = *deskey; - if (!key_call((u_long)KEY_DECRYPT, xdr_cryptkeyarg, (char *)&arg, - xdr_cryptkeyres, (char *)&res)) { - return (-1); - } - if (res.status != KEY_SUCCESS) { - debug("decrypt status is nonzero"); - return (-1); - } - *deskey = res.cryptkeyres_u.deskey; - return (0); -} - -int -key_gendes(key) - des_block *key; -{ - if (!key_call((u_long)KEY_GEN, xdr_void, (char *)NULL, - xdr_des_block, (char *)key)) { - return (-1); - } - return (0); -} - -int -key_setnet(arg) -struct netstarg *arg; -{ - keystatus status; - - - if (!key_call((u_long) KEY_NET_PUT, xdr_key_netstarg, (char *) arg, - xdr_keystatus, (char *) &status)){ - return (-1); - } - - if (status != KEY_SUCCESS) { - debug("key_setnet status is nonzero"); - return (-1); - } - return (1); -} - - -int -key_get_conv(pkey, deskey) - char *pkey; - des_block *deskey; -{ - cryptkeyres res; - - if (!key_call((u_long) KEY_GET_CONV, xdr_keybuf, pkey, - xdr_cryptkeyres, (char *)&res)) { - return (-1); - } - if (res.status != KEY_SUCCESS) { - debug("get_conv status is nonzero"); - return (-1); - } - *deskey = res.cryptkeyres_u.deskey; - return (0); -} - -struct key_call_private { - CLIENT *client; /* Client handle */ - pid_t pid; /* process-id at moment of creation */ - uid_t uid; /* user-id at last authorization */ -}; -static struct key_call_private *key_call_private_main = NULL; - -#ifdef foo -static void -key_call_destroy(void *vp) -{ - register struct key_call_private *kcp = (struct key_call_private *)vp; - - if (kcp) { - if (kcp->client) - clnt_destroy(kcp->client); - free(kcp); - } -} -#endif - -/* - * Keep the handle cached. This call may be made quite often. - */ -static CLIENT * -getkeyserv_handle(vers) -int vers; -{ - struct key_call_private *kcp = key_call_private_main; - struct timeval wait_time; - int fd; - struct sockaddr_un name; - int namelen = sizeof(struct sockaddr_un); - -#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */ -#define TOTAL_TRIES 5 /* Number of tries */ - - if (kcp == (struct key_call_private *)NULL) { - kcp = (struct key_call_private *)malloc(sizeof (*kcp)); - if (kcp == (struct key_call_private *)NULL) { - return ((CLIENT *) NULL); - } - key_call_private_main = kcp; - kcp->client = NULL; - } - - /* if pid has changed, destroy client and rebuild */ - if (kcp->client != NULL && kcp->pid != getpid()) { - clnt_destroy(kcp->client); - kcp->client = NULL; - } - - if (kcp->client != NULL) { - /* if other side closed socket, build handle again */ - clnt_control(kcp->client, CLGET_FD, (char *)&fd); - if (getpeername(fd,(struct sockaddr *)&name,&namelen) == -1) { - auth_destroy(kcp->client->cl_auth); - clnt_destroy(kcp->client); - kcp->client = NULL; - } - } - - if (kcp->client != NULL) { - /* if uid has changed, build client handle again */ - if (kcp->uid != geteuid()) { - kcp->uid = geteuid(); - auth_destroy(kcp->client->cl_auth); - kcp->client->cl_auth = - authsys_create("", kcp->uid, 0, 0, NULL); - if (kcp->client->cl_auth == NULL) { - clnt_destroy(kcp->client); - kcp->client = NULL; - return ((CLIENT *) NULL); - } - } - /* Change the version number to the new one */ - clnt_control(kcp->client, CLSET_VERS, (void *)&vers); - return (kcp->client); - } - - if ((kcp->client == (CLIENT *) NULL)) - /* Use the AF_UNIX transport */ - kcp->client = clnt_create("/var/run/keyservsock", KEY_PROG, - vers, "unix"); - - if (kcp->client == (CLIENT *) NULL) { - return ((CLIENT *) NULL); - } - kcp->uid = geteuid(); - kcp->pid = getpid(); - kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL); - if (kcp->client->cl_auth == NULL) { - clnt_destroy(kcp->client); - kcp->client = NULL; - return ((CLIENT *) NULL); - } - - wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES; - wait_time.tv_usec = 0; - (void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT, - (char *)&wait_time); - if (clnt_control(kcp->client, CLGET_FD, (char *)&fd)) - _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */ - - return (kcp->client); -} - -/* returns 0 on failure, 1 on success */ - -static int -key_call(proc, xdr_arg, arg, xdr_rslt, rslt) - u_long proc; - xdrproc_t xdr_arg; - char *arg; - xdrproc_t xdr_rslt; - char *rslt; -{ - CLIENT *clnt; - struct timeval wait_time; - - if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) { - cryptkeyres *res; - res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg); - *(cryptkeyres*)rslt = *res; - return (1); - } else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) { - cryptkeyres *res; - res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg); - *(cryptkeyres*)rslt = *res; - return (1); - } else if (proc == KEY_GEN && __key_gendes_LOCAL) { - des_block *res; - res = (*__key_gendes_LOCAL)(geteuid(), 0); - *(des_block*)rslt = *res; - return (1); - } - - if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) || - (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) || - (proc == KEY_GET_CONV)) - clnt = getkeyserv_handle(2); /* talk to version 2 */ - else - clnt = getkeyserv_handle(1); /* talk to version 1 */ - - if (clnt == NULL) { - return (0); - } - - wait_time.tv_sec = TOTAL_TIMEOUT; - wait_time.tv_usec = 0; - - if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt, - wait_time) == RPC_SUCCESS) { - return (1); - } else { - return (0); - } -} diff --git a/c/src/librpc/src/rpc/key_prot_xdr.c b/c/src/librpc/src/rpc/key_prot_xdr.c deleted file mode 100644 index 8cd6b6b067..0000000000 --- a/c/src/librpc/src/rpc/key_prot_xdr.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Please do not edit this file. - * It was generated using rpcgen. - */ - -#include -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" - -/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */ - -/* - * Compiled from key_prot.x using rpcgen. - * DO NOT EDIT THIS FILE! - * This is NOT source code! - */ - -bool_t -xdr_keystatus(register XDR *xdrs, keystatus *objp) -{ - - if (!xdr_enum(xdrs, (enum_t *)objp)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_keybuf(register XDR *xdrs, keybuf objp) -{ - - if (!xdr_opaque(xdrs, objp, HEXKEYBYTES)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_netnamestr(register XDR *xdrs, netnamestr *objp) -{ - - if (!xdr_string(xdrs, objp, MAXNETNAMELEN)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_cryptkeyarg(register XDR *xdrs, cryptkeyarg *objp) -{ - - if (!xdr_netnamestr(xdrs, &objp->remotename)) - return (FALSE); - if (!xdr_des_block(xdrs, &objp->deskey)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_cryptkeyarg2(register XDR *xdrs, cryptkeyarg2 *objp) -{ - - if (!xdr_netnamestr(xdrs, &objp->remotename)) - return (FALSE); - if (!xdr_netobj(xdrs, &objp->remotekey)) - return (FALSE); - if (!xdr_des_block(xdrs, &objp->deskey)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_cryptkeyres(register XDR *xdrs, cryptkeyres *objp) -{ - - if (!xdr_keystatus(xdrs, &objp->status)) - return (FALSE); - switch (objp->status) { - case KEY_SUCCESS: - if (!xdr_des_block(xdrs, &objp->cryptkeyres_u.deskey)) - return (FALSE); - break; - } - return (TRUE); -} - -bool_t -xdr_unixcred(register XDR *xdrs, unixcred *objp) -{ - - if (!xdr_u_int(xdrs, &objp->uid)) - return (FALSE); - if (!xdr_u_int(xdrs, &objp->gid)) - return (FALSE); - if (!xdr_array(xdrs, (char **)&objp->gids.gids_val, (u_int *) &objp->gids.gids_len, MAXGIDS, - sizeof (u_int), (xdrproc_t) xdr_u_int)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_getcredres(register XDR *xdrs, getcredres *objp) -{ - - if (!xdr_keystatus(xdrs, &objp->status)) - return (FALSE); - switch (objp->status) { - case KEY_SUCCESS: - if (!xdr_unixcred(xdrs, &objp->getcredres_u.cred)) - return (FALSE); - break; - } - return (TRUE); -} - -bool_t -xdr_key_netstarg(register XDR *xdrs, key_netstarg *objp) -{ - - if (!xdr_keybuf(xdrs, objp->st_priv_key)) - return (FALSE); - if (!xdr_keybuf(xdrs, objp->st_pub_key)) - return (FALSE); - if (!xdr_netnamestr(xdrs, &objp->st_netname)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_key_netstres(register XDR *xdrs, key_netstres *objp) -{ - - if (!xdr_keystatus(xdrs, &objp->status)) - return (FALSE); - switch (objp->status) { - case KEY_SUCCESS: - if (!xdr_key_netstarg(xdrs, &objp->key_netstres_u.knet)) - return (FALSE); - break; - } - return (TRUE); -} diff --git a/c/src/librpc/src/rpc/netname.c b/c/src/librpc/src/rpc/netname.c deleted file mode 100644 index 22167bee86..0000000000 --- a/c/src/librpc/src/rpc/netname.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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 or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro"; -#endif - -/* - * netname utility routines - * convert from unix names to network names and vice-versa - * This module is operating system dependent! - * What we define here will work with any unix system that has adopted - * the sun NIS domain architecture. - */ - -#include -#include -#include -#ifdef YP -#include -#include -#endif -#include -#include -#include -#include -#include - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif -#ifndef NGROUPS -#define NGROUPS 16 -#endif - -static char *OPSYS = "unix"; - -/* - * Figure out my fully qualified network name - */ -int -getnetname(name) - char name[MAXNETNAMELEN+1]; -{ - uid_t uid; - - uid = geteuid(); - if (uid == 0) { - return (host2netname(name, (char *) NULL, (char *) NULL)); - } else { - return (user2netname(name, uid, (char *) NULL)); - } -} - - -/* - * Convert unix cred to network-name - */ -int -user2netname(netname, uid, domain) - char netname[MAXNETNAMELEN + 1]; - uid_t uid; - char *domain; -{ - char *dfltdom; - -#define MAXIPRINT (11) /* max length of printed integer */ - - if (domain == NULL) { - if (_rpc_get_default_domain(&dfltdom) != 0) { - return (0); - } - domain = dfltdom; - } - if (strlen(domain) + 1 + MAXIPRINT > MAXNETNAMELEN) { - return (0); - } - (void) sprintf(netname, "%s.%ld@%s", OPSYS, (u_long)uid, domain); - return (1); -} - - -/* - * Convert host to network-name - */ -int -host2netname(netname, host, domain) - char netname[MAXNETNAMELEN + 1]; - char *host; - char *domain; -{ - char *dfltdom; - char hostname[MAXHOSTNAMELEN+1]; - - if (domain == NULL) { - if (_rpc_get_default_domain(&dfltdom) != 0) { - return (0); - } - domain = dfltdom; - } - if (host == NULL) { - (void) gethostname(hostname, sizeof(hostname)); - host = hostname; - } - if (strlen(domain) + 1 + strlen(host) > MAXNETNAMELEN) { - return (0); - } - (void) sprintf(netname, "%s.%s@%s", OPSYS, host, domain); - return (1); -} diff --git a/c/src/librpc/src/rpc/netnamer.c b/c/src/librpc/src/rpc/netnamer.c deleted file mode 100644 index eac9913119..0000000000 --- a/c/src/librpc/src/rpc/netnamer.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * 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 or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; -#endif -/* - * netname utility routines convert from unix names to network names and - * vice-versa This module is operating system dependent! What we define here - * will work with any unix system that has adopted the sun NIS domain - * architecture. - */ -#include -#include -#include -#ifdef YP -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -static char *OPSYS = "unix"; -#ifdef YP -static char *NETID = "netid.byname"; -#endif -static char *NETIDFILE = "/etc/netid"; - -static int getnetid __P(( char *, char * )); -static int _getgroups __P(( char *, gid_t * )); - -#ifndef NGROUPS -#define NGROUPS 16 -#endif - -/* - * Convert network-name into unix credential - */ -int -netname2user(netname, uidp, gidp, gidlenp, gidlist) - char netname[MAXNETNAMELEN + 1]; - uid_t *uidp; - gid_t *gidp; - int *gidlenp; - gid_t *gidlist; -{ - char *p; - int gidlen; - uid_t uid; - long luid; - struct passwd *pwd; - char val[1024]; - char *val1, *val2; - char *domain; - int vallen; - int err; - - if (getnetid(netname, val)) { - p = strtok(val, ":"); - if (p == NULL) - return (0); - *uidp = (uid_t) atol(val); - p = strtok(NULL, "\n,"); - *gidp = (gid_t) atol(p); - if (p == NULL) { - return (0); - } - gidlen = 0; - for (gidlen = 0; gidlen < NGROUPS; gidlen++) { - p = strtok(NULL, "\n,"); - if (p == NULL) - break; - gidlist[gidlen] = (gid_t) atol(p); - } - *gidlenp = gidlen; - - return (1); - } - val1 = strchr(netname, '.'); - if (val1 == NULL) - return (0); - if (strncmp(netname, OPSYS, (val1-netname))) - return (0); - val1++; - val2 = strchr(val1, '@'); - if (val2 == NULL) - return (0); - vallen = val2 - val1; - if (vallen > (1024 - 1)) - vallen = 1024 - 1; - (void) strncpy(val, val1, 1024); - val[vallen] = 0; - - err = _rpc_get_default_domain(&domain); /* change to rpc */ - if (err) - return (0); - - if (strcmp(val2 + 1, domain)) - return (0); /* wrong domain */ - - if (sscanf(val, "%ld", &luid) != 1) - return (0); - uid = luid; - - /* use initgroups method */ - pwd = getpwuid(uid); - if (pwd == NULL) - return (0); - *uidp = pwd->pw_uid; - *gidp = pwd->pw_gid; - *gidlenp = _getgroups(pwd->pw_name, gidlist); - return (1); -} - -/* - * initgroups - */ - -static int -_getgroups(uname, groups) - char *uname; - gid_t groups[NGROUPS]; -{ - gid_t ngroups = 0; - register struct group *grp; - register int i; - register int j; - int filter; - - setgrent(); - while ((grp = getgrent())) { - for (i = 0; grp->gr_mem[i]; i++) - if (!strcmp(grp->gr_mem[i], uname)) { - if (ngroups == NGROUPS) { -#ifdef DEBUG - fprintf(stderr, - "initgroups: %s is in too many groups\n", uname); -#endif - goto toomany; - } - /* filter out duplicate group entries */ - filter = 0; - for (j = 0; j < ngroups; j++) - if (groups[j] == grp->gr_gid) { - filter++; - break; - } - if (!filter) - groups[ngroups++] = grp->gr_gid; - } - } -toomany: - endgrent(); - return (ngroups); -} - -/* - * Convert network-name to hostname - */ -int -netname2host(netname, hostname, hostlen) - char netname[MAXNETNAMELEN + 1]; - char *hostname; - int hostlen; -{ - int err; - char valbuf[1024]; - char *val; - char *val2; - int vallen; - char *domain; - - if (getnetid(netname, valbuf)) { - val = valbuf; - if ((*val == '0') && (val[1] == ':')) { - (void) strncpy(hostname, val + 2, hostlen); - return (1); - } - } - val = strchr(netname, '.'); - if (val == NULL) - return (0); - if (strncmp(netname, OPSYS, (val - netname))) - return (0); - val++; - val2 = strchr(val, '@'); - if (val2 == NULL) - return (0); - vallen = val2 - val; - if (vallen > (hostlen - 1)) - vallen = hostlen - 1; - (void) strncpy(hostname, val, vallen); - hostname[vallen] = 0; - - err = _rpc_get_default_domain(&domain); /* change to rpc */ - if (err) - return (0); - - if (strcmp(val2 + 1, domain)) - return (0); /* wrong domain */ - else - return (1); -} - -/* - * reads the file /etc/netid looking for a + to optionally go to the - * network information service. - */ -int -getnetid(key, ret) - char *key, *ret; -{ - char buf[1024]; /* big enough */ - char *res; - char *mkey; - char *mval; - FILE *fd; -#ifdef YP - char *domain; - int err; - char *lookup; - int len; -#endif - - fd = fopen(NETIDFILE, "r"); - if (fd == (FILE *) 0) { -#ifdef YP - res = "+"; - goto getnetidyp; -#else - return (0); -#endif - } - for (;;) { - if (fd == (FILE *) 0) - return (0); /* getnetidyp brings us here */ - res = fgets(buf, 1024, fd); - if (res == 0) { - fclose(fd); - return (0); - } - if (res[0] == '#') - continue; - else if (res[0] == '+') { -#ifdef YP - getnetidyp: - err = yp_get_default_domain(&domain); - if (err) { - continue; - } - lookup = NULL; - err = yp_match(domain, NETID, key, - strlen(key), &lookup, &len); - if (err) { -#ifdef DEBUG - fprintf(stderr, "match failed error %d\n", err); -#endif - continue; - } - lookup[len] = 0; - strcpy(ret, lookup); - free(lookup); - if (fd != NULL) - fclose(fd); - return (2); -#else /* YP */ -#ifdef DEBUG - fprintf(stderr, -"Bad record in %s '+' -- NIS not supported in this library copy\n", - NETIDFILE); -#endif - continue; -#endif /* YP */ - } else { - mkey = strtok(buf, "\t "); - if (mkey == NULL) { - fprintf(stderr, - "Bad record in %s -- %s", NETIDFILE, buf); - continue; - } - mval = strtok(NULL, " \t#\n"); - if (mval == NULL) { - fprintf(stderr, - "Bad record in %s val problem - %s", NETIDFILE, buf); - continue; - } - if (strcmp(mkey, key) == 0) { - strcpy(ret, mval); - fclose(fd); - return (1); - - } - } - } -} diff --git a/c/src/librpc/src/rpc/pmap_clnt.c b/c/src/librpc/src/rpc/pmap_clnt.c deleted file mode 100644 index 469e65b233..0000000000 --- a/c/src/librpc/src/rpc/pmap_clnt.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_clnt.c,v 1.11 2000/01/27 23:06:39 jasone Exp $"; -#endif - -/* - * pmap_clnt.c - * Client interface to pmap rpc service. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include - -static struct timeval timeout = { 5, 0 }; -static struct timeval tottimeout = { 60, 0 }; - -void clnt_perror(); - -#ifndef PORTMAPSOCK -#define PORTMAPSOCK "/var/run/portmapsock" -#endif - -/* - * Set a mapping between program,version and port. - * Calls the pmap service remotely to do the mapping. - */ -bool_t -pmap_set(program, version, protocol, port) - u_long program; - u_long version; - int protocol; - u_short port; -{ - struct sockaddr_in myaddress; - int socket = -1; - register CLIENT *client; - struct pmap parms; - bool_t rslt; - struct stat st; - - /* - * Temporary hack for backwards compatibility. Eventually - * this test will go away and we'll use only the "unix" transport. - */ - if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK) - client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix"); - else { - if (get_myaddress(&myaddress) != 0) - return (FALSE); - myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, - timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); - } - - if (client == (CLIENT *)NULL) - return (FALSE); - parms.pm_prog = program; - parms.pm_vers = version; - parms.pm_prot = protocol; - parms.pm_port = port; - if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt, - tottimeout) != RPC_SUCCESS) { - clnt_perror(client, "Cannot register service"); - return (FALSE); - } - CLNT_DESTROY(client); - if (socket != -1) - (void)_RPC_close(socket); - return (rslt); -} - -/* - * Remove the mapping between program,version and port. - * Calls the pmap service remotely to do the un-mapping. - */ -bool_t -pmap_unset(program, version) - u_long program; - u_long version; -{ - struct sockaddr_in myaddress; - int socket = -1; - register CLIENT *client; - struct pmap parms; - bool_t rslt; - struct stat st; - - /* - * Temporary hack for backwards compatibility. Eventually - * this test will go away and we'll use only the "unix" transport. - */ - if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK) - client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix"); - else { - if (get_myaddress(&myaddress) != 0) - return (FALSE); - myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, - timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); - } - if (client == (CLIENT *)NULL) - return (FALSE); - parms.pm_prog = program; - parms.pm_vers = version; - parms.pm_port = parms.pm_prot = 0; - CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt, - tottimeout); - CLNT_DESTROY(client); - if (socket != -1) - (void)_RPC_close(socket); - return (rslt); -} diff --git a/c/src/librpc/src/rpc/pmap_getmaps.c b/c/src/librpc/src/rpc/pmap_getmaps.c deleted file mode 100644 index 3a5f6aa16e..0000000000 --- a/c/src/librpc/src/rpc/pmap_getmaps.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_getmaps.c,v 1.11 2000/01/27 23:06:39 jasone Exp $"; -#endif - -/* - * pmap_getmap.c - * Client interface to pmap rpc service. - * contains pmap_getmaps, which is only tcp service involved - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define NAMELEN 255 -#define MAX_BROADCAST_SIZE 1400 - -/* - * Get a copy of the current port maps. - * Calls the pmap service remotely to do get the maps. - */ -struct pmaplist * -pmap_getmaps(address) - struct sockaddr_in *address; -{ - struct pmaplist *head = (struct pmaplist *)NULL; - int socket = -1; - struct timeval minutetimeout; - register CLIENT *client; - - minutetimeout.tv_sec = 60; - minutetimeout.tv_usec = 0; - address->sin_port = htons(PMAPPORT); - client = clnttcp_create(address, PMAPPROG, - PMAPVERS, &socket, 50, 500); - if (client != (CLIENT *)NULL) { - if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist, - &head, minutetimeout) != RPC_SUCCESS) { - clnt_perror(client, "pmap_getmaps rpc problem"); - } - CLNT_DESTROY(client); - } - if (socket != -1) - (void)_RPC_close(socket); - address->sin_port = 0; - return (head); -} diff --git a/c/src/librpc/src/rpc/pmap_getport.c b/c/src/librpc/src/rpc/pmap_getport.c deleted file mode 100644 index 4029f1e5b9..0000000000 --- a/c/src/librpc/src/rpc/pmap_getport.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_getport.c,v 1.10 2000/01/27 23:06:40 jasone Exp $"; -#endif - -/* - * pmap_getport.c - * Client interface to pmap rpc service. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include - -static struct timeval timeout = { 5, 0 }; -static struct timeval tottimeout = { 60, 0 }; - -/* - * Find the mapped port for program,version. - * Calls the pmap service remotely to do the lookup. - * Returns 0 if no map exists. - */ -u_short -pmap_getport(address, program, version, protocol) - struct sockaddr_in *address; - u_long program; - u_long version; - u_int protocol; -{ - u_short port = 0; - int socket = -1; - register CLIENT *client; - struct pmap parms; - - address->sin_port = htons(PMAPPORT); - client = clntudp_bufcreate(address, PMAPPROG, - PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); - if (client != (CLIENT *)NULL) { - parms.pm_prog = program; - parms.pm_vers = version; - parms.pm_prot = protocol; - parms.pm_port = 0; /* not needed or used */ - if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, - xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ - rpc_createerr.cf_stat = RPC_PMAPFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - } else if (port == 0) { - rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - } - CLNT_DESTROY(client); - } - if (socket != -1) - (void)_RPC_close(socket); - address->sin_port = 0; - return (port); -} diff --git a/c/src/librpc/src/rpc/pmap_prot.c b/c/src/librpc/src/rpc/pmap_prot.c deleted file mode 100644 index ec7ab30812..0000000000 --- a/c/src/librpc/src/rpc/pmap_prot.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_prot.c,v 1.6 1999/08/28 00:00:42 peter Exp $"; -#endif - -/* - * pmap_prot.c - * Protocol for the local binder service, or pmap. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include - - -bool_t -xdr_pmap(xdrs, regs) - XDR *xdrs; - struct pmap *regs; -{ - - if (xdr_u_long(xdrs, ®s->pm_prog) && - xdr_u_long(xdrs, ®s->pm_vers) && - xdr_u_long(xdrs, ®s->pm_prot)) - return (xdr_u_long(xdrs, ®s->pm_port)); - return (FALSE); -} diff --git a/c/src/librpc/src/rpc/pmap_prot2.c b/c/src/librpc/src/rpc/pmap_prot2.c deleted file mode 100644 index e29efe62c1..0000000000 --- a/c/src/librpc/src/rpc/pmap_prot2.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_prot2.c,v 1.7 1999/08/28 00:00:42 peter Exp $"; -#endif - -/* - * pmap_prot2.c - * Protocol for the local binder service, or pmap. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include - - -/* - * What is going on with linked lists? (!) - * First recall the link list declaration from pmap_prot.h: - * - * struct pmaplist { - * struct pmap pml_map; - * struct pmaplist *pml_map; - * }; - * - * Compare that declaration with a corresponding xdr declaration that - * is (a) pointer-less, and (b) recursive: - * - * typedef union switch (bool_t) { - * - * case TRUE: struct { - * struct pmap; - * pmaplist_t foo; - * }; - * - * case FALSE: struct {}; - * } pmaplist_t; - * - * Notice that the xdr declaration has no nxt pointer while - * the C declaration has no bool_t variable. The bool_t can be - * interpreted as ``more data follows me''; if FALSE then nothing - * follows this bool_t; if TRUE then the bool_t is followed by - * an actual struct pmap, and then (recursively) by the - * xdr union, pamplist_t. - * - * This could be implemented via the xdr_union primitive, though this - * would cause a one recursive call per element in the list. Rather than do - * that we can ``unwind'' the recursion - * into a while loop and do the union arms in-place. - * - * The head of the list is what the C programmer wishes to past around - * the net, yet is the data that the pointer points to which is interesting; - * this sounds like a job for xdr_reference! - */ -bool_t -xdr_pmaplist(xdrs, rp) - register XDR *xdrs; - register struct pmaplist **rp; -{ - /* - * more_elements is pre-computed in case the direction is - * XDR_ENCODE or XDR_FREE. more_elements is overwritten by - * xdr_bool when the direction is XDR_DECODE. - */ - bool_t more_elements; - register int freeing = (xdrs->x_op == XDR_FREE); - register struct pmaplist **next = NULL; - - while (TRUE) { - more_elements = (bool_t)(*rp != NULL); - if (! xdr_bool(xdrs, &more_elements)) - return (FALSE); - if (! more_elements) - return (TRUE); /* we are done */ - /* - * the unfortunate side effect of non-recursion is that in - * the case of freeing we must remember the next object - * before we free the current object ... - */ - if (freeing) - next = &((*rp)->pml_next); - if (! xdr_reference(xdrs, (caddr_t *)rp, - (u_int)sizeof(struct pmaplist), xdr_pmap)) - return (FALSE); - rp = (freeing) ? next : &((*rp)->pml_next); - } -} diff --git a/c/src/librpc/src/rpc/pmap_rmt.c b/c/src/librpc/src/rpc/pmap_rmt.c deleted file mode 100644 index cb04941415..0000000000 --- a/c/src/librpc/src/rpc/pmap_rmt.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_rmt.c,v 1.15 2000/01/27 23:06:40 jasone Exp $"; -#endif - -/* - * pmap_rmt.c - * Client interface to pmap rpc service. - * remote call and broadcast service - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define MAX_BROADCAST_SIZE 1400 - -static struct timeval timeout = { 3, 0 }; - -/* - * pmapper remote-call-service interface. - * This routine is used to call the pmapper remote call service - * which will look up a service program in the port maps, and then - * remotely call that routine with the given parameters. This allows - * programs to do a lookup and call in one step. -*/ -enum clnt_stat -pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr) - struct sockaddr_in *addr; - u_long prog, vers, proc; - xdrproc_t xdrargs, xdrres; - caddr_t argsp, resp; - struct timeval tout; - u_long *port_ptr; -{ - int socket = -1; - register CLIENT *client; - struct rmtcallargs a; - struct rmtcallres r; - enum clnt_stat stat; - - addr->sin_port = htons(PMAPPORT); - client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket); - if (client != (CLIENT *)NULL) { - a.prog = prog; - a.vers = vers; - a.proc = proc; - a.args_ptr = argsp; - a.xdr_args = xdrargs; - r.port_ptr = port_ptr; - r.results_ptr = resp; - r.xdr_results = xdrres; - stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a, - xdr_rmtcallres, &r, tout); - CLNT_DESTROY(client); - } else { - stat = RPC_FAILED; - } - if (socket != -1) - (void)_RPC_close(socket); - addr->sin_port = 0; - return (stat); -} - - -/* - * XDR remote call arguments - * written for XDR_ENCODE direction only - */ -bool_t -xdr_rmtcall_args(xdrs, cap) - register XDR *xdrs; - register struct rmtcallargs *cap; -{ - u_int lenposition, argposition, position; - - if (xdr_u_long(xdrs, &(cap->prog)) && - xdr_u_long(xdrs, &(cap->vers)) && - xdr_u_long(xdrs, &(cap->proc))) { - lenposition = XDR_GETPOS(xdrs); - if (! xdr_u_long(xdrs, &(cap->arglen))) - return (FALSE); - argposition = XDR_GETPOS(xdrs); - if (! (*(cap->xdr_args))(xdrs, cap->args_ptr)) - return (FALSE); - position = XDR_GETPOS(xdrs); - cap->arglen = (u_long)position - (u_long)argposition; - XDR_SETPOS(xdrs, lenposition); - if (! xdr_u_long(xdrs, &(cap->arglen))) - return (FALSE); - XDR_SETPOS(xdrs, position); - return (TRUE); - } - return (FALSE); -} - -/* - * XDR remote call results - * written for XDR_DECODE direction only - */ -bool_t -xdr_rmtcallres(xdrs, crp) - register XDR *xdrs; - register struct rmtcallres *crp; -{ - caddr_t port_ptr; - - port_ptr = (caddr_t)crp->port_ptr; - if (xdr_reference(xdrs, &port_ptr, sizeof (u_long), - xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { - crp->port_ptr = (u_long *)port_ptr; - return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); - } - return (FALSE); -} - - -/* - * The following is kludged-up support for simple rpc broadcasts. - * Someday a large, complicated system will replace these trivial - * routines which only support udp/ip . - */ - -static int -getbroadcastnets(addrs, sock, buf) - struct in_addr *addrs; - int sock; /* any valid socket will do */ - char *buf; /* why allocxate more when we can use existing... */ -{ - struct ifconf ifc; - struct ifreq ifreq, *ifr; - struct sockaddr_in *sin; - struct in_addr addr; - char *cp, *cplim; - int n, i = 0; - - ifc.ifc_len = UDPMSGSIZE; - ifc.ifc_buf = buf; - if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { - perror("broadcast: ioctl (get interface configuration)"); - return (0); - } -#define max(a, b) (a > b ? a : b) -#define size(p) max((p).sa_len, sizeof(p)) - cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ - for (cp = buf; cp < cplim; - cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { - ifr = (struct ifreq *)cp; - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ifreq = *ifr; - if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) { - perror("broadcast: ioctl (get interface flags)"); - continue; - } - if ((ifreq.ifr_flags & IFF_BROADCAST) && - (ifreq.ifr_flags & IFF_UP)) { - sin = (struct sockaddr_in *)&ifr->ifr_addr; -#ifdef SIOCGIFBRDADDR /* 4.3BSD */ - if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { - addr = - inet_makeaddr(inet_netof(sin->sin_addr), - INADDR_ANY); - } else { - addr = ((struct sockaddr_in*) - &ifreq.ifr_addr)->sin_addr; - } -#else /* 4.2 BSD */ - addr = inet_makeaddr(inet_netof(sin->sin_addr), - INADDR_ANY); -#endif - for (n=i-1; n>=0; n--) { - if (addr.s_addr == addrs[n].s_addr) - break; - } - if (n<0) { - addrs[i++] = addr; - } - } - } - return (i); -} - -typedef bool_t (*resultproc_t)(); - -enum clnt_stat -clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) - u_long prog; /* program number */ - u_long vers; /* version number */ - u_long proc; /* procedure number */ - xdrproc_t xargs; /* xdr routine for args */ - caddr_t argsp; /* pointer to args */ - xdrproc_t xresults; /* xdr routine for results */ - caddr_t resultsp; /* pointer to results */ - resultproc_t eachresult; /* call with each result obtained */ -{ - enum clnt_stat stat; - AUTH *unix_auth = authunix_create_default(); - XDR xdr_stream; - register XDR *xdrs = &xdr_stream; - int outlen, inlen, fromlen, nets; - register int sock; - int on = 1; - fd_set *fds = 0, readfds; /* initialized to avoid warning */ - register int i; - bool_t done = FALSE; - register u_long xid; - u_long port; - struct in_addr addrs[20]; - struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ - struct rmtcallargs a; - struct rmtcallres r; - struct rpc_msg msg; - struct timeval t, tv; - char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; - static u_int32_t disrupt; - - if (disrupt == 0) - disrupt = (u_int32_t)(long)resultsp; - - /* - * initialization: create a socket, a broadcast address, and - * preserialize the arguments into a send buffer. - */ - if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - perror("Cannot create socket for broadcast rpc"); - stat = RPC_CANTSEND; - goto done_broad; - } -#ifdef SO_BROADCAST - if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { - perror("Cannot set socket option SO_BROADCAST"); - stat = RPC_CANTSEND; - goto done_broad; - } -#endif /* def SO_BROADCAST */ - if (sock + 1 > FD_SETSIZE) { - int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); - fds = (fd_set *)malloc(bytes); - if (fds == NULL) { - stat = RPC_CANTSEND; - goto done_broad; - } - memset(fds, 0, bytes); - } else { - fds = &readfds; - FD_ZERO(fds); - } - - nets = getbroadcastnets(addrs, sock, inbuf); - memset(&baddr, 0, sizeof (baddr)); - baddr.sin_len = sizeof(struct sockaddr_in); - baddr.sin_family = AF_INET; - baddr.sin_port = htons(PMAPPORT); - baddr.sin_addr.s_addr = htonl(INADDR_ANY); - (void)gettimeofday(&t, (struct timezone *)0); - msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec; - t.tv_usec = 0; - msg.rm_direction = CALL; - msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - msg.rm_call.cb_prog = PMAPPROG; - msg.rm_call.cb_vers = PMAPVERS; - msg.rm_call.cb_proc = PMAPPROC_CALLIT; - msg.rm_call.cb_cred = unix_auth->ah_cred; - msg.rm_call.cb_verf = unix_auth->ah_verf; - a.prog = prog; - a.vers = vers; - a.proc = proc; - a.xdr_args = xargs; - a.args_ptr = argsp; - r.port_ptr = &port; - r.xdr_results = xresults; - r.results_ptr = resultsp; - xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); - if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) { - stat = RPC_CANTENCODEARGS; - goto done_broad; - } - outlen = (int)xdr_getpos(xdrs); - xdr_destroy(xdrs); - /* - * Basic loop: broadcast a packet and wait a while for response(s). - * The response timeout grows larger per iteration. - * - * XXX This will loop about 5 times the stop. If there are - * lots of signals being received by the process it will quit - * send them all in one quick burst, not paying attention to - * the intended function of sending them slowly over half a - * minute or so - */ - for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { - for (i = 0; i < nets; i++) { - baddr.sin_addr = addrs[i]; - if (sendto(sock, outbuf, outlen, 0, - (struct sockaddr *)&baddr, - sizeof (struct sockaddr)) != outlen) { - perror("Cannot send broadcast packet"); - stat = RPC_CANTSEND; - goto done_broad; - } - } - if (eachresult == NULL) { - stat = RPC_SUCCESS; - goto done_broad; - } - recv_again: - msg.acpted_rply.ar_verf = _null_auth; - msg.acpted_rply.ar_results.where = (caddr_t)&r; - msg.acpted_rply.ar_results.proc = xdr_rmtcallres; - /* XXX we know the other bits are still clear */ - FD_SET(sock, fds); - tv = t; /* for select() that copies back */ - switch (select(sock + 1, fds, NULL, NULL, &tv)) { - - case 0: /* timed out */ - stat = RPC_TIMEDOUT; - continue; - - case -1: /* some kind of error */ - if (errno == EINTR) - goto recv_again; - perror("Broadcast select problem"); - stat = RPC_CANTRECV; - goto done_broad; - - } /* end of select results switch */ - try_again: - fromlen = sizeof(struct sockaddr); - inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, - (struct sockaddr *)&raddr, &fromlen); - if (inlen < 0) { - if (errno == EINTR) - goto try_again; - perror("Cannot receive reply to broadcast"); - stat = RPC_CANTRECV; - goto done_broad; - } - if (inlen < sizeof(u_int32_t)) - goto recv_again; - /* - * see if reply transaction id matches sent id. - * If so, decode the results. - */ - xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE); - if (xdr_replymsg(xdrs, &msg)) { - if ((msg.rm_xid == xid) && - (msg.rm_reply.rp_stat == MSG_ACCEPTED) && - (msg.acpted_rply.ar_stat == SUCCESS)) { - raddr.sin_port = htons((u_short)port); - done = (*eachresult)(resultsp, &raddr); - } - /* otherwise, we just ignore the errors ... */ - } - xdrs->x_op = XDR_FREE; - msg.acpted_rply.ar_results.proc = xdr_void; - (void)xdr_replymsg(xdrs, &msg); - (void)(*xresults)(xdrs, resultsp); - xdr_destroy(xdrs); - if (done) { - stat = RPC_SUCCESS; - goto done_broad; - } else { - goto recv_again; - } - } -done_broad: - if (fds != &readfds) - free(fds); - if (sock >= 0) - (void)_RPC_close(sock); - AUTH_DESTROY(unix_auth); - return (stat); -} - diff --git a/c/src/librpc/src/rpc/publickey.3 b/c/src/librpc/src/rpc/publickey.3 deleted file mode 100644 index 29094f98b2..0000000000 --- a/c/src/librpc/src/rpc/publickey.3 +++ /dev/null @@ -1,47 +0,0 @@ -.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC -.\" $FreeBSD: src/lib/libc/rpc/publickey.3,v 1.4 2000/03/02 09:13:46 sheldonh Exp $ -.\" -.TH PUBLICKEY 3R "6 October 1987" -.SH NAME -publickey, getpublickey, getsecretkey \- get public or secret key -.SH SYNOPSIS -.nf -.B #include -.B #include -.LP -.B getpublickey(netname, publickey) -.B char netname[\s-1MAXNETNAMELEN\s0+1]; -.B char publickey[\s-1HEXKEYBYTES\s0+1]; -.LP -.B getsecretkey(netname, secretkey, passwd) -.B char netname[\s-1MAXNETNAMELEN\s0+1]; -.B char secretkey[\s-1HEXKEYBYTES\s0+1]; -.B char *passwd; -.fi -.SH DESCRIPTION -.IX "getpublickey function" "" "\fLgetpublickey()\fP function" -.IX "getsecretkey function" "" "\fLgetsecretkey()\fP function" -These routines are used to get public and secret keys from the -.SM YP -database. -.B getsecretkey(\|) -has an extra argument, -.IR passwd , -which is used to decrypt the encrypted secret key stored in the database. -Both routines return 1 if they are successful in finding the key, 0 otherwise. -The keys are returned as -.SM NULL\s0-terminated, -hexadecimal strings. -If the password supplied to -.B getsecretkey(\|) -fails to decrypt the secret key, the routine will return 1 but the -.I secretkey -argument will be a -.SM NULL -string (``''). -.SH "SEE ALSO" -.BR publickey (5) -.LP -.I \s-1RPC\s0 Programmer's Manual -in -.TX NETP diff --git a/c/src/librpc/src/rpc/publickey.5 b/c/src/librpc/src/rpc/publickey.5 deleted file mode 100644 index 9f7a325488..0000000000 --- a/c/src/librpc/src/rpc/publickey.5 +++ /dev/null @@ -1,38 +0,0 @@ -.\" $FreeBSD: src/lib/libc/rpc/publickey.5,v 1.5 2000/03/02 09:13:46 sheldonh Exp $ -.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI; -.TH PUBLICKEY 5 "19 October 1987" -.SH NAME -publickey \- public key database -.SH SYNOPSIS -.B /etc/publickey -.SH DESCRIPTION -.LP -.B /etc/publickey -is the public key database used for secure -networking. -Each entry in -the database consists of a network user -name (which may either refer to -a user or a hostname), followed by the user's -public key (in hex -notation), a colon, and then the user's -secret key encrypted with -its login password (also in hex notation). -.LP -This file is altered either by the user through the -.BR chkey (1) -command or by the system administrator through the -.BR newkey (8) -command. -The file -.B /etc/publickey -should only contain data on the NIS master machine, where it -is converted into the -.SM NIS -database -.BR publickey.byname . -.SH SEE ALSO -.BR chkey (1), -.BR publickey (3R), -.BR newkey (8), -.BR ypupdated (8C) diff --git a/c/src/librpc/src/rpc/rpc.3 b/c/src/librpc/src/rpc/rpc.3 deleted file mode 100644 index f40b643827..0000000000 --- a/c/src/librpc/src/rpc/rpc.3 +++ /dev/null @@ -1,1767 +0,0 @@ -.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI -.\" $FreeBSD: src/lib/libc/rpc/rpc.3,v 1.11 2000/03/02 09:13:47 sheldonh Exp $ -.\" -.TH RPC 3 "16 February 1988" -.SH NAME -rpc \- library routines for remote procedure calls -.SH SYNOPSIS AND DESCRIPTION -These routines allow C programs to make procedure -calls on other machines across the network. -First, the client calls a procedure to send a -data packet to the server. -Upon receipt of the packet, the server calls a dispatch routine -to perform the requested service, and then sends back a -reply. -Finally, the procedure call returns to the client. -.LP -Routines that are used for Secure RPC (DES authentication) are described in -.BR rpc_secure (3). -Secure RPC can be used only if DES encryption is available. -.LP -.ft B -.nf -.sp .5 -#include -.fi -.ft R -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -void -auth_destroy(auth) -\s-1AUTH\s0 *auth; -.fi -.ft R -.IP -A macro that destroys the authentication information associated with -.IR auth . -Destruction usually involves deallocation of private data -structures. -The use of -.I auth -is undefined after calling -.BR auth_destroy(\|) . -.br -.if t .ne 6 -.LP -.ft B -.nf -.sp .5 -\s-1AUTH\s0 * -authnone_create(\|) -.fi -.ft R -.IP -Create and returns an -.SM RPC -authentication handle that passes nonusable authentication -information with each remote procedure call. -This is the -default authentication used by -.SM RPC. -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -\s-1AUTH\s0 * -authunix_create(host, uid, gid, len, aup_gids) -char *host; -int uid, gid, len, *aup.gids; -.fi -.ft R -.IP -Create and return an -.SM RPC -authentication handle that contains -.UX -authentication information. -The parameter -.I host -is the name of the machine on which the information was -created; -.I uid -is the user's user -.SM ID ; -.I gid -is the user's current group -.SM ID ; -.I len -and -.I aup_gids -refer to a counted array of groups to which the user belongs. -It is easy to impersonate a user. -.br -.if t .ne 5 -.LP -.ft B -.nf -.sp .5 -\s-1AUTH\s0 * -authunix_create_default(\|) -.fi -.ft R -.IP -Calls -.B authunix_create(\|) -with the appropriate parameters. -.br -.if t .ne 13 -.LP -.ft B -.nf -.sp .5 -callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) -char *host; -u_long prognum, versnum, procnum; -char *in, *out; -xdrproc_t inproc, outproc; -.fi -.ft R -.IP -Call the remote procedure associated with -.IR prognum , -.IR versnum , -and -.I procnum -on the machine, -.IR host . -The parameter -.I in -is the address of the procedure's argument(s), and -.I out -is the address of where to place the result(s); -.I inproc -is used to encode the procedure's parameters, and -.I outproc -is used to decode the procedure's results. -This routine returns zero if it succeeds, or the value of -.B "enum clnt_stat" -cast to an integer if it fails. -The routine -.B clnt_perrno(\|) -is handy for translating failure statuses into messages. -.IP -Warning: calling remote procedures with this routine -uses -.SM UDP/IP -as a transport; see -.B clntudp_create(\|) -for restrictions. -You do not have control of timeouts or authentication using -this routine. -.br -.if t .ne 16 -.LP -.ft B -.nf -.sp .5 -enum clnt_stat -clnt_broadcast(prognum, versnum, procnum, inproc, in, outproc, out, eachresult) -u_long prognum, versnum, procnum; -char *in, *out; -xdrproc_t inproc, outproc; -resultproc_t eachresult; -.fi -.ft R -.IP -Like -.BR callrpc(\|) , -except the call message is broadcast to all locally -connected broadcast nets. -Each time it receives a -response, this routine calls -.BR eachresult(\|) , -whose form is: -.IP -.RS 1i -.ft B -.nf -eachresult(out, addr) -char *out; -struct sockaddr_in *addr; -.ft R -.fi -.RE -.IP -where -.I out -is the same as -.I out -passed to -.BR clnt_broadcast(\|) , -except that the remote procedure's output is decoded there; -.I addr -points to the address of the machine that sent the results. -If -.B eachresult(\|) -returns zero, -.B clnt_broadcast(\|) -waits for more replies; otherwise it returns with appropriate -status. -.IP -Warning: broadcast sockets are limited in size to the -maximum transfer unit of the data link. -For ethernet, -this value is 1500 bytes. -.br -.if t .ne 13 -.LP -.ft B -.nf -.sp .5 -enum clnt_stat -clnt_call(clnt, procnum, inproc, in, outproc, out, tout) -\s-1CLIENT\s0 *clnt; -u_long -procnum; -xdrproc_t inproc, outproc; -char *in, *out; -struct timeval tout; -.fi -.ft R -.IP -A macro that calls the remote procedure -.I procnum -associated with the client handle, -.IR clnt , -which is obtained with an -.SM RPC -client creation routine such as -.BR clnt_create(\|) . -The parameter -.I in -is the address of the procedure's argument(s), and -.I out -is the address of where to place the result(s); -.I inproc -is used to encode the procedure's parameters, and -.I outproc -is used to decode the procedure's results; -.I tout -is the time allowed for results to come back. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -clnt_destroy(clnt) -\s-1CLIENT\s0 *clnt; -.fi -.ft R -.IP -A macro that destroys the client's -.SM RPC -handle. -Destruction usually involves deallocation -of private data structures, including -.I clnt -itself. Use of -.I clnt -is undefined after calling -.BR clnt_destroy(\|) . -If the -.SM RPC -library opened the associated socket, it will close it also. -Otherwise, the socket remains open. -.br -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -\s-1CLIENT\s0 * -clnt_create(host, prog, vers, proto) -char *host; -u_long prog, vers; -char *proto; -.fi -.ft R -.IP -Generic client creation routine. -.I host -identifies the name of the remote host where the server -is located. -.I proto -indicates which kind of transport protocol to use. -The -currently supported values for this field are \(lqudp\(rq -and \(lqtcp\(rq. -Default timeouts are set, but can be modified using -.BR clnt_control(\|) . -.IP -Warning: Using -.SM UDP -has its shortcomings. Since -.SM UDP\s0-based -.SM RPC -messages can only hold up to 8 Kbytes of encoded data, -this transport cannot be used for procedures that take -large arguments or return huge results. -.br -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -bool_t -clnt_control(cl, req, info) -\s-1CLIENT\s0 *cl; -u_int req; -char *info; -.fi -.ft R -.IP -A macro used to change or retrieve various information -about a client object. -.I req -indicates the type of operation, and -.I info -is a pointer to the information. -For both -.SM UDP -and -.SM TCP\s0, -the supported values of -.I req -and their argument types and what they do are: -.IP -.nf -.ta +2.0i +2.0i +2.0i -.SM CLSET_TIMEOUT\s0 struct timeval set total timeout -.SM CLGET_TIMEOUT\s0 struct timeval get total timeout -.fi -.IP -Note: if you set the timeout using -.BR clnt_control(\|) , -the timeout parameter passed to -.B clnt_call(\|) -will be ignored in all future calls. -.IP -.nf -.SM CLGET_SERVER_ADDR\s0 struct sockaddr_in get server's address -.fi -.br -.IP -The following operations are valid for -.SM UDP -only: -.IP -.nf -.ta +2.0i ; +2.0i ; +2.0i -.SM CLSET_RETRY_TIMEOUT\s0 struct timeval set the retry timeout -.SM CLGET_RETRY_TIMEOUT\s0 struct timeval get the retry timeout -.fi -.br -.IP -The retry timeout is the time that -.SM "UDP RPC" -waits for the server to reply before -retransmitting the request. -.br -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -clnt_freeres(clnt, outproc, out) -\s-1CLIENT\s0 *clnt; -xdrproc_t outproc; -char *out; -.fi -.ft R -.IP -A macro that frees any data allocated by the -.SM RPC/XDR -system when it decoded the results of an -.SM RPC -call. The -parameter -.I out -is the address of the results, and -.I outproc -is the -.SM XDR -routine describing the results. -This routine returns one if the results were successfully -freed, -and zero otherwise. -.br -.if t .ne 6 -.LP -.ft B -.nf -.sp .5 -void -clnt_geterr(clnt, errp) -\s-1CLIENT\s0 *clnt; -struct rpc_err *errp; -.fi -.ft R -.IP -A macro that copies the error structure out of the client -handle -to the structure at address -.IR errp . -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -void -clnt_pcreateerror(s) -char *s; -.fi -.ft R -.IP -Print a message to standard error indicating -why a client -.SM RPC -handle could not be created. -The message is prepended with string -.I s -and a colon. -Used when a -.BR clnt_create(\|) , -.BR clntraw_create(\|) , -.BR clnttcp_create(\|) , -or -.B clntudp_create(\|) -call fails. -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -void -clnt_perrno(stat) -enum clnt_stat stat; -.fi -.ft R -.IP -Print a message to standard error corresponding -to the condition indicated by -.IR stat . -Used after -.BR callrpc(\|) . -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -clnt_perror(clnt, s) -\s-1CLIENT\s0 *clnt; -char *s; -.fi -.ft R -.IP -Print a message to standard error indicating why an -.SM RPC -call failed; -.I clnt -is the handle used to do the call. -The message is prepended with string -.I s -and a colon. -Used after -.BR clnt_call(\|) . -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -char * -clnt_spcreateerror -char *s; -.fi -.ft R -.IP -Like -.BR clnt_pcreateerror(\|) , -except that it returns a string -instead of printing to the standard error. -.IP -Bugs: returns pointer to static data that is overwritten -on each call. -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -char * -clnt_sperrno(stat) -enum clnt_stat stat; -.fi -.ft R -.IP -Take the same arguments as -.BR clnt_perrno(\|) , -but instead of sending a message to the standard error -indicating why an -.SM RPC -call failed, return a pointer to a string which contains -the message. The string ends with a -.SM NEWLINE\s0. -.IP -.B clnt_sperrno(\|) -is used instead of -.B clnt_perrno(\|) -if the program does not have a standard error (as a program -running as a server quite likely does not), or if the -programmer -does not want the message to be output with -.BR printf , -or if a message format different from that supported by -.B clnt_perrno(\|) -is to be used. -Note: unlike -.B clnt_sperror(\|) -and -.BR clnt_spcreaterror(\|) , -.B clnt_sperrno(\|) -returns pointer to static data, but the -result will not get overwritten on each call. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -char * -clnt_sperror(rpch, s) -\s-1CLIENT\s0 *rpch; -char *s; -.fi -.ft R -.IP -Like -.BR clnt_perror(\|) , -except that (like -.BR clnt_sperrno(\|) ) -it returns a string instead of printing to standard error. -.IP -Bugs: returns pointer to static data that is overwritten -on each call. -.br -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -\s-1CLIENT\s0 * -clntraw_create(prognum, versnum) -u_long prognum, versnum; -.fi -.ft R -.IP -This routine creates a toy -.SM RPC -client for the remote program -.IR prognum , -version -.IR versnum . -The transport used to pass messages to the service is -actually a buffer within the process's address space, so the -corresponding -.SM RPC -server should live in the same address space; see -.BR svcraw_create(\|) . -This allows simulation of -.SM RPC -and acquisition of -.SM RPC -overheads, such as round trip times, without any -kernel interference. -This routine returns -.SM NULL -if it fails. -.br -.if t .ne 15 -.LP -.ft B -.nf -.sp .5 -\s-1CLIENT\s0 * -clnttcp_create(addr, prognum, versnum, sockp, sendsz, recvsz) -struct sockaddr_in *addr; -u_long prognum, versnum; -int *sockp; -u_int sendsz, recvsz; -.fi -.ft R -.IP -This routine creates an -.SM RPC -client for the remote program -.IR prognum , -version -.IR versnum ; -the client uses -.SM TCP/IP -as a transport. -The remote program is located at Internet -address -.IR *addr . -If -.\"The following in-line font conversion is necessary for the hyphen indicator -\fB\%addr\->sin_port\fR -is zero, then it is set to the actual port that the remote -program is listening on (the remote -.B portmap -service is consulted for this information). The parameter -.I sockp -is a socket; if it is -.BR \s-1RPC_ANYSOCK\s0 , -then this routine opens a new one and sets -.IR sockp . -Since -.SM TCP\s0-based -.SM RPC -uses buffered -.SM I/O , -the user may specify the size of the send and receive buffers -with the parameters -.I sendsz -and -.IR recvsz ; -values of zero choose suitable defaults. -This routine returns -.SM NULL -if it fails. -.br -.if t .ne 15 -.LP -.ft B -.nf -.sp .5 -\s-1CLIENT\s0 * -clntudp_create(addr, prognum, versnum, wait, sockp) -struct sockaddr_in *addr; -u_long prognum, versnum; -struct timeval wait; -int *sockp; -.fi -.ft R -.IP -This routine creates an -.SM RPC -client for the remote program -.IR prognum , -version -.IR versnum ; -the client uses -.SM UDP/IP -as a transport. -The remote program is located at Internet -address -.IR addr . -If -\fB\%addr\->sin_port\fR -is zero, then it is set to actual port that the remote -program is listening on (the remote -.B portmap -service is consulted for this information). The parameter -.I sockp -is a socket; if it is -.BR \s-1RPC_ANYSOCK\s0 , -then this routine opens a new one and sets -.IR sockp . -The -.SM UDP -transport resends the call message in intervals of -.B wait -time until a response is received or until the call times -out. -The total time for the call to time out is specified by -.BR clnt_call(\|) . -.IP -Warning: since -.SM UDP\s0-based -.SM RPC -messages can only hold up to 8 Kbytes -of encoded data, this transport cannot be used for procedures -that take large arguments or return huge results. -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -\s-1CLIENT\s0 * -clntudp_bufcreate(addr, prognum, versnum, wait, sockp, sendsize, recosize) -struct sockaddr_in *addr; -u_long prognum, versnum; -struct timeval wait; -int *sockp; -unsigned int sendsize; -unsigned int recosize; -.fi -.ft R -.IP -This routine creates an -.SM RPC -client for the remote program -.IR prognum , -on -.IR versnum ; -the client uses -.SM UDP/IP -as a transport. -The remote program is located at Internet -address -.IR addr . -If -\fB\%addr\->sin_port\fR -is zero, then it is set to actual port that the remote -program is listening on (the remote -.B portmap -service is consulted for this information). The parameter -.I sockp -is a socket; if it is -.BR \s-1RPC_ANYSOCK\s0 , -then this routine opens a new one and sets -.BR sockp . -The -.SM UDP -transport resends the call message in intervals of -.B wait -time until a response is received or until the call times -out. -The total time for the call to time out is specified by -.BR clnt_call(\|) . -.IP -This allows the user to specify the maximum packet size for sending and receiving -.SM UDP\s0-based -.SM RPC -messages. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -int -get_myaddress(addr) -struct sockaddr_in *addr; -.fi -.ft R -.IP -Stuff the machine's -.SM IP -address into -.IR *addr , -without consulting the library routines that deal with -.BR /etc/hosts . -The port number is always set to -.BR htons(\s-1PMAPPORT\s0) . -Returns zero on success, non-zero on failure. -.br -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -struct pmaplist * -pmap_getmaps(addr) -struct sockaddr_in *addr; -.fi -.ft R -.IP -A user interface to the -.B portmap -service, which returns a list of the current -.SM RPC -program-to-port mappings -on the host located at -.SM IP -address -.IR *addr . -This routine can return -.SM NULL . -The command -.RB ` "rpcinfo \-p" ' -uses this routine. -.br -.if t .ne 12 -.LP -.ft B -.nf -.sp .5 -u_short -pmap_getport(addr, prognum, versnum, protocol) -struct sockaddr_in *addr; -u_long prognum, versnum, protocol; -.fi -.ft R -.IP -A user interface to the -.B portmap -service, which returns the port number -on which waits a service that supports program number -.IR prognum , -version -.IR versnum , -and speaks the transport protocol associated with -.IR protocol . -The value of -.I protocol -is most likely -.B -.SM IPPROTO_UDP -or -.BR \s-1IPPROTO_TCP\s0 . -A return value of zero means that the mapping does not exist -or that -the -.SM RPC -system failed to contact the remote -.B portmap -service. In the latter case, the global variable -.B rpc_createerr(\|) -contains the -.SM RPC -status. -.br -.if t .ne 15 -.LP -.ft B -.nf -.sp .5 -enum clnt_stat -pmap_rmtcall(addr, prognum, versnum, procnum, inproc, in, outproc, out, tout, portp) -struct sockaddr_in *addr; -u_long prognum, versnum, procnum; -char *in, *out; -xdrproc_t inproc, outproc; -struct timeval tout; -u_long *portp; -.fi -.ft R -.IP -A user interface to the -.B portmap -service, which instructs -.B portmap -on the host at -.SM IP -address -.I *addr -to make an -.SM RPC -call on your behalf to a procedure on that host. -The parameter -.I *portp -will be modified to the program's port number if the -procedure -succeeds. -The definitions of other parameters are discussed -in -.B callrpc(\|) -and -.BR clnt_call(\|) . -This procedure should be used for a \(lqping\(rq and nothing -else. -See also -.BR clnt_broadcast(\|) . -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -pmap_set(prognum, versnum, protocol, port) -u_long prognum, versnum, protocol; -u_short port; -.fi -.ft R -.IP -A user interface to the -.B portmap -service, which establishes a mapping between the triple -.RI [ prognum , versnum , protocol\fR] -and -.I port -on the machine's -.B portmap -service. -The value of -.I protocol -is most likely -.B -.SM IPPROTO_UDP -or -.BR \s-1IPPROTO_TCP\s0 . -This routine returns one if it succeeds, zero otherwise. -Automatically done by -.BR svc_register(\|) . -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -pmap_unset(prognum, versnum) -u_long prognum, versnum; -.fi -.ft R -.IP -A user interface to the -.B portmap -service, which destroys all mapping between the triple -.RI [ prognum , versnum , *\fR] -and -.B ports -on the machine's -.B portmap -service. -This routine returns one if it succeeds, zero -otherwise. -.br -.if t .ne 15 -.LP -.ft B -.nf -.sp .5 -registerrpc(prognum, versnum, procnum, procname, inproc, outproc) -u_long prognum, versnum, procnum; -char *(*procname) (\|) ; -xdrproc_t inproc, outproc; -.fi -.ft R -.IP -Register procedure -.I procname -with the -.SM RPC -service package. If a request arrives for program -.IR prognum , -version -.IR versnum , -and procedure -.IR procnum , -.I procname -is called with a pointer to its parameter(s); -.I progname -should return a pointer to its static result(s); -.I inproc -is used to decode the parameters while -.I outproc -is used to encode the results. -This routine returns zero if the registration succeeded, \-1 -otherwise. -.IP -Warning: remote procedures registered in this form -are accessed using the -.SM UDP/IP -transport; see -.B svcudp_create(\|) -for restrictions. -.br -.if t .ne 5 -.LP -.ft B -.nf -.sp .5 -struct rpc_createerr rpc_createerr; -.fi -.ft R -.IP -A global variable whose value is set by any -.SM RPC -client creation routine -that does not succeed. Use the routine -.B clnt_pcreateerror(\|) -to print the reason why. -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -svc_destroy(xprt) -\s-1SVCXPRT\s0 * -xprt; -.fi -.ft R -.IP -A macro that destroys the -.SM RPC -service transport handle, -.IR xprt . -Destruction usually involves deallocation -of private data structures, including -.I xprt -itself. Use of -.I xprt -is undefined after calling this routine. -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -fd_set svc_fdset; -.fi -.ft R -.IP -A global variable reflecting the -.SM RPC -service side's -read file descriptor bit mask; it is suitable as a template parameter -to the -.B select -system call. -This is only of interest -if a service implementor does not call -.BR svc_run(\|) , -but rather does his own asynchronous event processing. -This variable is read-only (do not pass its address to -.BR select !), -yet it may change after calls to -.B svc_getreqset(\|) -or any creation routines. -.br -As well, note that if the process has descriptor limits -which are extended beyond -.BR FD_SETSIZE , -this variable will only be usable for the first -.BR FD_SETSIZE -descriptors. -.br -.if t .ne 6 -.LP -.ft B -.nf -.sp .5 -int svc_fds; -.fi -.ft R -.IP -Similar to -.BR svc_fedset(\|) , -but limited to 32 descriptors. -This -interface is obsoleted by -.BR svc_fdset(\|) . -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -svc_freeargs(xprt, inproc, in) -\s-1SVCXPRT\s0 *xprt; -xdrproc_t inproc; -char *in; -.fi -.ft R -.IP -A macro that frees any data allocated by the -.SM RPC/XDR -system when it decoded the arguments to a service procedure -using -.BR svc_getargs(\|) . -This routine returns 1 if the results were successfully -freed, -and zero otherwise. -.br -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -svc_getargs(xprt, inproc, in) -\s-1SVCXPRT\s0 *xprt; -xdrproc_t inproc; -char *in; -.fi -.ft R -.IP -A macro that decodes the arguments of an -.SM RPC -request -associated with the -.SM RPC -service transport handle, -.IR xprt . -The parameter -.I in -is the address where the arguments will be placed; -.I inproc -is the -.SM XDR -routine used to decode the arguments. -This routine returns one if decoding succeeds, and zero -otherwise. -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -struct sockaddr_in * -svc_getcaller(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -The approved way of getting the network address of the caller -of a procedure associated with the -.SM RPC -service transport handle, -.IR xprt . -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -svc_getreqset(rdfds) -fd_set *rdfds; -.fi -.ft R -.IP -This routine is only of interest if a service implementor -does not call -.BR svc_run(\|) , -but instead implements custom asynchronous event processing. -It is called when the -.B select -system call has determined that an -.SM RPC -request has arrived on some -.SM RPC -.B socket(s) ; -.I rdfds -is the resultant read file descriptor bit mask. -The routine returns when all sockets associated with the -value of -.I rdfds -have been serviced. -.br -.if t .ne 6 -.LP -.ft B -.nf -.sp .5 -svc_getreq(rdfds) -int rdfds; -.fi -.ft R -.IP -Similar to -.BR svc_getreqset(\|) , -but limited to 32 descriptors. -This interface is obsoleted by -.BR svc_getreqset(\|) . -.br -.if t .ne 17 -.LP -.ft B -.nf -.sp .5 -svc_register(xprt, prognum, versnum, dispatch, protocol) -\s-1SVCXPRT\s0 *xprt; -u_long prognum, versnum; -void (*dispatch) (\|); -u_long protocol; -.fi -.ft R -.IP -Associates -.I prognum -and -.I versnum -with the service dispatch procedure, -.IR dispatch . -If -.I protocol -is zero, the service is not registered with the -.B portmap -service. If -.I protocol -is non-zero, then a mapping of the triple -.RI [ prognum , versnum , protocol\fR] -to -\fB\%xprt\->xp_port\fR -is established with the local -.B portmap -service (generally -.I protocol -is zero, -.B -.SM IPPROTO_UDP -or -.B -.SM IPPROTO_TCP -). -The procedure -.I dispatch -has the following form: -.RS 1i -.ft B -.nf -dispatch(request, xprt) -struct svc_req *request; -\s-1SVCXPRT\s0 *xprt; -.ft R -.fi -.RE -.IP -The -.B svc_register(\|) -routine returns one if it succeeds, and zero otherwise. -.br -.if t .ne 6 -.LP -.ft B -.nf -.sp .5 -svc_run(\|) -.fi -.ft R -.IP -This routine never returns. -It waits for -.SM RPC -requests to arrive, and calls the appropriate service -procedure using -.B svc_getreq(\|) -when one arrives. -This procedure is usually waiting for a -.B select(\|) -system call to return. -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -svc_sendreply(xprt, outproc, out) -\s-1SVCXPRT\s0 *xprt; -xdrproc_t outproc; -char *out; -.fi -.ft R -.IP -Called by an -.SM RPC -service's dispatch routine to send the results of a -remote procedure call. The parameter -.I xprt -is the request's associated transport handle; -.I outproc -is the -.SM XDR -routine which is used to encode the results; and -.I out -is the address of the results. -This routine returns one if it succeeds, zero otherwise. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -void -svc_unregister(prognum, versnum) -u_long prognum, versnum; -.fi -.ft R -.IP -Remove all mapping of the double -.RI [ prognum , versnum ] -to dispatch routines, and of the triple -.RI [ prognum , versnum , *\fR] -to port number. -.br -.if t .ne 9 -.LP -.ft B -.nf -.sp .5 -void -svcerr_auth(xprt, why) -\s-1SVCXPRT\s0 *xprt; -enum auth_stat why; -.fi -.ft R -.IP -Called by a service dispatch routine that refuses to perform -a remote procedure call due to an authentication error. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -void -svcerr_decode(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -Called by a service dispatch routine that cannot successfully -decode its parameters. -See also -.BR svc_getargs(\|) . -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -void -svcerr_noproc(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -Called by a service dispatch routine that does not implement -the procedure number that the caller requests. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -void -svcerr_noprog(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -Called when the desired program is not registered with the -.SM RPC -package. -Service implementors usually do not need this routine. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -void -svcerr_progvers(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -Called when the desired version of a program is not registered -with the -.SM RPC -package. -Service implementors usually do not need this routine. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -void -svcerr_systemerr(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -Called by a service dispatch routine when it detects a system -error -not covered by any particular protocol. -For example, if a service can no longer allocate storage, -it may call this routine. -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -void -svcerr_weakauth(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -Called by a service dispatch routine that refuses to perform -a remote procedure call due to insufficient -authentication parameters. The routine calls -.BR "svcerr_auth(xprt, \s-1AUTH_TOOWEAK\s0)" . -.br -.if t .ne 11 -.LP -.ft B -.nf -.sp .5 -\s-1SVCXPRT\s0 * -svcraw_create(\|) -.fi -.ft R -.IP -This routine creates a toy -.SM RPC -service transport, to which it returns a pointer. The -transport -is really a buffer within the process's address space, -so the corresponding -.SM RPC -client should live in the same -address space; -see -.BR clntraw_create(\|) . -This routine allows simulation of -.SM RPC -and acquisition of -.SM RPC -overheads (such as round trip times), without any kernel -interference. -This routine returns -.SM NULL -if it fails. -.br -.if t .ne 11 -.LP -.ft B -.nf -.sp .5 -\s-1SVCXPRT\s0 * -svctcp_create(sock, send_buf_size, recv_buf_size) -int sock; -u_int send_buf_size, recv_buf_size; -.fi -.ft R -.IP -This routine creates a -.SM TCP/IP\s0-based -.SM RPC -service transport, to which it returns a pointer. -The transport is associated with the socket -.IR sock , -which may be -.BR \s-1RPC_ANYSOCK\s0 , -in which case a new socket is created. -If the socket is not bound to a local -.SM TCP -port, then this routine binds it to an arbitrary port. Upon -completion, -\fB\%xprt\->xp_sock\fR -is the transport's socket descriptor, and -\fB\%xprt\->xp_port\fR -is the transport's port number. -This routine returns -.SM NULL -if it fails. -Since -.SM TCP\s0-based -.SM RPC -uses buffered -.SM I/O , -users may specify the size of buffers; values of zero -choose suitable defaults. -.br -.if t .ne 11 -.LP -.ft B -.nf -.sp .5 -\s-1SVCXPRT\s0 * -svcfd_create(fd, sendsize, recvsize) -int fd; -u_int sendsize; -u_int recvsize; -.fi -.ft R -.IP -Create a service on top of any open descriptor. -Typically, -this -descriptor is a connected socket for a stream protocol such -as -.SM TCP\s0. -.I sendsize -and -.I recvsize -indicate sizes for the send and receive buffers. If they are -zero, a reasonable default is chosen. -.br -.if t .ne 10 -.LP -.ft B -.nf -.sp .5 -\s-1SVCXPRT\s0 * -svcudp_bufcreate(sock, sendsize, recosize) -int sock; -.fi -.ft R -.IP -This routine creates a -.SM UDP/IP\s0-based -.SM RPC -service transport, to which it returns a pointer. -The transport is associated with the socket -.IR sock , -which may be -.B \s-1RPC_ANYSOCK\s0 , -in which case a new socket is created. -If the socket is not bound to a local -.SM UDP -port, then this routine binds it to an arbitrary port. -Upon -completion, -\fB\%xprt\->xp_sock\fR -is the transport's socket descriptor, and -\fB\%xprt\->xp_port\fR -is the transport's port number. -This routine returns -.SM NULL -if it fails. -.IP -This allows the user to specify the maximum packet size for sending and -receiving -.SM UDP\s0-based -.SM RPC messages. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -xdr_accepted_reply(xdrs, ar) -\s-1XDR\s0 *xdrs; -struct accepted_reply *ar; -.fi -.ft R -.IP -Used for encoding -.SM RPC -reply messages. -This routine is useful for users who -wish to generate -\s-1RPC\s0-style -messages without using the -.SM RPC -package. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -xdr_authunix_parms(xdrs, aupp) -\s-1XDR\s0 *xdrs; -struct authunix_parms *aupp; -.fi -.ft R -.IP -Used for describing -.SM UNIX -credentials. -This routine is useful for users -who wish to generate these credentials without using the -.SM RPC -authentication package. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -void -xdr_callhdr(xdrs, chdr) -\s-1XDR\s0 *xdrs; -struct rpc_msg *chdr; -.fi -.ft R -.IP -Used for describing -.SM RPC -call header messages. -This routine is useful for users who wish to generate -.SM RPC\s0-style -messages without using the -.SM RPC -package. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -xdr_callmsg(xdrs, cmsg) -\s-1XDR\s0 *xdrs; -struct rpc_msg *cmsg; -.fi -.ft R -.IP -Used for describing -.SM RPC -call messages. -This routine is useful for users who wish to generate -.SM RPC\s0-style -messages without using the -.SM RPC -package. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -xdr_opaque_auth(xdrs, ap) -\s-1XDR\s0 *xdrs; -struct opaque_auth *ap; -.fi -.ft R -.IP -Used for describing -.SM RPC -authentication information messages. -This routine is useful for users who wish to generate -.SM RPC\s0-style -messages without using the -.SM RPC -package. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -xdr_pmap(xdrs, regs) -\s-1XDR\s0 *xdrs; -struct pmap *regs; -.fi -.ft R -.IP -Used for describing parameters to various -.B portmap -procedures, externally. -This routine is useful for users who wish to generate -these parameters without using the -.B pmap -interface. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -xdr_pmaplist(xdrs, rp) -\s-1XDR\s0 *xdrs; -struct pmaplist **rp; -.fi -.ft R -.IP -Used for describing a list of port mappings, externally. -This routine is useful for users who wish to generate -these parameters without using the -.B pmap -interface. -.br -.if t .ne 7 -.LP -.ft B -.nf -.sp .5 -xdr_rejected_reply(xdrs, rr) -\s-1XDR\s0 *xdrs; -struct rejected_reply *rr; -.fi -.ft R -.IP -Used for describing -.SM RPC -reply messages. -This routine is useful for users who wish to generate -.SM RPC\s0-style -messages without using the -.SM RPC -package. -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -xdr_replymsg(xdrs, rmsg) -\s-1XDR\s0 *xdrs; -struct rpc_msg *rmsg; -.fi -.ft R -.IP -Used for describing -.SM RPC -reply messages. -This routine is useful for users who wish to generate -.SM RPC -style messages without using the -.SM RPC -package. -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -void -xprt_register(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -After -.SM RPC -service transport handles are created, -they should register themselves with the -.SM RPC -service package. -This routine modifies the global variable -.BR svc_fds(\|) . -Service implementors usually do not need this routine. -.br -.if t .ne 8 -.LP -.ft B -.nf -.sp .5 -void -xprt_unregister(xprt) -\s-1SVCXPRT\s0 *xprt; -.fi -.ft R -.IP -Before an -.SM RPC -service transport handle is destroyed, -it should unregister itself with the -.SM RPC -service package. -This routine modifies the global variable -.BR svc_fds(\|) . -Service implementors usually do not need this routine. -.SH SEE ALSO -.BR rpc_secure (3), -.BR xdr (3) -.br -The following manuals: -.RS -.ft I -Remote Procedure Calls: Protocol Specification -.br -Remote Procedure Call Programming Guide -.br -rpcgen Programming Guide -.br -.ft R -.RE -.IR "\s-1RPC\s0: Remote Procedure Call Protocol Specification" , -.SM RFC1050, Sun Microsystems, Inc., -.SM USC-ISI\s0. - diff --git a/c/src/librpc/src/rpc/rpc.5 b/c/src/librpc/src/rpc/rpc.5 deleted file mode 100644 index 36f895dbf2..0000000000 --- a/c/src/librpc/src/rpc/rpc.5 +++ /dev/null @@ -1,35 +0,0 @@ -.\" $FreeBSD: src/lib/libc/rpc/rpc.5,v 1.6 1999/08/28 00:00:44 peter Exp $ -.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI; -.Dd September 26, 1985 -.Dt RPC 5 -.Sh NAME -.Nm rpc -.Nd rpc program number data base -.Sh SYNOPSIS -/etc/rpc -.Sh DESCRIPTION -The -.Pa /etc/rpc -file contains user readable names that -can be used in place of rpc program numbers. -Each line has the following information: -.Pp -.Bl -bullet -compact -.It -name of server for the rpc program -.It -rpc program number -.It -aliases -.El -.Pp -Items are separated by any number of blanks and/or -tab characters. -A ``#'' indicates the beginning of a comment; characters up to the end of -the line are not interpreted by routines which search the file. -.Sh FILES -.Bl -tag -compact -width /etc/rpc -.Pa /etc/rpc -.El -.Sh "SEE ALSO" -.Xr getrpcent 3 diff --git a/c/src/librpc/src/rpc/rpc_callmsg.c b/c/src/librpc/src/rpc/rpc_callmsg.c deleted file mode 100644 index 982fc47b45..0000000000 --- a/c/src/librpc/src/rpc/rpc_callmsg.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_callmsg.c,v 1.9 1999/08/28 00:00:45 peter Exp $"; -#endif - -/* - * rpc_callmsg.c - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - */ - -#include -#include -#include -#include - -/* - * XDR a call message - */ -bool_t -xdr_callmsg(xdrs, cmsg) - register XDR *xdrs; - register struct rpc_msg *cmsg; -{ - register int32_t *buf; - register struct opaque_auth *oa; - - if (xdrs->x_op == XDR_ENCODE) { - if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { - return (FALSE); - } - if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { - return (FALSE); - } - buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT - + RNDUP(cmsg->rm_call.cb_cred.oa_length) - + 2 * BYTES_PER_XDR_UNIT - + RNDUP(cmsg->rm_call.cb_verf.oa_length)); - if (buf != NULL) { - IXDR_PUT_LONG(buf, cmsg->rm_xid); - IXDR_PUT_ENUM(buf, cmsg->rm_direction); - if (cmsg->rm_direction != CALL) { - return (FALSE); - } - IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers); - if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { - return (FALSE); - } - IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog); - IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers); - IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc); - oa = &cmsg->rm_call.cb_cred; - IXDR_PUT_ENUM(buf, oa->oa_flavor); - IXDR_PUT_LONG(buf, oa->oa_length); - if (oa->oa_length) { - memcpy((caddr_t)buf, oa->oa_base, oa->oa_length); - buf += RNDUP(oa->oa_length) / sizeof (int32_t); - } - oa = &cmsg->rm_call.cb_verf; - IXDR_PUT_ENUM(buf, oa->oa_flavor); - IXDR_PUT_LONG(buf, oa->oa_length); - if (oa->oa_length) { - memcpy((caddr_t)buf, oa->oa_base, oa->oa_length); - /* no real need.... - buf += RNDUP(oa->oa_length) / sizeof (int32_t); - */ - } - return (TRUE); - } - } - if (xdrs->x_op == XDR_DECODE) { - buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); - if (buf != NULL) { - cmsg->rm_xid = IXDR_GET_LONG(buf); - cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); - if (cmsg->rm_direction != CALL) { - return (FALSE); - } - cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); - if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { - return (FALSE); - } - cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); - cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); - cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); - oa = &cmsg->rm_call.cb_cred; - oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); - oa->oa_length = IXDR_GET_LONG(buf); - if (oa->oa_length) { - if (oa->oa_length > MAX_AUTH_BYTES) { - return (FALSE); - } - if (oa->oa_base == NULL) { - oa->oa_base = (caddr_t) - mem_alloc(oa->oa_length); - } - buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); - if (buf == NULL) { - if (xdr_opaque(xdrs, oa->oa_base, - oa->oa_length) == FALSE) { - return (FALSE); - } - } else { - memcpy(oa->oa_base, (caddr_t)buf, - oa->oa_length); - /* no real need.... - buf += RNDUP(oa->oa_length) / - sizeof (int32_t); - */ - } - } - oa = &cmsg->rm_call.cb_verf; - buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || - xdr_u_int(xdrs, &oa->oa_length) == FALSE) { - return (FALSE); - } - } else { - oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); - oa->oa_length = IXDR_GET_LONG(buf); - } - if (oa->oa_length) { - if (oa->oa_length > MAX_AUTH_BYTES) { - return (FALSE); - } - if (oa->oa_base == NULL) { - oa->oa_base = (caddr_t) - mem_alloc(oa->oa_length); - } - buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); - if (buf == NULL) { - if (xdr_opaque(xdrs, oa->oa_base, - oa->oa_length) == FALSE) { - return (FALSE); - } - } else { - memcpy(oa->oa_base, (caddr_t)buf, - oa->oa_length); - /* no real need... - buf += RNDUP(oa->oa_length) / - sizeof (int32_t); - */ - } - } - return (TRUE); - } - } - if ( - xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) && - xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && - (cmsg->rm_direction == CALL) && - xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) && - (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && - xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) && - xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) && - xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) && - xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) ) - return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); - return (FALSE); -} - diff --git a/c/src/librpc/src/rpc/rpc_commondata.c b/c/src/librpc/src/rpc/rpc_commondata.c deleted file mode 100644 index bbe6003337..0000000000 --- a/c/src/librpc/src/rpc/rpc_commondata.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_commondata.c,v 1.7 1999/08/28 00:00:45 peter Exp $"; -#endif - -#include -/* - * This file should only contain common data (global data) that is exported - * by public interfaces - */ -struct opaque_auth _null_auth; -struct rpc_createerr rpc_createerr; diff --git a/c/src/librpc/src/rpc/rpc_dtablesize.c b/c/src/librpc/src/rpc/rpc_dtablesize.c deleted file mode 100644 index e07c0b6568..0000000000 --- a/c/src/librpc/src/rpc/rpc_dtablesize.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/ -/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_dtablesize.c,v 1.10 1999/08/28 00:00:45 peter Exp $"; -#endif - -#include -#include - -/* - * Cache the result of getdtablesize(), so we don't have to do an - * expensive system call every time. - */ -/* - * XXX In FreeBSD 2.x, you can have the maximum number of open file - * descriptors be greater than FD_SETSIZE (which us 256 by default). - * - * Since old programs tend to use this call to determine the first arg - * for select(), having this return > FD_SETSIZE is a Bad Idea(TM)! - */ -int -_rpc_dtablesize(void) -{ - static int size; - - if (size == 0) { - size = getdtablesize(); - if (size > FD_SETSIZE) - size = FD_SETSIZE; - } - return (size); -} diff --git a/c/src/librpc/src/rpc/rpc_prot.c b/c/src/librpc/src/rpc/rpc_prot.c deleted file mode 100644 index 14a2524c70..0000000000 --- a/c/src/librpc/src/rpc/rpc_prot.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_prot.c,v 1.8 1999/08/28 00:00:46 peter Exp $"; -#endif - -/* - * rpc_prot.c - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * This set of routines implements the rpc message definition, - * its serializer and some common rpc utility routines. - * The routines are meant for various implementations of rpc - - * they are NOT for the rpc client or rpc service implementations! - * Because authentication stuff is easy and is part of rpc, the opaque - * routines are also in this program. - */ - -#include - -#include - -/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ - -struct opaque_auth _null_auth; - -/* - * XDR an opaque authentication struct - * (see auth.h) - */ -bool_t -xdr_opaque_auth(xdrs, ap) - register XDR *xdrs; - register struct opaque_auth *ap; -{ - - if (xdr_enum(xdrs, &(ap->oa_flavor))) - return (xdr_bytes(xdrs, &ap->oa_base, - &ap->oa_length, MAX_AUTH_BYTES)); - return (FALSE); -} - -/* - * XDR a DES block - */ -bool_t -xdr_des_block(xdrs, blkp) - register XDR *xdrs; - register des_block *blkp; -{ - return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block))); -} - -/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ - -/* - * XDR the MSG_ACCEPTED part of a reply message union - */ -bool_t -xdr_accepted_reply(xdrs, ar) - register XDR *xdrs; - register struct accepted_reply *ar; -{ - - /* personalized union, rather than calling xdr_union */ - if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) - return (FALSE); - if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) - return (FALSE); - switch (ar->ar_stat) { - - case SUCCESS: - return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); - - case PROG_MISMATCH: - if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low))) - return (FALSE); - return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high))); - default: - break; - } - return (TRUE); /* TRUE => open ended set of problems */ -} - -/* - * XDR the MSG_DENIED part of a reply message union - */ -bool_t -xdr_rejected_reply(xdrs, rr) - register XDR *xdrs; - register struct rejected_reply *rr; -{ - - /* personalized union, rather than calling xdr_union */ - if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) - return (FALSE); - switch (rr->rj_stat) { - - case RPC_MISMATCH: - if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low))) - return (FALSE); - return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high))); - - case AUTH_ERROR: - return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); - } - return (FALSE); -} - -static struct xdr_discrim reply_dscrm[3] = { - { (int)MSG_ACCEPTED, xdr_accepted_reply }, - { (int)MSG_DENIED, xdr_rejected_reply }, - { __dontcare__, NULL_xdrproc_t } }; - -/* - * XDR a reply message - */ -bool_t -xdr_replymsg(xdrs, rmsg) - register XDR *xdrs; - register struct rpc_msg *rmsg; -{ - if ( - xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) && - xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && - (rmsg->rm_direction == REPLY) ) - return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), - (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t)); - return (FALSE); -} - - -/* - * Serializes the "static part" of a call message header. - * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. - * The rm_xid is not really static, but the user can easily munge on the fly. - */ -bool_t -xdr_callhdr(xdrs, cmsg) - register XDR *xdrs; - register struct rpc_msg *cmsg; -{ - - cmsg->rm_direction = CALL; - cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; - if ( - (xdrs->x_op == XDR_ENCODE) && - xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) && - xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && - xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) && - xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) ) - return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers))); - return (FALSE); -} - -/* ************************** Client utility routine ************* */ - -static void -accepted(acpt_stat, error) - register enum accept_stat acpt_stat; - register struct rpc_err *error; -{ - - switch (acpt_stat) { - - case PROG_UNAVAIL: - error->re_status = RPC_PROGUNAVAIL; - return; - - case PROG_MISMATCH: - error->re_status = RPC_PROGVERSMISMATCH; - return; - - case PROC_UNAVAIL: - error->re_status = RPC_PROCUNAVAIL; - return; - - case GARBAGE_ARGS: - error->re_status = RPC_CANTDECODEARGS; - return; - - case SYSTEM_ERR: - error->re_status = RPC_SYSTEMERROR; - return; - - case SUCCESS: - error->re_status = RPC_SUCCESS; - return; - } - /* something's wrong, but we don't know what ... */ - error->re_status = RPC_FAILED; - error->re_lb.s1 = (long)MSG_ACCEPTED; - error->re_lb.s2 = (long)acpt_stat; -} - -static void -rejected(rjct_stat, error) - register enum reject_stat rjct_stat; - register struct rpc_err *error; -{ - - switch (rjct_stat) { - - case RPC_VERSMISMATCH: - error->re_status = RPC_VERSMISMATCH; - return; - - case AUTH_ERROR: - error->re_status = RPC_AUTHERROR; - return; - default: - break; - } - /* something's wrong, but we don't know what ... */ - error->re_status = RPC_FAILED; - error->re_lb.s1 = (long)MSG_DENIED; - error->re_lb.s2 = (long)rjct_stat; -} - -/* - * given a reply message, fills in the error - */ -void -_seterr_reply(msg, error) - register struct rpc_msg *msg; - register struct rpc_err *error; -{ - - /* optimized for normal, SUCCESSful case */ - switch (msg->rm_reply.rp_stat) { - - case MSG_ACCEPTED: - if (msg->acpted_rply.ar_stat == SUCCESS) { - error->re_status = RPC_SUCCESS; - return; - }; - accepted(msg->acpted_rply.ar_stat, error); - break; - - case MSG_DENIED: - rejected(msg->rjcted_rply.rj_stat, error); - break; - - default: - error->re_status = RPC_FAILED; - error->re_lb.s1 = (long)(msg->rm_reply.rp_stat); - break; - } - switch (error->re_status) { - - case RPC_VERSMISMATCH: - error->re_vers.low = msg->rjcted_rply.rj_vers.low; - error->re_vers.high = msg->rjcted_rply.rj_vers.high; - break; - - case RPC_AUTHERROR: - error->re_why = msg->rjcted_rply.rj_why; - break; - - case RPC_PROGVERSMISMATCH: - error->re_vers.low = msg->acpted_rply.ar_vers.low; - error->re_vers.high = msg->acpted_rply.ar_vers.high; - break; - default: - break; - } -} diff --git a/c/src/librpc/src/rpc/rpc_secure.3 b/c/src/librpc/src/rpc/rpc_secure.3 deleted file mode 100644 index 4efd9b8614..0000000000 --- a/c/src/librpc/src/rpc/rpc_secure.3 +++ /dev/null @@ -1,254 +0,0 @@ -.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI -.\" $FreeBSD: src/lib/libc/rpc/rpc_secure.3,v 1.6 2000/03/02 09:13:48 sheldonh Exp $ -.\" -.Dd February 16, 1988 -.Dt RPC 3 -.Sh NAME -.Nm rpc_secure -.Nd library routines for secure remote procedure calls -.Sh SYNOPSIS -.Fd #include -.Ft AUTH * -.Fo authdes_create -.Fa "char *name" -.Fa "unsigned window" -.Fa "struct sockaddr *addr" -.Fa "des_block *ckey" -.Fc -.Ft int -.Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups" -.Ft int -.Fn getnetname "char *name" -.Ft int -.Fn host2netname "char *name" "char *host" "char *domain" -.Ft int -.Fn key_decryptsession "const char *remotename" "des_block *deskey" -.Ft int -.Fn key_encryptsession "const char *remotename" "des_block *deskey" -.Ft int -.Fn key_gendes "des_block *deskey" -.Ft int -.Fn key_setsecret "const char *key" -.Ft int -.Fn netname2host "char *name" "char *host" "int hostlen" -.Ft int -.Fn netname2user "char *name" "uid_t *uidp" "gid_t *gidp" "int *gidlenp" "gid_t *gidlist" -.Ft int -.Fn user2netname "char *name" "uid_t uid" "char *domain" -.Sh DESCRIPTION -These routines are part of the -.Tn RPC -library. They implement -.Tn DES -Authentication. See -.Xr rpc 3 -for further details about -.Tn RPC . -.Pp -The -.Fn authdes_create -is the first of two routines which interface to the -.Tn RPC -secure authentication system, known as -.Tn DES -authentication. -The second is -.Fn authdes_getucred , -below. -.Pp -Note: the keyserver daemon -.Xr keyserv 8 -must be running for the -.Tn DES -authentication system to work. -.Pp -.Fn Authdes_create , -used on the client side, returns an authentication handle that -will enable the use of the secure authentication system. -The first parameter -.Fa name -is the network name, or -.Fa netname , -of the owner of the server process. -This field usually -represents a -.Fa hostname -derived from the utility routine -.Fn host2netname , -but could also represent a user name using -.Fn user2netname . -The second field is window on the validity of -the client credential, given in seconds. A small -window is more secure than a large one, but choosing -too small of a window will increase the frequency of -resynchronizations because of clock drift. -The third -parameter -.Fa addr -is optional. If it is -.Dv NULL , -then the authentication system will assume -that the local clock is always in sync with the server's -clock, and will not attempt resynchronizations. -If an address -is supplied, however, then the system will use the address -for consulting the remote time service whenever -resynchronization -is required. -This parameter is usually the -address of the -.Tn RPC -server itself. -The final parameter -.Fa ckey -is also optional. If it is -.Dv NULL , -then the authentication system will -generate a random -.Tn DES -key to be used for the encryption of credentials. -If it is supplied, however, then it will be used instead. -.Pp -.Fn Authdes_getucred , -the second of the two -.Tn DES -authentication routines, -is used on the server side for converting a -.Tn DES -credential, which is -operating system independent, into a -.Ux -credential. -This routine differs from utility routine -.Fn netname2user -in that -.Fn authdes_getucred -pulls its information from a cache, and does not have to do a -Yellow Pages lookup every time it is called to get its information. -.Pp -.Fn Getnetname -installs the unique, operating-system independent netname of -the -caller in the fixed-length array -.Fa name . -Returns -.Dv TRUE -if it succeeds and -.Dv FALSE -if it fails. -.Pp -.Fn Host2netname -converts from a domain-specific hostname to an -operating-system independent netname. -Returns -.Dv TRUE -if it succeeds and -.Dv FALSE -if it fails. -Inverse of -.Fn netname2host . -.Pp -.Fn Key_decryptsession -is an interface to the keyserver daemon, which is associated -with -.Tn RPC Ns 's -secure authentication system ( -.Tn DES -authentication). -User programs rarely need to call it, or its associated routines -.Fn key_encryptsession , -.Fn key_gendes -and -.Fn key_setsecret . -System commands such as -.Xr login 1 -and the -.Tn RPC -library are the main clients of these four routines. -.Pp -.Fn Key_decryptsession -takes a server netname and a -.Tn DES -key, and decrypts the key by -using the the public key of the the server and the secret key -associated with the effective uid of the calling process. It -is the inverse of -.Fn key_encryptsession . -.Pp -.Fn Key_encryptsession -is a keyserver interface routine. -It -takes a server netname and a des key, and encrypts -it using the public key of the the server and the secret key -associated with the effective uid of the calling process. It -is the inverse of -.Fn key_decryptsession . -.Pp -.Fn Key_gendes -is a keyserver interface routine. -It -is used to ask the keyserver for a secure conversation key. -Choosing one -.Qq random -is usually not good enough, -because -the common ways of choosing random numbers, such as using the -current time, are very easy to guess. -.Pp -.Fn Key_setsecret -is a keyserver interface routine. -It is used to set the key for -the effective -.Fa uid -of the calling process. -.Pp -.Fn Netname2host -converts from an operating-system independent netname to a -domain-specific hostname. -Returns -.Dv TRUE -if it succeeds and -.Dv FALSE -if it fails. Inverse of -.Fn host2netname . -.Pp -.Fn Netname2user -converts from an operating-system independent netname to a -domain-specific user ID. -Returns -.Dv TRUE -if it succeeds and -.Dv FALSE -if it fails. -Inverse of -.Fn user2netname . -.Pp -.Fn User2netname -converts from a domain-specific username to an operating-system -independent netname. -Returns -.Dv TRUE -if it succeeds and -.Dv FALSE -if it fails. -Inverse of -.Fn netname2user . -.Sh SEE ALSO -.Xr rpc 3 , -.Xr xdr 3 , -.Xr keyserv 8 -.Pp -The following manuals: -.Rs -.%B Remote Procedure Calls: Protocol Specification -.Re -.Rs -.%B Remote Procedure Call Programming Guide -.Re -.Rs -.%B Rpcgen Programming Guide -.Re -.Rs -.%B RPC: Remote Procedure Call Protocol Specification -.%O RFC1050, Sun Microsystems Inc., USC-ISI -.Re diff --git a/c/src/librpc/src/rpc/rpcdname.c b/c/src/librpc/src/rpc/rpcdname.c deleted file mode 100644 index 39f7167bcd..0000000000 --- a/c/src/librpc/src/rpc/rpcdname.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#if !defined(lint) && defined(SCCSIDS) -static char sccsid[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro"; -#endif - -/* - * rpcdname.c - * Gets the default domain name - */ - -#include -#include -#include -#include - -#define default_domain ((char *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->rpcdname_default_domain) - -static char * -get_default_domain() -{ - char temp[256]; - - if (default_domain) - return (default_domain); - if (getdomainname(temp, sizeof(temp)) < 0) - return (0); - if ((int) strlen(temp) > 0) { - default_domain = (char *)malloc((strlen(temp)+(unsigned)1)); - if (default_domain == 0) - return (0); - (void) strcpy(default_domain, temp); - return (default_domain); - } - return (0); -} - -/* - * This is a wrapper for the system call getdomainname which returns a - * ypclnt.h error code in the failure case. It also checks to see that - * the domain name is non-null, knowing that the null string is going to - * get rejected elsewhere in the NIS client package. - */ -int -_rpc_get_default_domain(domain) - char **domain; -{ - if ((*domain = get_default_domain()) != 0) - return (0); - return (-1); -} diff --git a/c/src/librpc/src/rpc/rstat.1 b/c/src/librpc/src/rpc/rstat.1 deleted file mode 100644 index 6cc47c26c8..0000000000 --- a/c/src/librpc/src/rpc/rstat.1 +++ /dev/null @@ -1,58 +0,0 @@ -.\" $FreeBSD: src/lib/libc/rpc/rstat.1,v 1.5 1999/08/28 00:00:46 peter Exp $ -.\" @(#)rstat.1 2.1 88/08/03 4.0 RPCSRC -.TH RSTAT 1 "3 August 1988" -.SH NAME -rstat \- remote status display -.SH SYNOPSIS -.B rstat -.B host -.SH DESCRIPTION -.LP -.B rstat -displays a summary of the current system status of a particular -.BR host . -The output shows the current time of day, how long the system has -been up, -and the load averages. -The load average numbers give the number of jobs in the run queue -averaged over 1, 5 and 15 minutes. -.PP -The -.B rstat_svc(8) -daemon must be running on the remote host for this command to -work. -.B rstat -uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x. -.SH EXAMPLE -.RS -.ft B -.nf -example% rstat otherhost -7:36am up 6 days, 16:45, load average: 0.20, 0.23, 0.18 -example% -.ft R -.fi -.RE -.SH DIAGNOSTICS -.LP -rstat: RPC: Program not registered -.IP -The -.B rstat_svc -daemon has not been started on the remote host. -.LP -rstat: RPC: Timed out -.IP -A communication error occurred. Either the network is -excessively congested, or the -.B rstat_svc -daemon has terminated on the remote host. -.LP -rstat: RPC: Port mapper failure - RPC: Timed out -.IP -The remote host is not running the portmapper (see -.BR portmap(8) ), -and cannot accommodate any RPC-based services. The host may be down. -.SH "SEE ALSO" -.BR portmap (8), -.BR rstat_svc (8) diff --git a/c/src/librpc/src/rpc/rstat_svc.8 b/c/src/librpc/src/rpc/rstat_svc.8 deleted file mode 100644 index e2eae8be3d..0000000000 --- a/c/src/librpc/src/rpc/rstat_svc.8 +++ /dev/null @@ -1,22 +0,0 @@ -.\" $FreeBSD: src/lib/libc/rpc/rstat_svc.8,v 1.5 1999/08/28 00:00:47 peter Exp $ -.\" @(#)rstat_svc.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 87/09/09 SMI -.TH RSTAT_SVC 8 "24 November 1987" -.SH NAME -rstat_svc \- kernel statistics server -.SH SYNOPSIS -.B /etc/rstat_svc -.SH DESCRIPTION -.LP -.B rstat_svc -is a server which returns performance statistics -obtained from the kernel. -These statistics are graphically displayed by the Sun Microsystems program, -.BR perfmeter (1). -The -.B rstat_svc -daemon is normally invoked at boot time through /etc/rc.local. -.PP -.B rstat_svc -uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x. -.\" .SH "SEE ALSO" -.\" .BR rstat (1), diff --git a/c/src/librpc/src/rpc/rtems_portmapper.c b/c/src/librpc/src/rpc/rtems_portmapper.c deleted file mode 100644 index e33a3103c9..0000000000 --- a/c/src/librpc/src/rpc/rtems_portmapper.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void reg_service(); -static void callit(); -static struct pmaplist *pmaplist; -static int debugging = 0; - -#include -#define fork() (-1) - - -static rtems_task rtems_portmapper (rtems_task_argument unused) -{ - SVCXPRT *xprt; - int sock; - struct sockaddr_in addr; - int len = sizeof(struct sockaddr_in); - register struct pmaplist *pml; - - rtems_rpc_task_init (); - if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - perror("portmap cannot create socket"); - rtems_task_delete (RTEMS_SELF); - } - - addr.sin_addr.s_addr = 0; - addr.sin_family = AF_INET; - addr.sin_port = htons(PMAPPORT); - if (bind(sock, (struct sockaddr *)&addr, len) != 0) { - perror("portmap cannot bind"); - close (sock); - rtems_task_delete (RTEMS_SELF); - } - - if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) { - fprintf(stderr, "couldn't do udp_create\n"); - close (sock); - rtems_task_delete (RTEMS_SELF); - } - /* make an entry for ourself */ - pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); - pml->pml_next = 0; - pml->pml_map.pm_prog = PMAPPROG; - pml->pml_map.pm_vers = PMAPVERS; - pml->pml_map.pm_prot = IPPROTO_UDP; - pml->pml_map.pm_port = PMAPPORT; - pmaplist = pml; - - if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - perror("portmap cannot create socket"); - close (sock); - rtems_task_delete (RTEMS_SELF); - } - if (bind(sock, (struct sockaddr *)&addr, len) != 0) { - perror("portmap cannot bind"); - close (sock); - rtems_task_delete (RTEMS_SELF); - } - if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE)) - == (SVCXPRT *)NULL) { - fprintf(stderr, "couldn't do tcp_create\n"); - close (sock); - rtems_task_delete (RTEMS_SELF); - } - /* make an entry for ourself */ - pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); - pml->pml_map.pm_prog = PMAPPROG; - pml->pml_map.pm_vers = PMAPVERS; - pml->pml_map.pm_prot = IPPROTO_TCP; - pml->pml_map.pm_port = PMAPPORT; - pml->pml_next = pmaplist; - pmaplist = pml; - - (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); - - svc_run(); - fprintf(stderr, "run_svc returned unexpectedly\n"); - close (sock); - rtems_task_delete (RTEMS_SELF); -} - -static struct pmaplist * -find_service(prog, vers, prot) -u_long prog; -u_long vers; -{ -register struct pmaplist *hit = NULL; -register struct pmaplist *pml; - -for (pml = pmaplist; pml != NULL; pml = pml->pml_next) { - if ((pml->pml_map.pm_prog != prog) || - (pml->pml_map.pm_prot != prot)) - continue; - hit = pml; - if (pml->pml_map.pm_vers == vers) - break; -} - return (hit); -} - -/* - * 1 OK, 0 not - */ -static void reg_service(rqstp, xprt) - struct svc_req *rqstp; - SVCXPRT *xprt; -{ - struct pmap reg; - struct pmaplist *pml, *prevpml, *fnd; - int ans, port; - caddr_t t; - -#ifdef DEBUG - fprintf(stderr, "server: about do a switch\n"); -#endif - switch (rqstp->rq_proc) { - - case PMAPPROC_NULL: - /* - * Null proc call - */ - if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) { - abort(); - } - break; - - case PMAPPROC_SET: - /* - * Set a program,version to port mapping - */ - if (!svc_getargs(xprt, xdr_pmap, (caddr_t)®)) - svcerr_decode(xprt); - else { - /* - * check to see if already used - * find_service returns a hit even if - * the versions don't match, so check for it - */ - fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); - if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) { - if (fnd->pml_map.pm_port == reg.pm_port) { - ans = 1; - goto done; - } - else { - ans = 0; - goto done; - } - } else { - /* - * add to END of list - */ - pml = (struct pmaplist *) - malloc((u_int)sizeof(struct pmaplist)); - pml->pml_map = reg; - pml->pml_next = 0; - if (pmaplist == 0) { - pmaplist = pml; - } else { - for (fnd= pmaplist; fnd->pml_next != 0; - fnd = fnd->pml_next); - fnd->pml_next = pml; - } - ans = 1; - } - done: - if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && - debugging) { - fprintf(stderr, "svc_sendreply\n"); - abort(); - } - } - break; - - case PMAPPROC_UNSET: - /* - * Remove a program,version to port mapping. - */ - if (!svc_getargs(xprt, xdr_pmap, (caddr_t)®)) - svcerr_decode(xprt); - else { - ans = 0; - for (prevpml = NULL, pml = pmaplist; pml != NULL; ) { - if ((pml->pml_map.pm_prog != reg.pm_prog) || - (pml->pml_map.pm_vers != reg.pm_vers)) { - /* both pml & prevpml move forwards */ - prevpml = pml; - pml = pml->pml_next; - continue; - } - /* found it; pml moves forward, prevpml stays */ - ans = 1; - t = (caddr_t)pml; - pml = pml->pml_next; - if (prevpml == NULL) - pmaplist = pml; - else - prevpml->pml_next = pml; - free(t); - } - if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && - debugging) { - fprintf(stderr, "svc_sendreply\n"); - abort(); - } - } - break; - - case PMAPPROC_GETPORT: - /* - * Lookup the mapping for a program,version and return its port - */ - if (!svc_getargs(xprt, xdr_pmap, (caddr_t)®)) - svcerr_decode(xprt); - else { - fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); - if (fnd) - port = fnd->pml_map.pm_port; - else - port = 0; - if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) && - debugging) { - fprintf(stderr, "svc_sendreply\n"); - abort(); - } - } - break; - - case PMAPPROC_DUMP: - /* - * Return the current set of mapped program,version - */ - if (!svc_getargs(xprt, xdr_void, NULL)) - svcerr_decode(xprt); - else { - if ((!svc_sendreply(xprt, xdr_pmaplist, - (caddr_t)&pmaplist)) && debugging) { - fprintf(stderr, "svc_sendreply\n"); - abort(); - } - } - break; - - case PMAPPROC_CALLIT: - /* - * Calls a procedure on the local machine. If the requested - * procedure is not registered this procedure does not return - * error information!! - * This procedure is only supported on rpc/udp and calls via - * rpc/udp. It passes null authentication parameters. - */ - callit(rqstp, xprt); - break; - - default: - svcerr_noproc(xprt); - break; - } -} - - -/* - * Stuff for the rmtcall service - */ -#define ARGSIZE 9000 - -struct encap_parms { - u_long arglen; - char *args; -}; - -static bool_t -xdr_encap_parms(xdrs, epp) - XDR *xdrs; - struct encap_parms *epp; -{ - - return (xdr_bytes(xdrs, &(epp->args), (u_int*)&(epp->arglen), ARGSIZE)); -} - -struct rmtcallargs { - u_long rmt_prog; - u_long rmt_vers; - u_long rmt_port; - u_long rmt_proc; - struct encap_parms rmt_args; -}; - -static bool_t -xdr_rmtcall_args(xdrs, cap) - register XDR *xdrs; - register struct rmtcallargs *cap; -{ - - /* does not get a port number */ - if (xdr_u_long(xdrs, &(cap->rmt_prog)) && - xdr_u_long(xdrs, &(cap->rmt_vers)) && - xdr_u_long(xdrs, &(cap->rmt_proc))) { - return (xdr_encap_parms(xdrs, &(cap->rmt_args))); - } - return (FALSE); -} - -static bool_t -xdr_rmtcall_result(xdrs, cap) - register XDR *xdrs; - register struct rmtcallargs *cap; -{ - if (xdr_u_long(xdrs, &(cap->rmt_port))) - return (xdr_encap_parms(xdrs, &(cap->rmt_args))); - return (FALSE); -} - -/* - * only worries about the struct encap_parms part of struct rmtcallargs. - * The arglen must already be set!! - */ -static bool_t -xdr_opaque_parms(xdrs, cap) - XDR *xdrs; - struct rmtcallargs *cap; -{ - - return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen)); -} - -/* - * This routine finds and sets the length of incoming opaque paraters - * and then calls xdr_opaque_parms. - */ -static bool_t -xdr_len_opaque_parms(xdrs, cap) - register XDR *xdrs; - struct rmtcallargs *cap; -{ - register u_int beginpos, lowpos, highpos, currpos, pos; - - beginpos = lowpos = pos = xdr_getpos(xdrs); - highpos = lowpos + ARGSIZE; - while ((int)(highpos - lowpos) >= 0) { - currpos = (lowpos + highpos) / 2; - if (xdr_setpos(xdrs, currpos)) { - pos = currpos; - lowpos = currpos + 1; - } else { - highpos = currpos - 1; - } - } - xdr_setpos(xdrs, beginpos); - cap->rmt_args.arglen = pos - beginpos; - return (xdr_opaque_parms(xdrs, cap)); -} - -/* - * Call a remote procedure service - * This procedure is very quiet when things go wrong. - * The proc is written to support broadcast rpc. In the broadcast case, - * a machine should shut-up instead of complain, less the requestor be - * overrun with complaints at the expense of not hearing a valid reply ... - * - * This now forks so that the program & process that it calls can call - * back to the portmapper. - */ -static void -callit(rqstp, xprt) - struct svc_req *rqstp; - SVCXPRT *xprt; -{ - struct rmtcallargs a; - struct pmaplist *pml; - u_short port; - struct sockaddr_in me; - int pid, socket = -1; - CLIENT *client; - struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred; - struct timeval timeout; - char buf[ARGSIZE]; - - timeout.tv_sec = 5; - timeout.tv_usec = 0; - a.rmt_args.args = buf; - if (!svc_getargs(xprt, xdr_rmtcall_args, (caddr_t)&a)) - return; - if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL) - return; - /* - * fork a child to do the work. Parent immediately returns. - * Child exits upon completion. - */ - if ((pid = fork()) != 0) { - if (debugging && (pid < 0)) { - fprintf(stderr, "portmap CALLIT: cannot fork.\n"); - } - return; - } - port = pml->pml_map.pm_port; - get_myaddress(&me); - me.sin_port = htons(port); - client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket); - if (client != (CLIENT *)NULL) { - if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) { - client->cl_auth = authunix_create(au->aup_machname, - au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids); - } - a.rmt_port = (u_long)port; - if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a, - xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) { - svc_sendreply(xprt, xdr_rmtcall_result, (caddr_t)&a); - } - AUTH_DESTROY(client->cl_auth); - clnt_destroy(client); - } - (void)close(socket); - exit(0); -} - -/* - * Start the RPC portmapper - */ -int rtems_rpc_start_portmapper (int priority) -{ - rtems_mode mode; - rtems_status_code sc; - rtems_id tid; - static int started; - - rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode); - if (started) { - rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); - return RTEMS_SUCCESSFUL; - } - sc = rtems_task_create (rtems_build_name('P', 'M', 'A', 'P'), - priority, - 8000, - RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), - RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, - &tid); - if (sc != RTEMS_SUCCESSFUL) { - rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); - return sc; - } - sc = rtems_task_start (tid, rtems_portmapper, 0); - if (sc != RTEMS_SUCCESSFUL) { - rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); - return sc; - } - started = 1; - rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/librpc/src/rpc/rtems_rpc.c b/c/src/librpc/src/rpc/rtems_rpc.c deleted file mode 100644 index d2666e2f91..0000000000 --- a/c/src/librpc/src/rpc/rtems_rpc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * RTEMS multi-tasking support - */ - -#include -#include -#include - -/* - * RPC variables for single-thread - */ -static struct rtems_rpc_task_variables rpc_default = { - -1, /* svc_maxfd */ -}; - -/* - * RPC values for initializing a new per-task set of variables - */ -static const struct rtems_rpc_task_variables rpc_init = { - -1, /* svc_maxfd */ -}; - -/* - * Per-task pointer to RPC data - */ -void *rtems_rpc_task_variables = &rpc_default; - -/* - * Set up per-task RPC variables - */ -int rtems_rpc_task_init (void) -{ - rtems_status_code sc; - struct rtems_rpc_task_variables *tvp; - - if (rtems_rpc_task_variables == &rpc_default) { - tvp = malloc (sizeof *tvp); - if (tvp == NULL) - return RTEMS_NO_MEMORY; - /* - * FIXME: Should have destructor which cleans up - * all RPC stuff: - * - Close all files - * - Go through and free linked list elements - * - Free other allocated memory (e.g. clnt_perror_buf) - */ - sc = rtems_task_variable_add (RTEMS_SELF, &rtems_rpc_task_variables, NULL); - if (sc != RTEMS_SUCCESSFUL) { - free (tvp); - return sc; - } - *tvp = rpc_init; - rtems_rpc_task_variables = tvp; - } - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/librpc/src/rpc/rtime.3 b/c/src/librpc/src/rpc/rtime.3 deleted file mode 100644 index ad3e538c43..0000000000 --- a/c/src/librpc/src/rpc/rtime.3 +++ /dev/null @@ -1,47 +0,0 @@ -.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI -.\" $FreeBSD: src/lib/libc/rpc/rtime.3,v 1.4 2000/03/02 09:13:48 sheldonh Exp $ -.\" -.TH RTIME 3 "22 November 1987" -.SH NAME -rtime \- get remote time -.SH SYNOPSIS -.nf -.B #include -.B #include -.B #include -.LP -.B int rtime(addrp, timep, timeout) -.B struct sockaddr_in \(**addrp; -.B struct timeval \(**timep; -.B struct timeval \(**timeout; -.fi -.SH DESCRIPTION -.B rtime(\|) -consults the Internet Time Server at the address pointed to by -.I addrp -and returns the remote time in the -.B timeval -struct pointed to by -.IR timep . -Normally, the -.SM UDP -protocol is used when consulting the Time Server. -The -.I timeout -parameter specifies how long the -routine should wait before giving -up when waiting for a reply. If -.I timeout -is specified as -.SM NULL\s0, -however, the routine will instead use -.SM TCP -and block until a reply is received from the time server. -.LP -The routine returns 0 if it is successful. -Otherwise, -it returns \-1 and -.B errno -is set to reflect the cause of the error. -.SH "SEE ALSO" -.BR timed (8c) diff --git a/c/src/librpc/src/rpc/rtime.c b/c/src/librpc/src/rpc/rtime.c deleted file mode 100644 index ad83dee2dc..0000000000 --- a/c/src/librpc/src/rpc/rtime.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * Copyright (c) 1988 by Sun Microsystems, Inc. - - */ - -/* - * rtime - get time from remote machine - * - * gets time, obtaining value from host - * on the udp/time socket. Since timeserver returns - * with time of day in seconds since Jan 1, 1900, must - * subtract seconds before Jan 1, 1970 to get - * what unix uses. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(LIBC_SCCS) && !defined(lint) -/* from: static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; */ -static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/rtime.c,v 1.5 2000/01/27 23:06:41 jasone Exp $"; -#endif - -extern int _rpc_dtablesize __P(( void )); - -#define NYEARS (unsigned long)(1970 - 1900) -#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) - -static void do_close __P(( int )); - -int -rtime(addrp, timep, timeout) - struct sockaddr_in *addrp; - struct timeval *timep; - struct timeval *timeout; -{ - int s; - fd_set readfds; - int res; - unsigned long thetime; - struct sockaddr_in from; - int fromlen; - int type; - struct servent *serv; - - if (timeout == NULL) { - type = SOCK_STREAM; - } else { - type = SOCK_DGRAM; - } - s = socket(AF_INET, type, 0); - if (s < 0) { - return(-1); - } - addrp->sin_family = AF_INET; - - /* TCP and UDP port are the same in this case */ - if ((serv = getservbyname("time", "tcp")) == NULL) { - return(-1); - } - - addrp->sin_port = serv->s_port; - - if (type == SOCK_DGRAM) { - res = sendto(s, (char *)&thetime, sizeof(thetime), 0, - (struct sockaddr *)addrp, sizeof(*addrp)); - if (res < 0) { - do_close(s); - return(-1); - } - do { - FD_ZERO(&readfds); - FD_SET(s, &readfds); - res = select(_rpc_dtablesize(), &readfds, - (fd_set *)NULL, (fd_set *)NULL, timeout); - } while (res < 0 && errno == EINTR); - if (res <= 0) { - if (res == 0) { - errno = ETIMEDOUT; - } - do_close(s); - return(-1); - } - fromlen = sizeof(from); - res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0, - (struct sockaddr *)&from, &fromlen); - do_close(s); - if (res < 0) { - return(-1); - } - } else { - if (connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) { - do_close(s); - return(-1); - } - res = _RPC_read(s, (char *)&thetime, sizeof(thetime)); - do_close(s); - if (res < 0) { - return(-1); - } - } - if (res != sizeof(thetime)) { - errno = EIO; - return(-1); - } - thetime = ntohl(thetime); - timep->tv_sec = thetime - TOFFSET; - timep->tv_usec = 0; - return(0); -} - -static void -do_close(s) - int s; -{ - int save; - - save = errno; - (void)_RPC_close(s); - errno = save; -} diff --git a/c/src/librpc/src/rpc/svc.c b/c/src/librpc/src/rpc/svc.c deleted file mode 100644 index 92832a589b..0000000000 --- a/c/src/librpc/src/rpc/svc.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc.c,v 1.14 1999/08/28 00:00:48 peter Exp $"; -#endif - -/* - * svc.c, Server-side remote procedure call interface. - * - * There are two sets of procedures here. The xprt routines are - * for handling transport handles. The svc routines handle the - * list of service routines. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include - -#define xports ((SVCXPRT **)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xports) -#define xportssize (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xportssize) - -#define NULL_SVC ((struct svc_callout *)0) -#define RQCRED_SIZE 400 /* this size is excessive */ - -#define max(a, b) (a > b ? a : b) - -/* - * The services list - * Each entry represents a set of procedures (an rpc program). - * The dispatch routine takes request structs and runs the - * apropriate procedure. - */ -struct svc_callout { - struct svc_callout *sc_next; - u_long sc_prog; - u_long sc_vers; - void (*sc_dispatch)(); -}; -#define svc_head (struct svc_callout *)(((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_svc_head) - -static struct svc_callout *svc_find(); - -/* *************** SVCXPRT related stuff **************** */ - -/* - * Activate a transport handle. - */ -void -xprt_register(xprt) - SVCXPRT *xprt; -{ - register int sock = xprt->xp_sock; - - if (sock + 1 > __svc_fdsetsize) { - int bytes = sizeof (fd_set); - fd_set *fds; - - fds = (fd_set *)malloc(bytes); - memset(fds, 0, bytes); - if (__svc_fdset) { - memcpy(fds, __svc_fdset, bytes); - free(__svc_fdset); - } - __svc_fdset = fds; - __svc_fdsetsize = bytes * NBBY; - } - - if (sock < FD_SETSIZE) - FD_SET(sock, &svc_fdset); - FD_SET(sock, __svc_fdset); - - if (xports == NULL || sock + 1 > xportssize) { - SVCXPRT **xp; - int size = FD_SETSIZE; - - if (sock + 1 > size) - size = sock + 1; - xp = (SVCXPRT **)mem_alloc(size * sizeof(SVCXPRT *)); - memset(xp, 0, size * sizeof(SVCXPRT *)); - if (xports) { - memcpy(xp, xports, xportssize * sizeof(SVCXPRT *)); - free(xports); - } - xportssize = size; - xports = xp; - } - xports[sock] = xprt; - svc_maxfd = max(svc_maxfd, sock); -} - -/* - * De-activate a transport handle. - */ -void -xprt_unregister(xprt) - SVCXPRT *xprt; -{ - register int sock = xprt->xp_sock; - - if (xports[sock] == xprt) { - xports[sock] = (SVCXPRT *)0; - if (sock < FD_SETSIZE) - FD_CLR(sock, &svc_fdset); - FD_CLR(sock, __svc_fdset); - if (sock == svc_maxfd) { - for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--) - if (xports[svc_maxfd]) - break; - } - /* - * XXX could use svc_maxfd as a hint to - * decrease the size of __svc_fdset - */ - } -} - - -/* ********************** CALLOUT list related stuff ************* */ - -/* - * Add a service program to the callout list. - * The dispatch routine will be called when a rpc request for this - * program number comes in. - */ -bool_t -svc_register(xprt, prog, vers, dispatch, protocol) - SVCXPRT *xprt; - u_long prog; - u_long vers; - void (*dispatch)(); - int protocol; -{ - struct svc_callout *prev; - register struct svc_callout *s; - - if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { - if (s->sc_dispatch == dispatch) - goto pmap_it; /* he is registering another xptr */ - return (FALSE); - } - s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); - if (s == (struct svc_callout *)0) { - return (FALSE); - } - s->sc_prog = prog; - s->sc_vers = vers; - s->sc_dispatch = dispatch; - s->sc_next = svc_head; - svc_head = s; -pmap_it: - /* now register the information with the local binder service */ - if (protocol) { - return (pmap_set(prog, vers, protocol, xprt->xp_port)); - } - return (TRUE); -} - -/* - * Remove a service program from the callout list. - */ -void -svc_unregister(prog, vers) - u_long prog; - u_long vers; -{ - struct svc_callout *prev; - register struct svc_callout *s; - - if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) - return; - if (prev == NULL_SVC) { - svc_head = s->sc_next; - } else { - prev->sc_next = s->sc_next; - } - s->sc_next = NULL_SVC; - mem_free((char *) s, (u_int) sizeof(struct svc_callout)); - /* now unregister the information with the local binder service */ - (void)pmap_unset(prog, vers); -} - -/* - * Search the callout list for a program number, return the callout - * struct. - */ -static struct svc_callout * -svc_find(prog, vers, prev) - u_long prog; - u_long vers; - struct svc_callout **prev; -{ - register struct svc_callout *s, *p; - - p = NULL_SVC; - for (s = svc_head; s != NULL_SVC; s = s->sc_next) { - if ((s->sc_prog == prog) && (s->sc_vers == vers)) - goto done; - p = s; - } -done: - *prev = p; - return (s); -} - -/* ******************* REPLY GENERATION ROUTINES ************ */ - -/* - * Send a reply to an rpc request - */ -bool_t -svc_sendreply(xprt, xdr_results, xdr_location) - register SVCXPRT *xprt; - xdrproc_t xdr_results; - caddr_t xdr_location; -{ - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = SUCCESS; - rply.acpted_rply.ar_results.where = xdr_location; - rply.acpted_rply.ar_results.proc = xdr_results; - return (SVC_REPLY(xprt, &rply)); -} - -/* - * No procedure error reply - */ -void -svcerr_noproc(xprt) - register SVCXPRT *xprt; -{ - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = PROC_UNAVAIL; - SVC_REPLY(xprt, &rply); -} - -/* - * Can't decode args error reply - */ -void -svcerr_decode(xprt) - register SVCXPRT *xprt; -{ - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = GARBAGE_ARGS; - SVC_REPLY(xprt, &rply); -} - -/* - * Some system error - */ -void -svcerr_systemerr(xprt) - register SVCXPRT *xprt; -{ - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = SYSTEM_ERR; - SVC_REPLY(xprt, &rply); -} - -/* - * Authentication error reply - */ -void -svcerr_auth(xprt, why) - SVCXPRT *xprt; - enum auth_stat why; -{ - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_DENIED; - rply.rjcted_rply.rj_stat = AUTH_ERROR; - rply.rjcted_rply.rj_why = why; - SVC_REPLY(xprt, &rply); -} - -/* - * Auth too weak error reply - */ -void -svcerr_weakauth(xprt) - SVCXPRT *xprt; -{ - - svcerr_auth(xprt, AUTH_TOOWEAK); -} - -/* - * Program unavailable error reply - */ -void -svcerr_noprog(xprt) - register SVCXPRT *xprt; -{ - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = PROG_UNAVAIL; - SVC_REPLY(xprt, &rply); -} - -/* - * Program version mismatch error reply - */ -void -svcerr_progvers(xprt, low_vers, high_vers) - register SVCXPRT *xprt; - u_long low_vers; - u_long high_vers; -{ - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = PROG_MISMATCH; - rply.acpted_rply.ar_vers.low = low_vers; - rply.acpted_rply.ar_vers.high = high_vers; - SVC_REPLY(xprt, &rply); -} - -/* ******************* SERVER INPUT STUFF ******************* */ - -/* - * Get server side input from some transport. - * - * Statement of authentication parameters management: - * This function owns and manages all authentication parameters, specifically - * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and - * the "cooked" credentials (rqst->rq_clntcred). - * However, this function does not know the structure of the cooked - * credentials, so it make the following assumptions: - * a) the structure is contiguous (no pointers), and - * b) the cred structure size does not exceed RQCRED_SIZE bytes. - * In all events, all three parameters are freed upon exit from this routine. - * The storage is trivially management on the call stack in user land, but - * is mallocated in kernel land. - */ - -void -svc_getreq(rdfds) - int rdfds; -{ - fd_set readfds; - - FD_ZERO(&readfds); - readfds.fds_bits[0] = rdfds; - svc_getreqset(&readfds); -} - -void -svc_getreqset(readfds) - fd_set *readfds; -{ - svc_getreqset2(readfds, FD_SETSIZE); -} - -void -svc_getreqset2(readfds, width) - fd_set *readfds; - int width; -{ - enum xprt_stat stat; - struct rpc_msg msg; - int prog_found; - u_long low_vers; - u_long high_vers; - struct svc_req r; - register SVCXPRT *xprt; - register int bit; - register int sock; - register fd_mask mask, *maskp; - char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE]; - msg.rm_call.cb_cred.oa_base = cred_area; - msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); - r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); - - - maskp = readfds->fds_bits; - for (sock = 0; sock < width; sock += NFDBITS) { - for (mask = *maskp++; (bit = ffs(mask)); mask ^= (1 << (bit - 1))) { - /* sock has input waiting */ - xprt = xports[sock + bit - 1]; - if (xprt == NULL) - /* But do we control sock? */ - continue; - /* now receive msgs from xprtprt (support batch calls) */ - do { - if (SVC_RECV(xprt, &msg)) { - - /* now find the exported program and call it */ - register struct svc_callout *s; - enum auth_stat why; - - r.rq_xprt = xprt; - r.rq_prog = msg.rm_call.cb_prog; - r.rq_vers = msg.rm_call.cb_vers; - r.rq_proc = msg.rm_call.cb_proc; - r.rq_cred = msg.rm_call.cb_cred; - /* first authenticate the message */ - if ((why= _authenticate(&r, &msg)) != AUTH_OK) { - svcerr_auth(xprt, why); - goto call_done; - } - /* now match message with a registered service*/ - prog_found = FALSE; - low_vers = (u_long) - 1; - high_vers = 0; - for (s = svc_head; s != NULL_SVC; s = s->sc_next) { - if (s->sc_prog == r.rq_prog) { - if (s->sc_vers == r.rq_vers) { - (*s->sc_dispatch)(&r, xprt); - goto call_done; - } /* found correct version */ - prog_found = TRUE; - if (s->sc_vers < low_vers) - low_vers = s->sc_vers; - if (s->sc_vers > high_vers) - high_vers = s->sc_vers; - } /* found correct program */ - } - /* - * if we got here, the program or version - * is not served ... - */ - if (prog_found) - svcerr_progvers(xprt, - low_vers, high_vers); - else - svcerr_noprog(xprt); - /* Fall through to ... */ - } - call_done: - if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ - SVC_DESTROY(xprt); - break; - } - } while (stat == XPRT_MOREREQS); - } - } -} diff --git a/c/src/librpc/src/rpc/svc_auth.c b/c/src/librpc/src/rpc/svc_auth.c deleted file mode 100644 index b58596a397..0000000000 --- a/c/src/librpc/src/rpc/svc_auth.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986-1991 by Sun Microsystems Inc. - */ - -/* #ident "@(#)svc_auth.c 1.16 94/04/24 SMI" */ - -#if !defined(lint) && defined(SCCSIDS) -#if 0 -static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro"; -#else -static const char rcsid[] = - "$FreeBSD: src/lib/libc/rpc/svc_auth.c,v 1.7 1999/12/29 05:04:16 peter Exp $"; -#endif -#endif - -/* - * svc_auth.c, Server-side rpc authenticator interface. - * - */ - -#ifdef _KERNEL -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#endif -#include - -/* - * svcauthsw is the bdevsw of server side authentication. - * - * Server side authenticators are called from authenticate by - * using the client auth struct flavor field to index into svcauthsw. - * The server auth flavors must implement a routine that looks - * like: - * - * enum auth_stat - * flavorx_auth(rqst, msg) - * register struct svc_req *rqst; - * register struct rpc_msg *msg; - * - */ - -enum auth_stat _svcauth_null(); /* no authentication */ -enum auth_stat _svcauth_unix(); /* (system) unix style (uid, gids) */ -enum auth_stat _svcauth_short(); /* short hand unix style */ -enum auth_stat _svcauth_des(); /* des style */ - -/* declarations to allow servers to specify new authentication flavors */ -struct authsvc { - int flavor; - enum auth_stat (*handler)(); - struct authsvc *next; -}; -#define Auths ((struct authsvc *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_auths_Auths) - -/* - * The call rpc message, msg has been obtained from the wire. The msg contains - * the raw form of credentials and verifiers. authenticate returns AUTH_OK - * if the msg is successfully authenticated. If AUTH_OK then the routine also - * does the following things: - * set rqst->rq_xprt->verf to the appropriate response verifier; - * sets rqst->rq_client_cred to the "cooked" form of the credentials. - * - * NB: rqst->rq_cxprt->verf must be pre-alloctaed; - * its length is set appropriately. - * - * The caller still owns and is responsible for msg->u.cmb.cred and - * msg->u.cmb.verf. The authentication system retains ownership of - * rqst->rq_client_cred, the cooked credentials. - * - * There is an assumption that any flavour less than AUTH_NULL is - * invalid. - */ -enum auth_stat -_authenticate(rqst, msg) - register struct svc_req *rqst; - struct rpc_msg *msg; -{ - register int cred_flavor; - register struct authsvc *asp; - - rqst->rq_cred = msg->rm_call.cb_cred; - rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; - rqst->rq_xprt->xp_verf.oa_length = 0; - cred_flavor = rqst->rq_cred.oa_flavor; - switch (cred_flavor) { - case AUTH_NULL: - return(_svcauth_null(rqst, msg)); - case AUTH_UNIX: - return(_svcauth_unix(rqst, msg)); - case AUTH_SHORT: - return(_svcauth_short(rqst, msg)); - /* - * We leave AUTH_DES turned off by default because svcauth_des() - * needs getpublickey(), which is in librpcsvc, not libc. If we - * included AUTH_DES as a built-in flavor, programs that don't - * have -lrpcsvc in their Makefiles wouldn't link correctly, even - * though they don't use AUTH_DES. And I'm too lazy to go through - * the tree looking for all of them. - */ -#ifdef DES_BUILTIN - case AUTH_DES: - return(_svcauth_des(rqst, msg)); -#endif - } - - /* flavor doesn't match any of the builtin types, so try new ones */ - for (asp = Auths; asp; asp = asp->next) { - if (asp->flavor == cred_flavor) { - enum auth_stat as; - - as = (*asp->handler)(rqst, msg); - return (as); - } - } - - return (AUTH_REJECTEDCRED); -} - -/*ARGSUSED*/ -enum auth_stat -_svcauth_null(rqst, msg) - struct svc_req *rqst; - struct rpc_msg *msg; -{ - return (AUTH_OK); -} - -/* - * Allow the rpc service to register new authentication types that it is - * prepared to handle. When an authentication flavor is registered, - * the flavor is checked against already registered values. If not - * registered, then a new Auths entry is added on the list. - * - * There is no provision to delete a registration once registered. - * - * This routine returns: - * 0 if registration successful - * 1 if flavor already registered - * -1 if can't register (errno set) - */ - -int -svc_auth_reg(cred_flavor, handler) - register int cred_flavor; - enum auth_stat (*handler)(); -{ - register struct authsvc *asp; - - switch (cred_flavor) { - case AUTH_NULL: - case AUTH_UNIX: - case AUTH_SHORT: -#ifdef DES_BUILTIN - case AUTH_DES: -#endif - /* already registered */ - return (1); - - default: - for (asp = Auths; asp; asp = asp->next) { - if (asp->flavor == cred_flavor) { - /* already registered */ - return (1); - } - } - - /* this is a new one, so go ahead and register it */ - asp = (struct authsvc *)mem_alloc(sizeof (*asp)); - if (asp == NULL) { - return (-1); - } - asp->flavor = cred_flavor; - asp->handler = handler; - asp->next = Auths; - Auths = asp; - break; - } - return (0); -} diff --git a/c/src/librpc/src/rpc/svc_auth_des.c b/c/src/librpc/src/rpc/svc_auth_des.c deleted file mode 100644 index a107168e30..0000000000 --- a/c/src/librpc/src/rpc/svc_auth_des.c +++ /dev/null @@ -1,531 +0,0 @@ - -/* - * Copyright (c) 1988 by Sun Microsystems, Inc. - */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * svcauth_des.c, server-side des authentication - * - * We insure for the service the following: - * (1) The timestamp microseconds do not exceed 1 million. - * (2) The timestamp plus the window is less than the current time. - * (3) The timestamp is not less than the one previously - * seen in the current session. - * - * It is up to the server to determine if the window size is - * too small . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(LIBC_SCCS) && !defined(lint) -/* from: static char sccsid[] = "@(#)svcauth_des.c 2.3 89/07/11 4.0 RPCSRC; from 1.15 88/02/08 SMI"; */ -static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/svc_auth_des.c,v 1.3 1999/08/28 00:00:48 peter Exp $"; -#endif - -#define debug(msg) printf("svcauth_des: %s\n", msg) - -#define USEC_PER_SEC ((u_long) 1000000L) -#define BEFORE(t1, t2) timercmp(t1, t2, <) - -/* - * LRU cache of conversation keys and some other useful items. - */ -#define AUTHDES_CACHESZ 64 -struct cache_entry { - des_block key; /* conversation key */ - char *rname; /* client's name */ - u_int window; /* credential lifetime window */ - struct timeval laststamp; /* detect replays of creds */ - char *localcred; /* generic local credential */ -}; -static struct cache_entry *authdes_cache/* [AUTHDES_CACHESZ] */; -static short *authdes_lru/* [AUTHDES_CACHESZ] */; - -static void cache_init(); /* initialize the cache */ -static short cache_spot(); /* find an entry in the cache */ -static void cache_ref(/*short sid*/); /* note that sid was ref'd */ - -static void invalidate(); /* invalidate entry in cache */ - -/* - * cache statistics - */ -static struct { - u_long ncachehits; /* times cache hit, and is not replay */ - u_long ncachereplays; /* times cache hit, and is replay */ - u_long ncachemisses; /* times cache missed */ -} svcauthdes_stats; - -/* - * Service side authenticator for AUTH_DES - */ -enum auth_stat -_svcauth_des(rqst, msg) - register struct svc_req *rqst; - register struct rpc_msg *msg; -{ - - register long *ixdr; - des_block cryptbuf[2]; - register struct authdes_cred *cred; - struct authdes_verf verf; - int status; - register struct cache_entry *entry; - short sid = 0; - des_block *sessionkey; - des_block ivec; - u_int window; - struct timeval timestamp; - u_long namelen; - struct area { - struct authdes_cred area_cred; - char area_netname[MAXNETNAMELEN+1]; - } *area; - - if (authdes_cache == NULL) { - cache_init(); - } - - area = (struct area *)rqst->rq_clntcred; - cred = (struct authdes_cred *)&area->area_cred; - - /* - * Get the credential - */ - ixdr = (long *)msg->rm_call.cb_cred.oa_base; - cred->adc_namekind = IXDR_GET_ENUM(ixdr, enum authdes_namekind); - switch (cred->adc_namekind) { - case ADN_FULLNAME: - namelen = IXDR_GET_U_LONG(ixdr); - if (namelen > MAXNETNAMELEN) { - return (AUTH_BADCRED); - } - cred->adc_fullname.name = area->area_netname; - bcopy((char *)ixdr, cred->adc_fullname.name, - (u_int)namelen); - cred->adc_fullname.name[namelen] = 0; - ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT); - cred->adc_fullname.key.key.high = (u_long)*ixdr++; - cred->adc_fullname.key.key.low = (u_long)*ixdr++; - cred->adc_fullname.window = (u_long)*ixdr++; - break; - case ADN_NICKNAME: - cred->adc_nickname = (u_long)*ixdr++; - break; - default: - return (AUTH_BADCRED); - } - - /* - * Get the verifier - */ - ixdr = (long *)msg->rm_call.cb_verf.oa_base; - verf.adv_xtimestamp.key.high = (u_long)*ixdr++; - verf.adv_xtimestamp.key.low = (u_long)*ixdr++; - verf.adv_int_u = (u_long)*ixdr++; - - - /* - * Get the conversation key - */ - if (cred->adc_namekind == ADN_FULLNAME) { - netobj pkey; - char pkey_data[1024]; - - sessionkey = &cred->adc_fullname.key; - if (! getpublickey(cred->adc_fullname.name, pkey_data)) { - debug("getpublickey"); - return(AUTH_BADCRED); - } - pkey.n_bytes = pkey_data; - pkey.n_len = strlen(pkey_data) + 1; - if (key_decryptsession_pk(cred->adc_fullname.name, &pkey, - sessionkey) < 0) { - debug("decryptsessionkey"); - return (AUTH_BADCRED); /* key not found */ - } - } else { /* ADN_NICKNAME */ - sid = (short)cred->adc_nickname; - if (sid >= AUTHDES_CACHESZ) { - debug("bad nickname"); - return (AUTH_BADCRED); /* garbled credential */ - } - sessionkey = &authdes_cache[sid].key; - } - - - /* - * Decrypt the timestamp - */ - cryptbuf[0] = verf.adv_xtimestamp; - if (cred->adc_namekind == ADN_FULLNAME) { - cryptbuf[1].key.high = cred->adc_fullname.window; - cryptbuf[1].key.low = verf.adv_winverf; - ivec.key.high = ivec.key.low = 0; - status = cbc_crypt((char *)sessionkey, (char *)cryptbuf, - 2*sizeof(des_block), DES_DECRYPT | DES_HW, - (char *)&ivec); - } else { - status = ecb_crypt((char *)sessionkey, (char *)cryptbuf, - sizeof(des_block), DES_DECRYPT | DES_HW); - } - if (DES_FAILED(status)) { - debug("decryption failure"); - return (AUTH_FAILED); /* system error */ - } - - /* - * XDR the decrypted timestamp - */ - ixdr = (long *)cryptbuf; - timestamp.tv_sec = IXDR_GET_LONG(ixdr); - timestamp.tv_usec = IXDR_GET_LONG(ixdr); - - /* - * Check for valid credentials and verifiers. - * They could be invalid because the key was flushed - * out of the cache, and so a new session should begin. - * Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case. - */ - { - struct timeval current; - int nick; - int winverf; - - if (cred->adc_namekind == ADN_FULLNAME) { - window = IXDR_GET_U_LONG(ixdr); - winverf = IXDR_GET_U_LONG(ixdr); - if (winverf != window - 1) { - debug("window verifier mismatch"); - return (AUTH_BADCRED); /* garbled credential */ - } - sid = cache_spot(sessionkey, cred->adc_fullname.name, - ×tamp); - if (sid < 0) { - debug("replayed credential"); - return (AUTH_REJECTEDCRED); /* replay */ - } - nick = 0; - } else { /* ADN_NICKNAME */ - window = authdes_cache[sid].window; - nick = 1; - } - - if ((u_long)timestamp.tv_usec >= USEC_PER_SEC) { - debug("invalid usecs"); - /* cached out (bad key), or garbled verifier */ - return (nick ? AUTH_REJECTEDVERF : AUTH_BADVERF); - } - if (nick && BEFORE(×tamp, - &authdes_cache[sid].laststamp)) { - debug("timestamp before last seen"); - return (AUTH_REJECTEDVERF); /* replay */ - } - (void) gettimeofday(¤t, (struct timezone *)NULL); - current.tv_sec -= window; /* allow for expiration */ - if (!BEFORE(¤t, ×tamp)) { - debug("timestamp expired"); - /* replay, or garbled credential */ - return (nick ? AUTH_REJECTEDVERF : AUTH_BADCRED); - } - } - - /* - * Set up the reply verifier - */ - verf.adv_nickname = (u_long)sid; - - /* - * xdr the timestamp before encrypting - */ - ixdr = (long *)cryptbuf; - IXDR_PUT_LONG(ixdr, timestamp.tv_sec - 1); - IXDR_PUT_LONG(ixdr, timestamp.tv_usec); - - /* - * encrypt the timestamp - */ - status = ecb_crypt((char *)sessionkey, (char *)cryptbuf, - sizeof(des_block), DES_ENCRYPT | DES_HW); - if (DES_FAILED(status)) { - debug("encryption failure"); - return (AUTH_FAILED); /* system error */ - } - verf.adv_xtimestamp = cryptbuf[0]; - - /* - * Serialize the reply verifier, and update rqst - */ - ixdr = (long *)msg->rm_call.cb_verf.oa_base; - *ixdr++ = (long)verf.adv_xtimestamp.key.high; - *ixdr++ = (long)verf.adv_xtimestamp.key.low; - *ixdr++ = (long)verf.adv_int_u; - - rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES; - rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base; - rqst->rq_xprt->xp_verf.oa_length = - (char *)ixdr - msg->rm_call.cb_verf.oa_base; - - /* - * We succeeded, commit the data to the cache now and - * finish cooking the credential. - */ - entry = &authdes_cache[sid]; - entry->laststamp = timestamp; - cache_ref(sid); - if (cred->adc_namekind == ADN_FULLNAME) { - cred->adc_fullname.window = window; - cred->adc_nickname = (u_long)sid; /* save nickname */ - if (entry->rname != NULL) { - mem_free(entry->rname, strlen(entry->rname) + 1); - } - entry->rname = (char *)mem_alloc((u_int)strlen(cred->adc_fullname.name) - + 1); - if (entry->rname != NULL) { - (void) strcpy(entry->rname, cred->adc_fullname.name); - } else { - debug("out of memory"); - } - entry->key = *sessionkey; - entry->window = window; - invalidate(entry->localcred); /* mark any cached cred invalid */ - } else { /* ADN_NICKNAME */ - /* - * nicknames are cooked into fullnames - */ - cred->adc_namekind = ADN_FULLNAME; - cred->adc_fullname.name = entry->rname; - cred->adc_fullname.key = entry->key; - cred->adc_fullname.window = entry->window; - } - return (AUTH_OK); /* we made it!*/ -} - - -/* - * Initialize the cache - */ -static void -cache_init() -{ - register int i; - - authdes_cache = (struct cache_entry *) - mem_alloc(sizeof(struct cache_entry) * AUTHDES_CACHESZ); - bzero((char *)authdes_cache, - sizeof(struct cache_entry) * AUTHDES_CACHESZ); - - authdes_lru = (short *)mem_alloc(sizeof(short) * AUTHDES_CACHESZ); - /* - * Initialize the lru list - */ - for (i = 0; i < AUTHDES_CACHESZ; i++) { - authdes_lru[i] = i; - } -} - - -/* - * Find the lru victim - */ -static short -cache_victim() -{ - return (authdes_lru[AUTHDES_CACHESZ-1]); -} - -/* - * Note that sid was referenced - */ -static void -cache_ref(sid) - register short sid; -{ - register int i; - register short curr; - register short prev; - - prev = authdes_lru[0]; - authdes_lru[0] = sid; - for (i = 1; prev != sid; i++) { - curr = authdes_lru[i]; - authdes_lru[i] = prev; - prev = curr; - } -} - - -/* - * Find a spot in the cache for a credential containing - * the items given. Return -1 if a replay is detected, otherwise - * return the spot in the cache. - */ -static short -cache_spot(key, name, timestamp) - register des_block *key; - char *name; - struct timeval *timestamp; -{ - register struct cache_entry *cp; - register int i; - register u_long hi; - - hi = key->key.high; - for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; i++, cp++) { - if (cp->key.key.high == hi && - cp->key.key.low == key->key.low && - cp->rname != NULL && - bcmp(cp->rname, name, strlen(name) + 1) == 0) { - if (BEFORE(timestamp, &cp->laststamp)) { - svcauthdes_stats.ncachereplays++; - return (-1); /* replay */ - } - svcauthdes_stats.ncachehits++; - return (i); /* refresh */ - } - } - svcauthdes_stats.ncachemisses++; - return (cache_victim()); /* new credential */ -} - - -#if (defined(sun) || defined(vax) || defined(__FreeBSD__)) -/* - * Local credential handling stuff. - * NOTE: bsd unix dependent. - * Other operating systems should put something else here. - */ -#define UNKNOWN -2 /* grouplen, if cached cred is unknown user */ -#define INVALID -1 /* grouplen, if cache entry is invalid */ - -struct bsdcred { - short uid; /* cached uid */ - short gid; /* cached gid */ - short grouplen; /* length of cached groups */ - short groups[NGROUPS]; /* cached groups */ -}; - -/* - * Map a des credential into a unix cred. - * We cache the credential here so the application does - * not have to make an rpc call every time to interpret - * the credential. - */ -int -authdes_getucred(adc, uid, gid, grouplen, groups) - struct authdes_cred *adc; - uid_t *uid; - gid_t *gid; - int *grouplen; - register gid_t *groups; -{ - unsigned sid; - register int i; - uid_t i_uid; - gid_t i_gid; - int i_grouplen; - struct bsdcred *cred; - - sid = adc->adc_nickname; - if (sid >= AUTHDES_CACHESZ) { - debug("invalid nickname"); - return (0); - } - cred = (struct bsdcred *)authdes_cache[sid].localcred; - if (cred == NULL) { - cred = (struct bsdcred *)mem_alloc(sizeof(struct bsdcred)); - authdes_cache[sid].localcred = (char *)cred; - cred->grouplen = INVALID; - } - if (cred->grouplen == INVALID) { - /* - * not in cache: lookup - */ - if (!netname2user(adc->adc_fullname.name, &i_uid, &i_gid, - &i_grouplen, groups)) - { - debug("unknown netname"); - cred->grouplen = UNKNOWN; /* mark as lookup up, but not found */ - return (0); - } - debug("missed ucred cache"); - *uid = cred->uid = i_uid; - *gid = cred->gid = i_gid; - *grouplen = cred->grouplen = i_grouplen; - for (i = i_grouplen - 1; i >= 0; i--) { - cred->groups[i] = groups[i]; /* int to short */ - } - return (1); - } else if (cred->grouplen == UNKNOWN) { - /* - * Already lookup up, but no match found - */ - return (0); - } - - /* - * cached credentials - */ - *uid = cred->uid; - *gid = cred->gid; - *grouplen = cred->grouplen; - for (i = cred->grouplen - 1; i >= 0; i--) { - groups[i] = cred->groups[i]; /* short to int */ - } - return (1); -} - -static void -invalidate(cred) - char *cred; -{ - if (cred == NULL) { - return; - } - ((struct bsdcred *)cred)->grouplen = INVALID; -} -#endif - diff --git a/c/src/librpc/src/rpc/svc_auth_unix.c b/c/src/librpc/src/rpc/svc_auth_unix.c deleted file mode 100644 index 8b4e257a2c..0000000000 --- a/c/src/librpc/src/rpc/svc_auth_unix.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_auth_unix.c,v 1.8 1999/08/28 00:00:49 peter Exp $"; -#endif - -/* - * svc_auth_unix.c - * Handles UNIX flavor authentication parameters on the service side of rpc. - * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT. - * _svcauth_unix does full blown unix style uid,gid+gids auth, - * _svcauth_short uses a shorthand auth to index into a cache of longhand auths. - * Note: the shorthand has been gutted for efficiency. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include - -/* - * Unix longhand authenticator - */ -enum auth_stat -_svcauth_unix(rqst, msg) - register struct svc_req *rqst; - register struct rpc_msg *msg; -{ - register enum auth_stat stat; - XDR xdrs; - register struct authunix_parms *aup; - register int32_t *buf; - struct area { - struct authunix_parms area_aup; - char area_machname[MAX_MACHINE_NAME+1]; - int area_gids[NGRPS]; - } *area; - u_int auth_len; - int str_len, gid_len; - register int i; - - area = (struct area *) rqst->rq_clntcred; - aup = &area->area_aup; - aup->aup_machname = area->area_machname; - aup->aup_gids = area->area_gids; - auth_len = (u_int)msg->rm_call.cb_cred.oa_length; - xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE); - buf = XDR_INLINE(&xdrs, auth_len); - if (buf != NULL) { - aup->aup_time = IXDR_GET_LONG(buf); - str_len = IXDR_GET_U_LONG(buf); - if (str_len > MAX_MACHINE_NAME) { - stat = AUTH_BADCRED; - goto done; - } - memcpy(aup->aup_machname, (caddr_t)buf, (u_int)str_len); - aup->aup_machname[str_len] = 0; - str_len = RNDUP(str_len); - buf += str_len / sizeof (int32_t); - aup->aup_uid = IXDR_GET_LONG(buf); - aup->aup_gid = IXDR_GET_LONG(buf); - gid_len = IXDR_GET_U_LONG(buf); - if (gid_len > NGRPS) { - stat = AUTH_BADCRED; - goto done; - } - aup->aup_len = gid_len; - for (i = 0; i < gid_len; i++) { - aup->aup_gids[i] = IXDR_GET_LONG(buf); - } - /* - * five is the smallest unix credentials structure - - * timestamp, hostname len (0), uid, gid, and gids len (0). - */ - if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) { - (void) printf("bad auth_len gid %d str %d auth %d\n", - gid_len, str_len, auth_len); - stat = AUTH_BADCRED; - goto done; - } - } else if (! xdr_authunix_parms(&xdrs, aup)) { - xdrs.x_op = XDR_FREE; - (void)xdr_authunix_parms(&xdrs, aup); - stat = AUTH_BADCRED; - goto done; - } - - /* get the verifier */ - if ((u_int)msg->rm_call.cb_verf.oa_length) { - rqst->rq_xprt->xp_verf.oa_flavor = - msg->rm_call.cb_verf.oa_flavor; - rqst->rq_xprt->xp_verf.oa_base = - msg->rm_call.cb_verf.oa_base; - rqst->rq_xprt->xp_verf.oa_length = - msg->rm_call.cb_verf.oa_length; - } else { - rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL; - rqst->rq_xprt->xp_verf.oa_length = 0; - } - stat = AUTH_OK; -done: - XDR_DESTROY(&xdrs); - return (stat); -} - - -/* - * Shorthand unix authenticator - * Looks up longhand in a cache. - */ -/*ARGSUSED*/ -enum auth_stat -_svcauth_short(rqst, msg) - struct svc_req *rqst; - struct rpc_msg *msg; -{ - return (AUTH_REJECTEDCRED); -} diff --git a/c/src/librpc/src/rpc/svc_raw.c b/c/src/librpc/src/rpc/svc_raw.c deleted file mode 100644 index 686c61bdd4..0000000000 --- a/c/src/librpc/src/rpc/svc_raw.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_raw.c,v 1.7 1999/08/28 00:00:49 peter Exp $"; -#endif - -/* - * svc_raw.c, This a toy for simple testing and timing. - * Interface to create an rpc client and server in the same UNIX process. - * This lets us similate rpc and get rpc (round trip) overhead, without - * any interference from the kernal. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include - -/* - * This is the "network" that we will be moving data over - */ -struct svc_raw_private { - char _raw_buf[UDPMSGSIZE]; - SVCXPRT server; - XDR xdr_stream; - char verf_body[MAX_AUTH_BYTES]; -}; -#define svcraw_private ((struct svc_raw_private *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_raw_private) - -static bool_t svcraw_recv(); -static enum xprt_stat svcraw_stat(); -static bool_t svcraw_getargs(); -static bool_t svcraw_reply(); -static bool_t svcraw_freeargs(); -static void svcraw_destroy(); - -static struct xp_ops server_ops = { - svcraw_recv, - svcraw_stat, - svcraw_getargs, - svcraw_reply, - svcraw_freeargs, - svcraw_destroy -}; - -SVCXPRT * -svcraw_create() -{ - register struct svc_raw_private *srp = svcraw_private; - - if (srp == 0) { - srp = (struct svc_raw_private *)calloc(1, sizeof (*srp)); - if (srp == 0) - return (0); - } - srp->server.xp_sock = 0; - srp->server.xp_port = 0; - srp->server.xp_ops = &server_ops; - srp->server.xp_verf.oa_base = srp->verf_body; - xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE); - return (&srp->server); -} - -static enum xprt_stat -svcraw_stat() -{ - - return (XPRT_IDLE); -} - -static bool_t -svcraw_recv(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - register struct svc_raw_private *srp = svcraw_private; - register XDR *xdrs; - - if (srp == 0) - return (0); - xdrs = &srp->xdr_stream; - xdrs->x_op = XDR_DECODE; - XDR_SETPOS(xdrs, 0); - if (! xdr_callmsg(xdrs, msg)) - return (FALSE); - return (TRUE); -} - -static bool_t -svcraw_reply(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - register struct svc_raw_private *srp = svcraw_private; - register XDR *xdrs; - - if (srp == 0) - return (FALSE); - xdrs = &srp->xdr_stream; - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, 0); - if (! xdr_replymsg(xdrs, msg)) - return (FALSE); - (void)XDR_GETPOS(xdrs); /* called just for overhead */ - return (TRUE); -} - -static bool_t -svcraw_getargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - register struct svc_raw_private *srp = svcraw_private; - - if (srp == 0) - return (FALSE); - return ((*xdr_args)(&srp->xdr_stream, args_ptr)); -} - -static bool_t -svcraw_freeargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - register struct svc_raw_private *srp = svcraw_private; - register XDR *xdrs; - - if (srp == 0) - return (FALSE); - xdrs = &srp->xdr_stream; - xdrs->x_op = XDR_FREE; - return ((*xdr_args)(xdrs, args_ptr)); -} - -static void -svcraw_destroy() -{ -} diff --git a/c/src/librpc/src/rpc/svc_run.c b/c/src/librpc/src/rpc/svc_run.c deleted file mode 100644 index 5e8a9e683a..0000000000 --- a/c/src/librpc/src/rpc/svc_run.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_run.c,v 1.10 1999/08/28 00:00:49 peter Exp $"; -#endif - -/* - * This is the rpc server side idle loop - * Wait for input, call server program. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -void -svc_run() -{ - fd_set *fds; - - for (;;) { - if (__svc_fdset) { - int bytes = sizeof (fd_set); - fds = (fd_set *)malloc(bytes); - memcpy(fds, __svc_fdset, bytes); - } else - fds = NULL; - switch (select(svc_maxfd + 1, fds, NULL, NULL, - (struct timeval *)0)) { - case -1: - if (errno == EINTR) { - if (fds) - free(fds); - continue; - } - perror("svc_run: - select failed"); - if (fds) - free(fds); - return; - case 0: - if (fds) - free(fds); - continue; - default: - /* if fds == NULL, select() can't return a result */ - svc_getreqset2(fds, svc_maxfd + 1); - free(fds); - } - } -} diff --git a/c/src/librpc/src/rpc/svc_simple.c b/c/src/librpc/src/rpc/svc_simple.c deleted file mode 100644 index ebc700257a..0000000000 --- a/c/src/librpc/src/rpc/svc_simple.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_simple.c,v 1.9 1999/08/28 00:00:50 peter Exp $"; -#endif - -/* - * svc_simple.c - * Simplified front end to rpc. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include - -struct prog_lst { - char *(*p_progname)(); - int p_prognum; - int p_procnum; - xdrproc_t p_inproc, p_outproc; - struct prog_lst *p_nxt; -}; -static void universal(); -#define proglst ((struct prog_lst *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_simple_proglst) -#define pl ((struct prog_lst *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_simple_pl) -#define transp ((SVCXPRT *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_simple_transp) - -int -registerrpc(prognum, versnum, procnum, progname, inproc, outproc) - int prognum, versnum, procnum; - char *(*progname)(); - xdrproc_t inproc, outproc; -{ - - if (procnum == NULLPROC) { - (void) fprintf(stderr, - "can't reassign procedure number %ld\n", NULLPROC); - return (-1); - } - if (transp == 0) { - transp = svcudp_create(RPC_ANYSOCK); - if (transp == NULL) { - (void) fprintf(stderr, "couldn't create an rpc server\n"); - return (-1); - } - } - (void) pmap_unset((u_long)prognum, (u_long)versnum); - if (!svc_register(transp, (u_long)prognum, (u_long)versnum, - universal, IPPROTO_UDP)) { - (void) fprintf(stderr, "couldn't register prog %d vers %d\n", - prognum, versnum); - return (-1); - } - pl = (struct prog_lst *)malloc(sizeof(struct prog_lst)); - if (pl == NULL) { - (void) fprintf(stderr, "registerrpc: out of memory\n"); - return (-1); - } - pl->p_progname = progname; - pl->p_prognum = prognum; - pl->p_procnum = procnum; - pl->p_inproc = inproc; - pl->p_outproc = outproc; - pl->p_nxt = proglst; - proglst = pl; - return (0); -} - -static void -universal(rqstp, atransp) - struct svc_req *rqstp; - SVCXPRT *atransp; -{ - int prog, proc; - char *outdata; - char xdrbuf[UDPMSGSIZE]; - struct prog_lst *lpl; - - /* - * enforce "procnum 0 is echo" convention - */ - if (rqstp->rq_proc == NULLPROC) { - if (svc_sendreply(atransp, xdr_void, NULL) == FALSE) { - (void) fprintf(stderr, "xxx\n"); - exit(1); - } - return; - } - prog = rqstp->rq_prog; - proc = rqstp->rq_proc; - for (lpl = proglst; lpl != NULL; lpl = lpl->p_nxt) - if (lpl->p_prognum == prog && lpl->p_procnum == proc) { - /* decode arguments into a CLEAN buffer */ - memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */ - if (!svc_getargs(atransp, lpl->p_inproc, xdrbuf)) { - svcerr_decode(atransp); - return; - } - outdata = (*(lpl->p_progname))(xdrbuf); - if (outdata == NULL && lpl->p_outproc != xdr_void) - /* there was an error */ - return; - if (!svc_sendreply(atransp, lpl->p_outproc, outdata)) { - (void) fprintf(stderr, - "trouble replying to prog %d\n", - lpl->p_prognum); - exit(1); - } - /* free the decoded arguments */ - (void)svc_freeargs(atransp, lpl->p_inproc, xdrbuf); - return; - } - (void) fprintf(stderr, "never registered prog %d\n", prog); - exit(1); -} - diff --git a/c/src/librpc/src/rpc/svc_tcp.c b/c/src/librpc/src/rpc/svc_tcp.c deleted file mode 100644 index 0c2133a049..0000000000 --- a/c/src/librpc/src/rpc/svc_tcp.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_tcp.c,v 1.18 2000/01/27 23:06:41 jasone Exp $"; -#endif - -/* - * svc_tcp.c, Server side for TCP/IP based RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * Actually implements two flavors of transporter - - * a tcp rendezvouser (a listner and connection establisher) - * and a record/tcp stream. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Ops vector for TCP/IP based rpc service handle - */ -static bool_t svctcp_recv(); -static enum xprt_stat svctcp_stat(); -static bool_t svctcp_getargs(); -static bool_t svctcp_reply(); -static bool_t svctcp_freeargs(); -static void svctcp_destroy(); - -static struct xp_ops svctcp_op = { - svctcp_recv, - svctcp_stat, - svctcp_getargs, - svctcp_reply, - svctcp_freeargs, - svctcp_destroy -}; - -/* - * Ops vector for TCP/IP rendezvous handler - */ -static bool_t rendezvous_request(); -static enum xprt_stat rendezvous_stat(); - -static struct xp_ops svctcp_rendezvous_op = { - rendezvous_request, - rendezvous_stat, - (bool_t (*)())abort, - (bool_t (*)())abort, - (bool_t (*)())abort, - svctcp_destroy -}; - -static int readtcp(), writetcp(); -static SVCXPRT *makefd_xprt(); - -struct tcp_rendezvous { /* kept in xprt->xp_p1 */ - u_int sendsize; - u_int recvsize; -}; - -struct tcp_conn { /* kept in xprt->xp_p1 */ - enum xprt_stat strm_stat; - u_long x_id; - XDR xdrs; - char verf_body[MAX_AUTH_BYTES]; -}; - -/* - * Usage: - * xprt = svctcp_create(sock, send_buf_size, recv_buf_size); - * - * Creates, registers, and returns a (rpc) tcp based transporter. - * Once *xprt is initialized, it is registered as a transporter - * see (svc.h, xprt_register). This routine returns - * a NULL if a problem occurred. - * - * If sock<0 then a socket is created, else sock is used. - * If the socket, sock is not bound to a port then svctcp_create - * binds it to an arbitrary port. The routine then starts a tcp - * listener on the socket's associated port. In any (successful) case, - * xprt->xp_sock is the registered socket number and xprt->xp_port is the - * associated port number. - * - * Since tcp streams do buffered io similar to stdio, the caller can specify - * how big the send and receive buffers are via the second and third parms; - * 0 => use the system default. - */ -SVCXPRT * -svctcp_create(sock, sendsize, recvsize) - register int sock; - u_int sendsize; - u_int recvsize; -{ - bool_t madesock = FALSE; - register SVCXPRT *xprt; - register struct tcp_rendezvous *r; - struct sockaddr_in addr; - int len = sizeof(struct sockaddr_in); - int on; - - if (sock == RPC_ANYSOCK) { - if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - perror("svctcp_.c - udp socket creation problem"); - return ((SVCXPRT *)NULL); - } - madesock = TRUE; - } - on = 1; - if (ioctl(sock, FIONBIO, &on) < 0) { - perror("svc_tcp.c - cannot turn on non-blocking mode"); - if (madesock) - (void)_RPC_close(sock); - return ((SVCXPRT *)NULL); - } - memset(&addr, 0, sizeof (addr)); - addr.sin_len = sizeof(struct sockaddr_in); - addr.sin_family = AF_INET; - if (bindresvport(sock, &addr)) { - addr.sin_port = 0; - (void)bind(sock, (struct sockaddr *)&addr, len); - } - if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) || - (listen(sock, 2) != 0)) { - perror("svctcp_.c - cannot getsockname or listen"); - if (madesock) - (void)_RPC_close(sock); - return ((SVCXPRT *)NULL); - } - r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r)); - if (r == NULL) { - (void) fprintf(stderr, "svctcp_create: out of memory\n"); - return (NULL); - } - r->sendsize = sendsize; - r->recvsize = recvsize; - xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); - if (xprt == NULL) { - (void) fprintf(stderr, "svctcp_create: out of memory\n"); - return (NULL); - } - xprt->xp_p2 = NULL; - xprt->xp_p1 = (caddr_t)r; - xprt->xp_verf = _null_auth; - xprt->xp_ops = &svctcp_rendezvous_op; - xprt->xp_port = ntohs(addr.sin_port); - xprt->xp_sock = sock; - xprt_register(xprt); - return (xprt); -} - -/* - * Like svtcp_create(), except the routine takes any *open* UNIX file - * descriptor as its first input. - */ -SVCXPRT * -svcfd_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - - return (makefd_xprt(fd, sendsize, recvsize)); -} - -static SVCXPRT * -makefd_xprt(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - register SVCXPRT *xprt; - register struct tcp_conn *cd; - - xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); - if (xprt == (SVCXPRT *)NULL) { - (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); - goto done; - } - cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn)); - if (cd == (struct tcp_conn *)NULL) { - (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); - mem_free((char *) xprt, sizeof(SVCXPRT)); - xprt = (SVCXPRT *)NULL; - goto done; - } - cd->strm_stat = XPRT_IDLE; - xdrrec_create(&(cd->xdrs), sendsize, recvsize, - (caddr_t)xprt, readtcp, writetcp); - xprt->xp_p2 = NULL; - xprt->xp_p1 = (caddr_t)cd; - xprt->xp_verf.oa_base = cd->verf_body; - xprt->xp_addrlen = 0; - xprt->xp_ops = &svctcp_op; /* truely deals with calls */ - xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ - xprt->xp_sock = fd; - xprt_register(xprt); - done: - return (xprt); -} - -static bool_t -rendezvous_request(xprt) - register SVCXPRT *xprt; -{ - int sock; - struct tcp_rendezvous *r; - struct sockaddr_in addr; - int len; - int off; - - r = (struct tcp_rendezvous *)xprt->xp_p1; - again: - len = sizeof(struct sockaddr_in); - if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, - &len)) < 0) { - if (errno == EINTR) - goto again; - return (FALSE); - } - /* - * Guard against FTP bounce attacks. - */ - if (addr.sin_port == htons(20)) { - _RPC_close(sock); - return (FALSE); - } - /* - * The listening socket is in FIONBIO mode and we inherit it. - */ - off = 0; - if (ioctl(sock, FIONBIO, &off) < 0) { - _RPC_close(sock); - return (FALSE); - } - /* - * make a new transporter (re-uses xprt) - */ - xprt = makefd_xprt(sock, r->sendsize, r->recvsize); - xprt->xp_raddr = addr; - xprt->xp_addrlen = len; - return (FALSE); /* there is never an rpc msg to be processed */ -} - -static enum xprt_stat -rendezvous_stat() -{ - - return (XPRT_IDLE); -} - -static void -svctcp_destroy(xprt) - register SVCXPRT *xprt; -{ - register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1; - - xprt_unregister(xprt); - (void)_RPC_close(xprt->xp_sock); - if (xprt->xp_port != 0) { - /* a rendezvouser socket */ - xprt->xp_port = 0; - } else { - /* an actual connection socket */ - XDR_DESTROY(&(cd->xdrs)); - } - mem_free((caddr_t)cd, sizeof(struct tcp_conn)); - mem_free((caddr_t)xprt, sizeof(SVCXPRT)); -} - -/* - * All read operations timeout after 35 seconds. - * A timeout is fatal for the connection. - */ -static struct timeval wait_per_try = { 35, 0 }; - -/* - * reads data from the tcp conection. - * any error is fatal and the connection is closed. - * (And a read of zero bytes is a half closed stream => error.) - * - * Note: we have to be careful here not to allow ourselves to become - * blocked too long in this routine. While we're waiting for data from one - * client, another client may be trying to connect. To avoid this situation, - * some code from svc_run() is transplanted here: the select() loop checks - * all RPC descriptors including the one we want and calls svc_getreqset2() - * to handle new requests if any are detected. - */ -static int -readtcp(xprt, buf, len) - register SVCXPRT *xprt; - caddr_t buf; - register int len; -{ - register int sock = xprt->xp_sock; - struct timeval start, delta, tv; - struct timeval tmp1, tmp2; - fd_set *fds; - - delta = wait_per_try; - fds = NULL; - gettimeofday(&start, NULL); - do { - int bytes = sizeof (fd_set); - if (fds != NULL) - free(fds); - fds = (fd_set *)malloc(bytes); - if (fds == NULL) - goto fatal_err; - memcpy(fds, __svc_fdset, bytes); - - /* XXX we know the other bits are still clear */ - FD_SET(sock, fds); - tv = delta; /* in case select() implements writeback */ - switch (select(svc_maxfd + 1, fds, NULL, NULL, &tv)) { - case -1: - if (errno != EINTR) - goto fatal_err; - gettimeofday(&tmp1, NULL); - timersub(&tmp1, &start, &tmp2); - timersub(&wait_per_try, &tmp2, &tmp1); - if (tmp1.tv_sec < 0 || !timerisset(&tmp1)) - goto fatal_err; - delta = tmp1; - continue; - case 0: - goto fatal_err; - default: - if (!FD_ISSET(sock, fds)) { - svc_getreqset2(fds, svc_maxfd + 1); - gettimeofday(&tmp1, NULL); - timersub(&tmp1, &start, &tmp2); - timersub(&wait_per_try, &tmp2, &tmp1); - if (tmp1.tv_sec < 0 || !timerisset(&tmp1)) - goto fatal_err; - delta = tmp1; - continue; - } - } - } while (!FD_ISSET(sock, fds)); - if ((len = _RPC_read(sock, buf, len)) > 0) { - if (fds != NULL) - free(fds); - return (len); - } -fatal_err: - ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; - if (fds != NULL) - free(fds); - return (-1); -} - -/* - * writes data to the tcp connection. - * Any error is fatal and the connection is closed. - */ -static int -writetcp(xprt, buf, len) - register SVCXPRT *xprt; - caddr_t buf; - int len; -{ - register int i, cnt; - - for (cnt = len; cnt > 0; cnt -= i, buf += i) { - if ((i = _RPC_write(xprt->xp_sock, buf, cnt)) < 0) { - ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = - XPRT_DIED; - return (-1); - } - } - return (len); -} - -static enum xprt_stat -svctcp_stat(xprt) - SVCXPRT *xprt; -{ - register struct tcp_conn *cd = - (struct tcp_conn *)(xprt->xp_p1); - - if (cd->strm_stat == XPRT_DIED) - return (XPRT_DIED); - if (! xdrrec_eof(&(cd->xdrs))) - return (XPRT_MOREREQS); - return (XPRT_IDLE); -} - -static bool_t -svctcp_recv(xprt, msg) - SVCXPRT *xprt; - register struct rpc_msg *msg; -{ - register struct tcp_conn *cd = - (struct tcp_conn *)(xprt->xp_p1); - register XDR *xdrs = &(cd->xdrs); - - xdrs->x_op = XDR_DECODE; - (void)xdrrec_skiprecord(xdrs); - if (xdr_callmsg(xdrs, msg)) { - cd->x_id = msg->rm_xid; - return (TRUE); - } - cd->strm_stat = XPRT_DIED; /* XXXX */ - return (FALSE); -} - -static bool_t -svctcp_getargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - - return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr)); -} - -static bool_t -svctcp_freeargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - register XDR *xdrs = - &(((struct tcp_conn *)(xprt->xp_p1))->xdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_args)(xdrs, args_ptr)); -} - -static bool_t -svctcp_reply(xprt, msg) - SVCXPRT *xprt; - register struct rpc_msg *msg; -{ - register struct tcp_conn *cd = - (struct tcp_conn *)(xprt->xp_p1); - register XDR *xdrs = &(cd->xdrs); - register bool_t stat; - - xdrs->x_op = XDR_ENCODE; - msg->rm_xid = cd->x_id; - stat = xdr_replymsg(xdrs, msg); - (void)xdrrec_endofrecord(xdrs, TRUE); - return (stat); -} diff --git a/c/src/librpc/src/rpc/svc_udp.c b/c/src/librpc/src/rpc/svc_udp.c deleted file mode 100644 index 652683b3da..0000000000 --- a/c/src/librpc/src/rpc/svc_udp.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_udp.c,v 1.13 2000/01/27 23:06:41 jasone Exp $"; -#endif - -/* - * svc_udp.c, - * Server side for UDP/IP based RPC. (Does some caching in the hopes of - * achieving execute-at-most-once semantics.) - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define rpc_buffer(xprt) ((xprt)->xp_p1) -#define MAX(a, b) ((a > b) ? a : b) - -static bool_t svcudp_recv(); -static bool_t svcudp_reply(); -static enum xprt_stat svcudp_stat(); -static bool_t svcudp_getargs(); -static bool_t svcudp_freeargs(); -static void svcudp_destroy(); -static void cache_set __P((SVCXPRT *, u_long)); -static int cache_get __P((SVCXPRT *, struct rpc_msg *, char **, u_long *)); - -static struct xp_ops svcudp_op = { - svcudp_recv, - svcudp_stat, - svcudp_getargs, - svcudp_reply, - svcudp_freeargs, - svcudp_destroy -}; - -/* - * kept in xprt->xp_p2 - */ -struct svcudp_data { - u_int su_iosz; /* byte size of send.recv buffer */ - u_long su_xid; /* transaction id */ - XDR su_xdrs; /* XDR handle */ - char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ - char * su_cache; /* cached data, NULL if no cache */ -}; -#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) - -/* - * Usage: - * xprt = svcudp_create(sock); - * - * If sock<0 then a socket is created, else sock is used. - * If the socket, sock is not bound to a port then svcudp_create - * binds it to an arbitrary port. In any (successful) case, - * xprt->xp_sock is the registered socket number and xprt->xp_port is the - * associated port number. - * Once *xprt is initialized, it is registered as a transporter; - * see (svc.h, xprt_register). - * The routines returns NULL if a problem occurred. - */ -SVCXPRT * -svcudp_bufcreate(sock, sendsz, recvsz) - register int sock; - u_int sendsz, recvsz; -{ - bool_t madesock = FALSE; - register SVCXPRT *xprt; - register struct svcudp_data *su; - struct sockaddr_in addr; - int len = sizeof(struct sockaddr_in); - - if (sock == RPC_ANYSOCK) { - if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - perror("svcudp_create: socket creation problem"); - return ((SVCXPRT *)NULL); - } - madesock = TRUE; - } - memset((char *)&addr, 0, sizeof (addr)); - addr.sin_len = sizeof(struct sockaddr_in); - addr.sin_family = AF_INET; - if (bindresvport(sock, &addr)) { - addr.sin_port = 0; - (void)bind(sock, (struct sockaddr *)&addr, len); - } - if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) { - perror("svcudp_create - cannot getsockname"); - if (madesock) - (void)_RPC_close(sock); - return ((SVCXPRT *)NULL); - } - xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); - if (xprt == NULL) { - (void)fprintf(stderr, "svcudp_create: out of memory\n"); - return (NULL); - } - su = (struct svcudp_data *)mem_alloc(sizeof(*su)); - if (su == NULL) { - (void)fprintf(stderr, "svcudp_create: out of memory\n"); - return (NULL); - } - su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; - if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { - (void)fprintf(stderr, "svcudp_create: out of memory\n"); - return (NULL); - } - xdrmem_create( - &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); - su->su_cache = NULL; - xprt->xp_p2 = (caddr_t)su; - xprt->xp_verf.oa_base = su->su_verfbody; - xprt->xp_ops = &svcudp_op; - xprt->xp_port = ntohs(addr.sin_port); - xprt->xp_sock = sock; - xprt_register(xprt); - return (xprt); -} - -SVCXPRT * -svcudp_create(sock) - int sock; -{ - - return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); -} - -static enum xprt_stat -svcudp_stat(xprt) - SVCXPRT *xprt; -{ - - return (XPRT_IDLE); -} - -static bool_t -svcudp_recv(xprt, msg) - register SVCXPRT *xprt; - struct rpc_msg *msg; -{ - register struct svcudp_data *su = su_data(xprt); - register XDR *xdrs = &(su->su_xdrs); - register int rlen; - char *reply; - u_long replylen; - - again: - xprt->xp_addrlen = sizeof(struct sockaddr_in); - rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, - 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); - if (rlen == -1 && errno == EINTR) - goto again; - if (rlen == -1 || rlen < 4*sizeof(u_int32_t)) - return (FALSE); - xdrs->x_op = XDR_DECODE; - XDR_SETPOS(xdrs, 0); - if (! xdr_callmsg(xdrs, msg)) - return (FALSE); - su->su_xid = msg->rm_xid; - if (su->su_cache != NULL) { - if (cache_get(xprt, msg, &reply, &replylen)) { - (void) sendto(xprt->xp_sock, reply, (int) replylen, 0, - (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); - return (TRUE); - } - } - return (TRUE); -} - -static bool_t -svcudp_reply(xprt, msg) - register SVCXPRT *xprt; - struct rpc_msg *msg; -{ - register struct svcudp_data *su = su_data(xprt); - register XDR *xdrs = &(su->su_xdrs); - register int slen; - register bool_t stat = FALSE; - - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, 0); - msg->rm_xid = su->su_xid; - if (xdr_replymsg(xdrs, msg)) { - slen = (int)XDR_GETPOS(xdrs); - if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, - (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) - == slen) { - stat = TRUE; - if (su->su_cache && slen >= 0) { - cache_set(xprt, (u_long) slen); - } - } - } - return (stat); -} - -static bool_t -svcudp_getargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - - return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); -} - -static bool_t -svcudp_freeargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - register XDR *xdrs = &(su_data(xprt)->su_xdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_args)(xdrs, args_ptr)); -} - -static void -svcudp_destroy(xprt) - register SVCXPRT *xprt; -{ - register struct svcudp_data *su = su_data(xprt); - - xprt_unregister(xprt); - (void)_RPC_close(xprt->xp_sock); - XDR_DESTROY(&(su->su_xdrs)); - mem_free(rpc_buffer(xprt), su->su_iosz); - mem_free((caddr_t)su, sizeof(struct svcudp_data)); - mem_free((caddr_t)xprt, sizeof(SVCXPRT)); -} - - -/***********this could be a separate file*********************/ - -/* - * Fifo cache for udp server - * Copies pointers to reply buffers into fifo cache - * Buffers are sent again if retransmissions are detected. - */ - -#define SPARSENESS 4 /* 75% sparse */ - -#define CACHE_PERROR(msg) \ - (void) fprintf(stderr,"%s\n", msg) - -#define ALLOC(type, size) \ - (type *) mem_alloc((unsigned) (sizeof(type) * (size))) - -#define BZERO(addr, type, size) \ - memset((char *) addr, 0, sizeof(type) * (int) (size)) - -/* - * An entry in the cache - */ -typedef struct cache_node *cache_ptr; -struct cache_node { - /* - * Index into cache is xid, proc, vers, prog and address - */ - u_long cache_xid; - u_long cache_proc; - u_long cache_vers; - u_long cache_prog; - struct sockaddr_in cache_addr; - /* - * The cached reply and length - */ - char * cache_reply; - u_long cache_replylen; - /* - * Next node on the list, if there is a collision - */ - cache_ptr cache_next; -}; - - - -/* - * The entire cache - */ -struct udp_cache { - u_long uc_size; /* size of cache */ - cache_ptr *uc_entries; /* hash table of entries in cache */ - cache_ptr *uc_fifo; /* fifo list of entries in cache */ - u_long uc_nextvictim; /* points to next victim in fifo list */ - u_long uc_prog; /* saved program number */ - u_long uc_vers; /* saved version number */ - u_long uc_proc; /* saved procedure number */ - struct sockaddr_in uc_addr; /* saved caller's address */ -}; - - -/* - * the hashing function - */ -#define CACHE_LOC(transp, xid) \ - (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size)) - - -/* - * Enable use of the cache. - * Note: there is no disable. - */ -int svcudp_enablecache(transp, size) - SVCXPRT *transp; - u_long size; -{ - struct svcudp_data *su = su_data(transp); - struct udp_cache *uc; - - if (su->su_cache != NULL) { - CACHE_PERROR("enablecache: cache already enabled"); - return(0); - } - uc = ALLOC(struct udp_cache, 1); - if (uc == NULL) { - CACHE_PERROR("enablecache: could not allocate cache"); - return(0); - } - uc->uc_size = size; - uc->uc_nextvictim = 0; - uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS); - if (uc->uc_entries == NULL) { - CACHE_PERROR("enablecache: could not allocate cache data"); - return(0); - } - BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS); - uc->uc_fifo = ALLOC(cache_ptr, size); - if (uc->uc_fifo == NULL) { - CACHE_PERROR("enablecache: could not allocate cache fifo"); - return(0); - } - BZERO(uc->uc_fifo, cache_ptr, size); - su->su_cache = (char *) uc; - return(1); -} - - -/* - * Set an entry in the cache - */ -static void -cache_set(xprt, replylen) - SVCXPRT *xprt; - u_long replylen; -{ - register cache_ptr victim; - register cache_ptr *vicp; - register struct svcudp_data *su = su_data(xprt); - struct udp_cache *uc = (struct udp_cache *) su->su_cache; - u_int loc; - char *newbuf; - - /* - * Find space for the new entry, either by - * reusing an old entry, or by mallocing a new one - */ - victim = uc->uc_fifo[uc->uc_nextvictim]; - if (victim != NULL) { - loc = CACHE_LOC(xprt, victim->cache_xid); - for (vicp = &uc->uc_entries[loc]; - *vicp != NULL && *vicp != victim; - vicp = &(*vicp)->cache_next) - ; - if (*vicp == NULL) { - CACHE_PERROR("cache_set: victim not found"); - return; - } - *vicp = victim->cache_next; /* remote from cache */ - newbuf = victim->cache_reply; - } else { - victim = ALLOC(struct cache_node, 1); - if (victim == NULL) { - CACHE_PERROR("cache_set: victim alloc failed"); - return; - } - newbuf = mem_alloc(su->su_iosz); - if (newbuf == NULL) { - CACHE_PERROR("cache_set: could not allocate new rpc_buffer"); - return; - } - } - - /* - * Store it away - */ - victim->cache_replylen = replylen; - victim->cache_reply = rpc_buffer(xprt); - rpc_buffer(xprt) = newbuf; - xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE); - victim->cache_xid = su->su_xid; - victim->cache_proc = uc->uc_proc; - victim->cache_vers = uc->uc_vers; - victim->cache_prog = uc->uc_prog; - victim->cache_addr = uc->uc_addr; - loc = CACHE_LOC(xprt, victim->cache_xid); - victim->cache_next = uc->uc_entries[loc]; - uc->uc_entries[loc] = victim; - uc->uc_fifo[uc->uc_nextvictim++] = victim; - uc->uc_nextvictim %= uc->uc_size; -} - -/* - * Try to get an entry from the cache - * return 1 if found, 0 if not found - */ -static int -cache_get(xprt, msg, replyp, replylenp) - SVCXPRT *xprt; - struct rpc_msg *msg; - char **replyp; - u_long *replylenp; -{ - u_int loc; - register cache_ptr ent; - register struct svcudp_data *su = su_data(xprt); - register struct udp_cache *uc = (struct udp_cache *) su->su_cache; - -# define EQADDR(a1, a2) (memcmp(&a1, &a2, sizeof(a1)) == 0) - - loc = CACHE_LOC(xprt, su->su_xid); - for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) { - if (ent->cache_xid == su->su_xid && - ent->cache_proc == uc->uc_proc && - ent->cache_vers == uc->uc_vers && - ent->cache_prog == uc->uc_prog && - EQADDR(ent->cache_addr, uc->uc_addr)) { - *replyp = ent->cache_reply; - *replylenp = ent->cache_replylen; - return(1); - } - } - /* - * Failed to find entry - * Remember a few things so we can do a set later - */ - uc->uc_proc = msg->rm_call.cb_proc; - uc->uc_vers = msg->rm_call.cb_vers; - uc->uc_prog = msg->rm_call.cb_prog; - uc->uc_addr = xprt->xp_raddr; - return(0); -} - diff --git a/c/src/librpc/src/rpc/svc_unix.c b/c/src/librpc/src/rpc/svc_unix.c deleted file mode 100644 index 53772ecd4a..0000000000 --- a/c/src/librpc/src/rpc/svc_unix.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)svc_unix.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/ -/*static char *sccsid = "from: @(#)svc_unix.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_unix.c,v 1.7 2000/01/27 23:06:42 jasone Exp $"; -#endif - -/* - * svc_unix.c, Server side for TCP/IP based RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - * Actually implements two flavors of transporter - - * a unix rendezvouser (a listner and connection establisher) - * and a record/unix stream. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Ops vector for AF_UNIX based rpc service handle - */ -static bool_t svcunix_recv(); -static enum xprt_stat svcunix_stat(); -static bool_t svcunix_getargs(); -static bool_t svcunix_reply(); -static bool_t svcunix_freeargs(); -static void svcunix_destroy(); - -static struct xp_ops svcunix_op = { - svcunix_recv, - svcunix_stat, - svcunix_getargs, - svcunix_reply, - svcunix_freeargs, - svcunix_destroy -}; - -/* - * Ops vector for TCP/IP rendezvous handler - */ -static bool_t rendezvous_request(); -static enum xprt_stat rendezvous_stat(); - -static struct xp_ops svcunix_rendezvous_op = { - rendezvous_request, - rendezvous_stat, - (bool_t (*)())abort, - (bool_t (*)())abort, - (bool_t (*)())abort, - svcunix_destroy -}; - -static int readunix(), writeunix(); -static SVCXPRT *makefd_xprt(); - -struct unix_rendezvous { /* kept in xprt->xp_p1 */ - u_int sendsize; - u_int recvsize; -}; - -struct unix_conn { /* kept in xprt->xp_p1 */ - enum xprt_stat strm_stat; - u_long x_id; - XDR xdrs; - char verf_body[MAX_AUTH_BYTES]; -}; - - -struct cmessage { - struct cmsghdr cmsg; - struct cmsgcred cmcred; -}; - -static struct cmessage cm; - -static int __msgread(sock, buf, cnt) - int sock; - void *buf; - size_t cnt; -{ - struct iovec iov[1]; - struct msghdr msg; - - bzero((char *)&cm, sizeof(cm)); - iov[0].iov_base = buf; - iov[0].iov_len = cnt; - - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = (caddr_t)&cm; - msg.msg_controllen = sizeof(struct cmessage); - msg.msg_flags = 0; - - return(recvmsg(sock, &msg, 0)); -} - -static int __msgwrite(sock, buf, cnt) - int sock; - void *buf; - size_t cnt; -{ - struct iovec iov[1]; - struct msghdr msg; - - bzero((char *)&cm, sizeof(cm)); - iov[0].iov_base = buf; - iov[0].iov_len = cnt; - - cm.cmsg.cmsg_type = SCM_CREDS; - cm.cmsg.cmsg_level = SOL_SOCKET; - cm.cmsg.cmsg_len = sizeof(struct cmessage); - - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = (caddr_t)&cm; - msg.msg_controllen = sizeof(struct cmessage); - msg.msg_flags = 0; - - return(sendmsg(sock, &msg, 0)); -} - -/* - * Usage: - * xprt = svcunix_create(sock, send_buf_size, recv_buf_size); - * - * Creates, registers, and returns a (rpc) unix based transporter. - * Once *xprt is initialized, it is registered as a transporter - * see (svc.h, xprt_register). This routine returns - * a NULL if a problem occurred. - * - * If sock<0 then a socket is created, else sock is used. - * If the socket, sock is not bound to a port then svcunix_create - * binds it to an arbitrary port. The routine then starts a unix - * listener on the socket's associated port. In any (successful) case, - * xprt->xp_sock is the registered socket number and xprt->xp_port is the - * associated port number. - * - * Since unix streams do buffered io similar to stdio, the caller can specify - * how big the send and receive buffers are via the second and third parms; - * 0 => use the system default. - */ -SVCXPRT * -svcunix_create(sock, sendsize, recvsize, path) - register int sock; - u_int sendsize; - u_int recvsize; - char *path; -{ - bool_t madesock = FALSE; - register SVCXPRT *xprt; - register struct unix_rendezvous *r; - struct sockaddr_un addr; - int len = sizeof(struct sockaddr_un); - - if (sock == RPC_ANYSOCK) { - if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - perror("svc_unix.c - AF_UNIX socket creation problem"); - return ((SVCXPRT *)NULL); - } - madesock = TRUE; - } - memset(&addr, 0, sizeof (addr)); - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, path); - len = strlen(addr.sun_path) + sizeof(addr.sun_family) + - sizeof(addr.sun_len) + 1; - addr.sun_len = len; - - bind(sock, (struct sockaddr *)&addr, len); - - if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) || - (listen(sock, 2) != 0)) { - perror("svc_unix.c - cannot getsockname or listen"); - if (madesock) - (void)_RPC_close(sock); - return ((SVCXPRT *)NULL); - } - r = (struct unix_rendezvous *)mem_alloc(sizeof(*r)); - if (r == NULL) { - (void) fprintf(stderr, "svcunix_create: out of memory\n"); - return (NULL); - } - r->sendsize = sendsize; - r->recvsize = recvsize; - xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); - if (xprt == NULL) { - (void) fprintf(stderr, "svcunix_create: out of memory\n"); - return (NULL); - } - xprt->xp_p2 = NULL; - xprt->xp_p1 = (caddr_t)r; - xprt->xp_verf = _null_auth; - xprt->xp_ops = &svcunix_rendezvous_op; - xprt->xp_port = -1 /*ntohs(addr.sin_port)*/; - xprt->xp_sock = sock; - xprt_register(xprt); - return (xprt); -} - -/* - * Like svunix_create(), except the routine takes any *open* UNIX file - * descriptor as its first input. - */ -SVCXPRT * -svcunixfd_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - - return (makefd_xprt(fd, sendsize, recvsize)); -} - -static SVCXPRT * -makefd_xprt(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - register SVCXPRT *xprt; - register struct unix_conn *cd; - - xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); - if (xprt == (SVCXPRT *)NULL) { - (void) fprintf(stderr, "svc_unix: makefd_xprt: out of memory\n"); - goto done; - } - cd = (struct unix_conn *)mem_alloc(sizeof(struct unix_conn)); - if (cd == (struct unix_conn *)NULL) { - (void) fprintf(stderr, "svc_unix: makefd_xprt: out of memory\n"); - mem_free((char *) xprt, sizeof(SVCXPRT)); - xprt = (SVCXPRT *)NULL; - goto done; - } - cd->strm_stat = XPRT_IDLE; - xdrrec_create(&(cd->xdrs), sendsize, recvsize, - (caddr_t)xprt, readunix, writeunix); - xprt->xp_p2 = NULL; - xprt->xp_p1 = (caddr_t)cd; - xprt->xp_verf.oa_base = cd->verf_body; - xprt->xp_addrlen = 0; - xprt->xp_ops = &svcunix_op; /* truely deals with calls */ - xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ - xprt->xp_sock = fd; - xprt_register(xprt); - done: - return (xprt); -} - -static bool_t -rendezvous_request(xprt) - register SVCXPRT *xprt; -{ - int sock; - struct unix_rendezvous *r; - struct sockaddr_un addr; - struct sockaddr_in in_addr; - int len; - - r = (struct unix_rendezvous *)xprt->xp_p1; - again: - len = sizeof(struct sockaddr_in); - if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, - &len)) < 0) { - if (errno == EINTR) - goto again; - return (FALSE); - } - - /* - * make a new transporter (re-uses xprt) - */ - bzero((char *)&in_addr, sizeof(in_addr)); - in_addr.sin_family = AF_UNIX; - xprt = makefd_xprt(sock, r->sendsize, r->recvsize); - xprt->xp_raddr = in_addr; - xprt->xp_addrlen = len; - return (FALSE); /* there is never an rpc msg to be processed */ -} - -static enum xprt_stat -rendezvous_stat() -{ - - return (XPRT_IDLE); -} - -static void -svcunix_destroy(xprt) - register SVCXPRT *xprt; -{ - register struct unix_conn *cd = (struct unix_conn *)xprt->xp_p1; - - xprt_unregister(xprt); - (void)_RPC_close(xprt->xp_sock); - if (xprt->xp_port != 0) { - /* a rendezvouser socket */ - xprt->xp_port = 0; - } else { - /* an actual connection socket */ - XDR_DESTROY(&(cd->xdrs)); - } - mem_free((caddr_t)cd, sizeof(struct unix_conn)); - mem_free((caddr_t)xprt, sizeof(SVCXPRT)); -} - -/* - * All read operations timeout after 35 seconds. - * A timeout is fatal for the connection. - */ -static struct timeval wait_per_try = { 35, 0 }; - -/* - * reads data from the unix conection. - * any error is fatal and the connection is closed. - * (And a read of zero bytes is a half closed stream => error.) - * - * Note: we have to be careful here not to allow ourselves to become - * blocked too long in this routine. While we're waiting for data from one - * client, another client may be trying to connect. To avoid this situation, - * some code from svc_run() is transplanted here: the select() loop checks - * all RPC descriptors including the one we want and calls svc_getreqset2() - * to handle new requests if any are detected. - */ -static int -readunix(xprt, buf, len) - register SVCXPRT *xprt; - caddr_t buf; - register int len; -{ - register int sock = xprt->xp_sock; - struct timeval start, delta, tv; - struct timeval tmp1, tmp2; - fd_set *fds; - - delta = wait_per_try; - fds = NULL; - gettimeofday(&start, NULL); - do { - int bytes = sizeof (fd_set); - if (fds != NULL) - free(fds); - fds = (fd_set *)malloc(bytes); - if (fds == NULL) - goto fatal_err; - memcpy(fds, __svc_fdset, bytes); - - /* XXX we know the other bits are still clear */ - FD_SET(sock, fds); - tv = delta; /* in case select() implements writeback */ - switch (select(svc_maxfd + 1, fds, NULL, NULL, &tv)) { - case -1: - if (errno != EINTR) - goto fatal_err; - gettimeofday(&tmp1, NULL); - timersub(&tmp1, &start, &tmp2); - timersub(&wait_per_try, &tmp2, &tmp1); - if (tmp1.tv_sec < 0 || !timerisset(&tmp1)) - goto fatal_err; - delta = tmp1; - continue; - case 0: - goto fatal_err; - default: - if (!FD_ISSET(sock, fds)) { - svc_getreqset2(fds, svc_maxfd + 1); - gettimeofday(&tmp1, NULL); - timersub(&tmp1, &start, &tmp2); - timersub(&wait_per_try, &tmp2, &tmp1); - if (tmp1.tv_sec < 0 || !timerisset(&tmp1)) - goto fatal_err; - delta = tmp1; - continue; - } - } - } while (!FD_ISSET(sock, fds)); - if ((len = __msgread(sock, buf, len)) > 0) { - if (fds != NULL) - free(fds); - return (len); - } -fatal_err: - ((struct unix_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; - if (fds != NULL) - free(fds); - return (-1); -} - -/* - * writes data to the unix connection. - * Any error is fatal and the connection is closed. - */ -static int -writeunix(xprt, buf, len) - register SVCXPRT *xprt; - caddr_t buf; - int len; -{ - register int i, cnt; - - for (cnt = len; cnt > 0; cnt -= i, buf += i) { - if ((i = __msgwrite(xprt->xp_sock, buf, cnt)) < 0) { - ((struct unix_conn *)(xprt->xp_p1))->strm_stat = - XPRT_DIED; - return (-1); - } - } - return (len); -} - -static enum xprt_stat -svcunix_stat(xprt) - SVCXPRT *xprt; -{ - register struct unix_conn *cd = - (struct unix_conn *)(xprt->xp_p1); - - if (cd->strm_stat == XPRT_DIED) - return (XPRT_DIED); - if (! xdrrec_eof(&(cd->xdrs))) - return (XPRT_MOREREQS); - return (XPRT_IDLE); -} - -static bool_t -svcunix_recv(xprt, msg) - SVCXPRT *xprt; - register struct rpc_msg *msg; -{ - register struct unix_conn *cd = - (struct unix_conn *)(xprt->xp_p1); - register XDR *xdrs = &(cd->xdrs); - - xdrs->x_op = XDR_DECODE; - (void)xdrrec_skiprecord(xdrs); - if (xdr_callmsg(xdrs, msg)) { - cd->x_id = msg->rm_xid; - /* set up verifiers */ - msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX; - msg->rm_call.cb_verf.oa_base = (caddr_t)&cm; - msg->rm_call.cb_verf.oa_length = sizeof(cm); - return (TRUE); - } - cd->strm_stat = XPRT_DIED; /* XXXX */ - return (FALSE); -} - -static bool_t -svcunix_getargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - - return ((*xdr_args)(&(((struct unix_conn *)(xprt->xp_p1))->xdrs), args_ptr)); -} - -static bool_t -svcunix_freeargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - caddr_t args_ptr; -{ - register XDR *xdrs = - &(((struct unix_conn *)(xprt->xp_p1))->xdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_args)(xdrs, args_ptr)); -} - -static bool_t -svcunix_reply(xprt, msg) - SVCXPRT *xprt; - register struct rpc_msg *msg; -{ - register struct unix_conn *cd = - (struct unix_conn *)(xprt->xp_p1); - register XDR *xdrs = &(cd->xdrs); - register bool_t stat; - - xdrs->x_op = XDR_ENCODE; - msg->rm_xid = cd->x_id; - stat = xdr_replymsg(xdrs, msg); - (void)xdrrec_endofrecord(xdrs, TRUE); - return (stat); -} -- cgit v1.2.3