diff options
Diffstat (limited to 'lib/libc/rpc')
92 files changed, 0 insertions, 35444 deletions
diff --git a/lib/libc/rpc/DISCLAIMER b/lib/libc/rpc/DISCLAIMER deleted file mode 100644 index 9a3a991..0000000 --- a/lib/libc/rpc/DISCLAIMER +++ /dev/null @@ -1,31 +0,0 @@ -/* $NetBSD: DISCLAIMER,v 1.2 1998/01/09 04:11:51 perry Exp $ */ -/* $FreeBSD$ */ - -/* - * 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/lib/libc/rpc/LICENSE b/lib/libc/rpc/LICENSE deleted file mode 100644 index 5f1205c..0000000 --- a/lib/libc/rpc/LICENSE +++ /dev/null @@ -1,335 +0,0 @@ -$FreeBSD$ - -Sun Industry Standards Source License 1.0 - -DEFINITIONS - -1.1. "Commercial Use" means distribution or otherwise -making the Original Code available to a third party. - -1.2. "Contributor Version" means the combination of the -Original Code, and the Modifications made by that particular -Contributor. - -1.3. "Electronic Distribution Mechanism" means a mechanism -generally accepted in the software development community for -the electronic transfer of data. - -1.4. "Executable" means Original Code in any form other -than Source Code. - -1.5. "Initial Developer" means the individual or entity -identified as the Initial Developer in the Source Code -notice required by 2 (Exhibit A) - -1.6. "Larger Work" means a work which combines Original -Code or portions thereof with code not governed by the terms -of this License. - -1.7. "License" means this document. - -1.8. "Licensable" means having the right to grant, to the -maximum extent possible, whether at the time of the initial -grant or subsequently acquired, any and all of the rights -conveyed herein. - -1.9. "Modifications" means any addition to or deletion from -the substance or structure of either the Original Code or -any previous Modifications. A Modification is: - -A. Any addition to or deletion from the contents of a file -containing Original Code or previous Modifications. - -B. Any new file that contains any part of the Original Code -or previous Modifications. . - -1.10. "Original Code" means Source Code of computer -software code which is described in the Source Code notice -required by Exhibit A as Original Code. - -1.11. "Patent Claims" means any patent claims, now owned or -hereafter acquired, including without limitation, method, -process, and apparatus claims, in any patent Licensable by -grantor. - -1.12. "Source Code" means the preferred form of the -Original Code for making modifications to it, including all -modules it contains, plus any associated interface -definition files, or scripts used to control compilation and -installation of an Executable. - -1.13. "Standards" means the standard identified in Exhibit -B or a subsequent version of such standard. - -1.14. "You" or "Your" means an individual or a legal entity -exercising rights under, and complying with all of the terms -of, this License or a future version of this License issued -under Section 6.1. For legal entities, "You" includes any -entity which controls, is controlled by, or is under common -control with You. For purposes of this definition, -"control" means (a) the power, direct or indirect, to cause -the direction or management of such entity, whether by -contract or otherwise, or (b) ownership of more than fifty -percent (50%) of the outstanding shares or beneficial -ownership of such entity. - -2.0 SOURCE CODE LICENSE - -2.1 The Initial Developer Grant: The Initial Developer -hereby grants You a world-wide, royalty-free, non-exclusive -license, subject to third party intellectual property -claims: - -a) under intellectual property rights (other than patent or -trademark) Licensable by Initial Developer to use, -reproduce, modify, display, perform, sub license and -distribute the Original Code (or portions thereof )with or -without Modifications, and/or as part of a Larger Work; and - -b) under Patents Claims infringed by the making, using or -selling of Original Code, to make, have made, use, practice, -sell, and offer for sale, and/or otherwise dispose of the -Original Code (or portions thereof). - -c) the licenses granted in this Section 2.1(a ) and (b) are -effective on the date Initial Developer first distributes -Original Code under the terms of this License. - -d) Notwithstanding Section 2.1(b )above, no patent license -is granted: 1) for code that You delete from the Original -Code; 2) separate from the Original Code; or 3) for -infringements caused by: i) the modification of the -Original Code or - -ii) the combination of the Original Code with other software -or devices, including but not limited to Modifications. - -3.0 DISTRIBUTION OBLIGATIONS - -3.1 Application of License. The Source Code version of -Original Code may be distributed only under the terms of -this License or a future version of this License released -under Section 6.1, and You must include a copy of this -License with every copy of the Source Code You distribute. -You may not offer or impose any terms on any Source Code -version that alters or restricts the applicable version of -this License or the recipient's rights hereunder. Your -license for shipment of the Contributor Version is -conditioned upon your full compliance with this Section. -The Modifications which you create must comply with all -requirements set out by the Standards body in effect 120 -days before You ship the Contributor Version. In the event -that the Modifications do not meet such requirements, You -agree to publish (i) any deviation from the Standards -protocol resulting from implementation of your Modifications -and (ii) a reference implementation of Your Modifications, -and to make any such deviation and reference implementation -available to all third parties under the same terms as the -license on a royalty free basis within thirty (30) days of -Your first customer shipment of Your Modifications. - -3.2 Required Notices. You must duplicate the notice in -Exhibit A in each file of the Source Code. If it is not -possible to put such notice in a particular Source Code file -due to its structure, then You must include such notice in a -location (such as a relevant directory ) where a user would -be likely to look for such a notice. If You created one or -more Modifications ) You may add your name as a Contributor -to the notice described in Exhibit A. You must also -duplicate this License in any documentation for the Source -Code where You describe recipients' rights or ownership -rights relating to Initial Code. You may choose to offer, -and to charge a fee for, warranty, support, indemnity or -liability obligations to one or more recipients of Your -version of the Code. However, You may do so only - -on Your own behalf, and not on behalf of the Initial -Developer. You must make it absolutely clear than any such -warranty, support, indemnity or liability obligation is -offered by You alone, and You hereby agree to indemnify the -Initial Developer for any liability incurred by the Initial -Developer as a result of warranty, support, indemnity or -liability terms You offer. - -3.3 Distribution of Executable Versions. You may distribute -Original Code in Executable and Source form only if the -requirements of Section 3.1 and 3.2 have been met for that -Original Code, and if You include a notice stating that the -Source Code version of the Original Code is available under -the terms of this License. The notice must be conspicuously -included in any notice in an Executable or Source versions, -related documentation or collateral in which You describe -recipients' rights relating to the Original Code. You may -distribute the Executable and Source versions of Your -version of the Code or ownership rights under a license of -Your choice, which may contain terms different from this -License, provided that You are in compliance with the terms -of this License. If You distribute the Executable and -Source versions under a different license You must make it -absolutely clear that any terms which differ from this -License are offered by You alone, not by the Initial -Developer . You hereby agree to indemnify the Initial -Developer for any liability incurred by the Initial -Developer as a result of any such terms You offer . - -3.4 Larger Works. You may create a Larger Work by combining -Original Code with other code not governed by the terms of -this License and distribute the Larger Work as a single -product. In such a case, You must make sure the -requirements of this License are fulfilled for the Original -Code. - -4.0 INABILITY TO COMPLY DUE TO STATUTE OR REGULATION - -If it is impossible for You to comply with any of the terms -of this License with respect to some or all of the Original -Code due to statute, judicial order, or regulation then You -must: - -a) comply with the terms of this License to the maximum -extent possible; and - -b) describe the limitations and the code they affect. Such -description must be included in the LEGAL file described in -Section 3.2 and must be included with all distributions of -the Source Code. Except to the extent prohibited by statute -or regulation, such description must be sufficiently -detailed for a recipient of ordinary skill to be able to -understand it. - -5.0 APPLICATION OF THIS LICENSE This License applies to code -to which the Initial Developer has attached the notice in -Exhibit A and to related Modifications as set out in Section -3.1. - -6.0 VERSIONS OF THE LICENSE - -6.1 New Versions. Sun Microsystems, Inc. Sun may publish -revised and/or new versions of the License from time to -time. Each version will be given a distinguishing version -number . - -6.2 Effect of New Versions. Once Original Code has been -published under a particular version of the License, You may -always continue to use it under the terms of that version. -You may also choose to use such Original Code under the -terms of any subsequent version of the License published by -Sun. No one other than Sun has the right to modify the -terms applicable to Original Code. - -7. DISCLAIMER OF W ARRANTY. ORIGINAL CODE IS PROVIDED -UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF -ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT -LIMITATION, WARRANTIES THAT THE ORIGINAL CODE IS FREE OF -DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR -NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE ORIGINAL CODE IS WITH YOU. SHOULD ANY -ORIGINAL CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE -INITIAL DEVELOPER )ASSUME THE COST OF ANY NECESSARY -SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF -WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO -USE OF ANY ORIGINAL CODE IS AUTHORIZED HEREUNDER EXCEPT -UNDER THIS DISCLAIMER. - -8.0 TERMINATION - -8.1 This License and the rights granted hereunder will -terminate automatically if You fail to comply with terms -herein and fail to cure such breach within 30 days of -becoming aware of the breach. All sublicenses to the -Original Code which are properly granted shall survive any -termination of this License. Provisions which, by their -nature, must remain in effect beyond the termination of this -License shall survive. - -8.2 .In the event of termination under Section 8.1 above, -all end user license agreements (excluding distributors and -resellers) which have been validly granted by You or any -distributor hereunder prior to termination shall survive -termination. - -9.0 LIMIT OF LIABILITY UNDER NO CIRCUMSTANCES AND UNDER NO -LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE) ,CONTRACT, -OR OTHER WISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER -CONTRIBUTOR, OR ANY DISTRIBUTOR OF ORIGINAL CODE, OR ANY -SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR -ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR -LOSS OF GOOD WILL, WORK STOPPAGE, COMPUTER FAILURE OR -MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR -LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE -POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY -SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY -RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT -APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME -JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF -INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND -LIMITATION MAY NOT APPLY TO YOU. - -10.0 U .S. GOVERNMENT END USERS U.S. Government: If this -Software is being acquired by or on behalf of the U.S. -Government or by a U.S. Government prime contractor or -subcontractor (at any tier), then the Government's rights in -the Software and accompanying documentation shall be only as -set forth in this license; this is in accordance with 48 C.F -.R. 227.7201 through 227.7202-4 (for Department of Defense -(DoD) acquisitions )and with 48 C.F.R.2.101 and 12.212( for -non-DoD acquisitions). - -11.0 MISCELLANEOUS This License represents the complete -agreement concerning subject matter hereof. If any -provision of this License is held to be unenforceable, such -provision shall be reformed only to the extent necessary to -make it enforceable. This License shall be governed by -California law provisions (except to the extent applicable -law, if any, provides otherwise), excluding its -conflict-of-law provisions. With respect to disputes in -which at least one party is a citizen of, or an entity -chartered or registered to do business in the United States -of America, any litigation relating to this License shall be -subject to the jurisdiction of the Federal Courts of the -Northern District of California, with venue lying in Santa -Clara County, California, with the losing party responsible -for costs, including without limitation, court costs and -reasonable attorneys fees and expenses. The application of -the United Nations Convention on Contracts for the -International Sale of Goods is expressly excluded. Any law -or regulation which provides that the language of a contract -shall be construed against the drafter shall not apply to -this License. - -EXHIBIT A - Sun Standards - -"The contents of this file are subject to the Sun Standards -License Version 1.0 the (the "License";) You may not use -this file except in compliance with the License. You may -obtain a copy of the License at -_______________________________. - - Software distributed under the License is distributed on -an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either -express or implied. See the License for the specific -language governing rights and limitations under the License. - -The Original Code is Copyright 1998 by Sun Microsystems, Inc - -The Initial Developer of the Original Code is: Sun -Microsystems, Inc. - -Portions created by _____________________________ are -Copyright ______________________________. - -All Rights Reserved. - -Contributors: ______________________________________. - -EXHIBIT B - Sun Standards - -The Standard is defined as the following IETF RFCs: - -RFC1831: RPC: Remote Procedure Call Protocol Specification -Version 2 RFC1832: XDR: External Data REpresentation -Standard RFC1833: Binding Protocols for ONC RPC Version 2 -RFC2078: Generic Security Service Application Program -Interface, Version 2 RFC2203: RPCSEC_GSS Protocol -Specification RFC2695: Authentication Mechanisms for ONC RPC diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc deleted file mode 100644 index db0b8ad..0000000 --- a/lib/libc/rpc/Makefile.inc +++ /dev/null @@ -1,179 +0,0 @@ -# @(#)Makefile 5.11 (Berkeley) 9/6/90 -# $FreeBSD$ - -.PATH: ${.CURDIR}/rpc ${.CURDIR}/. -SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \ - clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \ - clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \ - getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \ - pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \ - rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \ - rpcb_st_xdr.c rpcsec_gss_stub.c svc.c svc_auth.c svc_dg.c \ - svc_auth_unix.c svc_generic.c svc_raw.c svc_run.c svc_simple.c \ - svc_vc.c - -# Secure-RPC -SRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \ - crypt_client.c key_call.c key_prot_xdr.c getpublickey.c \ - svc_auth_des.c - -# Resolver stuff -SRCS+= netname.c netnamer.c rpcdname.c - -# Misc Source -SRCS+= rtime.c - -# generated sources -SRCS+= crypt_clnt.c crypt_xdr.c crypt.h - -SYM_MAPS+=${.CURDIR}/rpc/Symbol.map - -CFLAGS+= -DBROKEN_DES -DPORTMAP -DDES_BUILTIN -CFLAGS+= -I${.CURDIR}/rpc - -CLEANFILES+= crypt_clnt.c crypt_xdr.c crypt.h - -RPCDIR= ${DESTDIR}/usr/include/rpcsvc -RPCGEN= rpcgen -C - -crypt_clnt.c: ${RPCDIR}/crypt.x crypt.h - ${RPCGEN} -l -o ${.TARGET} ${RPCDIR}/crypt.x - -crypt_xdr.c: ${RPCDIR}/crypt.x crypt.h - ${RPCGEN} -c -o ${.TARGET} ${RPCDIR}/crypt.x - -crypt.h: ${RPCDIR}/crypt.x - ${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/crypt.x -MAN+= bindresvport.3 des_crypt.3 getnetconfig.3 getnetpath.3 getrpcent.3 \ - getrpcport.3 rpc.3 rpc_soc.3 rpc_clnt_auth.3 rpc_clnt_calls.3 \ - rpc_clnt_create.3 rpc_svc_calls.3 rpc_svc_create.3 rpc_svc_err.3 \ - rpc_svc_reg.3 rpc_xdr.3 rpcbind.3 publickey.3 rpc_secure.3 \ - rtime.3 -MAN+= publickey.5 rpc.5 netconfig.5 -MLINKS+= bindresvport.3 bindresvport_sa.3 \ - des_crypt.3 ecb_crypt.3 \ - des_crypt.3 cbc_crypt.3 \ - des_crypt.3 des_setparity.3 \ - getnetconfig.3 setnetconfig.3 \ - getnetconfig.3 getnetconfigent.3 \ - getnetconfig.3 freenetconfigent.3 \ - getnetconfig.3 endnetconfig.3 \ - getnetconfig.3 nc_perror.3 \ - getnetconfig.3 nc_sperror.3 \ - getnetpath.3 setnetpath.3 \ - getnetpath.3 endnetpath.3 \ - getrpcent.3 getrpcbyname.3 \ - getrpcent.3 getrpcbynumber.3 \ - getrpcent.3 endrpcent.3 \ - getrpcent.3 setrpcent.3 \ - publickey.3 getpublickey.3 \ - publickey.3 getsecretkey.3 \ - rpc_clnt_auth.3 auth_destroy.3 \ - rpc_clnt_auth.3 authnone_create.3 \ - rpc_clnt_auth.3 authsys_create.3 \ - rpc_clnt_auth.3 authsys_create_default.3 \ - rpc_clnt_calls.3 clnt_call.3 \ - rpc_clnt_calls.3 clnt_perrno.3 \ - rpc_clnt_calls.3 clnt_perror.3 \ - rpc_clnt_calls.3 clnt_sperrno.3 \ - rpc_clnt_calls.3 clnt_sperror.3 \ - rpc_clnt_calls.3 rpc_call.3 \ - rpc_clnt_calls.3 rpc_broadcast.3 \ - rpc_clnt_calls.3 rpc_broadcast_exp.3 \ - rpc_clnt_calls.3 clnt_freeres.3 \ - rpc_clnt_calls.3 clnt_geterr.3 \ - rpc_clnt_create.3 clnt_control.3 \ - rpc_clnt_create.3 clnt_create.3 \ - rpc_clnt_create.3 clnt_create_timed.3 \ - rpc_clnt_create.3 clnt_create_vers.3 \ - rpc_clnt_create.3 clnt_create_vers_timed.3 \ - rpc_clnt_create.3 clnt_destroy.3 \ - rpc_clnt_create.3 clnt_pcreateerror.3 \ - rpc_clnt_create.3 clnt_spcreateerror.3 \ - rpc_clnt_create.3 clnt_dg_create.3 \ - rpc_clnt_create.3 clnt_raw_create.3 \ - rpc_clnt_create.3 clnt_tli_create.3 \ - rpc_clnt_create.3 clnt_tp_create.3 \ - rpc_clnt_create.3 clnt_tp_create_timed.3 \ - rpc_clnt_create.3 clnt_vc_create.3 \ - rpc_secure.3 authdes_create.3 \ - rpc_secure.3 authdes_getucred.3 \ - rpc_secure.3 getnetname.3 \ - rpc_secure.3 host2netname.3 \ - rpc_secure.3 key_decryptsession.3 \ - rpc_secure.3 key_encryptsession.3 \ - rpc_secure.3 key_gendes.3 \ - rpc_secure.3 key_setsecret.3 \ - rpc_secure.3 netname2host.3 \ - rpc_secure.3 netname2user.3 \ - rpc_secure.3 user2netname.3 \ - rpc_svc_calls.3 svc_dg_enablecache.3 \ - rpc_svc_calls.3 svc_exit.3 \ - rpc_svc_calls.3 svc_freeargs.3 \ - rpc_svc_calls.3 svc_getargs.3 \ - rpc_svc_calls.3 svc_getreq_common.3 \ - rpc_svc_calls.3 svc_getreq_poll.3 \ - rpc_svc_calls.3 svc_getreqset.3 \ - rpc_svc_calls.3 svc_getrpccaller.3 \ - rpc_svc_calls.3 __svc_getcallercreds.3 \ - rpc_svc_calls.3 svc_pollset.3 \ - rpc_svc_calls.3 svc_run.3 \ - rpc_svc_calls.3 svc_sendreply.3 \ - rpc_svc_create.3 svc_control.3 \ - rpc_svc_create.3 svc_create.3 \ - rpc_svc_create.3 svc_dg_create.3 \ - rpc_svc_create.3 svc_destroy.3 \ - rpc_svc_create.3 svc_fd_create.3 \ - rpc_svc_create.3 svc_raw_create.3 \ - rpc_svc_create.3 svc_tli_create.3 \ - rpc_svc_create.3 svc_tp_create.3 \ - rpc_svc_create.3 svc_vc_create.3 \ - rpc_svc_err.3 svcerr_auth.3 \ - rpc_svc_err.3 svcerr_decode.3 \ - rpc_svc_err.3 svcerr_noproc.3 \ - rpc_svc_err.3 svcerr_noprog.3 \ - rpc_svc_err.3 svcerr_progvers.3 \ - rpc_svc_err.3 svcerr_systemerr.3 \ - rpc_svc_err.3 svcerr_weakauth.3 \ - rpc_svc_reg.3 rpc_reg.3 \ - rpc_svc_reg.3 svc_reg.3 \ - rpc_svc_reg.3 svc_unreg.3 \ - rpc_svc_reg.3 svc_auth_reg.3 \ - rpc_svc_reg.3 xprt_register.3 \ - rpc_svc_reg.3 xprt_unregister.3 \ - rpcbind.3 rpcb_getmaps.3 \ - rpcbind.3 rpcb_getaddr.3 \ - rpcbind.3 rpcb_gettime.3 \ - rpcbind.3 rpcb_rmtcall.3 \ - rpcbind.3 rpcb_set.3 \ - rpcbind.3 rpcb_unset.3 \ - rpc_soc.3 authunix_create.3 \ - rpc_soc.3 authunix_create_default.3 \ - rpc_soc.3 callrpc.3 \ - rpc_soc.3 clnt_broadcast.3 \ - rpc_soc.3 clntraw_create.3 \ - rpc_soc.3 clnttcp_create.3 \ - rpc_soc.3 clntunix_create.3 \ - rpc_soc.3 clntudp_bufcreate.3 \ - rpc_soc.3 clntudp_create.3 \ - rpc_soc.3 get_myaddress.3 \ - rpc_soc.3 pmap_getmaps.3 \ - rpc_soc.3 pmap_getport.3 \ - rpc_soc.3 pmap_rmtcall.3 \ - rpc_soc.3 pmap_set.3 \ - rpc_soc.3 pmap_unset.3 \ - rpc_soc.3 registerrpc.3 \ - rpc_soc.3 rpc_createerr.3 \ - rpc_soc.3 svc_fds.3 \ - rpc_soc.3 svc_fdset.3 \ - rpc_soc.3 svc_getcaller.3 \ - rpc_soc.3 svc_register.3 \ - rpc_soc.3 svc_unregister.3 \ - rpc_soc.3 svcfd_create.3 \ - rpc_soc.3 svcunixfd_create.3 \ - rpc_soc.3 svcraw_create.3 \ - rpc_soc.3 svctcp_create.3 \ - rpc_soc.3 svcudp_bufcreate.3 \ - rpc_soc.3 svcunix_create.3 \ - rpc_soc.3 xdr_pmap.3 \ - rpc_soc.3 xdr_pmaplist.3 diff --git a/lib/libc/rpc/PSD.doc/nfs.rfc.ms b/lib/libc/rpc/PSD.doc/nfs.rfc.ms deleted file mode 100644 index 13d7619..0000000 --- a/lib/libc/rpc/PSD.doc/nfs.rfc.ms +++ /dev/null @@ -1,1374 +0,0 @@ -.\" -.\" Must use -- tbl -- with this one -.\" -.\" @(#)nfs.rfc.ms 2.2 88/08/05 4.0 RPCSRC -.\" $FreeBSD$ -.\" -.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<MAXNAMLEN>; -.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<MAXPATHLEN>; -.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<NFS_MAXDATA>; - 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<NFS_MAXDATA>; -}; - -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<MNTPATHLEN>; -.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<MNTNAMLEN>; -.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/lib/libc/rpc/PSD.doc/rpc.prog.ms b/lib/libc/rpc/PSD.doc/rpc.prog.ms deleted file mode 100644 index 8b79130..0000000 --- a/lib/libc/rpc/PSD.doc/rpc.prog.ms +++ /dev/null @@ -1,2686 +0,0 @@ -.\" -.\" Must use -- tbl and pic -- with this one -.\" -.\" @(#)rpc.prog.ms 2.3 88/08/11 4.0 RPCSRC -.\" $FreeBSD$ -.\" -.de BT -.if \\n%=1 .tl ''- % -'' -.. -.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 "Network Programming" "" "" "" PAGE MAJOR -.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 <stdio.h> - -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\fR -.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 <stdio.h> -#include <rpc/rpc.h> -#include <utmp.h> -#include <rpcsvc/rusers.h> - -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 <rpc/clnt.h> . -.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 <stdio.h> -#include <rpc/rpc.h> -#include <utmp.h> -#include <rpcsvc/rusers.h> - -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 daemon -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 <rpc/rpc.h> - -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 <stdio.h> -#include <rpc/rpc.h> -#include <utmp.h> -#include <rpcsvc/rusers.h> - -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 <stdio.h> -#include <rpc/rpc.h> -#include <utmp.h> -#include <rpcsvc/rusers.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netdb.h> - -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 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 <rpc/pmap_clnt.h> - . . . -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 <stdio.h> -#include <rpc/rpc.h> -#include <suntool/windows.h> - -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 <stdio.h> -#include <rpc/rpc.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netdb.h> -#include <suntool/windows.h> - -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 <sys/time.h> -#include <rpc/auth_des.h> - . . . - . . . -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\en", - 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 <stdio.h> -#include <rpc/rpc.h> - -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 <stdio.h> -#include <netdb.h> -#include <rpc/rpc.h> -#include <sys/socket.h> -#include <sys/time.h> - -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 <stdio.h> -#include <rpc/rpc.h> - -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 <stdio.h> -#include <rpc/rpc.h> -#include <sys/socket.h> - -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 <stdio.h> -#include <rpc/rpc.h> - -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 <stdio.h> -#include <rpc/rpc.h> -#include <sys/signal.h> - -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/lib/libc/rpc/PSD.doc/rpc.rfc.ms b/lib/libc/rpc/PSD.doc/rpc.rfc.ms deleted file mode 100644 index 9a948bd..0000000 --- a/lib/libc/rpc/PSD.doc/rpc.rfc.ms +++ /dev/null @@ -1,1304 +0,0 @@ -.\" -.\" Must use -- tbl -- with this one -.\" -.\" @(#)rpc.rfc.ms 2.2 88/08/05 4.0 RPCSRC -.\" $FreeBSD$ -.\" -.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<MAXNETNAMELEN>; /* \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/lib/libc/rpc/PSD.doc/rpcgen.ms b/lib/libc/rpc/PSD.doc/rpcgen.ms deleted file mode 100644 index e663e7f..0000000 --- a/lib/libc/rpc/PSD.doc/rpcgen.ms +++ /dev/null @@ -1,1301 +0,0 @@ -.\" -.\" Must use -- tbl -- for this one -.\" -.\" @(#)rpcgen.ms 2.2 88/08/04 4.0 RPCSRC -.\" $FreeBSD$ -.\" -.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 <stdio.h> - -main(argc, argv) - int argc; - char *argv[]; -{ - char *message; - - if (argc < 2) { - fprintf(stderr, "usage: %s <message>\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 <stdio.h> -#include <rpc/rpc.h> /* \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 <stdio.h> -#include <rpc/rpc.h> /* \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<MAXNAMELEN>; /* \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 <rpc/rpc.h> -#include <sys/dir.h> -#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 <stdio.h> -#include <rpc/rpc.h> /* \fIalways need this\fP */ -#include "dir.h" /* \fIwill be generated by rpcgen\fP */ - -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/lib/libc/rpc/PSD.doc/stubs b/lib/libc/rpc/PSD.doc/stubs deleted file mode 100644 index 78b0a2c..0000000 --- a/lib/libc/rpc/PSD.doc/stubs +++ /dev/null @@ -1,3 +0,0 @@ -.\" $FreeBSD$ -.\" -.if t .ftr L CR diff --git a/lib/libc/rpc/PSD.doc/xdr.nts.ms b/lib/libc/rpc/PSD.doc/xdr.nts.ms deleted file mode 100644 index 260c7f3..0000000 --- a/lib/libc/rpc/PSD.doc/xdr.nts.ms +++ /dev/null @@ -1,1968 +0,0 @@ -.\" -.\" Must use -- eqn -- with this one -.\" -.\" @(#)xdr.nts.ms 2.2 88/08/05 4.0 RPCSRC -.\" $FreeBSD$ -.\" -.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 <rpc/rpc.h> , -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 <stdio.h> -.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 <stdio.h> -.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 <stdio.h> -#include <rpc/rpc.h> /* \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 <stdio.h> -#include <rpc/rpc.h> /* \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 <rpc/xdr.h> , -automatically included by -.I <rpc/rpc.h> . -.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 <stdio.h> -#include <rpc/rpc.h> /* \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 <rpc/rpc.h> -.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 <rpc/rpc.h> /* \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 an 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/lib/libc/rpc/PSD.doc/xdr.rfc.ms b/lib/libc/rpc/PSD.doc/xdr.rfc.ms deleted file mode 100644 index 480a339..0000000 --- a/lib/libc/rpc/PSD.doc/xdr.rfc.ms +++ /dev/null @@ -1,1060 +0,0 @@ -.\" -.\" Must use -- tbl -- with this one -.\" -.\" @(#)xdr.rfc.ms 2.2 88/08/05 4.0 RPCSRC -.\" $FreeBSD$ -.\" -.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' -.if \n%=1 .bp -.SH -\&External Data Representation Standard: Protocol Specification -.IX "External Data Representation" -.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<m>; -.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<m>; -.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<m>; -.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 <<struct, union, or enum definition>> 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<MAXNAMELEN>; /*\fI data creator \fP*/ - case EXEC: - string interpretor<MAXNAMELEN>; /*\fI program interpretor \fP*/ -}; - -.ft I -/* - * A complete file: - */ -.ft CW - -struct file { - string filename<MAXNAMELEN>; /*\fI name of file \fP*/ - filetype type; /*\fI info about file \fP*/ - string owner<MAXUSERNAME>; /*\fI owner of file \fP*/ - opaque data<MAXFILELEN>; /*\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/lib/libc/rpc/README b/lib/libc/rpc/README deleted file mode 100644 index c915fad..0000000 --- a/lib/libc/rpc/README +++ /dev/null @@ -1,176 +0,0 @@ -$FreeBSD$ - -PLEASE READ THE DISCLAIMER FILE. DO NOT CALL THE SUN MICROSYSTEMS SUPPORT -LINE WITH QUESTIONS ON THIS RELEASE. THEY CANNOT ANSWER QUESTIONS ABOUT THIS -UNSUPPORTED SOURCE RELEASE. - -TIRPCSRC 2.3 29 Aug 1994 - -This distribution contains SunSoft's implementation of transport-independent -RPC (TI-RPC), External Data Representation (XDR), and various utilities and -documentation. These libraries and programs form the base of Open Network -Computing (ONC), and are derived directly from the Solaris 2.3 source. - -Previous releases of RPC Source based on SunOS 4.x were ported to 4.2BSD and -used Sockets as the transport interface. These versions were -transport-specific RPC (TS-RPC). - -TI-RPC is an enhanced version of TS-RPC that requires the UNIX System V -Transport Layer Interface (TLI) or an equivalent X/Open Transport Interface -(XTI). TI-RPC is on-the-wire compatible with the TS-RPC, which is supported -by almost 70 vendors on all major operating systems. TS-RPC source code -(RPCSRC 4.0) remains available from several internet sites. - -This release is a native source release, that is, it is compatible for -building on Solaris 2.3. This release was built on Solaris 2.3 using SunPro -SPARCompiler 2.0.1. - -Solaris 2.3 is based on System V, Release 4 (SVR4), and while this release -should be mostly compatible with other SVR4 systems, some Solaris facilities -that are assumed may not be available. In particular, this release uses the -Makefile format supported by SparcCompiler 2.0.1. Second, the Secure RPC -routines use the Solaris Name Service Switch to access public-key credential -databases. This code will need to be ported if your system does not support -the Name Service Switch. Finally, this release uses the synchronization -interfaces of UI Threads to make certain interfaces thread-safe. These -interfaces are found in libthread in Solaris 2.3 and later. - -Applications linked with this release's librpc must link with the United -States domestic version of libcrypt in order to resolve the cbc_crypt() and -ecb_crypt() functions. These routines are used with Secure RPC however all -RPC programs that link with this release's librpc will need to link with the -domestic libcrypt. Note that the Solaris 2.3 Encryption Kit is only available -within the United States. (PLEASE NOTE: The RPC implementation found in -Solaris 2.3's libnsl does *not* have this requirement; linking with libcrypt -is only a requirement for the TIRPCSRC 2.3 version of librpc.) - - -DOCUMENTATION NOTE - -The documentation found in the doc directory are derived from the Solaris 2.3 -Network Interfaces Programming Guide. A small number of compile examples are -given, and these use libnsl to link in the RPC library. This release builds -the RPC library as librpc. To use this release's librpc, use the link command -"-lrpc -lnsl -lcrypt". This links the application with TIRPCSRC 2.3's librpc -for RPC routines, Solaris's libnsl for other networking functions, and -libcrypt for the cbc_crypt() and ecb_crypt functions. - - -WHY IS THIS RELEASE BEING DONE? - -This release is being distributed to make the Sun implementation of the ONC -technologies available for reference and porting to non-Solaris platforms. -The current release is a native source distribution, and provides services -that are already available on Solaris 2.3 (such as the RPC headers, the RPC -library in libnsl, rpcbind, rpcinfo, etc.). It is not our intention to -replace these services. See the DISCLAIMER for further information about the -legal status of this release. - - -WHAT'S NEW IN THIS RELEASE: TIRPCSRC 2.3 - -The previous release was TIRPCSRC 2.0. - -1. This release is based on Solaris 2.3. The previous release was - based on Solaris 2.0. This release contains a siginificant number of - bug fixes and other enhancements over TIRPCSRC 2.0. - -2. The RPC library is thread safe for all client-side interfaces - (clnt_create, clnt_call, etc.). The server-side interfaces - (svc_create, svc_run, etc.) are not thread safe in this release. The - server-side interfaces will be made thread safe in the next release of - TIRPCSRC. Please see the manual pages for details about which - interfaces are thread safe. - -3. As part of the work to make the RPC library thread-safe, rpcgen has - been enhanced to generate thread-safe RPC stubs (the -M option). Note - that this modifies the call-signature for the stub functions; the - procedure calling the RPC stub must now pass to the stub a pointer to - an allocated structure where results will be placed by the stub. See - the rpcgen manual page and the rpcgen Programming Guide for details. - -4. The Remote Asynchronous Calls (RAC) library is now included. RAC was - first introduced in TIRPCSRC 1.0, and was bundled with librpc. It is - now a separate library. The asynchronous call model that RAC provides - can be achieved by using threads for making client-side RPC calls. - The ONC Technology group recommends using threads (where possible) to - achieve asynchrony rather than RAC. See the rpc_rac(3n) manual page - for details. - - -ROADMAP - -The directory hierarchy is as follows: - - cmd/ Utilities - cmd/rpcgen The RPC Language compiler (for .x files) - cmd/rpcbind The RPC bindery and portmapper - cmd/rpcinfo RPC bindery query utility - cmd/keyserv The Secure RPC keyserver - cmd/demo Some simple ONC demo services - - doc/ Postscript versions of ONC documentation - - head/ Header files - head/rpcsvc RPCL (.x) specifications for various ONC services, and - header files. - - lib/ Libraries - lib/librpc The RPC and XDR library - lib/librac The Remote Asynchronous Calls (RAC) library - - man/ Manual pages for the RPC library and utilities. - - uts/common/rpc RPC header files - - - -BUILD INSTRUCTIONS - -Prior to building the release, you must define the SRC environment variable -to be the path to the top-level Makefile. For example, if /usr/src/tirpcsrc -is where to top-level Makefile is located, execute this command prior to -building the release: - - setenv SRC /usr/src/tirpcsrc (csh) -or - SRC=/usr/src/tirpcsrc; export SRC (sh) - -The sources in the lib directory depend on header files installed from head -and uts/common/rpc, and the programs in the cmd directory depend on libraries -from lib. Therefore, you should do a "make install" to build the release. - -The top-level Makefile builds the release. The "ROOT" macro defines where the -headers and libraries are installed. The default for ROOT is "/proto". You -may change this by either modifiying Makefile.master, or issuing the build -command with a new definition for ROOT: - - make install ROOT=/opt/onc - -You will of course need write privileges for the destination directory. -The headers, libraries and executables will be built and installed under the -ROOT. - - -The demonstration services in the demo directory are not built by the -top-level "make install" command. To build these, cd to the cmd/demo -directory and enter "make". The four services will be built. -RPCGEN MUST BE INSTALLED in a path that make can find. To run the -services, rpcbind must be running, then 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 -rpcbind, and to ping the service (see rpcinfo's man page). You can -then use the corresponding client program to exercise the service. - - -BUILDING ONC APPLICATIONS - -See the Makefiles in the demonstration services for examples of building -ONC applications with this release. The $(ROOT)/usr/include directory -must be included in the compiler header file search path (-I), and the -$(ROOT)/usr/lib directory must be included in the linker library file search -path (-L). Also, to run executables built dynamically, the shared library -search path (LD_LIBRARY_PATH) must also include $(ROOT)/usr/lib. In addition -to linking in this release's librpc (via -lrpc), you must also link with -Solaris's libnsl (-lnsl) and the US domestic version of libcrypt (-lcrypt). - diff --git a/lib/libc/rpc/Symbol.map b/lib/libc/rpc/Symbol.map deleted file mode 100644 index 4f356de..0000000 --- a/lib/libc/rpc/Symbol.map +++ /dev/null @@ -1,247 +0,0 @@ -/* - * $FreeBSD$ - */ - -FBSD_1.0 { - /* From crypt_clnt.c (generated by rpcgen - include/rpcsvc/crypt.x) */ - des_crypt_1; - - /* From crypt_xdr.c (generated by rpcgen - include/rpcsvc/crypt.x) */ - xdr_des_dir; - xdr_des_mode; - xdr_desargs; - xdr_desresp; - - /* From yp_xdr.c (generated by rpcgen - include/rpcsvc/yp.x) */ - xdr_domainname; - xdr_keydat; - xdr_mapname; - xdr_peername; - xdr_valdat; - xdr_ypbind_binding; - xdr_ypbind_resp; - xdr_ypbind_resptype; - xdr_ypbind_setdom; - xdr_ypmap_parms; - xdr_ypmaplist; - xdr_yppush_status; - xdr_yppushresp_xfr; - xdr_ypreq_key; - xdr_ypreq_nokey; - xdr_ypreq_xfr; - xdr_ypreqtype; - xdr_yprequest; - xdr_ypresp_all; - xdr_ypresp_key_val; - xdr_ypresp_maplist; - xdr_ypresp_master; - xdr_ypresp_order; - xdr_ypresp_val; - xdr_ypresp_xfr; - xdr_ypresponse; - xdr_ypresptype; - xdr_ypstat; - xdr_ypxfrstat; - - authdes_seccreate; - authdes_pk_seccreate; - authnone_create; - authunix_create; - authunix_create_default; - xdr_authdes_cred; - xdr_authdes_verf; - xdr_authunix_parms; - bindresvport; - bindresvport_sa; - rpc_broadcast_exp; - rpc_broadcast; - clnt_dg_create; - clnt_create_vers; - clnt_create_vers_timed; - clnt_create; - clnt_create_timed; - clnt_tp_create; - clnt_tp_create_timed; - clnt_tli_create; - clnt_sperror; - clnt_perror; - clnt_sperrno; - clnt_perrno; - clnt_spcreateerror; - clnt_pcreateerror; - clnt_raw_create; - rpc_call; - clnt_vc_create; - cbc_crypt; - ecb_crypt; - des_setparity; - setnetconfig; - getnetconfig; - endnetconfig; - getnetconfigent; - freenetconfigent; - nc_sperror; - nc_perror; - setnetpath; - getnetpath; - endnetpath; - getpublicandprivatekey; - getpublickey; - getrpcbynumber; - getrpcbyname; - setrpcent; - endrpcent; - getrpcent; - getrpcport; - key_setsecret; - key_secretkey_is_set; - key_encryptsession_pk; - key_decryptsession_pk; - key_encryptsession; - key_decryptsession; - key_gendes; - key_setnet; - key_get_conv; - xdr_keystatus; - xdr_keybuf; - xdr_netnamestr; - xdr_cryptkeyarg; - xdr_cryptkeyarg2; - xdr_cryptkeyres; - xdr_unixcred; - xdr_getcredres; - xdr_key_netstarg; - xdr_key_netstres; - rpc_createerr; - __rpc_createerr; - getnetname; - user2netname; - host2netname; - netname2user; - netname2host; - pmap_set; - pmap_unset; - pmap_getmaps; - pmap_getport; - xdr_pmap; - xdr_pmaplist; - xdr_pmaplist_ptr; - pmap_rmtcall; - xdr_rmtcall_args; - xdr_rmtcallres; - xdr_callmsg; - _null_auth; - svc_fdset; - svc_maxfd; - _rpc_dtablesize; - __rpc_get_t_size; - __rpc_getconfip; - __rpc_setconf; - __rpc_getconf; - __rpc_endconf; - rpc_nullproc; - __rpc_fd2sockinfo; - __rpc_nconf2sockinfo; - __rpc_nconf2fd; - taddr2uaddr; - uaddr2taddr; - xdr_opaque_auth; - xdr_des_block; - xdr_accepted_reply; - xdr_rejected_reply; - xdr_replymsg; - xdr_callhdr; - _seterr_reply; - clntudp_bufcreate; - clntudp_create; - clnttcp_create; - clntraw_create; - svctcp_create; - svcudp_bufcreate; - svcfd_create; - svcudp_create; - svcraw_create; - get_myaddress; - callrpc; - registerrpc; - clnt_broadcast; - authdes_create; - clntunix_create; - svcunix_create; - svcunixfd_create; - rpcb_set; - rpcb_unset; - rpcb_getaddr; - rpcb_getmaps; - rpcb_rmtcall; - rpcb_gettime; - rpcb_taddr2uaddr; - rpcb_uaddr2taddr; - xdr_rpcb; - xdr_rpcblist_ptr; - xdr_rpcblist; - xdr_rpcb_entry; - xdr_rpcb_entry_list_ptr; - xdr_rpcb_rmtcallargs; - xdr_rpcb_rmtcallres; - xdr_netbuf; - xdr_rpcbs_addrlist; - xdr_rpcbs_rmtcalllist; - xdr_rpcbs_proc; - xdr_rpcbs_addrlist_ptr; - xdr_rpcbs_rmtcalllist_ptr; - xdr_rpcb_stat; - xdr_rpcb_stat_byvers; - rtime; - xprt_register; - xprt_unregister; - svc_reg; - svc_unreg; - svc_register; - svc_unregister; - svc_sendreply; - svcerr_noproc; - svcerr_decode; - svcerr_systemerr; - svcerr_auth; - svcerr_weakauth; - svcerr_noprog; - svcerr_progvers; - svc_getreq; - svc_getreqset; - svc_getreq_common; - svc_getreq_poll; - rpc_control; - _authenticate; - _svcauth_null; - svc_auth_reg; - _svcauth_des; - authdes_getucred; - _svcauth_unix; - _svcauth_short; - svc_dg_create; - svc_dg_enablecache; - svc_create; - svc_tp_create; - svc_tli_create; - __rpc_rawcombuf; - svc_raw_create; - svc_run; - svc_exit; - rpc_reg; - svc_vc_create; - svc_fd_create; - __rpc_get_local_uid; -}; - -FBSDprivate_1.0 { - __des_crypt_LOCAL; - __key_encryptsession_pk_LOCAL; - __key_decryptsession_pk_LOCAL; - __key_gendes_LOCAL; - __svc_clean_idle; - __rpc_gss_unwrap; - __rpc_gss_unwrap_stub; - __rpc_gss_wrap; - __rpc_gss_wrap_stub; -}; diff --git a/lib/libc/rpc/auth_des.c b/lib/libc/rpc/auth_des.c deleted file mode 100644 index 8f363e9..0000000 --- a/lib/libc/rpc/auth_des.c +++ /dev/null @@ -1,498 +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 "namespace.h" -#include "reentrant.h" -#include <err.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/cdefs.h> -#include <rpc/des_crypt.h> -#include <syslog.h> -#include <rpc/types.h> -#include <rpc/auth.h> -#include <rpc/auth_des.h> -#include <rpc/clnt.h> -#include <rpc/xdr.h> -#include <sys/socket.h> -#undef NIS -#include <rpcsvc/nis.h> -#include "un-namespace.h" -#include "mt_misc.h" - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#define USEC_PER_SEC 1000000 -#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) - -extern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *); -extern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *); -extern int key_encryptsession_pk(); - -extern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *, - char **, char **); - -/* - * DES authenticator operations vector - */ -static void authdes_nextverf(AUTH *); -static bool_t authdes_marshal(AUTH *, XDR *); -static bool_t authdes_validate(AUTH *, struct opaque_auth *); -static bool_t authdes_refresh(AUTH *, void *); -static void authdes_destroy(AUTH *); - -static struct auth_ops *authdes_ops(void); - -/* - * 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 netbuf 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_int 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 */ -}; - -AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *, - const des_block *, nis_server *); - -/* - * documented version of authdes_seccreate - */ -/* - servername: network name of server - win: time to live - timehost: optional hostname to sync with - ckey: optional conversation key to use -*/ - -AUTH * -authdes_seccreate(const char *servername, const u_int win, - const char *timehost, const des_block *ckey) -{ - u_char pkey_data[1024]; - netobj pkey; - AUTH *dummy; - - if (! getpublickey(servername, (char *) pkey_data)) { - syslog(LOG_ERR, - "authdes_seccreate: no public key found for %s", - servername); - return (NULL); - } - - pkey.n_bytes = (char *) pkey_data; - pkey.n_len = (u_int)strlen((char *)pkey_data) + 1; - dummy = authdes_pk_seccreate(servername, &pkey, win, timehost, - ckey, NULL); - return (dummy); -} - -/* - * Slightly modified version of authdessec_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_seccreate(const char *servername, netobj *pkey, u_int window, - const char *timehost, const des_block *ckey, nis_server *srvr) -{ - AUTH *auth; - struct ad_private *ad; - char namebuf[MAXNETNAMELEN+1]; - - /* - * Allocate everything now - */ - auth = ALLOC(AUTH); - if (auth == NULL) { - syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); - return (NULL); - } - ad = ALLOC(struct ad_private); - if (ad == NULL) { - syslog(LOG_ERR, "authdes_pk_seccreate: 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) { - syslog(LOG_ERR, "authdes_seccreate: out of memory"); - goto failed; - } - if (timehost != NULL) { - ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); - if (ad->ad_timehost == NULL) { - syslog(LOG_ERR, "authdes_seccreate: 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) { - syslog(LOG_ERR, - "authdes_seccreate: keyserv(1m) is unable to generate session 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, NULL)) { - 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, strlen(ad->ad_netid) + 1); - if (ad->ad_uaddr) - FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); - FREE(ad, sizeof (struct ad_private)); - } - return (NULL); -} - -/* - * Implement the five authentication operations - */ - - -/* - * 1. Next Verifier - */ -/*ARGSUSED*/ -static void -authdes_nextverf(AUTH *auth) -{ - /* what the heck am I supposed to do??? */ -} - - -/* - * 2. Marshal - */ -static bool_t -authdes_marshal(AUTH *auth, XDR *xdrs) -{ -/* LINTED pointer alignment */ - 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; - int len; - rpc_inline_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; - while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) { - ad->ad_timestamp.tv_usec -= USEC_PER_SEC; - ad->ad_timestamp.tv_sec++; - } - - /* - * XDR the timestamp and possibly some other things, then - * encrypt them. - */ - ixdr = (rpc_inline_t *)cryptbuf; - IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec); - IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec); - if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { - IXDR_PUT_U_INT32(ixdr, ad->ad_window); - IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1); - ivec.key.high = ivec.key.low = 0; - status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf, - (u_int) 2 * sizeof (des_block), - DES_ENCRYPT | DES_HW, (char *)&ivec); - } else { - status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf, - (u_int) sizeof (des_block), - DES_ENCRYPT | DES_HW); - } - if (DES_FAILED(status)) { - syslog(LOG_ERR, "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_INT32(ixdr, AUTH_DES); - IXDR_PUT_INT32(ixdr, len); - } else { - ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor)); - ATTEMPT(xdr_putint32(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_INT32(ixdr, AUTH_DES); - IXDR_PUT_INT32(ixdr, len); - } else { - ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor)); - ATTEMPT(xdr_putint32(xdrs, &len)); - } - ATTEMPT(xdr_authdes_verf(xdrs, verf)); - return (TRUE); -} - - -/* - * 3. Validate - */ -static bool_t -authdes_validate(AUTH *auth, struct opaque_auth *rverf) -{ -/* LINTED pointer alignment */ - struct ad_private *ad = AUTH_PRIVATE(auth); - struct authdes_verf verf; - int status; - uint32_t *ixdr; - des_block buf; - - if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) { - return (FALSE); - } -/* LINTED pointer alignment */ - ixdr = (uint32_t *)rverf->oa_base; - buf.key.high = (uint32_t)*ixdr++; - buf.key.low = (uint32_t)*ixdr++; - verf.adv_int_u = (uint32_t)*ixdr++; - - /* - * Decrypt the timestamp - */ - status = ecb_crypt((char *)&auth->ah_key, (char *)&buf, - (u_int)sizeof (des_block), DES_DECRYPT | DES_HW); - - if (DES_FAILED(status)) { - syslog(LOG_ERR, "authdes_validate: DES decryption failure"); - return (FALSE); - } - - /* - * xdr the decrypted timestamp - */ -/* LINTED pointer alignment */ - ixdr = (uint32_t *)buf.c; - verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1; - verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr); - - /* - * validate - */ - if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, - sizeof(struct timeval)) != 0) { - syslog(LOG_DEBUG, "authdes_validate: verifier mismatch"); - 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 - */ -/*ARGSUSED*/ -static bool_t -authdes_refresh(AUTH *auth, void *dummy) -{ -/* LINTED pointer alignment */ - struct ad_private *ad = AUTH_PRIVATE(auth); - struct authdes_cred *cred = &ad->ad_cred; - int ok; - netobj pkey; - - if (ad->ad_dosync) { - ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr, - ad->ad_timehost, &(ad->ad_uaddr), - &(ad->ad_netid)); - if (! ok) { - /* - * Hope the clocks are synced! - */ - ad->ad_dosync = 0; - syslog(LOG_DEBUG, - "authdes_refresh: unable to synchronize clock"); - } - } - ad->ad_xkey = auth->ah_key; - pkey.n_bytes = (char *)(ad->ad_pkey); - pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1; - if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) { - syslog(LOG_INFO, - "authdes_refresh: keyserv(1m) is unable to encrypt session 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) -{ -/* LINTED pointer alignment */ - struct ad_private *ad = AUTH_PRIVATE(auth); - - FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); - 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, strlen(ad->ad_netid) + 1); - if (ad->ad_uaddr) - FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); - FREE(ad, sizeof (struct ad_private)); - FREE(auth, sizeof(AUTH)); -} - -static struct auth_ops * -authdes_ops(void) -{ - static struct auth_ops ops; - - /* VARIABLES PROTECTED BY ops_lock: ops */ - - mutex_lock(&authdes_ops_lock); - if (ops.ah_nextverf == NULL) { - ops.ah_nextverf = authdes_nextverf; - ops.ah_marshal = authdes_marshal; - ops.ah_validate = authdes_validate; - ops.ah_refresh = authdes_refresh; - ops.ah_destroy = authdes_destroy; - } - mutex_unlock(&authdes_ops_lock); - return (&ops); -} diff --git a/lib/libc/rpc/auth_none.c b/lib/libc/rpc/auth_none.c deleted file mode 100644 index 01ad701..0000000 --- a/lib/libc/rpc/auth_none.c +++ /dev/null @@ -1,176 +0,0 @@ -/* $NetBSD: auth_none.c,v 1.13 2000/01/22 22:19:17 mycroft Exp $ */ - -/* - * 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 *sccsid2 = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * auth_none.c - * Creates a client authentication handle for passing "null" - * credentials and verifiers to remote systems. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <assert.h> -#include <stdlib.h> -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/auth.h> -#include "un-namespace.h" -#include "mt_misc.h" - -#define MAX_MARSHAL_SIZE 20 - -/* - * Authenticator operations routines - */ - -static bool_t authnone_marshal (AUTH *, XDR *); -static void authnone_verf (AUTH *); -static bool_t authnone_validate (AUTH *, struct opaque_auth *); -static bool_t authnone_refresh (AUTH *, void *); -static void authnone_destroy (AUTH *); - -extern bool_t xdr_opaque_auth(); - -static struct auth_ops *authnone_ops(); - -static struct authnone_private { - AUTH no_client; - char marshalled_client[MAX_MARSHAL_SIZE]; - u_int mcnt; -} *authnone_private; - -AUTH * -authnone_create() -{ - struct authnone_private *ap = authnone_private; - XDR xdr_stream; - XDR *xdrs; - - mutex_lock(&authnone_lock); - if (ap == 0) { - ap = (struct authnone_private *)calloc(1, sizeof (*ap)); - if (ap == 0) { - mutex_unlock(&authnone_lock); - 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 = authnone_ops(); - xdrs = &xdr_stream; - xdrmem_create(xdrs, ap->marshalled_client, - (u_int)MAX_MARSHAL_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); - } - mutex_unlock(&authnone_lock); - return (&ap->no_client); -} - -/*ARGSUSED*/ -static bool_t -authnone_marshal(AUTH *client, XDR *xdrs) -{ - struct authnone_private *ap; - bool_t dummy; - - assert(xdrs != NULL); - - ap = authnone_private; - if (ap == NULL) { - mutex_unlock(&authnone_lock); - return (FALSE); - } - dummy = (*xdrs->x_ops->x_putbytes)(xdrs, - ap->marshalled_client, ap->mcnt); - mutex_unlock(&authnone_lock); - return (dummy); -} - -/* All these unused parameters are required to keep ANSI-C from grumbling */ -/*ARGSUSED*/ -static void -authnone_verf(AUTH *client) -{ -} - -/*ARGSUSED*/ -static bool_t -authnone_validate(AUTH *client, struct opaque_auth *opaque) -{ - - return (TRUE); -} - -/*ARGSUSED*/ -static bool_t -authnone_refresh(AUTH *client, void *dummy) -{ - - return (FALSE); -} - -/*ARGSUSED*/ -static void -authnone_destroy(AUTH *client) -{ -} - -static struct auth_ops * -authnone_ops() -{ - static struct auth_ops ops; - -/* VARIABLES PROTECTED BY ops_lock: ops */ - - mutex_lock(&ops_lock); - if (ops.ah_nextverf == NULL) { - ops.ah_nextverf = authnone_verf; - ops.ah_marshal = authnone_marshal; - ops.ah_validate = authnone_validate; - ops.ah_refresh = authnone_refresh; - ops.ah_destroy = authnone_destroy; - } - mutex_unlock(&ops_lock); - return (&ops); -} diff --git a/lib/libc/rpc/auth_time.c b/lib/libc/rpc/auth_time.c deleted file mode 100644 index 7aea232..0000000 --- a/lib/libc/rpc/auth_time.c +++ /dev/null @@ -1,507 +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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <stdio.h> -#include <syslog.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <netdb.h> -#include <sys/signal.h> -#include <sys/errno.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <rpc/rpc.h> -#include <rpc/rpc_com.h> -#include <rpc/rpcb_prot.h> -#undef NIS -#include <rpcsvc/nis.h> -#include "un-namespace.h" - -extern int _rpc_dtablesize( void ); - -#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]; - endpoint *ep; - - 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, ep = eps; (he->h_addr_list[i] != NULL) && (num_ep < maxep); - i++, ep++, 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)); - ep->uaddr = strdup(hname); - ep->family = strdup("inet"); - ep->proto = strdup("tcp"); - if (ep->uaddr == NULL || ep->family == NULL || ep->proto == NULL) { - free_eps(eps, num_ep + 1); - return (NULL); - } - } - - for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep); - i++, ep++, 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)); - ep->uaddr = strdup(hname); - ep->family = strdup("inet"); - ep->proto = strdup("udp"); - if (ep->uaddr == NULL || ep->family == NULL || ep->proto == NULL) { - free_eps(eps, num_ep + 1); - return (NULL); - } - } - - 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; - socklen_t len; - int s = RPC_ANYSOCK; - 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, (xdrproc_t)xdr_void, NULL, - (xdrproc_t)xdr_u_long, &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 = _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)_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)_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/lib/libc/rpc/auth_unix.c b/lib/libc/rpc/auth_unix.c deleted file mode 100644 index ff3ca7b..0000000 --- a/lib/libc/rpc/auth_unix.c +++ /dev/null @@ -1,381 +0,0 @@ -/* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include "reentrant.h" -#include <sys/param.h> - -#include <assert.h> -#include <err.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/auth.h> -#include <rpc/auth_unix.h> -#include "un-namespace.h" -#include "mt_misc.h" - -/* auth_unix.c */ -static void authunix_nextverf (AUTH *); -static bool_t authunix_marshal (AUTH *, XDR *); -static bool_t authunix_validate (AUTH *, struct opaque_auth *); -static bool_t authunix_refresh (AUTH *, void *); -static void authunix_destroy (AUTH *); -static void marshal_new_auth (AUTH *); -static struct auth_ops *authunix_ops (void); - -/* - * 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) - -/* - * 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; - int len; - int *aup_gids; -{ - struct authunix_parms aup; - char mymem[MAX_AUTH_BYTES]; - struct timeval now; - XDR xdrs; - AUTH *auth; - struct audata *au; - - /* - * Allocate and set up auth handle - */ - au = NULL; - auth = mem_alloc(sizeof(*auth)); -#ifndef _KERNEL - if (auth == NULL) { - warnx("authunix_create: out of memory"); - goto cleanup_authunix_create; - } -#endif - au = mem_alloc(sizeof(*au)); -#ifndef _KERNEL - if (au == NULL) { - warnx("authunix_create: out of memory"); - goto cleanup_authunix_create; - } -#endif - auth->ah_ops = authunix_ops(); - auth->ah_private = (caddr_t)au; - auth->ah_verf = au->au_shcred = _null_auth; - au->au_shfaults = 0; - au->au_origcred.oa_base = NULL; - - /* - * fill in param struct from the given params - */ - (void)gettimeofday(&now, NULL); - aup.aup_time = now.tv_sec; - aup.aup_machname = machname; - aup.aup_uid = uid; - aup.aup_gid = gid; - 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) { - warnx("authunix_create: out of memory"); - goto cleanup_authunix_create; - } -#endif - memmove(au->au_origcred.oa_base, mymem, (size_t)len); - - /* - * set auth handle to reflect new cred. - */ - auth->ah_cred = au->au_origcred; - marshal_new_auth(auth); - return (auth); -#ifndef _KERNEL - cleanup_authunix_create: - if (auth) - mem_free(auth, sizeof(*auth)); - if (au) { - if (au->au_origcred.oa_base) - mem_free(au->au_origcred.oa_base, (u_int)len); - mem_free(au, sizeof(*au)); - } - return (NULL); -#endif -} - -/* - * Returns an auth handle with parameters determined by doing lots of - * syscalls. - */ -AUTH * -authunix_create_default() -{ - int ngids; - long ngids_max; - char machname[MAXHOSTNAMELEN + 1]; - uid_t uid; - gid_t gid; - gid_t *gids; - - ngids_max = sysconf(_SC_NGROUPS_MAX) + 1; - gids = malloc(sizeof(gid_t) * ngids_max); - if (gids == NULL) - return (NULL); - - if (gethostname(machname, sizeof machname) == -1) - abort(); - machname[sizeof(machname) - 1] = 0; - uid = geteuid(); - gid = getegid(); - if ((ngids = getgroups(ngids_max, gids)) < 0) - abort(); - if (ngids > NGRPS) - ngids = NGRPS; - /* XXX: interface problem; those should all have been unsigned */ - return (authunix_create(machname, (int)uid, (int)gid, ngids, - (int *)gids)); -} - -/* - * authunix operations - */ - -/* ARGSUSED */ -static void -authunix_nextverf(auth) - AUTH *auth; -{ - /* no action necessary */ -} - -static bool_t -authunix_marshal(auth, xdrs) - AUTH *auth; - XDR *xdrs; -{ - struct audata *au; - - assert(auth != NULL); - assert(xdrs != NULL); - - au = AUTH_PRIVATE(auth); - return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); -} - -static bool_t -authunix_validate(auth, verf) - AUTH *auth; - struct opaque_auth *verf; -{ - struct audata *au; - XDR xdrs; - - assert(auth != NULL); - assert(verf != NULL); - - 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 *auth, void *dummy) -{ - struct audata *au = AUTH_PRIVATE(auth); - struct authunix_parms aup; - struct timeval now; - XDR xdrs; - int stat; - - assert(auth != NULL); - - 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 = 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, NULL); - 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) - AUTH *auth; -{ - struct audata *au; - - assert(auth != NULL); - - 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(auth, sizeof(*auth)); -} - -/* - * Marshals (pre-serializes) an auth struct. - * sets private data, au_marshed and au_mpos - */ -static void -marshal_new_auth(auth) - AUTH *auth; -{ - XDR xdr_stream; - XDR *xdrs = &xdr_stream; - struct audata *au; - - assert(auth != NULL); - - 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)))) - warnx("auth_none.c - Fatal marshalling problem"); - else - au->au_mpos = XDR_GETPOS(xdrs); - XDR_DESTROY(xdrs); -} - -static struct auth_ops * -authunix_ops() -{ - static struct auth_ops ops; - - /* VARIABLES PROTECTED BY ops_lock: ops */ - - mutex_lock(&ops_lock); - if (ops.ah_nextverf == NULL) { - ops.ah_nextverf = authunix_nextverf; - ops.ah_marshal = authunix_marshal; - ops.ah_validate = authunix_validate; - ops.ah_refresh = authunix_refresh; - ops.ah_destroy = authunix_destroy; - } - mutex_unlock(&ops_lock); - return (&ops); -} diff --git a/lib/libc/rpc/authdes_prot.c b/lib/libc/rpc/authdes_prot.c deleted file mode 100644 index 5be1f12..0000000 --- a/lib/libc/rpc/authdes_prot.c +++ /dev/null @@ -1,94 +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 -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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. - */ - -/* - * authdes_prot.c, XDR routines for DES authentication - */ - -#include "namespace.h" -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/auth.h> -#include <rpc/auth_des.h> -#include "un-namespace.h" - -#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) - -bool_t -xdr_authdes_cred(xdrs, cred) - XDR *xdrs; - struct authdes_cred *cred; -{ - enum authdes_namekind *padc_namekind = &cred->adc_namekind; - /* - * Unrolled xdr - */ - ATTEMPT(xdr_enum(xdrs, (enum_t *) padc_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) - XDR *xdrs; - 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/lib/libc/rpc/authunix_prot.c b/lib/libc/rpc/authunix_prot.c deleted file mode 100644 index 7699e28..0000000 --- a/lib/libc/rpc/authunix_prot.c +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: authunix_prot.c,v 1.12 2000/01/22 22:19:17 mycroft Exp $ */ - -/* - * 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 *sccsid2 = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * authunix_prot.c - * XDR for UNIX style authentication parameters for RPC - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <assert.h> - -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/auth.h> -#include <rpc/auth_unix.h> -#include "un-namespace.h" - -/* - * XDR for unix authentication parameters. - */ -bool_t -xdr_authunix_parms(xdrs, p) - XDR *xdrs; - struct authunix_parms *p; -{ - int **paup_gids; - - assert(xdrs != NULL); - assert(p != NULL); - - paup_gids = &p->aup_gids; - - 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, (char **) paup_gids, - &(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int) ) { - return (TRUE); - } - return (FALSE); -} diff --git a/lib/libc/rpc/bindresvport.3 b/lib/libc/rpc/bindresvport.3 deleted file mode 100644 index 28e86e5..0000000 --- a/lib/libc/rpc/bindresvport.3 +++ /dev/null @@ -1,103 +0,0 @@ -.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI -.\" $NetBSD: bindresvport.3,v 1.8 2000/07/05 15:45:33 msaitoh Exp $ -.\" $FreeBSD$ -.\" -.Dd November 22, 1987 -.Dt BINDRESVPORT 3 -.Os -.Sh NAME -.Nm bindresvport , -.Nm bindresvport_sa -.Nd bind a socket to a privileged IP port -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In rpc/rpc.h -.Ft int -.Fn bindresvport "int sd" "struct sockaddr_in *sin" -.Ft int -.Fn bindresvport_sa "int sd" "struct sockaddr *sa" -.Sh DESCRIPTION -The -.Fn bindresvport -and -.Fn bindresvport_sa -functions -are used to bind a socket descriptor to a privileged -.Tn IP -port, that is, a -port number in the range 0-1023. -.Pp -If -.Fa sin -is a pointer to a -.Ft "struct sockaddr_in" -then the appropriate fields in the structure should be defined. -Note that -.Fa sin->sin_family -must be initialized to the address family of the socket, passed by -.Fa sd . -If -.Fa sin->sin_port -is -.Sq 0 -then an anonymous port (in the range 600-1023) will be -chosen, and if -.Xr bind 2 -is successful, the -.Fa sin->sin_port -will be updated to contain the allocated port. -.Pp -If -.Fa sin -is the -.Dv NULL -pointer, -an anonymous port will be allocated (as above). -However, there is no way for -.Fn bindresvport -to return the allocated port in this case. -.Pp -Only root can bind to a privileged port; this call will fail for any -other users. -.Pp -Function prototype of -.Fn bindresvport -is biased to -.Dv AF_INET -socket. -The -.Fn bindresvport_sa -function -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 -.Rv -std bindresvport -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EPFNOSUPPORT -If second argument was supplied, -and address family did not match between arguments. -.El -.Pp -The -.Fn bindresvport -function -may also fail and set -.Va errno -for any of the errors specified for the calls -.Xr bind 2 , -.Xr getsockopt 2 , -or -.Xr setsockopt 2 . -.Sh SEE ALSO -.Xr bind 2 , -.Xr getsockopt 2 , -.Xr setsockopt 2 , -.Xr ip 4 diff --git a/lib/libc/rpc/bindresvport.c b/lib/libc/rpc/bindresvport.c deleted file mode 100644 index 75a1c8f..0000000 --- a/lib/libc/rpc/bindresvport.c +++ /dev/null @@ -1,161 +0,0 @@ -/* $NetBSD: bindresvport.c,v 1.19 2000/07/06 03:03:59 christos Exp $ */ - -/* - * 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 *sccsid2 = "from: @(#)bindresvport.c 1.8 88/02/08 SMI"; -static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC"; -#endif -/* from: $OpenBSD: bindresvport.c,v 1.7 1996/07/30 16:25:47 downsj Exp $ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Copyright (c) 1987 by Sun Microsystems, Inc. - * - * Portions Copyright(C) 1996, Jason Downs. All rights reserved. - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/socket.h> - -#include <netinet/in.h> - -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#include <rpc/rpc.h> - -#include <string.h> -#include "un-namespace.h" - -/* - * 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); -} - -/* - * Bind a socket to a privileged IP port - */ -int -bindresvport_sa(sd, sa) - int sd; - struct sockaddr *sa; -{ - int old, error, af; - struct sockaddr_storage myaddr; - struct sockaddr_in *sin; -#ifdef INET6 - struct sockaddr_in6 *sin6; -#endif - int proto, portrange, portlow; - u_int16_t *portp; - socklen_t 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(sa, 0, salen); - } else - af = sa->sa_family; - - switch (af) { - case AF_INET: - proto = IPPROTO_IP; - portrange = IP_PORTRANGE; - portlow = IP_PORTRANGE_LOW; - sin = (struct sockaddr_in *)sa; - salen = sizeof(struct sockaddr_in); - portp = &sin->sin_port; - break; -#ifdef INET6 - case AF_INET6: - proto = IPPROTO_IPV6; - portrange = IPV6_PORTRANGE; - portlow = IPV6_PORTRANGE_LOW; - sin6 = (struct sockaddr_in6 *)sa; - salen = sizeof(struct sockaddr_in6); - portp = &sin6->sin6_port; - break; -#endif - default: - errno = EPFNOSUPPORT; - return (-1); - } - sa->sa_family = af; - sa->sa_len = salen; - - if (*portp == 0) { - socklen_t 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 (*portp == 0) { - int saved_errno = errno; - - if (error < 0) { - 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); -} diff --git a/lib/libc/rpc/clnt_bcast.c b/lib/libc/rpc/clnt_bcast.c deleted file mode 100644 index 612007e..0000000 --- a/lib/libc/rpc/clnt_bcast.c +++ /dev/null @@ -1,673 +0,0 @@ -/* $NetBSD: clnt_bcast.c,v 1.3 2000/07/06 03:05:20 christos Exp $ */ - -/* - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -#ident "@(#)clnt_bcast.c 1.18 94/05/03 SMI" -static char sccsid[] = "@(#)clnt_bcast.c 1.15 89/04/21 Copyr 1988 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - - -/* - * clnt_bcast.c - * Client interface to broadcast service. - * - * Copyright (C) 1988, Sun Microsystems, Inc. - * - * The following is kludged-up support for simple rpc broadcasts. - * Someday a large, complicated system will replace these routines. - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/queue.h> -#include <net/if.h> -#include <netinet/in.h> -#include <ifaddrs.h> -#include <sys/poll.h> -#include <rpc/rpc.h> -#ifdef PORTMAP -#include <rpc/pmap_prot.h> -#include <rpc/pmap_clnt.h> -#include <rpc/pmap_rmt.h> -#endif /* PORTMAP */ -#include <rpc/nettype.h> -#include <arpa/inet.h> -#ifdef RPC_DEBUG -#include <stdio.h> -#endif -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <netdb.h> -#include <err.h> -#include <string.h> -#include "un-namespace.h" - -#include "rpc_com.h" - -#define MAXBCAST 20 /* Max no of broadcasting transports */ -#define INITTIME 4000 /* Time to wait initially */ -#define WAITTIME 8000 /* Maximum time to wait */ - -/* - * If nettype is NULL, it broadcasts on all the available - * datagram_n transports. May potentially lead to broadacst storms - * and hence should be used with caution, care and courage. - * - * The current parameter xdr packet size is limited by the max tsdu - * size of the transport. If the max tsdu size of any transport is - * smaller than the parameter xdr packet, then broadcast is not - * sent on that transport. - * - * Also, the packet size should be less the packet size of - * the data link layer (for ethernet it is 1400 bytes). There is - * no easy way to find out the max size of the data link layer and - * we are assuming that the args would be smaller than that. - * - * The result size has to be smaller than the transport tsdu size. - * - * If PORTMAP has been defined, we send two packets for UDP, one for - * rpcbind and one for portmap. For those machines which support - * both rpcbind and portmap, it will cause them to reply twice, and - * also here it will get two responses ... inefficient and clumsy. - */ - -struct broadif { - int index; - struct sockaddr_storage broadaddr; - TAILQ_ENTRY(broadif) link; -}; - -typedef TAILQ_HEAD(, broadif) broadlist_t; - -int __rpc_getbroadifs(int, int, int, broadlist_t *); -void __rpc_freebroadifs(broadlist_t *); -int __rpc_broadenable(int, int, struct broadif *); - -int __rpc_lowvers = 0; - -int -__rpc_getbroadifs(int af, int proto, int socktype, broadlist_t *list) -{ - int count = 0; - struct broadif *bip; - struct ifaddrs *ifap, *ifp; -#ifdef INET6 - struct sockaddr_in6 *sin6; -#endif - struct sockaddr_in *sin; - struct addrinfo hints, *res; - - if (getifaddrs(&ifp) < 0) - return 0; - - memset(&hints, 0, sizeof hints); - - hints.ai_family = af; - hints.ai_protocol = proto; - hints.ai_socktype = socktype; - - if (getaddrinfo(NULL, "sunrpc", &hints, &res) != 0) { - freeifaddrs(ifp); - return 0; - } - - for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { - if (ifap->ifa_addr->sa_family != af || - !(ifap->ifa_flags & IFF_UP)) - continue; - bip = (struct broadif *)malloc(sizeof *bip); - if (bip == NULL) - break; - bip->index = if_nametoindex(ifap->ifa_name); - if ( -#ifdef INET6 - af != AF_INET6 && -#endif - (ifap->ifa_flags & IFF_BROADCAST) && - ifap->ifa_broadaddr) { - memcpy(&bip->broadaddr, ifap->ifa_broadaddr, - (size_t)ifap->ifa_broadaddr->sa_len); - sin = (struct sockaddr_in *)(void *)&bip->broadaddr; - sin->sin_port = - ((struct sockaddr_in *) - (void *)res->ai_addr)->sin_port; - } else -#ifdef INET6 - if (af == AF_INET6 && (ifap->ifa_flags & IFF_MULTICAST)) { - sin6 = (struct sockaddr_in6 *)(void *)&bip->broadaddr; - inet_pton(af, RPCB_MULTICAST_ADDR, &sin6->sin6_addr); - sin6->sin6_family = af; - sin6->sin6_len = sizeof *sin6; - sin6->sin6_port = - ((struct sockaddr_in6 *) - (void *)res->ai_addr)->sin6_port; - sin6->sin6_scope_id = bip->index; - } else -#endif - { - free(bip); - continue; - } - TAILQ_INSERT_TAIL(list, bip, link); - count++; - } - freeifaddrs(ifp); - freeaddrinfo(res); - - return count; -} - -void -__rpc_freebroadifs(broadlist_t *list) -{ - struct broadif *bip, *next; - - bip = TAILQ_FIRST(list); - - while (bip != NULL) { - next = TAILQ_NEXT(bip, link); - free(bip); - bip = next; - } -} - -int -/*ARGSUSED*/ -__rpc_broadenable(int af, int s, struct broadif *bip) -{ - int o = 1; - -#if 0 - if (af == AF_INET6) { - fprintf(stderr, "set v6 multicast if to %d\n", bip->index); - if (_setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &bip->index, - sizeof bip->index) < 0) - return -1; - } else -#endif - if (_setsockopt(s, SOL_SOCKET, SO_BROADCAST, &o, sizeof o) < 0) - return -1; - - return 0; -} - - -enum clnt_stat -rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp, - eachresult, inittime, waittime, nettype) - rpcprog_t prog; /* program number */ - rpcvers_t vers; /* version number */ - rpcproc_t 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 */ - int inittime; /* how long to wait initially */ - int waittime; /* maximum time to wait */ - const char *nettype; /* transport type */ -{ - enum clnt_stat stat = RPC_SUCCESS; /* Return status */ - XDR xdr_stream; /* XDR stream */ - XDR *xdrs = &xdr_stream; - struct rpc_msg msg; /* RPC message */ - struct timeval t; - char *outbuf = NULL; /* Broadcast msg buffer */ - char *inbuf = NULL; /* Reply buf */ - int inlen; - u_int maxbufsize = 0; - AUTH *sys_auth = authunix_create_default(); - int i; - void *handle; - char uaddress[1024]; /* A self imposed limit */ - char *uaddrp = uaddress; - int pmap_reply_flag; /* reply recvd from PORTMAP */ - /* An array of all the suitable broadcast transports */ - struct { - int fd; /* File descriptor */ - int af; - int proto; - struct netconfig *nconf; /* Netconfig structure */ - u_int asize; /* Size of the addr buf */ - u_int dsize; /* Size of the data buf */ - struct sockaddr_storage raddr; /* Remote address */ - broadlist_t nal; - } fdlist[MAXBCAST]; - struct pollfd pfd[MAXBCAST]; - size_t fdlistno = 0; - struct r_rpcb_rmtcallargs barg; /* Remote arguments */ - struct r_rpcb_rmtcallres bres; /* Remote results */ - size_t outlen; - struct netconfig *nconf; - int msec; - int pollretval; - int fds_found; - -#ifdef PORTMAP - size_t outlen_pmap = 0; - u_long port; /* Remote port number */ - int pmap_flag = 0; /* UDP exists ? */ - char *outbuf_pmap = NULL; - struct rmtcallargs barg_pmap; /* Remote arguments */ - struct rmtcallres bres_pmap; /* Remote results */ - u_int udpbufsz = 0; -#endif /* PORTMAP */ - - if (sys_auth == NULL) { - return (RPC_SYSTEMERROR); - } - /* - * initialization: create a fd, a broadcast address, and send the - * request on the broadcast transport. - * Listen on all of them and on replies, call the user supplied - * function. - */ - - if (nettype == NULL) - nettype = "datagram_n"; - if ((handle = __rpc_setconf(nettype)) == NULL) { - AUTH_DESTROY(sys_auth); - return (RPC_UNKNOWNPROTO); - } - while ((nconf = __rpc_getconf(handle)) != NULL) { - int fd; - struct __rpc_sockinfo si; - - if (nconf->nc_semantics != NC_TPI_CLTS) - continue; - if (fdlistno >= MAXBCAST) - break; /* No more slots available */ - if (!__rpc_nconf2sockinfo(nconf, &si)) - continue; - - TAILQ_INIT(&fdlist[fdlistno].nal); - if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype, - &fdlist[fdlistno].nal) == 0) - continue; - - fd = _socket(si.si_af, si.si_socktype, si.si_proto); - if (fd < 0) { - stat = RPC_CANTSEND; - continue; - } - fdlist[fdlistno].af = si.si_af; - fdlist[fdlistno].proto = si.si_proto; - fdlist[fdlistno].fd = fd; - fdlist[fdlistno].nconf = nconf; - fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af); - pfd[fdlistno].events = POLLIN | POLLPRI | - POLLRDNORM | POLLRDBAND; - pfd[fdlistno].fd = fdlist[fdlistno].fd = fd; - fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto, - 0); - - if (maxbufsize <= fdlist[fdlistno].dsize) - maxbufsize = fdlist[fdlistno].dsize; - -#ifdef PORTMAP - if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) { - udpbufsz = fdlist[fdlistno].dsize; - if ((outbuf_pmap = malloc(udpbufsz)) == NULL) { - _close(fd); - stat = RPC_SYSTEMERROR; - goto done_broad; - } - pmap_flag = 1; - } -#endif /* PORTMAP */ - fdlistno++; - } - - if (fdlistno == 0) { - if (stat == RPC_SUCCESS) - stat = RPC_UNKNOWNPROTO; - goto done_broad; - } - if (maxbufsize == 0) { - if (stat == RPC_SUCCESS) - stat = RPC_CANTSEND; - goto done_broad; - } - inbuf = malloc(maxbufsize); - outbuf = malloc(maxbufsize); - if ((inbuf == NULL) || (outbuf == NULL)) { - stat = RPC_SYSTEMERROR; - goto done_broad; - } - - /* Serialize all the arguments which have to be sent */ - (void) gettimeofday(&t, NULL); - msg.rm_xid = __RPC_GETXID(&t); - msg.rm_direction = CALL; - msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - msg.rm_call.cb_prog = RPCBPROG; - msg.rm_call.cb_vers = RPCBVERS; - msg.rm_call.cb_proc = RPCBPROC_CALLIT; - barg.prog = prog; - barg.vers = vers; - barg.proc = proc; - barg.args.args_val = argsp; - barg.xdr_args = xargs; - bres.addr = uaddrp; - bres.results.results_val = resultsp; - bres.xdr_res = xresults; - msg.rm_call.cb_cred = sys_auth->ah_cred; - msg.rm_call.cb_verf = sys_auth->ah_verf; - xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE); - if ((!xdr_callmsg(xdrs, &msg)) || - (!xdr_rpcb_rmtcallargs(xdrs, - (struct rpcb_rmtcallargs *)(void *)&barg))) { - stat = RPC_CANTENCODEARGS; - goto done_broad; - } - outlen = xdr_getpos(xdrs); - xdr_destroy(xdrs); - -#ifdef PORTMAP - /* Prepare the packet for version 2 PORTMAP */ - if (pmap_flag) { - msg.rm_xid++; /* One way to distinguish */ - msg.rm_call.cb_prog = PMAPPROG; - msg.rm_call.cb_vers = PMAPVERS; - msg.rm_call.cb_proc = PMAPPROC_CALLIT; - barg_pmap.prog = prog; - barg_pmap.vers = vers; - barg_pmap.proc = proc; - barg_pmap.args_ptr = argsp; - barg_pmap.xdr_args = xargs; - bres_pmap.port_ptr = &port; - bres_pmap.xdr_results = xresults; - bres_pmap.results_ptr = resultsp; - xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE); - if ((! xdr_callmsg(xdrs, &msg)) || - (! xdr_rmtcall_args(xdrs, &barg_pmap))) { - stat = RPC_CANTENCODEARGS; - goto done_broad; - } - outlen_pmap = xdr_getpos(xdrs); - xdr_destroy(xdrs); - } -#endif /* PORTMAP */ - - /* - * Basic loop: broadcast the packets to transports which - * support data packets of size such that one can encode - * all the arguments. - * Wait a while for response(s). - * The response timeout grows larger per iteration. - */ - for (msec = inittime; msec <= waittime; msec += msec) { - struct broadif *bip; - - /* Broadcast all the packets now */ - for (i = 0; i < fdlistno; i++) { - if (fdlist[i].dsize < outlen) { - stat = RPC_CANTSEND; - continue; - } - for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL; - bip = TAILQ_NEXT(bip, link)) { - void *addr; - - addr = &bip->broadaddr; - - __rpc_broadenable(fdlist[i].af, fdlist[i].fd, - bip); - - /* - * Only use version 3 if lowvers is not set - */ - - if (!__rpc_lowvers) - if (_sendto(fdlist[i].fd, outbuf, - outlen, 0, (struct sockaddr*)addr, - (size_t)fdlist[i].asize) != - outlen) { -#ifdef RPC_DEBUG - perror("sendto"); -#endif - warnx("clnt_bcast: cannot send " - "broadcast packet"); - stat = RPC_CANTSEND; - continue; - }; -#ifdef RPC_DEBUG - if (!__rpc_lowvers) - fprintf(stderr, "Broadcast packet sent " - "for %s\n", - fdlist[i].nconf->nc_netid); -#endif -#ifdef PORTMAP - /* - * Send the version 2 packet also - * for UDP/IP - */ - if (pmap_flag && - fdlist[i].proto == IPPROTO_UDP) { - if (_sendto(fdlist[i].fd, outbuf_pmap, - outlen_pmap, 0, addr, - (size_t)fdlist[i].asize) != - outlen_pmap) { - warnx("clnt_bcast: " - "Cannot send broadcast packet"); - stat = RPC_CANTSEND; - continue; - } - } -#ifdef RPC_DEBUG - fprintf(stderr, "PMAP Broadcast packet " - "sent for %s\n", - fdlist[i].nconf->nc_netid); -#endif -#endif /* PORTMAP */ - } - /* End for sending all packets on this transport */ - } /* End for sending on all transports */ - - if (eachresult == NULL) { - stat = RPC_SUCCESS; - goto done_broad; - } - - /* - * Get all the replies from these broadcast requests - */ - recv_again: - - switch (pollretval = _poll(pfd, fdlistno, msec)) { - case 0: /* timed out */ - stat = RPC_TIMEDOUT; - continue; - case -1: /* some kind of error - we ignore it */ - goto recv_again; - } /* end of poll results switch */ - - for (i = fds_found = 0; - i < fdlistno && fds_found < pollretval; i++) { - bool_t done = FALSE; - - if (pfd[i].revents == 0) - continue; - else if (pfd[i].revents & POLLNVAL) { - /* - * Something bad has happened to this descri- - * ptor. We can cause _poll() to ignore - * it simply by using a negative fd. We do that - * rather than compacting the pfd[] and fdlist[] - * arrays. - */ - pfd[i].fd = -1; - fds_found++; - continue; - } else - fds_found++; -#ifdef RPC_DEBUG - fprintf(stderr, "response for %s\n", - fdlist[i].nconf->nc_netid); -#endif - try_again: - inlen = _recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize, - 0, (struct sockaddr *)(void *)&fdlist[i].raddr, - &fdlist[i].asize); - if (inlen < 0) { - if (errno == EINTR) - goto try_again; - warnx("clnt_bcast: Cannot receive reply to " - "broadcast"); - stat = RPC_CANTRECV; - continue; - } - if (inlen < sizeof (u_int32_t)) - continue; /* Drop that and go ahead */ - /* - * see if reply transaction id matches sent id. - * If so, decode the results. If return id is xid + 1 - * it was a PORTMAP reply - */ - if (*((u_int32_t *)(void *)(inbuf)) == - *((u_int32_t *)(void *)(outbuf))) { - pmap_reply_flag = 0; - msg.acpted_rply.ar_verf = _null_auth; - msg.acpted_rply.ar_results.where = - (caddr_t)(void *)&bres; - msg.acpted_rply.ar_results.proc = - (xdrproc_t)xdr_rpcb_rmtcallres; -#ifdef PORTMAP - } else if (pmap_flag && - *((u_int32_t *)(void *)(inbuf)) == - *((u_int32_t *)(void *)(outbuf_pmap))) { - pmap_reply_flag = 1; - msg.acpted_rply.ar_verf = _null_auth; - msg.acpted_rply.ar_results.where = - (caddr_t)(void *)&bres_pmap; - msg.acpted_rply.ar_results.proc = - (xdrproc_t)xdr_rmtcallres; -#endif /* PORTMAP */ - } else - continue; - xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE); - if (xdr_replymsg(xdrs, &msg)) { - if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) && - (msg.acpted_rply.ar_stat == SUCCESS)) { - struct netbuf taddr, *np; - struct sockaddr_in *sin; - -#ifdef PORTMAP - if (pmap_flag && pmap_reply_flag) { - sin = (struct sockaddr_in *) - (void *)&fdlist[i].raddr; - sin->sin_port = - htons((u_short)port); - taddr.len = taddr.maxlen = - fdlist[i].raddr.ss_len; - taddr.buf = &fdlist[i].raddr; - done = (*eachresult)(resultsp, - &taddr, fdlist[i].nconf); - } else { -#endif /* PORTMAP */ -#ifdef RPC_DEBUG - fprintf(stderr, "uaddr %s\n", - uaddrp); -#endif - np = uaddr2taddr( - fdlist[i].nconf, uaddrp); - done = (*eachresult)(resultsp, - np, fdlist[i].nconf); - free(np); -#ifdef PORTMAP - } -#endif /* PORTMAP */ - } - /* otherwise, we just ignore the errors ... */ - } - /* else some kind of deserialization problem ... */ - - xdrs->x_op = XDR_FREE; - msg.acpted_rply.ar_results.proc = (xdrproc_t) 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; - } - } /* The recv for loop */ - } /* The giant for loop */ - -done_broad: - if (inbuf) - (void) free(inbuf); - if (outbuf) - (void) free(outbuf); -#ifdef PORTMAP - if (outbuf_pmap) - (void) free(outbuf_pmap); -#endif /* PORTMAP */ - for (i = 0; i < fdlistno; i++) { - (void)_close(fdlist[i].fd); - __rpc_freebroadifs(&fdlist[i].nal); - } - AUTH_DESTROY(sys_auth); - (void) __rpc_endconf(handle); - - return (stat); -} - - -enum clnt_stat -rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, - eachresult, nettype) - rpcprog_t prog; /* program number */ - rpcvers_t vers; /* version number */ - rpcproc_t 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 */ - const char *nettype; /* transport type */ -{ - enum clnt_stat dummy; - - dummy = rpc_broadcast_exp(prog, vers, proc, xargs, argsp, - xresults, resultsp, eachresult, - INITTIME, WAITTIME, nettype); - return (dummy); -} diff --git a/lib/libc/rpc/clnt_dg.c b/lib/libc/rpc/clnt_dg.c deleted file mode 100644 index 9c52e1e..0000000 --- a/lib/libc/rpc/clnt_dg.c +++ /dev/null @@ -1,859 +0,0 @@ -/* $NetBSD: clnt_dg.c,v 1.4 2000/07/14 08:40:41 fvdl Exp $ */ - -/* - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -#ident "@(#)clnt_dg.c 1.23 94/04/22 SMI" -static char sccsid[] = "@(#)clnt_dg.c 1.19 89/03/16 Copyr 1988 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Implements a connectionless client side RPC. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/event.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <arpa/inet.h> -#include <rpc/rpc.h> -#include <rpc/rpcsec_gss.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#include <unistd.h> -#include <err.h> -#include "un-namespace.h" -#include "rpc_com.h" -#include "mt_misc.h" - - -#ifdef _FREEFALL_CONFIG -/* - * Disable RPC exponential back-off for FreeBSD.org systems. - */ -#define RPC_MAX_BACKOFF 1 /* second */ -#else -#define RPC_MAX_BACKOFF 30 /* seconds */ -#endif - - -static struct clnt_ops *clnt_dg_ops(void); -static bool_t time_not_ok(struct timeval *); -static enum clnt_stat clnt_dg_call(CLIENT *, rpcproc_t, xdrproc_t, void *, - xdrproc_t, void *, struct timeval); -static void clnt_dg_geterr(CLIENT *, struct rpc_err *); -static bool_t clnt_dg_freeres(CLIENT *, xdrproc_t, void *); -static void clnt_dg_abort(CLIENT *); -static bool_t clnt_dg_control(CLIENT *, u_int, void *); -static void clnt_dg_destroy(CLIENT *); - - - - -/* - * This machinery implements per-fd locks for MT-safety. It is not - * sufficient to do per-CLIENT handle locks for MT-safety because a - * user may create more than one CLIENT handle with the same fd behind - * it. Therfore, we allocate an array of flags (dg_fd_locks), protected - * by the clnt_fd_lock mutex, and an array (dg_cv) of condition variables - * similarly protected. Dg_fd_lock[fd] == 1 => a call is activte on some - * CLIENT handle created for that fd. - * The current implementation holds locks across the entire RPC and reply, - * including retransmissions. Yes, this is silly, and as soon as this - * code is proven to work, this should be the first thing fixed. One step - * at a time. - */ -static int *dg_fd_locks; -static cond_t *dg_cv; -#define release_fd_lock(fd, mask) { \ - mutex_lock(&clnt_fd_lock); \ - dg_fd_locks[fd] = 0; \ - mutex_unlock(&clnt_fd_lock); \ - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); \ - cond_signal(&dg_cv[fd]); \ -} - -static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory"; - -/* VARIABLES PROTECTED BY clnt_fd_lock: dg_fd_locks, dg_cv */ - -#define MCALL_MSG_SIZE 24 - -/* - * Private data kept per client handle - */ -struct cu_data { - int cu_fd; /* connections fd */ - bool_t cu_closeit; /* opened by library */ - struct sockaddr_storage cu_raddr; /* remote address */ - int cu_rlen; - struct timeval cu_wait; /* retransmit interval */ - struct timeval cu_total; /* total time for the call */ - struct rpc_err cu_error; - XDR cu_outxdrs; - u_int cu_xdrpos; - u_int cu_sendsz; /* send size */ - char cu_outhdr[MCALL_MSG_SIZE]; - char *cu_outbuf; - u_int cu_recvsz; /* recv size */ - int cu_async; - int cu_connect; /* Use connect(). */ - int cu_connected; /* Have done connect(). */ - struct kevent cu_kin; - int cu_kq; - char cu_inbuf[1]; -}; - -/* - * Connection less client creation returns with client handle parameters. - * Default options are set, which the user can change using clnt_control(). - * fd should be open and bound. - * NB: The rpch->cl_auth is initialized to null authentication. - * Caller may wish to set this something more useful. - * - * sendsz and recvsz are the maximum allowable packet sizes that can be - * sent and received. Normally they are the same, but they can be - * changed to improve the program efficiency and buffer allocation. - * If they are 0, use the transport default. - * - * If svcaddr is NULL, returns NULL. - */ -CLIENT * -clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz) - int fd; /* open file descriptor */ - const struct netbuf *svcaddr; /* servers address */ - rpcprog_t program; /* program number */ - rpcvers_t version; /* version number */ - u_int sendsz; /* buffer recv size */ - u_int recvsz; /* buffer send size */ -{ - CLIENT *cl = NULL; /* client handle */ - struct cu_data *cu = NULL; /* private data */ - struct timeval now; - struct rpc_msg call_msg; - sigset_t mask; - sigset_t newmask; - struct __rpc_sockinfo si; - int one = 1; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - if (dg_fd_locks == (int *) NULL) { - int cv_allocsz; - size_t fd_allocsz; - int dtbsize = __rpc_dtbsize(); - - fd_allocsz = dtbsize * sizeof (int); - dg_fd_locks = (int *) mem_alloc(fd_allocsz); - if (dg_fd_locks == (int *) NULL) { - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - goto err1; - } else - memset(dg_fd_locks, '\0', fd_allocsz); - - cv_allocsz = dtbsize * sizeof (cond_t); - dg_cv = (cond_t *) mem_alloc(cv_allocsz); - if (dg_cv == (cond_t *) NULL) { - mem_free(dg_fd_locks, fd_allocsz); - dg_fd_locks = (int *) NULL; - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - goto err1; - } else { - int i; - - for (i = 0; i < dtbsize; i++) - cond_init(&dg_cv[i], 0, (void *) 0); - } - } - - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - - if (svcaddr == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNADDR; - return (NULL); - } - - if (!__rpc_fd2sockinfo(fd, &si)) { - rpc_createerr.cf_stat = RPC_TLIERROR; - rpc_createerr.cf_error.re_errno = 0; - return (NULL); - } - /* - * Find the receive and the send size - */ - sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz); - recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz); - if ((sendsz == 0) || (recvsz == 0)) { - rpc_createerr.cf_stat = RPC_TLIERROR; /* XXX */ - rpc_createerr.cf_error.re_errno = 0; - return (NULL); - } - - if ((cl = mem_alloc(sizeof (CLIENT))) == NULL) - goto err1; - /* - * Should be multiple of 4 for XDR. - */ - sendsz = ((sendsz + 3) / 4) * 4; - recvsz = ((recvsz + 3) / 4) * 4; - cu = mem_alloc(sizeof (*cu) + sendsz + recvsz); - if (cu == NULL) - goto err1; - (void) memcpy(&cu->cu_raddr, svcaddr->buf, (size_t)svcaddr->len); - cu->cu_rlen = svcaddr->len; - cu->cu_outbuf = &cu->cu_inbuf[recvsz]; - /* Other values can also be set through clnt_control() */ - cu->cu_wait.tv_sec = 15; /* heuristically chosen */ - cu->cu_wait.tv_usec = 0; - cu->cu_total.tv_sec = -1; - cu->cu_total.tv_usec = -1; - cu->cu_sendsz = sendsz; - cu->cu_recvsz = recvsz; - cu->cu_async = FALSE; - cu->cu_connect = FALSE; - cu->cu_connected = FALSE; - (void) gettimeofday(&now, NULL); - call_msg.rm_xid = __RPC_GETXID(&now); - call_msg.rm_call.cb_prog = program; - call_msg.rm_call.cb_vers = version; - xdrmem_create(&(cu->cu_outxdrs), cu->cu_outhdr, MCALL_MSG_SIZE, - XDR_ENCODE); - if (! xdr_callhdr(&cu->cu_outxdrs, &call_msg)) { - rpc_createerr.cf_stat = RPC_CANTENCODEARGS; /* XXX */ - rpc_createerr.cf_error.re_errno = 0; - goto err2; - } - cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); - XDR_DESTROY(&cu->cu_outxdrs); - xdrmem_create(&cu->cu_outxdrs, cu->cu_outbuf, sendsz, XDR_ENCODE); - - /* XXX fvdl - do we still want this? */ -#if 0 - (void)bindresvport_sa(fd, (struct sockaddr *)svcaddr->buf); -#endif - _ioctl(fd, FIONBIO, (char *)(void *)&one); - - /* - * By default, closeit is always FALSE. It is users responsibility - * to do a close on it, else the user may use clnt_control - * to let clnt_destroy do it for him/her. - */ - cu->cu_closeit = FALSE; - cu->cu_fd = fd; - cl->cl_ops = clnt_dg_ops(); - cl->cl_private = (caddr_t)(void *)cu; - cl->cl_auth = authnone_create(); - cl->cl_tp = NULL; - cl->cl_netid = NULL; - cu->cu_kq = -1; - EV_SET(&cu->cu_kin, cu->cu_fd, EVFILT_READ, EV_ADD, 0, 0, 0); - return (cl); -err1: - warnx(mem_err_clnt_dg); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; -err2: - if (cl) { - mem_free(cl, sizeof (CLIENT)); - if (cu) - mem_free(cu, sizeof (*cu) + sendsz + recvsz); - } - return (NULL); -} - -static enum clnt_stat -clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) - CLIENT *cl; /* client handle */ - rpcproc_t proc; /* procedure number */ - xdrproc_t xargs; /* xdr routine for args */ - void *argsp; /* pointer to args */ - xdrproc_t xresults; /* xdr routine for results */ - void *resultsp; /* pointer to results */ - struct timeval utimeout; /* seconds to wait before giving up */ -{ - struct cu_data *cu = (struct cu_data *)cl->cl_private; - XDR *xdrs; - size_t outlen = 0; - struct rpc_msg reply_msg; - XDR reply_xdrs; - bool_t ok; - int nrefreshes = 2; /* number of times to refresh cred */ - int nretries = 0; /* number of times we retransmitted */ - struct timeval timeout; - struct timeval retransmit_time; - struct timeval next_sendtime, starttime, time_waited, tv; - struct timespec ts; - struct kevent kv; - struct sockaddr *sa; - sigset_t mask; - sigset_t newmask; - socklen_t inlen, salen; - ssize_t recvlen = 0; - int kin_len, n, rpc_lock_value; - u_int32_t xid; - - outlen = 0; - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (dg_fd_locks[cu->cu_fd]) - cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); - if (__isthreaded) - rpc_lock_value = 1; - else - rpc_lock_value = 0; - dg_fd_locks[cu->cu_fd] = rpc_lock_value; - mutex_unlock(&clnt_fd_lock); - if (cu->cu_total.tv_usec == -1) { - timeout = utimeout; /* use supplied timeout */ - } else { - timeout = cu->cu_total; /* use default timeout */ - } - - if (cu->cu_connect && !cu->cu_connected) { - if (_connect(cu->cu_fd, (struct sockaddr *)&cu->cu_raddr, - cu->cu_rlen) < 0) { - cu->cu_error.re_errno = errno; - cu->cu_error.re_status = RPC_CANTSEND; - goto out; - } - cu->cu_connected = 1; - } - if (cu->cu_connected) { - sa = NULL; - salen = 0; - } else { - sa = (struct sockaddr *)&cu->cu_raddr; - salen = cu->cu_rlen; - } - time_waited.tv_sec = 0; - time_waited.tv_usec = 0; - retransmit_time = next_sendtime = cu->cu_wait; - gettimeofday(&starttime, NULL); - - /* Clean up in case the last call ended in a longjmp(3) call. */ - if (cu->cu_kq >= 0) - _close(cu->cu_kq); - if ((cu->cu_kq = kqueue()) < 0) { - cu->cu_error.re_errno = errno; - cu->cu_error.re_status = RPC_CANTSEND; - goto out; - } - kin_len = 1; - -call_again: - if (cu->cu_async == TRUE && xargs == NULL) - goto get_reply; - /* - * the transaction is the first thing in the out buffer - * XXX Yes, and it's in network byte order, so we should to - * be careful when we increment it, shouldn't we. - */ - xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr)); - xid++; - *(u_int32_t *)(void *)(cu->cu_outhdr) = htonl(xid); -call_again_same_xid: - xdrs = &(cu->cu_outxdrs); - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, 0); - - if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) { - if ((! XDR_PUTBYTES(xdrs, cu->cu_outhdr, cu->cu_xdrpos)) || - (! XDR_PUTINT32(xdrs, &proc)) || - (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || - (! (*xargs)(xdrs, argsp))) { - cu->cu_error.re_status = RPC_CANTENCODEARGS; - goto out; - } - } else { - *(uint32_t *) &cu->cu_outhdr[cu->cu_xdrpos] = htonl(proc); - if (!__rpc_gss_wrap(cl->cl_auth, cu->cu_outhdr, - cu->cu_xdrpos + sizeof(uint32_t), - xdrs, xargs, argsp)) { - cu->cu_error.re_status = RPC_CANTENCODEARGS; - goto out; - } - } - outlen = (size_t)XDR_GETPOS(xdrs); - -send_again: - if (_sendto(cu->cu_fd, cu->cu_outbuf, outlen, 0, sa, salen) != outlen) { - cu->cu_error.re_errno = errno; - cu->cu_error.re_status = RPC_CANTSEND; - goto out; - } - - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { - cu->cu_error.re_status = RPC_TIMEDOUT; - goto out; - } - -get_reply: - - /* - * 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; - if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) { - reply_msg.acpted_rply.ar_results.where = resultsp; - reply_msg.acpted_rply.ar_results.proc = xresults; - } else { - reply_msg.acpted_rply.ar_results.where = NULL; - reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; - } - - for (;;) { - /* Decide how long to wait. */ - if (timercmp(&next_sendtime, &timeout, <)) - timersub(&next_sendtime, &time_waited, &tv); - else - timersub(&timeout, &time_waited, &tv); - if (tv.tv_sec < 0 || tv.tv_usec < 0) - tv.tv_sec = tv.tv_usec = 0; - TIMEVAL_TO_TIMESPEC(&tv, &ts); - - n = _kevent(cu->cu_kq, &cu->cu_kin, kin_len, &kv, 1, &ts); - /* We don't need to register the event again. */ - kin_len = 0; - - if (n == 1) { - if (kv.flags & EV_ERROR) { - cu->cu_error.re_errno = kv.data; - cu->cu_error.re_status = RPC_CANTRECV; - goto out; - } - /* We have some data now */ - do { - recvlen = _recvfrom(cu->cu_fd, cu->cu_inbuf, - cu->cu_recvsz, 0, NULL, NULL); - } while (recvlen < 0 && errno == EINTR); - if (recvlen < 0 && errno != EWOULDBLOCK) { - cu->cu_error.re_errno = errno; - cu->cu_error.re_status = RPC_CANTRECV; - goto out; - } - if (recvlen >= sizeof(u_int32_t) && - (cu->cu_async == TRUE || - *((u_int32_t *)(void *)(cu->cu_inbuf)) == - *((u_int32_t *)(void *)(cu->cu_outbuf)))) { - /* We now assume we have the proper reply. */ - break; - } - } - if (n == -1 && errno != EINTR) { - cu->cu_error.re_errno = errno; - cu->cu_error.re_status = RPC_CANTRECV; - goto out; - } - gettimeofday(&tv, NULL); - timersub(&tv, &starttime, &time_waited); - - /* Check for timeout. */ - if (timercmp(&time_waited, &timeout, >)) { - cu->cu_error.re_status = RPC_TIMEDOUT; - goto out; - } - - /* Retransmit if necessary. */ - if (timercmp(&time_waited, &next_sendtime, >)) { - /* update retransmit_time */ - if (retransmit_time.tv_sec < RPC_MAX_BACKOFF) - timeradd(&retransmit_time, &retransmit_time, - &retransmit_time); - timeradd(&next_sendtime, &retransmit_time, - &next_sendtime); - nretries++; - - /* - * When retransmitting a RPCSEC_GSS message, - * we must use a new sequence number (handled - * by __rpc_gss_wrap above). - */ - if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) - goto send_again; - else - goto call_again_same_xid; - } - } - inlen = (socklen_t)recvlen; - - /* - * now decode and validate the response - */ - - xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)recvlen, XDR_DECODE); - ok = xdr_replymsg(&reply_xdrs, &reply_msg); - /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ - if (ok) { - if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) && - (reply_msg.acpted_rply.ar_stat == SUCCESS)) - cu->cu_error.re_status = RPC_SUCCESS; - else - _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)) { - if (nretries && - cl->cl_auth->ah_cred.oa_flavor - == RPCSEC_GSS) - /* - * If we retransmitted, its - * possible that we will - * receive a reply for one of - * the earlier transmissions - * (which will use an older - * RPCSEC_GSS sequence - * number). In this case, just - * go back and listen for a - * new reply. We could keep a - * record of all the seq - * numbers we have transmitted - * so far so that we could - * accept a reply for any of - * them here. - */ - goto get_reply; - cu->cu_error.re_status = RPC_AUTHERROR; - cu->cu_error.re_why = AUTH_INVALIDRESP; - } else { - if (cl->cl_auth->ah_cred.oa_flavor - == RPCSEC_GSS) { - if (!__rpc_gss_unwrap(cl->cl_auth, - &reply_xdrs, xresults, - resultsp)) - cu->cu_error.re_status = - RPC_CANTDECODERES; - } - } - 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 */ - /* - * If unsuccesful AND error is an authentication error - * then refresh credentials and try again, else break - */ - else if (cu->cu_error.re_status == RPC_AUTHERROR) - /* maybe our credentials need to be refreshed ... */ - if (nrefreshes > 0 && - AUTH_REFRESH(cl->cl_auth, &reply_msg)) { - nrefreshes--; - goto call_again; - } - /* end of unsuccessful completion */ - } /* end of valid reply message */ - else { - cu->cu_error.re_status = RPC_CANTDECODERES; - - } -out: - if (cu->cu_kq >= 0) - _close(cu->cu_kq); - cu->cu_kq = -1; - release_fd_lock(cu->cu_fd, mask); - return (cu->cu_error.re_status); -} - -static void -clnt_dg_geterr(cl, errp) - CLIENT *cl; - struct rpc_err *errp; -{ - struct cu_data *cu = (struct cu_data *)cl->cl_private; - - *errp = cu->cu_error; -} - -static bool_t -clnt_dg_freeres(cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - void *res_ptr; -{ - struct cu_data *cu = (struct cu_data *)cl->cl_private; - XDR *xdrs = &(cu->cu_outxdrs); - bool_t dummy; - sigset_t mask; - sigset_t newmask; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (dg_fd_locks[cu->cu_fd]) - cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); - xdrs->x_op = XDR_FREE; - dummy = (*xdr_res)(xdrs, res_ptr); - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &mask, NULL); - cond_signal(&dg_cv[cu->cu_fd]); - return (dummy); -} - -/*ARGSUSED*/ -static void -clnt_dg_abort(h) - CLIENT *h; -{ -} - -static bool_t -clnt_dg_control(cl, request, info) - CLIENT *cl; - u_int request; - void *info; -{ - struct cu_data *cu = (struct cu_data *)cl->cl_private; - struct netbuf *addr; - sigset_t mask; - sigset_t newmask; - int rpc_lock_value; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (dg_fd_locks[cu->cu_fd]) - cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); - if (__isthreaded) - rpc_lock_value = 1; - else - rpc_lock_value = 0; - dg_fd_locks[cu->cu_fd] = rpc_lock_value; - mutex_unlock(&clnt_fd_lock); - switch (request) { - case CLSET_FD_CLOSE: - cu->cu_closeit = TRUE; - release_fd_lock(cu->cu_fd, mask); - return (TRUE); - case CLSET_FD_NCLOSE: - cu->cu_closeit = FALSE; - release_fd_lock(cu->cu_fd, mask); - return (TRUE); - } - - /* for other requests which use info */ - if (info == NULL) { - release_fd_lock(cu->cu_fd, mask); - return (FALSE); - } - switch (request) { - case CLSET_TIMEOUT: - if (time_not_ok((struct timeval *)info)) { - release_fd_lock(cu->cu_fd, mask); - return (FALSE); - } - cu->cu_total = *(struct timeval *)info; - break; - case CLGET_TIMEOUT: - *(struct timeval *)info = cu->cu_total; - break; - case CLGET_SERVER_ADDR: /* Give him the fd address */ - /* Now obsolete. Only for backward compatibility */ - (void) memcpy(info, &cu->cu_raddr, (size_t)cu->cu_rlen); - break; - case CLSET_RETRY_TIMEOUT: - if (time_not_ok((struct timeval *)info)) { - release_fd_lock(cu->cu_fd, mask); - return (FALSE); - } - cu->cu_wait = *(struct timeval *)info; - break; - case CLGET_RETRY_TIMEOUT: - *(struct timeval *)info = cu->cu_wait; - break; - case CLGET_FD: - *(int *)info = cu->cu_fd; - break; - case CLGET_SVC_ADDR: - addr = (struct netbuf *)info; - addr->buf = &cu->cu_raddr; - addr->len = cu->cu_rlen; - addr->maxlen = sizeof cu->cu_raddr; - break; - case CLSET_SVC_ADDR: /* set to new address */ - addr = (struct netbuf *)info; - if (addr->len < sizeof cu->cu_raddr) { - release_fd_lock(cu->cu_fd, mask); - return (FALSE); - } - (void) memcpy(&cu->cu_raddr, addr->buf, addr->len); - cu->cu_rlen = addr->len; - 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 - */ - *(u_int32_t *)info = - ntohl(*(u_int32_t *)(void *)cu->cu_outhdr); - break; - - case CLSET_XID: - /* This will set the xid of the NEXT call */ - *(u_int32_t *)(void *)cu->cu_outhdr = - htonl(*(u_int32_t *)info - 1); - /* decrement by 1 as clnt_dg_call() increments once */ - break; - - 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 - */ - *(u_int32_t *)info = - ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr + - 4 * BYTES_PER_XDR_UNIT)); - break; - - case CLSET_VERS: - *(u_int32_t *)(void *)(cu->cu_outhdr + 4 * BYTES_PER_XDR_UNIT) - = htonl(*(u_int32_t *)info); - break; - - case CLGET_PROG: - /* - * This RELIES on the information that, in the call body, - * the program number field is the fourth field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - *(u_int32_t *)info = - ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr + - 3 * BYTES_PER_XDR_UNIT)); - break; - - case CLSET_PROG: - *(u_int32_t *)(void *)(cu->cu_outhdr + 3 * BYTES_PER_XDR_UNIT) - = htonl(*(u_int32_t *)info); - break; - case CLSET_ASYNC: - cu->cu_async = *(int *)info; - break; - case CLSET_CONNECT: - cu->cu_connect = *(int *)info; - break; - default: - release_fd_lock(cu->cu_fd, mask); - return (FALSE); - } - release_fd_lock(cu->cu_fd, mask); - return (TRUE); -} - -static void -clnt_dg_destroy(cl) - CLIENT *cl; -{ - struct cu_data *cu = (struct cu_data *)cl->cl_private; - int cu_fd = cu->cu_fd; - sigset_t mask; - sigset_t newmask; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (dg_fd_locks[cu_fd]) - cond_wait(&dg_cv[cu_fd], &clnt_fd_lock); - if (cu->cu_closeit) - (void)_close(cu_fd); - if (cu->cu_kq >= 0) - _close(cu->cu_kq); - XDR_DESTROY(&(cu->cu_outxdrs)); - mem_free(cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz)); - if (cl->cl_netid && cl->cl_netid[0]) - mem_free(cl->cl_netid, strlen(cl->cl_netid) +1); - if (cl->cl_tp && cl->cl_tp[0]) - mem_free(cl->cl_tp, strlen(cl->cl_tp) +1); - mem_free(cl, sizeof (CLIENT)); - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &mask, NULL); - cond_signal(&dg_cv[cu_fd]); -} - -static struct clnt_ops * -clnt_dg_ops() -{ - static struct clnt_ops ops; - sigset_t mask; - sigset_t newmask; - -/* VARIABLES PROTECTED BY ops_lock: ops */ - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&ops_lock); - if (ops.cl_call == NULL) { - ops.cl_call = clnt_dg_call; - ops.cl_abort = clnt_dg_abort; - ops.cl_geterr = clnt_dg_geterr; - ops.cl_freeres = clnt_dg_freeres; - ops.cl_destroy = clnt_dg_destroy; - ops.cl_control = clnt_dg_control; - } - mutex_unlock(&ops_lock); - thr_sigsetmask(SIG_SETMASK, &mask, NULL); - return (&ops); -} - -/* - * Make sure that the time is not garbage. -1 value is allowed. - */ -static bool_t -time_not_ok(t) - struct timeval *t; -{ - return (t->tv_sec < -1 || t->tv_sec > 100000000 || - t->tv_usec < -1 || t->tv_usec > 1000000); -} - diff --git a/lib/libc/rpc/clnt_generic.c b/lib/libc/rpc/clnt_generic.c deleted file mode 100644 index 302a30e..0000000 --- a/lib/libc/rpc/clnt_generic.c +++ /dev/null @@ -1,466 +0,0 @@ -/* $NetBSD: clnt_generic.c,v 1.18 2000/07/06 03:10:34 christos Exp $ */ - -/* - * The contents of this file are subject to the Sun Standards - * License Version 1.0 the (the "License";) You may not use - * this file except in compliance with the License. You may - * obtain a copy of the License at lib/libc/rpc/LICENSE - * - * Software distributed under the License is distributed on - * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for the specific - * language governing rights and limitations under the License. - * - * The Original Code is Copyright 1998 by Sun Microsystems, Inc - * - * The Initial Developer of the Original Code is: Sun - * Microsystems, Inc. - * - * All Rights Reserved. - * - * 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 - */ - -/* #ident "@(#)clnt_generic.c 1.40 99/04/21 SMI" */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char *sccsid2 = "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"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Copyright (c) 1986-1996,1998 by Sun Microsystems, Inc. - * All rights reserved. - */ -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <stdio.h> -#include <errno.h> -#include <netdb.h> -#include <syslog.h> -#include <rpc/rpc.h> -#include <rpc/nettype.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include "un-namespace.h" -#include "rpc_com.h" - -extern bool_t __rpc_is_local_host(const char *); -int __rpc_raise_fd(int); - -#ifndef NETIDLEN -#define NETIDLEN 32 -#endif - - -/* - * Generic client creation with version checking the value of - * vers_out is set to the highest server supported value - * vers_low <= vers_out <= vers_high AND an error results - * if this can not be done. - * - * It calls clnt_create_vers_timed() with a NULL value for the timeout - * pointer, which indicates that the default timeout should be used. - */ -CLIENT * -clnt_create_vers(const char *hostname, rpcprog_t prog, rpcvers_t *vers_out, - rpcvers_t vers_low, rpcvers_t vers_high, const char *nettype) -{ - - return (clnt_create_vers_timed(hostname, prog, vers_out, vers_low, - vers_high, nettype, NULL)); -} - -/* - * This the routine has the same definition as clnt_create_vers(), - * except it takes an additional timeout parameter - a pointer to - * a timeval structure. A NULL value for the pointer indicates - * that the default timeout value should be used. - */ -CLIENT * -clnt_create_vers_timed(const char *hostname, rpcprog_t prog, - rpcvers_t *vers_out, rpcvers_t vers_low, rpcvers_t vers_high, - const char *nettype, const struct timeval *tp) -{ - CLIENT *clnt; - struct timeval to; - enum clnt_stat rpc_stat; - struct rpc_err rpcerr; - - clnt = clnt_create_timed(hostname, prog, vers_high, nettype, tp); - if (clnt == NULL) { - return (NULL); - } - to.tv_sec = 10; - to.tv_usec = 0; - rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void, - (char *)NULL, (xdrproc_t)xdr_void, (char *)NULL, to); - if (rpc_stat == RPC_SUCCESS) { - *vers_out = vers_high; - return (clnt); - } - while (rpc_stat == RPC_PROGVERSMISMATCH && vers_high > vers_low) { - unsigned int minvers, maxvers; - - clnt_geterr(clnt, &rpcerr); - minvers = rpcerr.re_vers.low; - maxvers = rpcerr.re_vers.high; - if (maxvers < vers_high) - vers_high = maxvers; - else - vers_high--; - if (minvers > vers_low) - vers_low = minvers; - if (vers_low > vers_high) { - goto error; - } - CLNT_CONTROL(clnt, CLSET_VERS, (char *)&vers_high); - rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void, - (char *)NULL, (xdrproc_t)xdr_void, - (char *)NULL, to); - if (rpc_stat == RPC_SUCCESS) { - *vers_out = vers_high; - return (clnt); - } - } - clnt_geterr(clnt, &rpcerr); - -error: - rpc_createerr.cf_stat = rpc_stat; - rpc_createerr.cf_error = rpcerr; - clnt_destroy(clnt); - return (NULL); -} - -/* - * Top level client creation routine. - * Generic client creation: takes (servers name, program-number, nettype) and - * returns client handle. Default options are set, which the user can - * change using the rpc equivalent of _ioctl()'s. - * - * It tries for all the netids in that particular class of netid until - * it succeeds. - * XXX The error message in the case of failure will be the one - * pertaining to the last create error. - * - * It calls clnt_create_timed() with the default timeout. - */ -CLIENT * -clnt_create(const char *hostname, rpcprog_t prog, rpcvers_t vers, - const char *nettype) -{ - - return (clnt_create_timed(hostname, prog, vers, nettype, NULL)); -} - -/* - * This the routine has the same definition as clnt_create(), - * except it takes an additional timeout parameter - a pointer to - * a timeval structure. A NULL value for the pointer indicates - * that the default timeout value should be used. - * - * This function calls clnt_tp_create_timed(). - */ -CLIENT * -clnt_create_timed(const char *hostname, rpcprog_t prog, rpcvers_t vers, - const char *netclass, const struct timeval *tp) -{ - struct netconfig *nconf; - CLIENT *clnt = NULL; - void *handle; - enum clnt_stat save_cf_stat = RPC_SUCCESS; - struct rpc_err save_cf_error; - char nettype_array[NETIDLEN]; - char *nettype = &nettype_array[0]; - - if (netclass == NULL) - nettype = NULL; - else { - size_t len = strlen(netclass); - if (len >= sizeof (nettype_array)) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - strcpy(nettype, netclass); - } - - if ((handle = __rpc_setconf((char *)nettype)) == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - rpc_createerr.cf_stat = RPC_SUCCESS; - while (clnt == NULL) { - if ((nconf = __rpc_getconf(handle)) == NULL) { - if (rpc_createerr.cf_stat == RPC_SUCCESS) - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - break; - } -#ifdef CLNT_DEBUG - printf("trying netid %s\n", nconf->nc_netid); -#endif - clnt = clnt_tp_create_timed(hostname, prog, vers, nconf, tp); - if (clnt) - break; - else - /* - * Since we didn't get a name-to-address - * translation failure here, we remember - * this particular error. The object of - * this is to enable us to return to the - * caller a more-specific error than the - * unhelpful ``Name to address translation - * failed'' which might well occur if we - * merely returned the last error (because - * the local loopbacks are typically the - * last ones in /etc/netconfig and the most - * likely to be unable to translate a host - * name). We also check for a more - * meaningful error than ``unknown host - * name'' for the same reasons. - */ - if (rpc_createerr.cf_stat != RPC_N2AXLATEFAILURE && - rpc_createerr.cf_stat != RPC_UNKNOWNHOST) { - save_cf_stat = rpc_createerr.cf_stat; - save_cf_error = rpc_createerr.cf_error; - } - } - - /* - * Attempt to return an error more specific than ``Name to address - * translation failed'' or ``unknown host name'' - */ - if ((rpc_createerr.cf_stat == RPC_N2AXLATEFAILURE || - rpc_createerr.cf_stat == RPC_UNKNOWNHOST) && - (save_cf_stat != RPC_SUCCESS)) { - rpc_createerr.cf_stat = save_cf_stat; - rpc_createerr.cf_error = save_cf_error; - } - __rpc_endconf(handle); - return (clnt); -} - -/* - * Generic client creation: takes (servers name, program-number, netconf) and - * returns client handle. Default options are set, which the user can - * change using the rpc equivalent of _ioctl()'s : clnt_control() - * It finds out the server address from rpcbind and calls clnt_tli_create(). - * - * It calls clnt_tp_create_timed() with the default timeout. - */ -CLIENT * -clnt_tp_create(const char *hostname, rpcprog_t prog, rpcvers_t vers, - const struct netconfig *nconf) -{ - - return (clnt_tp_create_timed(hostname, prog, vers, nconf, NULL)); -} - -/* - * This has the same definition as clnt_tp_create(), except it - * takes an additional parameter - a pointer to a timeval structure. - * A NULL value for the timeout pointer indicates that the default - * value for the timeout should be used. - */ -CLIENT * -clnt_tp_create_timed(const char *hostname, rpcprog_t prog, rpcvers_t vers, - const struct netconfig *nconf, const struct timeval *tp) -{ - struct netbuf *svcaddr; /* servers address */ - CLIENT *cl = NULL; /* client handle */ - - if (nconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - - /* - * Get the address of the server - */ - if ((svcaddr = __rpcb_findaddr_timed(prog, vers, - (struct netconfig *)nconf, (char *)hostname, - &cl, (struct timeval *)tp)) == NULL) { - /* appropriate error number is set by rpcbind libraries */ - return (NULL); - } - if (cl == NULL) { - cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr, - prog, vers, 0, 0); - } else { - /* Reuse the CLIENT handle and change the appropriate fields */ - if (CLNT_CONTROL(cl, CLSET_SVC_ADDR, (void *)svcaddr) == TRUE) { - if (cl->cl_netid == NULL) - cl->cl_netid = strdup(nconf->nc_netid); - if (cl->cl_tp == NULL) - cl->cl_tp = strdup(nconf->nc_device); - (void) CLNT_CONTROL(cl, CLSET_PROG, (void *)&prog); - (void) CLNT_CONTROL(cl, CLSET_VERS, (void *)&vers); - } else { - CLNT_DESTROY(cl); - cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr, - prog, vers, 0, 0); - } - } - free(svcaddr->buf); - free(svcaddr); - return (cl); -} - -/* - * Generic client creation: returns client handle. - * Default options are set, which the user can - * change using the rpc equivalent of _ioctl()'s : clnt_control(). - * If fd is RPC_ANYFD, it will be opened using nconf. - * It will be bound if not so. - * If sizes are 0; appropriate defaults will be chosen. - */ -CLIENT * -clnt_tli_create(int fd, const struct netconfig *nconf, - struct netbuf *svcaddr, rpcprog_t prog, rpcvers_t vers, - uint sendsz, uint recvsz) -{ - CLIENT *cl; /* client handle */ - bool_t madefd = FALSE; /* whether fd opened here */ - long servtype; - int one = 1; - struct __rpc_sockinfo si; - extern int __rpc_minfd; - - if (fd == RPC_ANYFD) { - if (nconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - - fd = __rpc_nconf2fd(nconf); - - if (fd == -1) - goto err; - if (fd < __rpc_minfd) - fd = __rpc_raise_fd(fd); - madefd = TRUE; - servtype = nconf->nc_semantics; - if (!__rpc_fd2sockinfo(fd, &si)) - goto err; - bindresvport(fd, NULL); - } else { - if (!__rpc_fd2sockinfo(fd, &si)) - goto err; - servtype = __rpc_socktype2seman(si.si_socktype); - if (servtype == -1) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - } - - if (si.si_af != ((struct sockaddr *)svcaddr->buf)->sa_family) { - rpc_createerr.cf_stat = RPC_UNKNOWNHOST; /* XXX */ - goto err1; - } - - switch (servtype) { - case NC_TPI_COTS: - cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz); - break; - case NC_TPI_COTS_ORD: - if (nconf && ((strcmp(nconf->nc_protofmly, "inet") == 0))) { - _setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, - sizeof (one)); - } - cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz); - break; - case NC_TPI_CLTS: - cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz); - break; - default: - goto err; - } - - if (cl == NULL) - goto err1; /* borrow errors from clnt_dg/vc creates */ - if (nconf) { - cl->cl_netid = strdup(nconf->nc_netid); - cl->cl_tp = strdup(nconf->nc_device); - } else { - cl->cl_netid = ""; - cl->cl_tp = ""; - } - if (madefd) { - (void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); -/* (void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, NULL); */ - }; - - return (cl); - -err: - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; -err1: if (madefd) - (void)_close(fd); - return (NULL); -} - -/* - * To avoid conflicts with the "magic" file descriptors (0, 1, and 2), - * we try to not use them. The __rpc_raise_fd() routine will dup - * a descriptor to a higher value. If we fail to do it, we continue - * to use the old one (and hope for the best). - */ -int __rpc_minfd = 3; - -int -__rpc_raise_fd(int fd) -{ - int nfd; - - if (fd >= __rpc_minfd) - return (fd); - - if ((nfd = _fcntl(fd, F_DUPFD, __rpc_minfd)) == -1) - return (fd); - - if (_fsync(nfd) == -1) { - _close(nfd); - return (fd); - } - - if (_close(fd) == -1) { - /* this is okay, we will syslog an error, then use the new fd */ - (void) syslog(LOG_ERR, - "could not close() fd %d; mem & fd leak", fd); - } - - return (nfd); -} diff --git a/lib/libc/rpc/clnt_perror.c b/lib/libc/rpc/clnt_perror.c deleted file mode 100644 index efe9043..0000000 --- a/lib/libc/rpc/clnt_perror.c +++ /dev/null @@ -1,333 +0,0 @@ -/* $NetBSD: clnt_perror.c,v 1.24 2000/06/02 23:11:07 fvdl Exp $ */ - - -/* - * 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 *sccsid2 = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * clnt_perror.c - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - */ -#include "namespace.h" -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <rpc/rpc.h> -#include <rpc/types.h> -#include <rpc/auth.h> -#include <rpc/clnt.h> -#include "un-namespace.h" - -static char *buf; - -static char *_buf(void); -static char *auth_errmsg(enum auth_stat); -#define CLNT_PERROR_BUFLEN 256 - -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; - const char *s; -{ - struct rpc_err e; - char *err; - char *str; - char *strstart; - size_t len, i; - - assert(rpch != NULL); - assert(s != NULL); - - str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */ - if (str == 0) - return (0); - len = CLNT_PERROR_BUFLEN; - strstart = str; - CLNT_GETERR(rpch, &e); - - if ((i = snprintf(str, len, "%s: ", s)) > 0) { - str += i; - len -= i; - } - - (void)strncpy(str, clnt_sperrno(e.re_status), len - 1); - i = strlen(str); - str += i; - len -= i; - - 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: - i = snprintf(str, len, "; errno = %s", strerror(e.re_errno)); - if (i > 0) { - str += i; - len -= i; - } - break; - - case RPC_VERSMISMATCH: - i = snprintf(str, len, "; low version = %u, high version = %u", - e.re_vers.low, e.re_vers.high); - if (i > 0) { - str += i; - len -= i; - } - break; - - case RPC_AUTHERROR: - err = auth_errmsg(e.re_why); - i = snprintf(str, len, "; why = "); - if (i > 0) { - str += i; - len -= i; - } - if (err != NULL) { - i = snprintf(str, len, "%s",err); - } else { - i = snprintf(str, len, - "(unknown authentication error - %d)", - (int) e.re_why); - } - if (i > 0) { - str += i; - len -= i; - } - break; - - case RPC_PROGVERSMISMATCH: - i = snprintf(str, len, "; low version = %u, high version = %u", - e.re_vers.low, e.re_vers.high); - if (i > 0) { - str += i; - len -= i; - } - break; - - default: /* unknown */ - i = snprintf(str, len, "; s1 = %u, s2 = %u", - e.re_lb.s1, e.re_lb.s2); - if (i > 0) { - str += i; - len -= i; - } - break; - } - strstart[CLNT_PERROR_BUFLEN-1] = '\0'; - return(strstart) ; -} - -void -clnt_perror(rpch, s) - CLIENT *rpch; - const char *s; -{ - - assert(rpch != NULL); - assert(s != NULL); - - (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]))) - /* LINTED interface problem */ - 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) - const char *s; -{ - char *str; - size_t len, i; - - assert(s != NULL); - - str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */ - if (str == 0) - return(0); - len = CLNT_PERROR_BUFLEN; - i = snprintf(str, len, "%s: ", s); - if (i > 0) - len -= i; - (void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1); - switch (rpc_createerr.cf_stat) { - case RPC_PMAPFAILURE: - (void) strncat(str, " - ", len - 1); - (void) strncat(str, - clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4); - break; - - case RPC_SYSTEMERROR: - (void)strncat(str, " - ", len - 1); - (void)strncat(str, strerror(rpc_createerr.cf_error.re_errno), - len - 4); - break; - - case RPC_CANTSEND: - case RPC_CANTDECODERES: - case RPC_CANTENCODEARGS: - case RPC_SUCCESS: - case RPC_UNKNOWNPROTO: - case RPC_PROGNOTREGISTERED: - case RPC_FAILED: - case RPC_UNKNOWNHOST: - case RPC_CANTDECODEARGS: - case RPC_PROCUNAVAIL: - case RPC_PROGVERSMISMATCH: - case RPC_PROGUNAVAIL: - case RPC_AUTHERROR: - case RPC_VERSMISMATCH: - case RPC_TIMEDOUT: - case RPC_CANTRECV: - default: - break; - } - str[CLNT_PERROR_BUFLEN-1] = '\0'; - return (str); -} - -void -clnt_pcreateerror(s) - const char *s; -{ - - assert(s != NULL); - - (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 */ - "Kerberos generic error", /* 8 - AUTH_KERB_GENERIC*/ - "Kerberos credential expired", /* 9 - AUTH_TIMEEXPIRE */ - "Bad kerberos ticket file", /* 10 - AUTH_TKT_FILE */ - "Can't decode kerberos authenticator", /* 11 - AUTH_DECODE */ - "Address wrong in kerberos ticket", /* 12 - AUTH_NET_ADDR */ - "GSS-API crediential problem", /* 13 - RPCSEC_GSS_CREDPROBLEM */ - "GSS-API context problem" /* 14 - RPCSEC_GSS_CTXPROBLEM */ -}; - -static char * -auth_errmsg(stat) - enum auth_stat stat; -{ - unsigned int errnum = stat; - - if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0]))) - /* LINTED interface problem */ - return (char *)auth_errlist[errnum]; - - return(NULL); -} diff --git a/lib/libc/rpc/clnt_raw.c b/lib/libc/rpc/clnt_raw.c deleted file mode 100644 index cd3a384..0000000 --- a/lib/libc/rpc/clnt_raw.c +++ /dev/null @@ -1,315 +0,0 @@ -/* $NetBSD: clnt_raw.c,v 1.20 2000/12/10 04:12:03 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 kernel. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <assert.h> -#include <err.h> -#include <stdio.h> -#include <stdlib.h> - -#include <rpc/rpc.h> -#include <rpc/raw.h> -#include "un-namespace.h" -#include "mt_misc.h" - -#define MCALL_MSG_SIZE 24 - -/* - * This is the "network" we will be moving stuff over. - */ -static struct clntraw_private { - CLIENT client_object; - XDR xdr_stream; - char *_raw_buf; - union { - struct rpc_msg mashl_rpcmsg; - char mashl_callmsg[MCALL_MSG_SIZE]; - } u; - u_int mcnt; -} *clntraw_private; - -static enum clnt_stat clnt_raw_call(CLIENT *, rpcproc_t, xdrproc_t, void *, - xdrproc_t, void *, struct timeval); -static void clnt_raw_geterr(CLIENT *, struct rpc_err *); -static bool_t clnt_raw_freeres(CLIENT *, xdrproc_t, void *); -static void clnt_raw_abort(CLIENT *); -static bool_t clnt_raw_control(CLIENT *, u_int, void *); -static void clnt_raw_destroy(CLIENT *); -static struct clnt_ops *clnt_raw_ops(void); - -/* - * Create a client handle for memory based rpc. - */ -CLIENT * -clnt_raw_create(prog, vers) - rpcprog_t prog; - rpcvers_t vers; -{ - struct clntraw_private *clp; - struct rpc_msg call_msg; - XDR *xdrs; - CLIENT *client; - - mutex_lock(&clntraw_lock); - if ((clp = clntraw_private) == NULL) { - clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); - if (clp == NULL) { - mutex_unlock(&clntraw_lock); - return NULL; - } - if (__rpc_rawcombuf == NULL) - __rpc_rawcombuf = - (char *)calloc(UDPMSGSIZE, sizeof (char)); - clp->_raw_buf = __rpc_rawcombuf; - clntraw_private = clp; - } - xdrs = &clp->xdr_stream; - client = &clp->client_object; - - /* - * 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; - /* XXX: prog and vers have been long historically :-( */ - call_msg.rm_call.cb_prog = (u_int32_t)prog; - call_msg.rm_call.cb_vers = (u_int32_t)vers; - xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); - if (! xdr_callhdr(xdrs, &call_msg)) - warnx("clntraw_create - 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 = clnt_raw_ops(); - client->cl_auth = authnone_create(); - mutex_unlock(&clntraw_lock); - return (client); -} - -/* ARGSUSED */ -static enum clnt_stat -clnt_raw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) - CLIENT *h; - rpcproc_t proc; - xdrproc_t xargs; - void *argsp; - xdrproc_t xresults; - void *resultsp; - struct timeval timeout; -{ - struct clntraw_private *clp = clntraw_private; - XDR *xdrs = &clp->xdr_stream; - struct rpc_msg msg; - enum clnt_stat status; - struct rpc_err error; - - assert(h != NULL); - - mutex_lock(&clntraw_lock); - if (clp == NULL) { - mutex_unlock(&clntraw_lock); - return (RPC_FAILED); - } - mutex_unlock(&clntraw_lock); - -call_again: - /* - * send request - */ - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, 0); - clp->u.mashl_rpcmsg.rm_xid ++ ; - if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) || - (! XDR_PUTINT32(xdrs, &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_common(FD_SETSIZE); - - /* - * 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)) { - /* - * 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 = xdrs->x_op; - xdrs->x_op = XDR_FREE; - xdr_replymsg(xdrs, &msg); - xdrs->x_op = op; - 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, &msg)) - 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); -} - -/*ARGSUSED*/ -static void -clnt_raw_geterr(cl, err) - CLIENT *cl; - struct rpc_err *err; -{ -} - - -/* ARGSUSED */ -static bool_t -clnt_raw_freeres(cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - void *res_ptr; -{ - struct clntraw_private *clp = clntraw_private; - XDR *xdrs = &clp->xdr_stream; - bool_t rval; - - mutex_lock(&clntraw_lock); - if (clp == NULL) { - rval = (bool_t) RPC_FAILED; - mutex_unlock(&clntraw_lock); - return (rval); - } - mutex_unlock(&clntraw_lock); - xdrs->x_op = XDR_FREE; - return ((*xdr_res)(xdrs, res_ptr)); -} - -/*ARGSUSED*/ -static void -clnt_raw_abort(cl) - CLIENT *cl; -{ -} - -/*ARGSUSED*/ -static bool_t -clnt_raw_control(cl, ui, str) - CLIENT *cl; - u_int ui; - void *str; -{ - return (FALSE); -} - -/*ARGSUSED*/ -static void -clnt_raw_destroy(cl) - CLIENT *cl; -{ -} - -static struct clnt_ops * -clnt_raw_ops() -{ - static struct clnt_ops ops; - - /* VARIABLES PROTECTED BY ops_lock: ops */ - - mutex_lock(&ops_lock); - if (ops.cl_call == NULL) { - ops.cl_call = clnt_raw_call; - ops.cl_abort = clnt_raw_abort; - ops.cl_geterr = clnt_raw_geterr; - ops.cl_freeres = clnt_raw_freeres; - ops.cl_destroy = clnt_raw_destroy; - ops.cl_control = clnt_raw_control; - } - mutex_unlock(&ops_lock); - return (&ops); -} diff --git a/lib/libc/rpc/clnt_simple.c b/lib/libc/rpc/clnt_simple.c deleted file mode 100644 index ba21d2d..0000000 --- a/lib/libc/rpc/clnt_simple.c +++ /dev/null @@ -1,206 +0,0 @@ -/* $NetBSD: clnt_simple.c,v 1.21 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char *sccsid2 = "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"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * clnt_simple.c - * Simplified front end to client rpc. - * - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/param.h> -#include <stdio.h> -#include <errno.h> -#include <rpc/rpc.h> -#include <string.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include "un-namespace.h" -#include "mt_misc.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#ifndef NETIDLEN -#define NETIDLEN 32 -#endif - -struct rpc_call_private { - int valid; /* Is this entry valid ? */ - CLIENT *client; /* Client handle */ - pid_t pid; /* process-id at moment of creation */ - rpcprog_t prognum; /* Program */ - rpcvers_t versnum; /* Version */ - char host[MAXHOSTNAMELEN]; /* Servers host */ - char nettype[NETIDLEN]; /* Network type */ -}; -static struct rpc_call_private *rpc_call_private_main; -static thread_key_t rpc_call_key; -static once_t rpc_call_once = ONCE_INITIALIZER; -static int rpc_call_key_error; - -static void rpc_call_key_init(void); -static void rpc_call_destroy(void *); - -static void -rpc_call_destroy(void *vp) -{ - struct rpc_call_private *rcp = (struct rpc_call_private *)vp; - - if (rcp) { - if (rcp->client) - CLNT_DESTROY(rcp->client); - free(rcp); - } -} - -static void -rpc_call_key_init(void) -{ - - rpc_call_key_error = thr_keycreate(&rpc_call_key, rpc_call_destroy); -} - -/* - * This is the simplified interface to the client rpc layer. - * The client handle is not destroyed here and is reused for - * the future calls to same prog, vers, host and nettype combination. - * - * The total time available is 25 seconds. - */ -enum clnt_stat -rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype) - const char *host; /* host name */ - rpcprog_t prognum; /* program number */ - rpcvers_t versnum; /* version number */ - rpcproc_t procnum; /* procedure number */ - xdrproc_t inproc, outproc; /* in/out XDR procedures */ - const char *in; - char *out; /* recv/send data */ - const char *nettype; /* nettype */ -{ - struct rpc_call_private *rcp = (struct rpc_call_private *) 0; - enum clnt_stat clnt_stat; - struct timeval timeout, tottimeout; - int main_thread = 1; - - if ((main_thread = thr_main())) { - rcp = rpc_call_private_main; - } else { - if (thr_once(&rpc_call_once, rpc_call_key_init) != 0 || - rpc_call_key_error != 0) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = rpc_call_key_error; - return (rpc_createerr.cf_stat); - } - rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key); - } - if (rcp == NULL) { - rcp = malloc(sizeof (*rcp)); - if (rcp == NULL) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - return (rpc_createerr.cf_stat); - } - if (main_thread) - rpc_call_private_main = rcp; - else - thr_setspecific(rpc_call_key, (void *) rcp); - rcp->valid = 0; - rcp->client = NULL; - } - if ((nettype == NULL) || (nettype[0] == 0)) - nettype = "netpath"; - if (!(rcp->valid && rcp->pid == getpid() && - (rcp->prognum == prognum) && - (rcp->versnum == versnum) && - (!strcmp(rcp->host, host)) && - (!strcmp(rcp->nettype, nettype)))) { - int fd; - - rcp->valid = 0; - if (rcp->client) - CLNT_DESTROY(rcp->client); - /* - * Using the first successful transport for that type - */ - rcp->client = clnt_create(host, prognum, versnum, nettype); - rcp->pid = getpid(); - if (rcp->client == NULL) { - return (rpc_createerr.cf_stat); - } - /* - * Set time outs for connectionless case. Do it - * unconditionally. Faster than doing a t_getinfo() - * and then doing the right thing. - */ - timeout.tv_usec = 0; - timeout.tv_sec = 5; - (void) CLNT_CONTROL(rcp->client, - CLSET_RETRY_TIMEOUT, (char *)(void *)&timeout); - if (CLNT_CONTROL(rcp->client, CLGET_FD, (char *)(void *)&fd)) - _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */ - rcp->prognum = prognum; - rcp->versnum = versnum; - if ((strlen(host) < (size_t)MAXHOSTNAMELEN) && - (strlen(nettype) < (size_t)NETIDLEN)) { - (void) strcpy(rcp->host, host); - (void) strcpy(rcp->nettype, nettype); - rcp->valid = 1; - } else { - rcp->valid = 0; - } - } /* else reuse old client */ - tottimeout.tv_sec = 25; - tottimeout.tv_usec = 0; - /*LINTED const castaway*/ - clnt_stat = CLNT_CALL(rcp->client, procnum, inproc, (char *) in, - outproc, out, tottimeout); - /* - * if call failed, empty cache - */ - if (clnt_stat != RPC_SUCCESS) - rcp->valid = 0; - return (clnt_stat); -} diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c deleted file mode 100644 index 07eff46..0000000 --- a/lib/libc/rpc/clnt_vc.c +++ /dev/null @@ -1,871 +0,0 @@ -/* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */ - -/* - * 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 *sccsid2 = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC"; -static char sccsid3[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/poll.h> -#include <sys/syslog.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/uio.h> - -#include <arpa/inet.h> -#include <assert.h> -#include <err.h> -#include <errno.h> -#include <netdb.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> - -#include <rpc/rpc.h> -#include <rpc/rpcsec_gss.h> -#include "un-namespace.h" -#include "rpc_com.h" -#include "mt_misc.h" - -#define MCALL_MSG_SIZE 24 - -struct cmessage { - struct cmsghdr cmsg; - struct cmsgcred cmcred; -}; - -static enum clnt_stat clnt_vc_call(CLIENT *, rpcproc_t, xdrproc_t, void *, - xdrproc_t, void *, struct timeval); -static void clnt_vc_geterr(CLIENT *, struct rpc_err *); -static bool_t clnt_vc_freeres(CLIENT *, xdrproc_t, void *); -static void clnt_vc_abort(CLIENT *); -static bool_t clnt_vc_control(CLIENT *, u_int, void *); -static void clnt_vc_destroy(CLIENT *); -static struct clnt_ops *clnt_vc_ops(void); -static bool_t time_not_ok(struct timeval *); -static int read_vc(void *, void *, int); -static int write_vc(void *, void *, int); -static int __msgwrite(int, void *, size_t); -static int __msgread(int, void *, size_t); - -struct ct_data { - int ct_fd; /* connection's fd */ - bool_t ct_closeit; /* close it on destroy */ - struct timeval ct_wait; /* wait interval in milliseconds */ - bool_t ct_waitset; /* wait set by clnt_control? */ - struct netbuf ct_addr; /* remote addr */ - struct rpc_err ct_error; - union { - char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */ - u_int32_t ct_mcalli; - } ct_u; - u_int ct_mpos; /* pos after marshal */ - XDR ct_xdrs; /* XDR stream */ -}; - -/* - * This machinery implements per-fd locks for MT-safety. It is not - * sufficient to do per-CLIENT handle locks for MT-safety because a - * user may create more than one CLIENT handle with the same fd behind - * it. Therfore, we allocate an array of flags (vc_fd_locks), protected - * by the clnt_fd_lock mutex, and an array (vc_cv) of condition variables - * similarly protected. Vc_fd_lock[fd] == 1 => a call is activte on some - * CLIENT handle created for that fd. - * The current implementation holds locks across the entire RPC and reply. - * Yes, this is silly, and as soon as this code is proven to work, this - * should be the first thing fixed. One step at a time. - */ -static int *vc_fd_locks; -static cond_t *vc_cv; -#define release_fd_lock(fd, mask) { \ - mutex_lock(&clnt_fd_lock); \ - vc_fd_locks[fd] = 0; \ - mutex_unlock(&clnt_fd_lock); \ - thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \ - cond_signal(&vc_cv[fd]); \ -} - -static const char clnt_vc_errstr[] = "%s : %s"; -static const char clnt_vc_str[] = "clnt_vc_create"; -static const char clnt_read_vc_str[] = "read_vc"; -static const char __no_mem_str[] = "out of memory"; - -/* - * Create a client handle for a connection. - * Default options are set, which the user can change using clnt_control()'s. - * The rpc/vc package does buffering similar to stdio, so the client - * must pick send and receive buffer sizes, 0 => use the default. - * NB: fd is copied into a private area. - * NB: The rpch->cl_auth is set null authentication. Caller may wish to - * set this something more useful. - * - * fd should be an open socket - */ -CLIENT * -clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) - int fd; /* open file descriptor */ - const struct netbuf *raddr; /* servers address */ - const rpcprog_t prog; /* program number */ - const rpcvers_t vers; /* version number */ - u_int sendsz; /* buffer recv size */ - u_int recvsz; /* buffer send size */ -{ - CLIENT *cl; /* client handle */ - struct ct_data *ct = NULL; /* client handle */ - struct timeval now; - struct rpc_msg call_msg; - static u_int32_t disrupt; - sigset_t mask; - sigset_t newmask; - struct sockaddr_storage ss; - socklen_t slen; - struct __rpc_sockinfo si; - - if (disrupt == 0) - disrupt = (u_int32_t)(long)raddr; - - cl = (CLIENT *)mem_alloc(sizeof (*cl)); - ct = (struct ct_data *)mem_alloc(sizeof (*ct)); - if ((cl == (CLIENT *)NULL) || (ct == (struct ct_data *)NULL)) { - (void) syslog(LOG_ERR, clnt_vc_errstr, - clnt_vc_str, __no_mem_str); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - goto err; - } - ct->ct_addr.buf = NULL; - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - if (vc_fd_locks == (int *) NULL) { - int cv_allocsz, fd_allocsz; - int dtbsize = __rpc_dtbsize(); - - fd_allocsz = dtbsize * sizeof (int); - vc_fd_locks = (int *) mem_alloc(fd_allocsz); - if (vc_fd_locks == (int *) NULL) { - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - goto err; - } else - memset(vc_fd_locks, '\0', fd_allocsz); - - assert(vc_cv == (cond_t *) NULL); - cv_allocsz = dtbsize * sizeof (cond_t); - vc_cv = (cond_t *) mem_alloc(cv_allocsz); - if (vc_cv == (cond_t *) NULL) { - mem_free(vc_fd_locks, fd_allocsz); - vc_fd_locks = (int *) NULL; - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - goto err; - } else { - int i; - - for (i = 0; i < dtbsize; i++) - cond_init(&vc_cv[i], 0, (void *) 0); - } - } else - assert(vc_cv != (cond_t *) NULL); - - /* - * XXX - fvdl connecting while holding a mutex? - */ - slen = sizeof ss; - if (_getpeername(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) { - if (errno != ENOTCONN) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - goto err; - } - if (_connect(fd, (struct sockaddr *)raddr->buf, raddr->len) < 0){ - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - goto err; - } - } - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - if (!__rpc_fd2sockinfo(fd, &si)) - goto err; - - ct->ct_closeit = FALSE; - - /* - * Set up private data struct - */ - ct->ct_fd = fd; - ct->ct_wait.tv_usec = 0; - ct->ct_waitset = FALSE; - ct->ct_addr.buf = malloc(raddr->maxlen); - if (ct->ct_addr.buf == NULL) - goto err; - memcpy(ct->ct_addr.buf, raddr->buf, raddr->len); - ct->ct_addr.len = raddr->maxlen; - ct->ct_addr.maxlen = raddr->maxlen; - - /* - * Initialize call message - */ - (void)gettimeofday(&now, NULL); - call_msg.rm_xid = ((u_int32_t)++disrupt) ^ __RPC_GETXID(&now); - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = (u_int32_t)prog; - call_msg.rm_call.cb_vers = (u_int32_t)vers; - - /* - * pre-serialize the static part of the call msg and stash it away - */ - xdrmem_create(&(ct->ct_xdrs), ct->ct_u.ct_mcallc, MCALL_MSG_SIZE, - XDR_ENCODE); - if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { - if (ct->ct_closeit) { - (void)_close(fd); - } - goto err; - } - ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); - XDR_DESTROY(&(ct->ct_xdrs)); - assert(ct->ct_mpos + sizeof(uint32_t) <= MCALL_MSG_SIZE); - - /* - * Create a client handle which uses xdrrec for serialization - * and authnone for authentication. - */ - cl->cl_ops = clnt_vc_ops(); - cl->cl_private = ct; - cl->cl_auth = authnone_create(); - sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz); - recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz); - xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, - cl->cl_private, read_vc, write_vc); - return (cl); - -err: - if (cl) { - if (ct) { - if (ct->ct_addr.len) - mem_free(ct->ct_addr.buf, ct->ct_addr.len); - mem_free(ct, sizeof (struct ct_data)); - } - if (cl) - mem_free(cl, sizeof (CLIENT)); - } - return ((CLIENT *)NULL); -} - -static enum clnt_stat -clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) - CLIENT *cl; - rpcproc_t proc; - xdrproc_t xdr_args; - void *args_ptr; - xdrproc_t xdr_results; - void *results_ptr; - struct timeval timeout; -{ - struct ct_data *ct = (struct ct_data *) cl->cl_private; - XDR *xdrs = &(ct->ct_xdrs); - struct rpc_msg reply_msg; - u_int32_t x_id; - u_int32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */ - bool_t shipnow; - int refreshes = 2; - sigset_t mask, newmask; - int rpc_lock_value; - bool_t reply_stat; - - assert(cl != NULL); - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (vc_fd_locks[ct->ct_fd]) - cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); - if (__isthreaded) - rpc_lock_value = 1; - else - rpc_lock_value = 0; - vc_fd_locks[ct->ct_fd] = rpc_lock_value; - mutex_unlock(&clnt_fd_lock); - if (!ct->ct_waitset) { - /* If time is not within limits, we ignore it. */ - if (time_not_ok(&timeout) == FALSE) - ct->ct_wait = timeout; - } - - shipnow = - (xdr_results == NULL && 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 (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) { - if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) || - (! XDR_PUTINT32(xdrs, &proc)) || - (! AUTH_MARSHALL(cl->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); - release_fd_lock(ct->ct_fd, mask); - return (ct->ct_error.re_status); - } - } else { - *(uint32_t *) &ct->ct_u.ct_mcallc[ct->ct_mpos] = htonl(proc); - if (! __rpc_gss_wrap(cl->cl_auth, ct->ct_u.ct_mcallc, - ct->ct_mpos + sizeof(uint32_t), - xdrs, xdr_args, args_ptr)) { - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTENCODEARGS; - (void)xdrrec_endofrecord(xdrs, TRUE); - release_fd_lock(ct->ct_fd, mask); - return (ct->ct_error.re_status); - } - } - if (! xdrrec_endofrecord(xdrs, shipnow)) { - release_fd_lock(ct->ct_fd, mask); - return (ct->ct_error.re_status = RPC_CANTSEND); - } - if (! shipnow) { - release_fd_lock(ct->ct_fd, mask); - return (RPC_SUCCESS); - } - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { - release_fd_lock(ct->ct_fd, mask); - 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 = (xdrproc_t)xdr_void; - if (! xdrrec_skiprecord(xdrs)) { - release_fd_lock(ct->ct_fd, mask); - 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; - release_fd_lock(ct->ct_fd, mask); - 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(cl->cl_auth, - &reply_msg.acpted_rply.ar_verf)) { - ct->ct_error.re_status = RPC_AUTHERROR; - ct->ct_error.re_why = AUTH_INVALIDRESP; - } else { - if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) { - reply_stat = (*xdr_results)(xdrs, results_ptr); - } else { - reply_stat = __rpc_gss_unwrap(cl->cl_auth, - xdrs, xdr_results, results_ptr); - } - if (! reply_stat) { - 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(cl->cl_auth, &reply_msg)) - goto call_again; - } /* end of unsuccessful completion */ - release_fd_lock(ct->ct_fd, mask); - return (ct->ct_error.re_status); -} - -static void -clnt_vc_geterr(cl, errp) - CLIENT *cl; - struct rpc_err *errp; -{ - struct ct_data *ct; - - assert(cl != NULL); - assert(errp != NULL); - - ct = (struct ct_data *) cl->cl_private; - *errp = ct->ct_error; -} - -static bool_t -clnt_vc_freeres(cl, xdr_res, res_ptr) - CLIENT *cl; - xdrproc_t xdr_res; - void *res_ptr; -{ - struct ct_data *ct; - XDR *xdrs; - bool_t dummy; - sigset_t mask; - sigset_t newmask; - - assert(cl != NULL); - - ct = (struct ct_data *)cl->cl_private; - xdrs = &(ct->ct_xdrs); - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (vc_fd_locks[ct->ct_fd]) - cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); - xdrs->x_op = XDR_FREE; - dummy = (*xdr_res)(xdrs, res_ptr); - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - cond_signal(&vc_cv[ct->ct_fd]); - - return dummy; -} - -/*ARGSUSED*/ -static void -clnt_vc_abort(cl) - CLIENT *cl; -{ -} - -static bool_t -clnt_vc_control(cl, request, info) - CLIENT *cl; - u_int request; - void *info; -{ - struct ct_data *ct; - void *infop = info; - sigset_t mask; - sigset_t newmask; - int rpc_lock_value; - - assert(cl != NULL); - - ct = (struct ct_data *)cl->cl_private; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (vc_fd_locks[ct->ct_fd]) - cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); - if (__isthreaded) - rpc_lock_value = 1; - else - rpc_lock_value = 0; - vc_fd_locks[ct->ct_fd] = rpc_lock_value; - mutex_unlock(&clnt_fd_lock); - - switch (request) { - case CLSET_FD_CLOSE: - ct->ct_closeit = TRUE; - release_fd_lock(ct->ct_fd, mask); - return (TRUE); - case CLSET_FD_NCLOSE: - ct->ct_closeit = FALSE; - release_fd_lock(ct->ct_fd, mask); - return (TRUE); - default: - break; - } - - /* for other requests which use info */ - if (info == NULL) { - release_fd_lock(ct->ct_fd, mask); - return (FALSE); - } - switch (request) { - case CLSET_TIMEOUT: - if (time_not_ok((struct timeval *)info)) { - release_fd_lock(ct->ct_fd, mask); - return (FALSE); - } - ct->ct_wait = *(struct timeval *)infop; - ct->ct_waitset = TRUE; - break; - case CLGET_TIMEOUT: - *(struct timeval *)infop = ct->ct_wait; - break; - case CLGET_SERVER_ADDR: - (void) memcpy(info, ct->ct_addr.buf, (size_t)ct->ct_addr.len); - break; - case CLGET_FD: - *(int *)info = ct->ct_fd; - break; - case CLGET_SVC_ADDR: - /* The caller should not free this memory area */ - *(struct netbuf *)info = ct->ct_addr; - break; - case CLSET_SVC_ADDR: /* set to new address */ - release_fd_lock(ct->ct_fd, mask); - return (FALSE); - 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 - */ - *(u_int32_t *)info = - ntohl(*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli); - break; - case CLSET_XID: - /* This will set the xid of the NEXT call */ - *(u_int32_t *)(void *)&ct->ct_u.ct_mcalli = - htonl(*((u_int32_t *)info) + 1); - /* increment by 1 as clnt_vc_call() decrements once */ - break; - 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 - */ - *(u_int32_t *)info = - ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + - 4 * BYTES_PER_XDR_UNIT)); - break; - - case CLSET_VERS: - *(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + - 4 * BYTES_PER_XDR_UNIT) = - htonl(*(u_int32_t *)info); - break; - - case CLGET_PROG: - /* - * This RELIES on the information that, in the call body, - * the program number field is the fourth field from the - * begining of the RPC header. MUST be changed if the - * call_struct is changed - */ - *(u_int32_t *)info = - ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + - 3 * BYTES_PER_XDR_UNIT)); - break; - - case CLSET_PROG: - *(u_int32_t *)(void *)(ct->ct_u.ct_mcallc + - 3 * BYTES_PER_XDR_UNIT) = - htonl(*(u_int32_t *)info); - break; - - default: - release_fd_lock(ct->ct_fd, mask); - return (FALSE); - } - release_fd_lock(ct->ct_fd, mask); - return (TRUE); -} - - -static void -clnt_vc_destroy(cl) - CLIENT *cl; -{ - struct ct_data *ct = (struct ct_data *) cl->cl_private; - int ct_fd = ct->ct_fd; - sigset_t mask; - sigset_t newmask; - - assert(cl != NULL); - - ct = (struct ct_data *) cl->cl_private; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); - while (vc_fd_locks[ct_fd]) - cond_wait(&vc_cv[ct_fd], &clnt_fd_lock); - if (ct->ct_closeit && ct->ct_fd != -1) { - (void)_close(ct->ct_fd); - } - XDR_DESTROY(&(ct->ct_xdrs)); - if (ct->ct_addr.buf) - free(ct->ct_addr.buf); - mem_free(ct, sizeof(struct ct_data)); - mem_free(cl, sizeof(CLIENT)); - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - cond_signal(&vc_cv[ct_fd]); -} - -/* - * 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 -read_vc(ctp, buf, len) - void *ctp; - void *buf; - int len; -{ - struct sockaddr sa; - socklen_t sal; - struct ct_data *ct = (struct ct_data *)ctp; - struct pollfd fd; - int milliseconds = (int)((ct->ct_wait.tv_sec * 1000) + - (ct->ct_wait.tv_usec / 1000)); - - if (len == 0) - return (0); - fd.fd = ct->ct_fd; - fd.events = POLLIN; - for (;;) { - switch (_poll(&fd, 1, milliseconds)) { - case 0: - ct->ct_error.re_status = RPC_TIMEDOUT; - return (-1); - - case -1: - if (errno == EINTR) - continue; - ct->ct_error.re_status = RPC_CANTRECV; - ct->ct_error.re_errno = errno; - return (-1); - } - break; - } - - sal = sizeof(sa); - if ((_getpeername(ct->ct_fd, &sa, &sal) == 0) && - (sa.sa_family == AF_LOCAL)) { - len = __msgread(ct->ct_fd, buf, (size_t)len); - } else { - len = _read(ct->ct_fd, buf, (size_t)len); - } - - switch (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 -write_vc(ctp, buf, len) - void *ctp; - void *buf; - int len; -{ - struct sockaddr sa; - socklen_t sal; - struct ct_data *ct = (struct ct_data *)ctp; - int i, cnt; - - sal = sizeof(sa); - if ((_getpeername(ct->ct_fd, &sa, &sal) == 0) && - (sa.sa_family == AF_LOCAL)) { - for (cnt = len; cnt > 0; cnt -= i, buf = (char *)buf + i) { - if ((i = __msgwrite(ct->ct_fd, buf, - (size_t)cnt)) == -1) { - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTSEND; - return (-1); - } - } - } else { - for (cnt = len; cnt > 0; cnt -= i, buf = (char *)buf + i) { - if ((i = _write(ct->ct_fd, buf, (size_t)cnt)) == -1) { - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTSEND; - return (-1); - } - } - } - return (len); -} - -static struct clnt_ops * -clnt_vc_ops() -{ - static struct clnt_ops ops; - sigset_t mask, newmask; - - /* VARIABLES PROTECTED BY ops_lock: ops */ - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&ops_lock); - if (ops.cl_call == NULL) { - ops.cl_call = clnt_vc_call; - ops.cl_abort = clnt_vc_abort; - ops.cl_geterr = clnt_vc_geterr; - ops.cl_freeres = clnt_vc_freeres; - ops.cl_destroy = clnt_vc_destroy; - ops.cl_control = clnt_vc_control; - } - mutex_unlock(&ops_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); - return (&ops); -} - -/* - * Make sure that the time is not garbage. -1 value is disallowed. - * Note this is different from time_not_ok in clnt_dg.c - */ -static bool_t -time_not_ok(t) - struct timeval *t; -{ - return (t->tv_sec <= -1 || t->tv_sec > 100000000 || - t->tv_usec <= -1 || t->tv_usec > 1000000); -} - -static int -__msgread(sock, buf, cnt) - int sock; - void *buf; - size_t cnt; -{ - struct iovec iov[1]; - struct msghdr msg; - union { - struct cmsghdr cmsg; - char control[CMSG_SPACE(sizeof(struct cmsgcred))]; - } 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 = CMSG_SPACE(sizeof(struct cmsgcred)); - 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; - union { - struct cmsghdr cmsg; - char control[CMSG_SPACE(sizeof(struct cmsgcred))]; - } 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 = CMSG_LEN(sizeof(struct cmsgcred)); - - 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 = CMSG_SPACE(sizeof(struct cmsgcred)); - msg.msg_flags = 0; - - return(_sendmsg(sock, &msg, 0)); -} diff --git a/lib/libc/rpc/crypt_client.c b/lib/libc/rpc/crypt_client.c deleted file mode 100644 index 255b266..0000000 --- a/lib/libc/rpc/crypt_client.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 1996 - * Bill Paul <wpaul@ctr.columbia.edu>. 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <err.h> -#include <sys/types.h> -#include <rpc/des_crypt.h> -#include <rpc/des.h> -#include <string.h> -#include <rpcsvc/crypt.h> -#include "un-namespace.h" - -int -_des_crypt_call(buf, len, dparms) - char *buf; - int len; - struct desparams *dparms; -{ - CLIENT *clnt; - desresp *result_1; - desargs des_crypt_1_arg; - struct netconfig *nconf; - void *localhandle; - int stat; - - nconf = NULL; - localhandle = setnetconfig(); - while ((nconf = getnetconfig(localhandle)) != NULL) { - if (nconf->nc_protofmly != NULL && - strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) - break; - } - if (nconf == NULL) { - warnx("getnetconfig: %s", nc_sperror()); - return(DESERR_HWERROR); - } - clnt = clnt_tp_create(NULL, CRYPT_PROG, CRYPT_VERS, nconf); - if (clnt == (CLIENT *) NULL) { - endnetconfig(localhandle); - return(DESERR_HWERROR); - } - endnetconfig(localhandle); - - 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, (xdrproc_t)xdr_desresp, result_1); - clnt_destroy(clnt); - - return(stat); -} diff --git a/lib/libc/rpc/des_crypt.3 b/lib/libc/rpc/des_crypt.3 deleted file mode 100644 index b40a62c..0000000 --- a/lib/libc/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$ -.\" -.Dd October 6, 1987 -.Dt DES_CRYPT 3 -.Os -.Sh NAME -.Nm des_crypt , ecb_crypt , cbc_crypt , des_setparity -.Nd "fast DES encryption" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/des_crypt.h -.Ft int -.Fn ecb_crypt "char *key" "char *data" "unsigned datalen" "unsigned mode" -.Ft int -.Fn cbc_crypt "char *key" "char *data" "unsigned datalen" "unsigned mode" "char *ivec" -.Ft void -.Fn des_setparity "char *key" -.Sh DESCRIPTION -The -.Fn ecb_crypt -and -.Fn cbc_crypt -functions -implement the -.Tn NBS -.Tn DES -(Data Encryption Standard). -These routines are faster and more general purpose than -.Xr crypt 3 . -They also are able to utilize -.Tn DES -hardware if it is available. -The -.Fn ecb_crypt -function -encrypts in -.Tn ECB -(Electronic Code Book) -mode, which encrypts blocks of data independently. -The -.Fn cbc_crypt -function -encrypts in -.Tn CBC -(Cipher Block Chaining) -mode, which chains together -successive blocks. -.Tn CBC -mode protects against insertions, deletions and -substitutions of blocks. -Also, regularities in the clear text will -not appear in the cipher text. -.Pp -Here is how to use these routines. -The first argument, -.Fa key , -is the 8-byte encryption key with parity. -To set the key's parity, which for -.Tn DES -is in the low bit of each byte, use -.Fn des_setparity . -The second argument, -.Fa data , -contains the data to be encrypted or decrypted. -The -third argument, -.Fa datalen , -is the length in bytes of -.Fa data , -which must be a multiple of 8. -The fourth argument, -.Fa mode , -is formed by -.Em OR Ns 'ing -together some things. -For the encryption direction -.Em OR -in either -.Dv DES_ENCRYPT -or -.Dv DES_DECRYPT . -For software versus hardware -encryption, -.Em OR -in either -.Dv DES_HW -or -.Dv DES_SW . -If -.Dv DES_HW -is specified, and there is no hardware, then the encryption is performed -in software and the routine returns -.Er DESERR_NOHWDEVICE . -For -.Fn cbc_crypt , -the -.Fa ivec -argument -is the 8-byte initialization -vector for the chaining. -It is updated to the next initialization -vector upon return. -.Sh ERRORS -.Bl -tag -width [DESERR_NOHWDEVICE] -compact -.It Bq Er DESERR_NONE -No error. -.It Bq Er DESERR_NOHWDEVICE -Encryption succeeded, but done in software instead of the requested hardware. -.It Bq Er DESERR_HWERR -An error occurred in the hardware or driver. -.It Bq Er DESERR_BADPARAM -Bad argument to routine. -.El -.Pp -Given a result status -.Va stat , -the macro -.Fn DES_FAILED stat -is false only for the first two statuses. -.Sh SEE ALSO -.\" .Xr des 1 , -.Xr crypt 3 -.Sh RESTRICTIONS -These routines are not available in RPCSRC 4.0. -This information is provided to describe the -.Tn DES -interface expected by -Secure RPC. diff --git a/lib/libc/rpc/des_crypt.c b/lib/libc/rpc/des_crypt.c deleted file mode 100644 index 238d55a..0000000 --- a/lib/libc/rpc/des_crypt.c +++ /dev/null @@ -1,154 +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 <sys/types.h> -#include <rpc/des_crypt.h> -#include <rpc/des.h> - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)des_crypt.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -static int common_crypt( char *, char *, unsigned, unsigned, struct desparams * ); -int (*__des_crypt_LOCAL)() = 0; -extern int _des_crypt_call(char *, int, struct desparams *); -/* - * Copy 8 bytes - */ -#define COPY8(src, dst) { \ - char *a = (char *) dst; \ - 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) { \ - char *a = (char *) dst; \ - char *b = (char *) src; \ - 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; - unsigned len; - unsigned mode; - struct desparams *desp; -{ - 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/lib/libc/rpc/des_soft.c b/lib/libc/rpc/des_soft.c deleted file mode 100644 index daed265..0000000 --- a/lib/libc/rpc/des_soft.c +++ /dev/null @@ -1,71 +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[] = "@(#)des_soft.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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/lib/libc/rpc/getnetconfig.3 b/lib/libc/rpc/getnetconfig.3 deleted file mode 100644 index e67b9bb..0000000 --- a/lib/libc/rpc/getnetconfig.3 +++ /dev/null @@ -1,222 +0,0 @@ -.\" @(#)getnetconfig.3n 1.28 93/06/02 SMI; from SVr4 -.\" $NetBSD: getnetconfig.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $ -.\" $FreeBSD$ -.\" Copyright 1989 AT&T -.Dd April 22, 2000 -.Dt GETNETCONFIG 3 -.Os -.Sh NAME -.Nm getnetconfig , -.Nm setnetconfig , -.Nm endnetconfig , -.Nm getnetconfigent , -.Nm freenetconfigent , -.Nm nc_perror , -.Nm nc_sperror -.Nd get network configuration database entry -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In netconfig.h -.Ft "struct netconfig *" -.Fn getnetconfig "void *handlep" -.Ft "void *" -.Fn setnetconfig "void" -.Ft int -.Fn endnetconfig "void *handlep" -.Ft "struct netconfig *" -.Fn getnetconfigent "const char *netid" -.Ft void -.Fn freenetconfigent "struct netconfig *netconfigp" -.Ft void -.Fn nc_perror "const char *msg" -.Ft "char *" -.Fn nc_sperror "void" -.Sh DESCRIPTION -The library routines described on this page -provide the application access to -the system network configuration database, -.Pa /etc/netconfig . -The -.Fn getnetconfig -function -returns a pointer to the -current entry in the -netconfig -database, formatted as a -.Ft "struct netconfig" . -Successive calls will return successive netconfig -entries in the netconfig database. -The -.Fn getnetconfig -function -can be used to search the entire netconfig -file. -The -.Fn getnetconfig -function -returns -.Dv NULL -at the end of the file. -The -.Fa handlep -argument -is the handle obtained through -.Fn setnetconfig . -.Pp -A call to -.Fn setnetconfig -has the effect of -.Dq binding -to or -.Dq rewinding -the netconfig database. -The -.Fn setnetconfig -function -must be called before the first call to -.Fn getnetconfig -and may be called at any other time. -The -.Fn setnetconfig -function -need not be called before a call to -.Fn getnetconfigent . -The -.Fn setnetconfig -function -returns a unique handle to be used by -.Fn getnetconfig . -.Pp -The -.Fn endnetconfig -function -should be called when processing is complete to release resources for reuse. -The -.Fa handlep -argument -is the handle obtained through -.Fn setnetconfig . -Programmers should be aware, however, that the last call to -.Fn endnetconfig -frees all memory allocated by -.Fn getnetconfig -for the -.Ft "struct netconfig" -data structure. -The -.Fn endnetconfig -function -may not be called before -.Fn setnetconfig . -.Pp -The -.Fn getnetconfigent -function -returns a pointer -to the netconfig structure corresponding -to -.Fa netid . -It returns -.Dv NULL -if -.Fa netid -is invalid -(that is, does not name an entry in the netconfig database). -.Pp -The -.Fn freenetconfigent -function -frees the netconfig structure pointed to by -.Fa netconfigp -(previously returned by -.Fn getnetconfigent ) . -.Pp -The -.Fn nc_perror -function -prints a message to the standard error indicating why any of the -above routines failed. -The message is prepended with the string -.Fa msg -and a colon. -A newline character is appended at the end of the message. -.Pp -The -.Fn nc_sperror -function -is similar to -.Fn nc_perror -but instead of sending the message -to the standard error, will return a pointer to a string that -contains the error message. -.Pp -The -.Fn nc_perror -and -.Fn nc_sperror -functions -can also be used with the -.Ev NETPATH -access routines defined in -.Xr getnetpath 3 . -.Sh RETURN VALUES -The -.Fn setnetconfig -function -returns a unique handle to be used by -.Fn getnetconfig . -In the case of an error, -.Fn setnetconfig -returns -.Dv NULL -and -.Fn nc_perror -or -.Fn nc_sperror -can be used to print the reason for failure. -.Pp -The -.Fn getnetconfig -function -returns a pointer to the current entry in the netconfig -database, formatted as a -.Ft "struct netconfig" . -The -.Fn getnetconfig -function -returns -.Dv NULL -at the end of the file, or upon failure. -.Pp -The -.Fn endnetconfig -function -returns 0 on success and \-1 on failure -(for example, if -.Fn setnetconfig -was not called previously). -.Pp -On success, -.Fn getnetconfigent -returns a pointer to the -.Ft "struct netconfig" -structure corresponding to -.Fa netid ; -otherwise it returns -.Dv NULL . -.Pp -The -.Fn nc_sperror -function -returns a pointer to a buffer which contains the error message string. -This buffer is overwritten on each call. -In multithreaded applications, this buffer is -implemented as thread-specific data. -.Sh FILES -.Bl -tag -width /etc/netconfig -compact -.It Pa /etc/netconfig -.El -.Sh SEE ALSO -.Xr getnetpath 3 , -.Xr netconfig 5 diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c deleted file mode 100644 index 1310e36..0000000 --- a/lib/libc/rpc/getnetconfig.c +++ /dev/null @@ -1,742 +0,0 @@ -/* $NetBSD: getnetconfig.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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[] = "@(#)getnetconfig.c 1.12 91/12/19 SMI"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Copyright (c) 1989 by Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <stdio.h> -#include <errno.h> -#include <netconfig.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <rpc/rpc.h> -#include <unistd.h> -#include "un-namespace.h" -#include "rpc_com.h" - -/* - * The five library routines in this file provide application access to the - * system network configuration database, /etc/netconfig. In addition to the - * netconfig database and the routines for accessing it, the environment - * variable NETPATH and its corresponding routines in getnetpath.c may also be - * used to specify the network transport to be used. - */ - - -/* - * netconfig errors - */ - -#define NC_NONETCONFIG ENOENT -#define NC_NOMEM ENOMEM -#define NC_NOTINIT EINVAL /* setnetconfig was not called first */ -#define NC_BADFILE EBADF /* format for netconfig file is bad */ -#define NC_NOTFOUND ENOPROTOOPT /* specified netid was not found */ - -/* - * semantics as strings (should be in netconfig.h) - */ -#define NC_TPI_CLTS_S "tpi_clts" -#define NC_TPI_COTS_S "tpi_cots" -#define NC_TPI_COTS_ORD_S "tpi_cots_ord" -#define NC_TPI_RAW_S "tpi_raw" - -/* - * flags as characters (also should be in netconfig.h) - */ -#define NC_NOFLAG_C '-' -#define NC_VISIBLE_C 'v' -#define NC_BROADCAST_C 'b' - -/* - * Character used to indicate there is no name-to-address lookup library - */ -#define NC_NOLOOKUP "-" - -static const char * const _nc_errors[] = { - "Netconfig database not found", - "Not enough memory", - "Not initialized", - "Netconfig database has invalid format", - "Netid not found in netconfig database" -}; - -struct netconfig_info { - int eof; /* all entries has been read */ - int ref; /* # of times setnetconfig() has been called */ - struct netconfig_list *head; /* head of the list */ - struct netconfig_list *tail; /* last of the list */ -}; - -struct netconfig_list { - char *linep; /* hold line read from netconfig */ - struct netconfig *ncp; - struct netconfig_list *next; -}; - -struct netconfig_vars { - int valid; /* token that indicates a valid netconfig_vars */ - int flag; /* first time flag */ - struct netconfig_list *nc_configs; /* pointer to the current netconfig entry */ -}; - -#define NC_VALID 0xfeed -#define NC_STORAGE 0xf00d -#define NC_INVALID 0 - - -static int *__nc_error(void); -static int parse_ncp(char *, struct netconfig *); -static struct netconfig *dup_ncp(struct netconfig *); - - -static FILE *nc_file; /* for netconfig db */ -static mutex_t nc_file_lock = MUTEX_INITIALIZER; - -static struct netconfig_info ni = { 0, 0, NULL, NULL}; -static mutex_t ni_lock = MUTEX_INITIALIZER; - -static thread_key_t nc_key; -static once_t nc_once = ONCE_INITIALIZER; -static int nc_key_error; - -static void -nc_key_init(void) -{ - - nc_key_error = thr_keycreate(&nc_key, free); -} - -#define MAXNETCONFIGLINE 1000 - -static int * -__nc_error() -{ - static int nc_error = 0; - int *nc_addr; - - /* - * Use the static `nc_error' if we are the main thread - * (including non-threaded programs), or if an allocation - * fails. - */ - if (thr_main()) - return (&nc_error); - if (thr_once(&nc_once, nc_key_init) != 0 || nc_key_error != 0) - return (&nc_error); - if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) { - nc_addr = (int *)malloc(sizeof (int)); - if (thr_setspecific(nc_key, (void *) nc_addr) != 0) { - if (nc_addr) - free(nc_addr); - return (&nc_error); - } - *nc_addr = 0; - } - return (nc_addr); -} - -#define nc_error (*(__nc_error())) -/* - * A call to setnetconfig() establishes a /etc/netconfig "session". A session - * "handle" is returned on a successful call. At the start of a session (after - * a call to setnetconfig()) searches through the /etc/netconfig database will - * proceed from the start of the file. The session handle must be passed to - * getnetconfig() to parse the file. Each call to getnetconfig() using the - * current handle will process one subsequent entry in /etc/netconfig. - * setnetconfig() must be called before the first call to getnetconfig(). - * (Handles are used to allow for nested calls to setnetpath()). - * - * A new session is established with each call to setnetconfig(), with a new - * handle being returned on each call. Previously established sessions remain - * active until endnetconfig() is called with that session's handle as an - * argument. - * - * setnetconfig() need *not* be called before a call to getnetconfigent(). - * setnetconfig() returns a NULL pointer on failure (for example, if - * the netconfig database is not present). - */ -void * -setnetconfig() -{ - struct netconfig_vars *nc_vars; - - if ((nc_vars = (struct netconfig_vars *)malloc(sizeof - (struct netconfig_vars))) == NULL) { - return(NULL); - } - - /* - * For multiple calls, i.e. nc_file is not NULL, we just return the - * handle without reopening the netconfig db. - */ - mutex_lock(&ni_lock); - ni.ref++; - mutex_unlock(&ni_lock); - - mutex_lock(&nc_file_lock); - if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) { - nc_vars->valid = NC_VALID; - nc_vars->flag = 0; - nc_vars->nc_configs = ni.head; - mutex_unlock(&nc_file_lock); - return ((void *)nc_vars); - } - mutex_unlock(&nc_file_lock); - - mutex_lock(&ni_lock); - ni.ref--; - mutex_unlock(&ni_lock); - - nc_error = NC_NONETCONFIG; - free(nc_vars); - return (NULL); -} - - -/* - * When first called, getnetconfig() returns a pointer to the first entry in - * the netconfig database, formatted as a struct netconfig. On each subsequent - * call, getnetconfig() returns a pointer to the next entry in the database. - * getnetconfig() can thus be used to search the entire netconfig file. - * getnetconfig() returns NULL at end of file. - */ - -struct netconfig * -getnetconfig(handlep) -void *handlep; -{ - struct netconfig_vars *ncp = (struct netconfig_vars *)handlep; - char *stringp; /* tmp string pointer */ - struct netconfig_list *list; - struct netconfig *np; - struct netconfig *result; - - /* - * Verify that handle is valid - */ - mutex_lock(&nc_file_lock); - if (ncp == NULL || nc_file == NULL) { - nc_error = NC_NOTINIT; - mutex_unlock(&nc_file_lock); - return (NULL); - } - mutex_unlock(&nc_file_lock); - - switch (ncp->valid) { - case NC_VALID: - /* - * If entry has already been read into the list, - * we return the entry in the linked list. - * If this is the first time call, check if there are any entries in - * linked list. If no entries, we need to read the netconfig db. - * If we have been here and the next entry is there, we just return - * it. - */ - if (ncp->flag == 0) { /* first time */ - ncp->flag = 1; - mutex_lock(&ni_lock); - ncp->nc_configs = ni.head; - mutex_unlock(&ni_lock); - if (ncp->nc_configs != NULL) /* entry already exist */ - return(ncp->nc_configs->ncp); - } - else if (ncp->nc_configs != NULL && ncp->nc_configs->next != NULL) { - ncp->nc_configs = ncp->nc_configs->next; - return(ncp->nc_configs->ncp); - } - - /* - * If we cannot find the entry in the list and is end of file, - * we give up. - */ - mutex_lock(&ni_lock); - if (ni.eof == 1) { - mutex_unlock(&ni_lock); - return(NULL); - } - mutex_unlock(&ni_lock); - - break; - default: - nc_error = NC_NOTINIT; - return (NULL); - } - - stringp = (char *) malloc(MAXNETCONFIGLINE); - if (stringp == NULL) - return (NULL); - -#ifdef MEM_CHK - if (malloc_verify() == 0) { - fprintf(stderr, "memory heap corrupted in getnetconfig\n"); - exit(1); - } -#endif - - /* - * Read a line from netconfig file. - */ - mutex_lock(&nc_file_lock); - do { - if (fgets(stringp, MAXNETCONFIGLINE, nc_file) == NULL) { - free(stringp); - mutex_lock(&ni_lock); - ni.eof = 1; - mutex_unlock(&ni_lock); - mutex_unlock(&nc_file_lock); - return (NULL); - } - } while (*stringp == '#'); - mutex_unlock(&nc_file_lock); - - list = (struct netconfig_list *) malloc(sizeof (struct netconfig_list)); - if (list == NULL) { - free(stringp); - return(NULL); - } - np = (struct netconfig *) malloc(sizeof (struct netconfig)); - if (np == NULL) { - free(stringp); - free(list); - return(NULL); - } - list->ncp = np; - list->next = NULL; - list->ncp->nc_lookups = NULL; - list->linep = stringp; - if (parse_ncp(stringp, list->ncp) == -1) { - free(stringp); - free(np); - free(list); - return (NULL); - } - else { - /* - * If this is the first entry that's been read, it is the head of - * the list. If not, put the entry at the end of the list. - * Reposition the current pointer of the handle to the last entry - * in the list. - */ - mutex_lock(&ni_lock); - if (ni.head == NULL) { /* first entry */ - ni.head = ni.tail = list; - } - else { - ni.tail->next = list; - ni.tail = ni.tail->next; - } - ncp->nc_configs = ni.tail; - result = ni.tail->ncp; - mutex_unlock(&ni_lock); - return(result); - } -} - -/* - * endnetconfig() may be called to "unbind" or "close" the netconfig database - * when processing is complete, releasing resources for reuse. endnetconfig() - * may not be called before setnetconfig(). endnetconfig() returns 0 on - * success and -1 on failure (for example, if setnetconfig() was not called - * previously). - */ -int -endnetconfig(handlep) -void *handlep; -{ - struct netconfig_vars *nc_handlep = (struct netconfig_vars *)handlep; - - struct netconfig_list *q, *p; - - /* - * Verify that handle is valid - */ - if (nc_handlep == NULL || (nc_handlep->valid != NC_VALID && - nc_handlep->valid != NC_STORAGE)) { - nc_error = NC_NOTINIT; - return (-1); - } - - /* - * Return 0 if anyone still needs it. - */ - nc_handlep->valid = NC_INVALID; - nc_handlep->flag = 0; - nc_handlep->nc_configs = NULL; - mutex_lock(&ni_lock); - if (--ni.ref > 0) { - mutex_unlock(&ni_lock); - free(nc_handlep); - return(0); - } - - /* - * Noone needs these entries anymore, then frees them. - * Make sure all info in netconfig_info structure has been reinitialized. - */ - q = ni.head; - ni.eof = ni.ref = 0; - ni.head = NULL; - ni.tail = NULL; - mutex_unlock(&ni_lock); - - while (q != NULL) { - p = q->next; - if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups); - free(q->ncp); - free(q->linep); - free(q); - q = p; - } - free(nc_handlep); - - mutex_lock(&nc_file_lock); - fclose(nc_file); - nc_file = NULL; - mutex_unlock(&nc_file_lock); - - return (0); -} - -/* - * getnetconfigent(netid) returns a pointer to the struct netconfig structure - * corresponding to netid. It returns NULL if netid is invalid (that is, does - * not name an entry in the netconfig database). It returns NULL and sets - * errno in case of failure (for example, if the netconfig database cannot be - * opened). - */ - -struct netconfig * -getnetconfigent(netid) - const char *netid; -{ - FILE *file; /* NETCONFIG db's file pointer */ - char *linep; /* holds current netconfig line */ - char *stringp; /* temporary string pointer */ - struct netconfig *ncp = NULL; /* returned value */ - struct netconfig_list *list; /* pointer to cache list */ - - nc_error = NC_NOTFOUND; /* default error. */ - if (netid == NULL || strlen(netid) == 0) { - return (NULL); - } - - /* - * Look up table if the entries have already been read and parsed in - * getnetconfig(), then copy this entry into a buffer and return it. - * If we cannot find the entry in the current list and there are more - * entries in the netconfig db that has not been read, we then read the - * db and try find the match netid. - * If all the netconfig db has been read and placed into the list and - * there is no match for the netid, return NULL. - */ - mutex_lock(&ni_lock); - if (ni.head != NULL) { - for (list = ni.head; list; list = list->next) { - if (strcmp(list->ncp->nc_netid, netid) == 0) { - mutex_unlock(&ni_lock); - return(dup_ncp(list->ncp)); - } - } - if (ni.eof == 1) { /* that's all the entries */ - mutex_unlock(&ni_lock); - return(NULL); - } - } - mutex_unlock(&ni_lock); - - - if ((file = fopen(NETCONFIG, "r")) == NULL) { - nc_error = NC_NONETCONFIG; - return (NULL); - } - - if ((linep = malloc(MAXNETCONFIGLINE)) == NULL) { - fclose(file); - nc_error = NC_NOMEM; - return (NULL); - } - do { - ptrdiff_t len; - char *tmpp; /* tmp string pointer */ - - do { - if ((stringp = fgets(linep, MAXNETCONFIGLINE, file)) == NULL) { - break; - } - } while (*stringp == '#'); - if (stringp == NULL) { /* eof */ - break; - } - if ((tmpp = strpbrk(stringp, "\t ")) == NULL) { /* can't parse file */ - nc_error = NC_BADFILE; - break; - } - if (strlen(netid) == (size_t) (len = tmpp - stringp) && /* a match */ - strncmp(stringp, netid, (size_t)len) == 0) { - if ((ncp = (struct netconfig *) - malloc(sizeof (struct netconfig))) == NULL) { - break; - } - ncp->nc_lookups = NULL; - if (parse_ncp(linep, ncp) == -1) { - free(ncp); - ncp = NULL; - } - break; - } - } while (stringp != NULL); - if (ncp == NULL) { - free(linep); - } - fclose(file); - return(ncp); -} - -/* - * freenetconfigent(netconfigp) frees the netconfig structure pointed to by - * netconfigp (previously returned by getnetconfigent()). - */ - -void -freenetconfigent(netconfigp) - struct netconfig *netconfigp; -{ - if (netconfigp != NULL) { - free(netconfigp->nc_netid); /* holds all netconfigp's strings */ - if (netconfigp->nc_lookups != NULL) - free(netconfigp->nc_lookups); - free(netconfigp); - } - return; -} - -/* - * Parse line and stuff it in a struct netconfig - * Typical line might look like: - * udp tpi_cots vb inet udp /dev/udp /usr/lib/ip.so,/usr/local/ip.so - * - * We return -1 if any of the tokens don't parse, or malloc fails. - * - * Note that we modify stringp (putting NULLs after tokens) and - * we set the ncp's string field pointers to point to these tokens within - * stringp. - */ - -static int -parse_ncp(stringp, ncp) -char *stringp; /* string to parse */ -struct netconfig *ncp; /* where to put results */ -{ - char *tokenp; /* for processing tokens */ - char *lasts; - char **nc_lookups; - - nc_error = NC_BADFILE; /* nearly anything that breaks is for this reason */ - stringp[strlen(stringp)-1] = '\0'; /* get rid of newline */ - /* netid */ - if ((ncp->nc_netid = strtok_r(stringp, "\t ", &lasts)) == NULL) { - return (-1); - } - - /* semantics */ - if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) { - return (-1); - } - if (strcmp(tokenp, NC_TPI_COTS_ORD_S) == 0) - ncp->nc_semantics = NC_TPI_COTS_ORD; - else if (strcmp(tokenp, NC_TPI_COTS_S) == 0) - ncp->nc_semantics = NC_TPI_COTS; - else if (strcmp(tokenp, NC_TPI_CLTS_S) == 0) - ncp->nc_semantics = NC_TPI_CLTS; - else if (strcmp(tokenp, NC_TPI_RAW_S) == 0) - ncp->nc_semantics = NC_TPI_RAW; - else - return (-1); - - /* flags */ - if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) { - return (-1); - } - for (ncp->nc_flag = NC_NOFLAG; *tokenp != '\0'; - tokenp++) { - switch (*tokenp) { - case NC_NOFLAG_C: - break; - case NC_VISIBLE_C: - ncp->nc_flag |= NC_VISIBLE; - break; - case NC_BROADCAST_C: - ncp->nc_flag |= NC_BROADCAST; - break; - default: - return (-1); - } - } - /* protocol family */ - if ((ncp->nc_protofmly = strtok_r(NULL, "\t ", &lasts)) == NULL) { - return (-1); - } - /* protocol name */ - if ((ncp->nc_proto = strtok_r(NULL, "\t ", &lasts)) == NULL) { - return (-1); - } - /* network device */ - if ((ncp->nc_device = strtok_r(NULL, "\t ", &lasts)) == NULL) { - return (-1); - } - if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) { - return (-1); - } - if (strcmp(tokenp, NC_NOLOOKUP) == 0) { - ncp->nc_nlookups = 0; - ncp->nc_lookups = NULL; - } else { - char *cp; /* tmp string */ - - if (ncp->nc_lookups != NULL) /* from last visit */ - free(ncp->nc_lookups); - ncp->nc_lookups = NULL; - ncp->nc_nlookups = 0; - while ((cp = tokenp) != NULL) { - if ((nc_lookups = realloc(ncp->nc_lookups, - (ncp->nc_nlookups + 1) * sizeof *ncp->nc_lookups)) == NULL) { - free(ncp->nc_lookups); - ncp->nc_lookups = NULL; - return (-1); - } - tokenp = _get_next_token(cp, ','); - ncp->nc_lookups = nc_lookups; - ncp->nc_lookups[ncp->nc_nlookups++] = cp; - } - } - return (0); -} - - -/* - * Returns a string describing the reason for failure. - */ -char * -nc_sperror() -{ - const char *message; - - switch(nc_error) { - case NC_NONETCONFIG: - message = _nc_errors[0]; - break; - case NC_NOMEM: - message = _nc_errors[1]; - break; - case NC_NOTINIT: - message = _nc_errors[2]; - break; - case NC_BADFILE: - message = _nc_errors[3]; - break; - case NC_NOTFOUND: - message = _nc_errors[4]; - break; - default: - message = "Unknown network selection error"; - } - /* LINTED const castaway */ - return ((char *)message); -} - -/* - * Prints a message onto standard error describing the reason for failure. - */ -void -nc_perror(s) - const char *s; -{ - fprintf(stderr, "%s: %s\n", s, nc_sperror()); -} - -/* - * Duplicates the matched netconfig buffer. - */ -static struct netconfig * -dup_ncp(ncp) -struct netconfig *ncp; -{ - struct netconfig *p; - char *tmp; - u_int i; - - if ((tmp=malloc(MAXNETCONFIGLINE)) == NULL) - return(NULL); - if ((p=(struct netconfig *)malloc(sizeof(struct netconfig))) == NULL) { - free(tmp); - return(NULL); - } - /* - * First we dup all the data from matched netconfig buffer. Then we - * adjust some of the member pointer to a pre-allocated buffer where - * contains part of the data. - * To follow the convention used in parse_ncp(), we store all the - * necessary information in the pre-allocated buffer and let each - * of the netconfig char pointer member point to the right address - * in the buffer. - */ - *p = *ncp; - p->nc_netid = (char *)strcpy(tmp,ncp->nc_netid); - tmp = strchr(tmp, '\0') + 1; - p->nc_protofmly = (char *)strcpy(tmp,ncp->nc_protofmly); - tmp = strchr(tmp, '\0') + 1; - p->nc_proto = (char *)strcpy(tmp,ncp->nc_proto); - tmp = strchr(tmp, '\0') + 1; - p->nc_device = (char *)strcpy(tmp,ncp->nc_device); - p->nc_lookups = (char **)malloc((size_t)(p->nc_nlookups+1) * sizeof(char *)); - if (p->nc_lookups == NULL) { - free(p->nc_netid); - free(p); - return(NULL); - } - for (i=0; i < p->nc_nlookups; i++) { - tmp = strchr(tmp, '\0') + 1; - p->nc_lookups[i] = (char *)strcpy(tmp,ncp->nc_lookups[i]); - } - return(p); -} diff --git a/lib/libc/rpc/getnetpath.3 b/lib/libc/rpc/getnetpath.3 deleted file mode 100644 index 5dfe68a..0000000 --- a/lib/libc/rpc/getnetpath.3 +++ /dev/null @@ -1,170 +0,0 @@ -.\" @(#)getnetpath.3n 1.26 93/05/07 SMI; from SVr4 -.\" $NetBSD: getnetpath.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $ -.\" $FreeBSD$ -.\" Copyright 1989 AT&T -.Dd April 22, 2000 -.Dt GETNETPATH 3 -.Os -.Sh NAME -.Nm getnetpath , -.Nm setnetpath , -.Nm endnetpath -.Nd get -.Pa /etc/netconfig -entry corresponding to -.Ev NETPATH -component -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In netconfig.h -.Ft "struct netconfig *" -.Fn getnetpath "void *handlep" -.Ft "void *" -.Fn setnetpath "void" -.Ft int -.Fn endnetpath "void *handlep" -.Sh DESCRIPTION -The routines described in this page provide the application access to the system -network configuration database, -.Pa /etc/netconfig , -as it is -.Dq filtered -by the -.Ev NETPATH -environment variable (see -.Xr environ 7 ) . -See -.Xr getnetconfig 3 -for other routines that also access the -network configuration database directly. -The -.Ev NETPATH -variable is a list of colon-separated network identifiers. -.Pp -The -.Fn getnetpath -function -returns a pointer to the -netconfig database entry corresponding to the first valid -.Ev NETPATH -component. -The netconfig entry is formatted as a -.Ft "struct netconfig" . -On each subsequent call, -.Fn getnetpath -returns a pointer to the netconfig entry that corresponds to the next -valid -.Ev NETPATH -component. -The -.Fn getnetpath -function -can thus be used to search the netconfig database for all networks -included in the -.Ev NETPATH -variable. -When -.Ev NETPATH -has been exhausted, -.Fn getnetpath -returns -.Dv NULL . -.Pp -A call to -.Fn setnetpath -.Dq binds -to or -.Dq rewinds -.Ev NETPATH . -The -.Fn setnetpath -function -must be called before the first call to -.Fn getnetpath -and may be called at any other time. -It returns a handle that is used by -.Fn getnetpath . -.Pp -The -.Fn getnetpath -function -silently ignores invalid -.Ev NETPATH -components. -A -.Ev NETPATH -component is invalid if there is no corresponding -entry in the netconfig database. -.Pp -If the -.Ev NETPATH -variable is unset, -.Fn getnetpath -behaves as if -.Ev NETPATH -were set to the sequence of -.Dq default -or -.Dq visible -networks in the netconfig database, in the -order in which they are listed. -.\"This proviso holds also for this -.\"whole manpage. -.Pp -The -.Fn endnetpath -function -may be called to -.Dq unbind -from -.Ev NETPATH -when processing is complete, releasing resources for reuse. -Programmers should be aware, however, that -.Fn endnetpath -frees all memory allocated by -.Fn getnetpath -for the struct netconfig data structure. -.Sh RETURN VALUES -The -.Fn setnetpath -function -returns a handle that is used by -.Fn getnetpath . -In case of an error, -.Fn setnetpath -returns -.Dv NULL . -.Pp -The -.Fn endnetpath -function -returns 0 on success and \-1 on failure -(for example, if -.Fn setnetpath -was not called previously). -The -.Fn nc_perror -or -.Fn nc_sperror -function -can be used to print out the reason for failure. -See -.Xr getnetconfig 3 . -.Pp -When first called, -.Fn getnetpath -returns a pointer to the netconfig database entry corresponding to the first -valid -.Ev NETPATH -component. -When -.Ev NETPATH -has been exhausted, -.Fn getnetpath -returns -.Dv NULL . -.Sh SEE ALSO -.Xr getnetconfig 3 , -.Xr netconfig 5 , -.Xr environ 7 diff --git a/lib/libc/rpc/getnetpath.c b/lib/libc/rpc/getnetpath.c deleted file mode 100644 index d1ea554..0000000 --- a/lib/libc/rpc/getnetpath.c +++ /dev/null @@ -1,276 +0,0 @@ -/* $NetBSD: getnetpath.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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[] = "@(#)getnetpath.c 1.11 91/12/19 SMI"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Copyright (c) 1989 by Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <stdio.h> -#include <errno.h> -#include <netconfig.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include "un-namespace.h" - -/* - * internal structure to keep track of a netpath "session" - */ -struct netpath_chain { - struct netconfig *ncp; /* an nconf entry */ - struct netpath_chain *nchain_next; /* next nconf entry allocated */ -}; - - -struct netpath_vars { - int valid; /* token that indicates a valid netpath_vars */ - void *nc_handlep; /* handle for current netconfig "session" */ - char *netpath; /* pointer to current view-point in NETPATH */ - char *netpath_start; /* pointer to start of our copy of NETPATH */ - struct netpath_chain *ncp_list; /* list of nconfs allocated this session*/ -}; - -#define NP_VALID 0xf00d -#define NP_INVALID 0 - -char *_get_next_token(char *, int); - - -/* - * A call to setnetpath() establishes a NETPATH "session". setnetpath() - * must be called before the first call to getnetpath(). A "handle" is - * returned to distinguish the session; this handle should be passed - * subsequently to getnetpath(). (Handles are used to allow for nested calls - * to setnetpath()). - * If setnetpath() is unable to establish a session (due to lack of memory - * resources, or the absence of the /etc/netconfig file), a NULL pointer is - * returned. - */ - -void * -setnetpath() -{ - - struct netpath_vars *np_sessionp; /* this session's variables */ - char *npp; /* NETPATH env variable */ - -#ifdef MEM_CHK - malloc_debug(1); -#endif - - if ((np_sessionp = - (struct netpath_vars *)malloc(sizeof (struct netpath_vars))) == NULL) { - return (NULL); - } - if ((np_sessionp->nc_handlep = setnetconfig()) == NULL) { - free(np_sessionp); - syslog (LOG_ERR, "rpc: failed to open " NETCONFIG); - return (NULL); - } - np_sessionp->valid = NP_VALID; - np_sessionp->ncp_list = NULL; - if ((npp = getenv(NETPATH)) == NULL) { - np_sessionp->netpath = NULL; - } else { - (void) endnetconfig(np_sessionp->nc_handlep);/* won't need nc session*/ - np_sessionp->nc_handlep = NULL; - if ((np_sessionp->netpath = malloc(strlen(npp)+1)) == NULL) - goto failed; - else { - (void) strcpy(np_sessionp->netpath, npp); - } - } - np_sessionp->netpath_start = np_sessionp->netpath; - return ((void *)np_sessionp); - -failed: - free(np_sessionp); - return (NULL); -} - -/* - * When first called, getnetpath() returns a pointer to the netconfig - * database entry corresponding to the first valid NETPATH component. The - * netconfig entry is formatted as a struct netconfig. - * On each subsequent call, getnetpath returns a pointer to the netconfig - * entry that corresponds to the next valid NETPATH component. getnetpath - * can thus be used to search the netconfig database for all networks - * included in the NETPATH variable. - * When NETPATH has been exhausted, getnetpath() returns NULL. It returns - * NULL and sets errno in case of an error (e.g., setnetpath was not called - * previously). - * getnetpath() silently ignores invalid NETPATH components. A NETPATH - * compnent is invalid if there is no corresponding entry in the netconfig - * database. - * If the NETPATH variable is unset, getnetpath() behaves as if NETPATH - * were set to the sequence of default or visible networks in the netconfig - * database, in the order in which they are listed. - */ - -struct netconfig * -getnetpath(handlep) - void *handlep; -{ - struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep; - struct netconfig *ncp = NULL; /* temp. holds a netconfig session */ - struct netpath_chain *chainp; /* holds chain of ncp's we alloc */ - char *npp; /* holds current NETPATH */ - - if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) { - errno = EINVAL; - return (NULL); - } - if (np_sessionp->netpath_start == NULL) { /* NETPATH was not set */ - do { /* select next visible network */ - if (np_sessionp->nc_handlep == NULL) { - np_sessionp->nc_handlep = setnetconfig(); - if (np_sessionp->nc_handlep == NULL) - syslog (LOG_ERR, "rpc: failed to open " NETCONFIG); - } - if ((ncp = getnetconfig(np_sessionp->nc_handlep)) == NULL) { - return(NULL); - } - } while ((ncp->nc_flag & NC_VISIBLE) == 0); - return (ncp); - } - /* - * Find first valid network ID in netpath. - */ - while ((npp = np_sessionp->netpath) != NULL && strlen(npp) != 0) { - np_sessionp->netpath = _get_next_token(npp, ':'); - /* - * npp is a network identifier. - */ - if ((ncp = getnetconfigent(npp)) != NULL) { - chainp = (struct netpath_chain *) /* cobble alloc chain entry */ - malloc(sizeof (struct netpath_chain)); - chainp->ncp = ncp; - chainp->nchain_next = NULL; - if (np_sessionp->ncp_list == NULL) { - np_sessionp->ncp_list = chainp; - } else { - np_sessionp->ncp_list->nchain_next = chainp; - } - return (ncp); - } - /* couldn't find this token in the database; go to next one. */ - } - return (NULL); -} - -/* - * endnetpath() may be called to unbind NETPATH when processing is complete, - * releasing resources for reuse. It returns 0 on success and -1 on failure - * (e.g. if setnetpath() was not called previously. - */ -int -endnetpath(handlep) - void *handlep; -{ - struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep; - struct netpath_chain *chainp, *lastp; - - if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) { - errno = EINVAL; - return (-1); - } - if (np_sessionp->nc_handlep != NULL) - endnetconfig(np_sessionp->nc_handlep); - if (np_sessionp->netpath_start != NULL) - free(np_sessionp->netpath_start); - for (chainp = np_sessionp->ncp_list; chainp != NULL; - lastp=chainp, chainp=chainp->nchain_next, free(lastp)) { - freenetconfigent(chainp->ncp); - } - free(np_sessionp); -#ifdef MEM_CHK - if (malloc_verify() == 0) { - fprintf(stderr, "memory heap corrupted in endnetpath\n"); - exit(1); - } -#endif - return (0); -} - - - -/* - * Returns pointer to the rest-of-the-string after the current token. - * The token itself starts at arg, and we null terminate it. We return NULL - * if either the arg is empty, or if this is the last token. - */ - -char * -_get_next_token(npp, token) -char *npp; /* string */ -int token; /* char to parse string for */ -{ - char *cp; /* char pointer */ - char *np; /* netpath pointer */ - char *ep; /* escape pointer */ - - if ((cp = strchr(npp, token)) == NULL) { - return (NULL); - } - /* - * did find a token, but it might be escaped. - */ - if ((cp > npp) && (cp[-1] == '\\')) { - /* if slash was also escaped, carry on, otherwise find next token */ - if ((cp > npp + 1) && (cp[-2] != '\\')) { - /* shift r-o-s onto the escaped token */ - strcpy(&cp[-1], cp); /* XXX: overlapping string copy */ - /* - * Do a recursive call. - * We don't know how many escaped tokens there might be. - */ - return (_get_next_token(cp, token)); - } - } - - *cp++ = '\0'; /* null-terminate token */ - /* get rid of any backslash escapes */ - ep = npp; - while ((np = strchr(ep, '\\')) != 0) { - if (np[1] == '\\') - np++; - strcpy(np, (ep = &np[1])); /* XXX: overlapping string copy */ - } - return (cp); /* return ptr to r-o-s */ -} diff --git a/lib/libc/rpc/getpublickey.c b/lib/libc/rpc/getpublickey.c deleted file mode 100644 index 3c95338..0000000 --- a/lib/libc/rpc/getpublickey.c +++ /dev/null @@ -1,179 +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[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * publickey.c - * Copyright (C) 1986, Sun Microsystems, Inc. - */ - -/* - * Public key lookup routines - */ -#include "namespace.h" -#include <stdio.h> -#include <pwd.h> -#include <rpc/rpc.h> -#include <rpc/key_prot.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#include <string.h> -#include <stdlib.h> -#include "un-namespace.h" - -#define PKFILE "/etc/publickey" - -/* - * Hack to let ypserv/rpc.nisd use AUTH_DES. - */ -int (*__getpublickey_LOCAL)() = 0; - -/* - * Get somebody's public key - */ -static int -__getpublickey_real(netname, publickey) - const 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) - const char *key; - char *ret; -{ - char buf[1024]; /* big enough */ - char *res; - FILE *fd; - char *mkey; - char *mval; - - fd = fopen(PKFILE, "r"); - if (fd == NULL) - return (0); - for (;;) { - res = fgets(buf, sizeof(buf), fd); - if (res == NULL) { - 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 = strsep(&res, "\t "); - if (mkey == NULL) { - fprintf(stderr, - "Bad record in %s -- %s", PKFILE, buf); - continue; - } - do { - mval = strsep(&res, " \t#\n"); - } while (mval != NULL && !*mval); - 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) - const char *netname; - char *publickey; -{ - if (__getpublickey_LOCAL != NULL) - return(__getpublickey_LOCAL(netname, publickey)); - else - return(__getpublickey_real(netname, publickey)); -} diff --git a/lib/libc/rpc/getrpcent.3 b/lib/libc/rpc/getrpcent.3 deleted file mode 100644 index 1a999eb..0000000 --- a/lib/libc/rpc/getrpcent.3 +++ /dev/null @@ -1,109 +0,0 @@ -.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI -.\" $NetBSD: getrpcent.3,v 1.6 1998/02/05 18:49:06 perry Exp $ -.\" $FreeBSD$ -.\" -.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 LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.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_aliases -offset indent -.It Va r_name -The name of the server for this rpc program. -.It Va r_aliases -A zero terminated list of alternate names for the rpc program. -.It Va 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. -.Pp -The -.Fn setrpcent -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 -.Dq getrpc -calls). -.Pp -The -.Fn endrpcent -function -closes the file. -.Pp -The -.Fn getrpcbyname -and -.Fn getrpcbynumber -functions -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 DIAGNOSTICS -A -.Dv NULL -pointer is returned on -.Dv EOF -or error. -.Sh SEE ALSO -.Xr rpc 5 , -.Xr rpcinfo 8 , -.Xr ypserv 8 -.Sh BUGS -All information -is contained in a static area -so it must be copied if it is -to be saved. diff --git a/lib/libc/rpc/getrpcent.c b/lib/libc/rpc/getrpcent.c deleted file mode 100644 index 1f198fa..0000000 --- a/lib/libc/rpc/getrpcent.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */ - -/* - * 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 = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Copyright (c) 1984 by Sun Microsystems, Inc. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <assert.h> -#include <errno.h> -#include <nsswitch.h> -#include <netinet/in.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <rpc/rpc.h> -#ifdef YP -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#endif -#include <unistd.h> -#include "namespace.h" -#include "reentrant.h" -#include "un-namespace.h" -#include "libc_private.h" -#include "nss_tls.h" -#ifdef NS_CACHING -#include "nscache.h" -#endif - -#define RPCDB "/etc/rpc" - -/* nsswitch declarations */ -enum constants -{ - SETRPCENT = 1, - ENDRPCENT = 2, - RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */ - RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */ -}; - -static const ns_src defaultsrc[] = { - { NSSRC_FILES, NS_SUCCESS }, -#ifdef YP - { NSSRC_NIS, NS_SUCCESS }, -#endif - { NULL, 0 } -}; - -/* files backend declarations */ -struct files_state { - FILE *fp; - int stayopen; -}; - -static int files_rpcent(void *, void *, va_list); -static int files_setrpcent(void *, void *, va_list); - -static void files_endstate(void *); -NSS_TLS_HANDLING(files); - -/* nis backend declarations */ -#ifdef YP -struct nis_state { - char domain[MAXHOSTNAMELEN]; - char *current; - int currentlen; - int stepping; - int no_name_map; -}; - -static int nis_rpcent(void *, void *, va_list); -static int nis_setrpcent(void *, void *, va_list); - -static void nis_endstate(void *); -NSS_TLS_HANDLING(nis); -#endif - -/* get** wrappers for get**_r functions declarations */ -struct rpcent_state { - struct rpcent rpc; - char *buffer; - size_t bufsize; -}; -static void rpcent_endstate(void *); -NSS_TLS_HANDLING(rpcent); - -union key { - const char *name; - int number; -}; - -static int wrap_getrpcbyname_r(union key, struct rpcent *, char *, - size_t, struct rpcent **); -static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *, - size_t, struct rpcent **); -static int wrap_getrpcent_r(union key, struct rpcent *, char *, - size_t, struct rpcent **); -static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *, - size_t, struct rpcent **), union key); - -#ifdef NS_CACHING -static int rpc_id_func(char *, size_t *, va_list, void *); -static int rpc_marshal_func(char *, size_t *, void *, va_list, void *); -static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *); -#endif - -static int -rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases, - size_t aliases_size, int *errnop) -{ - char *cp, **q; - - assert(p != NULL); - - if (*p == '#') - return (-1); - cp = strpbrk(p, "#\n"); - if (cp == NULL) - return (-1); - *cp = '\0'; - cp = strpbrk(p, " \t"); - if (cp == NULL) - return (-1); - *cp++ = '\0'; - /* THIS STUFF IS INTERNET SPECIFIC */ - rpc->r_name = p; - while (*cp == ' ' || *cp == '\t') - cp++; - rpc->r_number = atoi(cp); - q = rpc->r_aliases = r_aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - if (q < &(r_aliases[aliases_size - 1])) - *q++ = cp; - else { - *errnop = ERANGE; - return -1; - } - - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - } - *q = NULL; - return 0; -} - -/* files backend implementation */ -static void -files_endstate(void *p) -{ - FILE * f; - - if (p == NULL) - return; - - f = ((struct files_state *)p)->fp; - if (f != NULL) - fclose(f); - - free(p); -} - -static int -files_rpcent(void *retval, void *mdata, va_list ap) -{ - char *name; - int number; - struct rpcent *rpc; - char *buffer; - size_t bufsize; - int *errnop; - - char *line; - size_t linesize; - char **aliases; - int aliases_size; - char **rp; - - struct files_state *st; - int rv; - int stayopen; - enum nss_lookup_type how; - - how = (enum nss_lookup_type)mdata; - switch (how) - { - case nss_lt_name: - name = va_arg(ap, char *); - break; - case nss_lt_id: - number = va_arg(ap, int); - break; - case nss_lt_all: - break; - default: - return (NS_NOTFOUND); - } - - rpc = va_arg(ap, struct rpcent *); - buffer = va_arg(ap, char *); - bufsize = va_arg(ap, size_t); - errnop = va_arg(ap, int *); - - *errnop = files_getstate(&st); - if (*errnop != 0) - return (NS_UNAVAIL); - - if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) { - *errnop = errno; - return (NS_UNAVAIL); - } - - if (how == nss_lt_all) - stayopen = 1; - else { - rewind(st->fp); - stayopen = st->stayopen; - } - - do { - if ((line = fgetln(st->fp, &linesize)) == NULL) { - *errnop = errno; - rv = NS_RETURN; - break; - } - - if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - - aliases = (char **)_ALIGN(&buffer[linesize+1]); - aliases_size = (buffer + bufsize - - (char *)aliases)/sizeof(char *); - if (aliases_size < 1) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - - memcpy(buffer, line, linesize); - buffer[linesize] = '\0'; - - rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop); - if (rv != 0) { - if (*errnop == 0) { - rv = NS_NOTFOUND; - continue; - } - else { - rv = NS_RETURN; - break; - } - } - - switch (how) - { - case nss_lt_name: - if (strcmp(rpc->r_name, name) == 0) - goto done; - for (rp = rpc->r_aliases; *rp != NULL; rp++) { - if (strcmp(*rp, name) == 0) - goto done; - } - rv = NS_NOTFOUND; - continue; -done: - rv = NS_SUCCESS; - break; - case nss_lt_id: - rv = (rpc->r_number == number) ? NS_SUCCESS : - NS_NOTFOUND; - break; - case nss_lt_all: - rv = NS_SUCCESS; - break; - } - - } while (!(rv & NS_TERMINATE)); - - if (!stayopen && st->fp!=NULL) { - fclose(st->fp); - st->fp = NULL; - } - - if ((rv == NS_SUCCESS) && (retval != NULL)) - *((struct rpcent **)retval) = rpc; - - return (rv); -} - -static int -files_setrpcent(void *retval, void *mdata, va_list ap) -{ - struct files_state *st; - int rv; - int f; - - rv = files_getstate(&st); - if (rv != 0) - return (NS_UNAVAIL); - - switch ((enum constants)mdata) - { - case SETRPCENT: - f = va_arg(ap,int); - if (st->fp == NULL) - st->fp = fopen(RPCDB, "r"); - else - rewind(st->fp); - st->stayopen |= f; - break; - case ENDRPCENT: - if (st->fp != NULL) { - fclose(st->fp); - st->fp = NULL; - } - st->stayopen = 0; - break; - default: - break; - } - - return (NS_UNAVAIL); -} - -/* nis backend implementation */ -#ifdef YP -static void -nis_endstate(void *p) -{ - if (p == NULL) - return; - - free(((struct nis_state *)p)->current); - free(p); -} - -static int -nis_rpcent(void *retval, void *mdata, va_list ap) -{ - char *name; - int number; - struct rpcent *rpc; - char *buffer; - size_t bufsize; - int *errnop; - - char **rp; - char **aliases; - int aliases_size; - - char *lastkey; - char *resultbuf; - int resultbuflen; - char buf[YPMAXRECORD + 2]; - - struct nis_state *st; - int rv; - enum nss_lookup_type how; - int no_name_active; - - how = (enum nss_lookup_type)mdata; - switch (how) - { - case nss_lt_name: - name = va_arg(ap, char *); - break; - case nss_lt_id: - number = va_arg(ap, int); - break; - case nss_lt_all: - break; - default: - return (NS_NOTFOUND); - } - - rpc = va_arg(ap, struct rpcent *); - buffer = va_arg(ap, char *); - bufsize = va_arg(ap, size_t); - errnop = va_arg(ap, int *); - - *errnop = nis_getstate(&st); - if (*errnop != 0) - return (NS_UNAVAIL); - - if (st->domain[0] == '\0') { - if (getdomainname(st->domain, sizeof(st->domain)) != 0) { - *errnop = errno; - return (NS_UNAVAIL); - } - } - - no_name_active = 0; - do { - switch (how) - { - case nss_lt_name: - if (!st->no_name_map) - { - snprintf(buf, sizeof buf, "%s", name); - rv = yp_match(st->domain, "rpc.byname", buf, - strlen(buf), &resultbuf, &resultbuflen); - - switch (rv) { - case 0: - break; - case YPERR_MAP: - st->stepping = 0; - no_name_active = 1; - how = nss_lt_all; - - rv = NS_NOTFOUND; - continue; - default: - rv = NS_NOTFOUND; - goto fin; - } - } else { - st->stepping = 0; - no_name_active = 1; - how = nss_lt_all; - - rv = NS_NOTFOUND; - continue; - } - break; - case nss_lt_id: - snprintf(buf, sizeof buf, "%d", number); - if (yp_match(st->domain, "rpc.bynumber", buf, - strlen(buf), &resultbuf, &resultbuflen)) { - rv = NS_NOTFOUND; - goto fin; - } - break; - case nss_lt_all: - if (!st->stepping) { - rv = yp_first(st->domain, "rpc.bynumber", - &st->current, - &st->currentlen, &resultbuf, - &resultbuflen); - if (rv) { - rv = NS_NOTFOUND; - goto fin; - } - st->stepping = 1; - } else { - lastkey = st->current; - rv = yp_next(st->domain, "rpc.bynumber", - st->current, - st->currentlen, &st->current, - &st->currentlen, - &resultbuf, &resultbuflen); - free(lastkey); - if (rv) { - st->stepping = 0; - rv = NS_NOTFOUND; - goto fin; - } - } - break; - } - - /* we need a room for additional \n symbol */ - if (bufsize <= resultbuflen + 1 + _ALIGNBYTES + - sizeof(char *)) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - - aliases=(char **)_ALIGN(&buffer[resultbuflen+2]); - aliases_size = (buffer + bufsize - (char *)aliases) / - sizeof(char *); - if (aliases_size < 1) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - - /* - * rpcent_unpack expects lines terminated with \n -- make it happy - */ - memcpy(buffer, resultbuf, resultbuflen); - buffer[resultbuflen] = '\n'; - buffer[resultbuflen+1] = '\0'; - free(resultbuf); - - if (rpcent_unpack(buffer, rpc, aliases, aliases_size, - errnop) != 0) { - if (*errnop == 0) - rv = NS_NOTFOUND; - else - rv = NS_RETURN; - } else { - if ((how == nss_lt_all) && (no_name_active != 0)) { - if (strcmp(rpc->r_name, name) == 0) - goto done; - for (rp = rpc->r_aliases; *rp != NULL; rp++) { - if (strcmp(*rp, name) == 0) - goto done; - } - rv = NS_NOTFOUND; - continue; -done: - rv = NS_SUCCESS; - } else - rv = NS_SUCCESS; - } - - } while (!(rv & NS_TERMINATE) && (how == nss_lt_all)); - -fin: - if ((rv == NS_SUCCESS) && (retval != NULL)) - *((struct rpcent **)retval) = rpc; - - return (rv); -} - -static int -nis_setrpcent(void *retval, void *mdata, va_list ap) -{ - struct nis_state *st; - int rv; - - rv = nis_getstate(&st); - if (rv != 0) - return (NS_UNAVAIL); - - switch ((enum constants)mdata) - { - case SETRPCENT: - case ENDRPCENT: - free(st->current); - st->current = NULL; - st->stepping = 0; - break; - default: - break; - } - - return (NS_UNAVAIL); -} -#endif - -#ifdef NS_CACHING -static int -rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) -{ - char *name; - int rpc; - - size_t desired_size, size; - enum nss_lookup_type lookup_type; - int res = NS_UNAVAIL; - - lookup_type = (enum nss_lookup_type)cache_mdata; - switch (lookup_type) { - case nss_lt_name: - name = va_arg(ap, char *); - - size = strlen(name); - desired_size = sizeof(enum nss_lookup_type) + size + 1; - if (desired_size > *buffer_size) { - res = NS_RETURN; - goto fin; - } - - memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); - memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1); - - res = NS_SUCCESS; - break; - case nss_lt_id: - rpc = va_arg(ap, int); - - desired_size = sizeof(enum nss_lookup_type) + sizeof(int); - if (desired_size > *buffer_size) { - res = NS_RETURN; - goto fin; - } - - memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); - memcpy(buffer + sizeof(enum nss_lookup_type), &rpc, - sizeof(int)); - - res = NS_SUCCESS; - break; - default: - /* should be unreachable */ - return (NS_UNAVAIL); - } - -fin: - *buffer_size = desired_size; - return (res); -} - -static int -rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, - void *cache_mdata) -{ - char *name; - int num; - struct rpcent *rpc; - char *orig_buf; - size_t orig_buf_size; - - struct rpcent new_rpc; - size_t desired_size, size, aliases_size; - char *p; - char **alias; - - switch ((enum nss_lookup_type)cache_mdata) { - case nss_lt_name: - name = va_arg(ap, char *); - break; - case nss_lt_id: - num = va_arg(ap, int); - break; - case nss_lt_all: - break; - default: - /* should be unreachable */ - return (NS_UNAVAIL); - } - - rpc = va_arg(ap, struct rpcent *); - orig_buf = va_arg(ap, char *); - orig_buf_size = va_arg(ap, size_t); - - desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *); - if (rpc->r_name != NULL) - desired_size += strlen(rpc->r_name) + 1; - - if (rpc->r_aliases != NULL) { - aliases_size = 0; - for (alias = rpc->r_aliases; *alias; ++alias) { - desired_size += strlen(*alias) + 1; - ++aliases_size; - } - - desired_size += _ALIGNBYTES + (aliases_size + 1) * - sizeof(char *); - } - - if (*buffer_size < desired_size) { - /* this assignment is here for future use */ - *buffer_size = desired_size; - return (NS_RETURN); - } - - new_rpc = *rpc; - - *buffer_size = desired_size; - memset(buffer, 0, desired_size); - p = buffer + sizeof(struct rpcent) + sizeof(char *); - memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *)); - p = (char *)_ALIGN(p); - - if (new_rpc.r_name != NULL) { - size = strlen(new_rpc.r_name); - memcpy(p, new_rpc.r_name, size); - new_rpc.r_name = p; - p += size + 1; - } - - if (new_rpc.r_aliases != NULL) { - p = (char *)_ALIGN(p); - memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size); - new_rpc.r_aliases = (char **)p; - p += sizeof(char *) * (aliases_size + 1); - - for (alias = new_rpc.r_aliases; *alias; ++alias) { - size = strlen(*alias); - memcpy(p, *alias, size); - *alias = p; - p += size + 1; - } - } - - memcpy(buffer, &new_rpc, sizeof(struct rpcent)); - return (NS_SUCCESS); -} - -static int -rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, - void *cache_mdata) -{ - char *name; - int num; - struct rpcent *rpc; - char *orig_buf; - size_t orig_buf_size; - int *ret_errno; - - char *p; - char **alias; - - switch ((enum nss_lookup_type)cache_mdata) { - case nss_lt_name: - name = va_arg(ap, char *); - break; - case nss_lt_id: - num = va_arg(ap, int); - break; - case nss_lt_all: - break; - default: - /* should be unreachable */ - return (NS_UNAVAIL); - } - - rpc = va_arg(ap, struct rpcent *); - orig_buf = va_arg(ap, char *); - orig_buf_size = va_arg(ap, size_t); - ret_errno = va_arg(ap, int *); - - if (orig_buf_size < - buffer_size - sizeof(struct rpcent) - sizeof(char *)) { - *ret_errno = ERANGE; - return (NS_RETURN); - } - - memcpy(rpc, buffer, sizeof(struct rpcent)); - memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *)); - - orig_buf = (char *)_ALIGN(orig_buf); - memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) + - _ALIGN(p) - (size_t)p, - buffer_size - sizeof(struct rpcent) - sizeof(char *) - - _ALIGN(p) + (size_t)p); - p = (char *)_ALIGN(p); - - NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *); - if (rpc->r_aliases != NULL) { - NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **); - - for (alias = rpc->r_aliases ; *alias; ++alias) - NS_APPLY_OFFSET(*alias, orig_buf, p, char *); - } - - if (retval != NULL) - *((struct rpcent **)retval) = rpc; - - return (NS_SUCCESS); -} - -NSS_MP_CACHE_HANDLING(rpc); -#endif /* NS_CACHING */ - - -/* get**_r functions implementation */ -static int -getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer, - size_t bufsize, struct rpcent **result) -{ -#ifdef NS_CACHING - static const nss_cache_info cache_info = - NS_COMMON_CACHE_INFO_INITIALIZER( - rpc, (void *)nss_lt_name, - rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); -#endif - static const ns_dtab dtab[] = { - { NSSRC_FILES, files_rpcent, (void *)nss_lt_name }, -#ifdef YP - { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name }, -#endif -#ifdef NS_CACHING - NS_CACHE_CB(&cache_info) -#endif - { NULL, NULL, NULL } - }; - int rv, ret_errno; - - ret_errno = 0; - *result = NULL; - rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc, - name, rpc, buffer, bufsize, &ret_errno); - - if (rv == NS_SUCCESS) - return (0); - else - return (ret_errno); -} - -static int -getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer, - size_t bufsize, struct rpcent **result) -{ -#ifdef NS_CACHING - static const nss_cache_info cache_info = - NS_COMMON_CACHE_INFO_INITIALIZER( - rpc, (void *)nss_lt_id, - rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); -#endif - static const ns_dtab dtab[] = { - { NSSRC_FILES, files_rpcent, (void *)nss_lt_id }, -#ifdef YP - { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id }, -#endif -#ifdef NS_CACHING - NS_CACHE_CB(&cache_info) -#endif - { NULL, NULL, NULL } - }; - int rv, ret_errno; - - ret_errno = 0; - *result = NULL; - rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc, - number, rpc, buffer, bufsize, &ret_errno); - - if (rv == NS_SUCCESS) - return (0); - else - return (ret_errno); -} - -static int -getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize, - struct rpcent **result) -{ -#ifdef NS_CACHING - static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( - rpc, (void *)nss_lt_all, - rpc_marshal_func, rpc_unmarshal_func); -#endif - static const ns_dtab dtab[] = { - { NSSRC_FILES, files_rpcent, (void *)nss_lt_all }, -#ifdef YP - { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all }, -#endif -#ifdef NS_CACHING - NS_CACHE_CB(&cache_info) -#endif - { NULL, NULL, NULL } - }; - int rv, ret_errno; - - ret_errno = 0; - *result = NULL; - rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc, - rpc, buffer, bufsize, &ret_errno); - - if (rv == NS_SUCCESS) - return (0); - else - return (ret_errno); -} - -/* get** wrappers for get**_r functions implementation */ -static void -rpcent_endstate(void *p) -{ - if (p == NULL) - return; - - free(((struct rpcent_state *)p)->buffer); - free(p); -} - -static int -wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer, - size_t bufsize, struct rpcent **res) -{ - return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res)); -} - -static int -wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer, - size_t bufsize, struct rpcent **res) -{ - return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res)); -} - -static int -wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer, - size_t bufsize, struct rpcent **res) -{ - return (getrpcent_r(rpc, buffer, bufsize, res)); -} - -static struct rpcent * -getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **), - union key key) -{ - int rv; - struct rpcent *res; - struct rpcent_state * st; - - rv=rpcent_getstate(&st); - if (rv != 0) { - errno = rv; - return NULL; - } - - if (st->buffer == NULL) { - st->buffer = malloc(RPCENT_STORAGE_INITIAL); - if (st->buffer == NULL) - return (NULL); - st->bufsize = RPCENT_STORAGE_INITIAL; - } - do { - rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res); - if (res == NULL && rv == ERANGE) { - free(st->buffer); - if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) { - st->buffer = NULL; - errno = ERANGE; - return (NULL); - } - st->bufsize <<= 1; - st->buffer = malloc(st->bufsize); - if (st->buffer == NULL) - return (NULL); - } - } while (res == NULL && rv == ERANGE); - if (rv != 0) - errno = rv; - - return (res); -} - -struct rpcent * -getrpcbyname(char *name) -{ - union key key; - - key.name = name; - - return (getrpc(wrap_getrpcbyname_r, key)); -} - -struct rpcent * -getrpcbynumber(int number) -{ - union key key; - - key.number = number; - - return (getrpc(wrap_getrpcbynumber_r, key)); -} - -struct rpcent * -getrpcent() -{ - union key key; - - key.number = 0; /* not used */ - - return (getrpc(wrap_getrpcent_r, key)); -} - -void -setrpcent(int stayopen) -{ -#ifdef NS_CACHING - static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( - rpc, (void *)nss_lt_all, - NULL, NULL); -#endif - - static const ns_dtab dtab[] = { - { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT }, -#ifdef YP - { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT }, -#endif -#ifdef NS_CACHING - NS_CACHE_CB(&cache_info) -#endif - { NULL, NULL, NULL } - }; - - (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, - stayopen); -} - -void -endrpcent() -{ -#ifdef NS_CACHING - static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( - rpc, (void *)nss_lt_all, - NULL, NULL); -#endif - - static const ns_dtab dtab[] = { - { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT }, -#ifdef YP - { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT }, -#endif -#ifdef NS_CACHING - NS_CACHE_CB(&cache_info) -#endif - { NULL, NULL, NULL } - }; - - (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc); -} diff --git a/lib/libc/rpc/getrpcport.3 b/lib/libc/rpc/getrpcport.3 deleted file mode 100644 index 6e1f199..0000000 --- a/lib/libc/rpc/getrpcport.3 +++ /dev/null @@ -1,36 +0,0 @@ -.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI -.\" $FreeBSD$ -.\" -.Dd October 6, 1987 -.Dt GETRPCPORT 3 -.Os -.Sh NAME -.Nm getrpcport -.Nd get RPC port number -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.Ft int -.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto" -.Sh DESCRIPTION -The -.Fn getrpcport -function -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/lib/libc/rpc/getrpcport.c b/lib/libc/rpc/getrpcport.c deleted file mode 100644 index 676a1f5..0000000 --- a/lib/libc/rpc/getrpcport.c +++ /dev/null @@ -1,78 +0,0 @@ -/* $NetBSD: getrpcport.c,v 1.16 2000/01/22 22:19:18 mycroft Exp $ */ - -/* - * 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 *sccsid2 = "@(#)getrpcport.c 1.3 87/08/11 SMI"; -static char *sccsid = "@(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Copyright (c) 1985 by Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/socket.h> - -#include <assert.h> -#include <netdb.h> -#include <stdio.h> -#include <string.h> - -#include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> -#include "un-namespace.h" - -int -getrpcport(host, prognum, versnum, proto) - char *host; - int prognum, versnum, proto; -{ - struct sockaddr_in addr; - struct hostent *hp; - - assert(host != NULL); - - 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; - if (hp->h_length > addr.sin_len) - hp->h_length = addr.sin_len; - memcpy(&addr.sin_addr.s_addr, hp->h_addr, (size_t)hp->h_length); - /* Inconsistent interfaces need casts! :-( */ - return (pmap_getport(&addr, (u_long)prognum, (u_long)versnum, - (u_int)proto)); -} diff --git a/lib/libc/rpc/key_call.c b/lib/libc/rpc/key_call.c deleted file mode 100644 index afb11c8..0000000 --- a/lib/libc/rpc/key_call.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 - */ -/* - * Copyright (c) 1986-1991 by Sun Microsystems Inc. - */ - -#ident "@(#)key_call.c 1.25 94/04/24 SMI" -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include "reentrant.h" -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <rpc/rpc.h> -#include <rpc/auth.h> -#include <rpc/auth_unix.h> -#include <rpc/key_prot.h> -#include <string.h> -#include <netconfig.h> -#include <sys/utsname.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/fcntl.h> -#include "un-namespace.h" -#include "mt_misc.h" - - -#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( u_long, xdrproc_t, void *, xdrproc_t, void *); - -int -key_setsecret(secretkey) - const char *secretkey; -{ - keystatus status; - - if (!key_call((u_long) KEY_SET, (xdrproc_t)xdr_keybuf, - (void *)secretkey, - (xdrproc_t)xdr_keystatus, &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, (xdrproc_t)xdr_void, NULL, - (xdrproc_t)xdr_key_netstres, &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, (xdrproc_t)xdr_cryptkeyarg2, &arg, - (xdrproc_t)xdr_cryptkeyres, &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, (xdrproc_t)xdr_cryptkeyarg2, &arg, - (xdrproc_t)xdr_cryptkeyres, &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, (xdrproc_t)xdr_cryptkeyarg, &arg, - (xdrproc_t)xdr_cryptkeyres, &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, (xdrproc_t)xdr_cryptkeyarg, &arg, - (xdrproc_t)xdr_cryptkeyres, &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, (xdrproc_t)xdr_void, NULL, - (xdrproc_t)xdr_des_block, key)) { - return (-1); - } - return (0); -} - -int -key_setnet(arg) -struct key_netstarg *arg; -{ - keystatus status; - - - if (!key_call((u_long) KEY_NET_PUT, (xdrproc_t)xdr_key_netstarg, arg, - (xdrproc_t)xdr_keystatus, &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, (xdrproc_t)xdr_keybuf, pkey, - (xdrproc_t)xdr_cryptkeyres, &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; -static thread_key_t key_call_key; -static once_t key_call_once = ONCE_INITIALIZER; -static int key_call_key_error; - -static void -key_call_destroy(void *vp) -{ - struct key_call_private *kcp = (struct key_call_private *)vp; - - if (kcp) { - if (kcp->client) - clnt_destroy(kcp->client); - free(kcp); - } -} - -static void -key_call_init(void) -{ - - key_call_key_error = thr_keycreate(&key_call_key, key_call_destroy); -} - -/* - * Keep the handle cached. This call may be made quite often. - */ -static CLIENT * -getkeyserv_handle(vers) -int vers; -{ - void *localhandle; - struct netconfig *nconf; - struct netconfig *tpconf; - struct key_call_private *kcp; - struct timeval wait_time; - struct utsname u; - int main_thread; - int fd; - -#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */ -#define TOTAL_TRIES 5 /* Number of tries */ - - if ((main_thread = thr_main())) { - kcp = key_call_private_main; - } else { - if (thr_once(&key_call_once, key_call_init) != 0 || - key_call_key_error != 0) - return ((CLIENT *) NULL); - kcp = (struct key_call_private *)thr_getspecific(key_call_key); - } - 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); - } - if (main_thread) - key_call_private_main = kcp; - else - thr_setspecific(key_call_key, (void *) 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 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 (!(localhandle = setnetconfig())) { - return ((CLIENT *) NULL); - } - tpconf = NULL; -#if defined(__FreeBSD__) - if (uname(&u) == -1) -#else -#if defined(i386) - if (_nuname(&u) == -1) -#elif defined(sparc) - if (_uname(&u) == -1) -#else -#error Unknown architecture! -#endif -#endif - { - endnetconfig(localhandle); - return ((CLIENT *) NULL); - } - while ((nconf = getnetconfig(localhandle)) != NULL) { - if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { - /* - * We use COTS_ORD here so that the caller can - * find out immediately if the server is dead. - */ - if (nconf->nc_semantics == NC_TPI_COTS_ORD) { - kcp->client = clnt_tp_create(u.nodename, - KEY_PROG, vers, nconf); - if (kcp->client) - break; - } else { - tpconf = nconf; - } - } - } - if ((kcp->client == (CLIENT *) NULL) && (tpconf)) - /* Now, try the CLTS or COTS loopback transport */ - kcp->client = clnt_tp_create(u.nodename, - KEY_PROG, vers, tpconf); - endnetconfig(localhandle); - - 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; - void *arg; - xdrproc_t xdr_rslt; - void *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/lib/libc/rpc/key_prot_xdr.c b/lib/libc/rpc/key_prot_xdr.c deleted file mode 100644 index bcead6a..0000000 --- a/lib/libc/rpc/key_prot_xdr.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Please do not edit this file. - * It was generated using rpcgen. - */ - -#include "namespace.h" -#include <rpc/key_prot.h> -#include "un-namespace.h" -/* - * 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) 1990, 1991 Sun Microsystems, Inc. */ - -/* #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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; - default: - break; - } - return (TRUE); -} - -bool_t -xdr_unixcred(register XDR *xdrs, unixcred *objp) -{ - u_int **pgids_val; - - if (!xdr_u_int(xdrs, &objp->uid)) - return (FALSE); - if (!xdr_u_int(xdrs, &objp->gid)) - return (FALSE); - pgids_val = &objp->gids.gids_val; - if (!xdr_array(xdrs, (char **) pgids_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; - default: - 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; - default: - break; - } - return (TRUE); -} diff --git a/lib/libc/rpc/mt_misc.c b/lib/libc/rpc/mt_misc.c deleted file mode 100644 index 7abcaed..0000000 --- a/lib/libc/rpc/mt_misc.c +++ /dev/null @@ -1,117 +0,0 @@ -/* $NetBSD: mt_misc.c,v 1.1 2000/06/02 23:11:11 fvdl Exp $ */ - -/* #pragma ident "@(#)mt_misc.c 1.24 93/04/29 SMI" */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include "reentrant.h" -#include <rpc/rpc.h> -#include <sys/time.h> -#include <stdlib.h> -#include <string.h> -#include "un-namespace.h" -#include "mt_misc.h" - -/* Take these objects out of the application namespace. */ -#define svc_lock __svc_lock -#define svc_fd_lock __svc_fd_lock -#define rpcbaddr_cache_lock __rpcbaddr_cache_lock -#define authdes_ops_lock __authdes_ops_lock -#define authnone_lock __authnone_lock -#define authsvc_lock __authsvc_lock -#define clnt_fd_lock __clnt_fd_lock -#define clntraw_lock __clntraw_lock -#define dupreq_lock __dupreq_lock -#define loopnconf_lock __loopnconf_lock -#define ops_lock __ops_lock -#define proglst_lock __proglst_lock -#define rpcsoc_lock __rpcsoc_lock -#define svcraw_lock __svcraw_lock -#define xprtlist_lock __xprtlist_lock - -/* protects the services list (svc.c) */ -pthread_rwlock_t svc_lock = PTHREAD_RWLOCK_INITIALIZER; - -/* protects svc_fdset and the xports[] array */ -pthread_rwlock_t svc_fd_lock = PTHREAD_RWLOCK_INITIALIZER; - -/* protects the RPCBIND address cache */ -pthread_rwlock_t rpcbaddr_cache_lock = PTHREAD_RWLOCK_INITIALIZER; - -/* serializes authdes ops initializations */ -pthread_mutex_t authdes_ops_lock = PTHREAD_MUTEX_INITIALIZER; - -/* protects des stats list */ -pthread_mutex_t svcauthdesstats_lock = PTHREAD_MUTEX_INITIALIZER; - -/* auth_none.c serialization */ -pthread_mutex_t authnone_lock = PTHREAD_MUTEX_INITIALIZER; - -/* protects the Auths list (svc_auth.c) */ -pthread_mutex_t authsvc_lock = PTHREAD_MUTEX_INITIALIZER; - -/* protects client-side fd lock array */ -pthread_mutex_t clnt_fd_lock = PTHREAD_MUTEX_INITIALIZER; - -/* clnt_raw.c serialization */ -pthread_mutex_t clntraw_lock = PTHREAD_MUTEX_INITIALIZER; - -/* dupreq variables (svc_dg.c) */ -pthread_mutex_t dupreq_lock = PTHREAD_MUTEX_INITIALIZER; - -/* loopnconf (rpcb_clnt.c) */ -pthread_mutex_t loopnconf_lock = PTHREAD_MUTEX_INITIALIZER; - -/* serializes ops initializations */ -pthread_mutex_t ops_lock = PTHREAD_MUTEX_INITIALIZER; - -/* protects proglst list (svc_simple.c) */ -pthread_mutex_t proglst_lock = PTHREAD_MUTEX_INITIALIZER; - -/* serializes clnt_com_create() (rpc_soc.c) */ -pthread_mutex_t rpcsoc_lock = PTHREAD_MUTEX_INITIALIZER; - -/* svc_raw.c serialization */ -pthread_mutex_t svcraw_lock = PTHREAD_MUTEX_INITIALIZER; - -/* xprtlist (svc_generic.c) */ -pthread_mutex_t xprtlist_lock = PTHREAD_MUTEX_INITIALIZER; - -#undef rpc_createerr - -struct rpc_createerr rpc_createerr; -static thread_key_t rce_key; -static once_t rce_once = ONCE_INITIALIZER; -static int rce_key_error; - -static void -rce_key_init(void) -{ - - rce_key_error = thr_keycreate(&rce_key, free); -} - -struct rpc_createerr * -__rpc_createerr() -{ - struct rpc_createerr *rce_addr = 0; - - if (thr_main()) - return (&rpc_createerr); - if (thr_once(&rce_once, rce_key_init) != 0 || rce_key_error != 0) - return (&rpc_createerr); - rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key); - if (!rce_addr) { - rce_addr = (struct rpc_createerr *) - malloc(sizeof (struct rpc_createerr)); - if (thr_setspecific(rce_key, (void *) rce_addr) != 0) { - if (rce_addr) - free(rce_addr); - return (&rpc_createerr); - } - memset(rce_addr, 0, sizeof (struct rpc_createerr)); - return (rce_addr); - } - return (rce_addr); -} diff --git a/lib/libc/rpc/mt_misc.h b/lib/libc/rpc/mt_misc.h deleted file mode 100644 index 9cc2349..0000000 --- a/lib/libc/rpc/mt_misc.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2006 The FreeBSD Project. 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. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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$ - */ -#ifndef _MT_MISC_H -#define _MT_MISC_H - -/* Take these locks out of the application namespace. */ -#define svc_lock __svc_lock -#define svc_fd_lock __svc_fd_lock -#define rpcbaddr_cache_lock __rpcbaddr_cache_lock -#define authdes_ops_lock __authdes_ops_lock -#define authnone_lock __authnone_lock -#define authsvc_lock __authsvc_lock -#define clnt_fd_lock __clnt_fd_lock -#define clntraw_lock __clntraw_lock -#define dupreq_lock __dupreq_lock -#define loopnconf_lock __loopnconf_lock -#define ops_lock __ops_lock -#define proglst_lock __proglst_lock -#define rpcsoc_lock __rpcsoc_lock -#define svcraw_lock __svcraw_lock -#define xprtlist_lock __xprtlist_lock - -extern pthread_rwlock_t svc_lock; -extern pthread_rwlock_t svc_fd_lock; -extern pthread_rwlock_t rpcbaddr_cache_lock; -extern pthread_mutex_t authdes_ops_lock; -extern pthread_mutex_t svcauthdesstats_lock; -extern pthread_mutex_t authnone_lock; -extern pthread_mutex_t authsvc_lock; -extern pthread_mutex_t clnt_fd_lock; -extern pthread_mutex_t clntraw_lock; -extern pthread_mutex_t dupreq_lock; -extern pthread_mutex_t loopnconf_lock; -extern pthread_mutex_t ops_lock; -extern pthread_mutex_t proglst_lock; -extern pthread_mutex_t rpcsoc_lock; -extern pthread_mutex_t svcraw_lock; -extern pthread_mutex_t tsd_lock; -extern pthread_mutex_t xprtlist_lock; - -#endif diff --git a/lib/libc/rpc/netconfig.5 b/lib/libc/rpc/netconfig.5 deleted file mode 100644 index edd2f63..0000000 --- a/lib/libc/rpc/netconfig.5 +++ /dev/null @@ -1,132 +0,0 @@ -.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $ -.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $ -.\" $FreeBSD$ -.Dd November 17, 2000 -.Dt NETCONFIG 5 -.Os -.Sh NAME -.Nm netconfig -.Nd network configuration data base -.Sh SYNOPSIS -.Pa /etc/netconfig -.Sh DESCRIPTION -The -.Nm -file defines a list of -.Dq transport names , -describing their semantics and protocol. -In -.Fx , -this file is only used by the RPC library code. -.Pp -Entries have the following format: -.Pp -.Ar network_id semantics flags family protoname device libraries -.Pp -Entries consist of the following fields: -.Bl -tag -width network_id -.It Ar network_id -The name of the transport described. -.It Ar semantics -Describes the semantics of the transport. -This can be one of: -.Bl -tag -width tpi_cots_ord -offset indent -.It Sy tpi_clts -Connectionless transport. -.It Sy tpi_cots -Connection-oriented transport -.It Sy tpi_cots_ord -Connection-oriented, ordered transport. -.It Sy tpi_raw -A raw connection. -.El -.It Ar flags -This field is either blank (specified by -.Dq Li - ) , -or contains one or more of the following characters: -.Bl -tag -width b -offset indent -.It Sy b -The network represented by this entry is broadcast capable. -This flag is meaningless in -.Fx . -.It Sy v -The entry may be returned by the -.Xr getnetpath 3 -function. -.El -.It Ar family -The protocol family of the transport. -This is currently one of: -.Bl -tag -width loopback -offset indent -.It Sy inet6 -The IPv6 -.Pq Dv PF_INET6 -family of protocols. -.It Sy inet -The IPv4 -.Pq Dv PF_INET -family of protocols. -.It Sy loopback -The -.Dv PF_LOCAL -protocol family. -.El -.It Ar protoname -The name of the protocol used for this transport. -Can currently be either -.Sy udp , -.Sy tcp -or empty. -.It Ar device -This field is always empty in -.Fx . -.It Ar libraries -This field is always empty in -.Fx . -.El -.Pp -The order of entries in this file will determine which transport will -be preferred by the RPC library code, given a match on a specified -network type. -For example, if a sample network config file would look like this: -.Bd -literal -offset indent -udp6 tpi_clts v inet6 udp - - -tcp6 tpi_cots_ord v inet6 tcp - - -udp tpi_clts v inet udp - - -tcp tpi_cots_ord v inet tcp - - -rawip tpi_raw - inet - - - -local tpi_cots_ord - loopback - - - -.Ed -.Pp -then using the network type -.Sy udp -in calls to the RPC library function (see -.Xr rpc 3 ) -will make the code first try -.Sy udp6 , -and then -.Sy udp . -.Pp -.Xr getnetconfig 3 -and associated functions will parse this file and return structures of -the following format: -.Bd -literal -struct netconfig { - char *nc_netid; /* Network ID */ - unsigned long nc_semantics; /* Semantics */ - unsigned long nc_flag; /* Flags */ - char *nc_protofmly; /* Protocol family */ - char *nc_proto; /* Protocol name */ - char *nc_device; /* Network device pathname (unused) */ - unsigned long nc_nlookups; /* Number of lookup libs (unused) */ - char **nc_lookups; /* Names of the libraries (unused) */ - unsigned long nc_unused[9]; /* reserved */ -}; -.Ed -.Sh FILES -.Bl -tag -width /etc/netconfig -compact -.It Pa /etc/netconfig -.El -.Sh SEE ALSO -.Xr getnetconfig 3 , -.Xr getnetpath 3 diff --git a/lib/libc/rpc/netname.c b/lib/libc/rpc/netname.c deleted file mode 100644 index 72361ba..0000000 --- a/lib/libc/rpc/netname.c +++ /dev/null @@ -1,150 +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[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include <sys/param.h> -#include <rpc/rpc.h> -#include <rpc/rpc_com.h> -#ifdef YP -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#endif -#include <ctype.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "un-namespace.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - -#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) - -#define TYPE_SIGNED(type) (((type) -1) < 0) - -/* -** 302 / 1000 is log10(2.0) rounded up. -** Subtract one for the sign bit if the type is signed; -** add one for integer division truncation; -** add one more for a minus sign if the type is signed. -*/ -#define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) - -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]; - const uid_t uid; - const char *domain; -{ - char *dfltdom; - - if (domain == NULL) { - if (__rpc_get_default_domain(&dfltdom) != 0) { - return (0); - } - domain = dfltdom; - } - if (strlen(domain) + 1 + INT_STRLEN_MAXIMUM(u_long) + 1 + strlen(OPSYS) > 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]; - const char *host; - const 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) + 1 + strlen(OPSYS) > MAXNETNAMELEN) { - return (0); - } - (void) sprintf(netname, "%s.%s@%s", OPSYS, host, domain); - return (1); -} diff --git a/lib/libc/rpc/netnamer.c b/lib/libc/rpc/netnamer.c deleted file mode 100644 index 772160a..0000000 --- a/lib/libc/rpc/netnamer.c +++ /dev/null @@ -1,331 +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[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include <sys/param.h> -#include <rpc/rpc.h> -#include <rpc/rpc_com.h> -#ifdef YP -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#endif -#include <ctype.h> -#include <stdio.h> -#include <grp.h> -#include <pwd.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include "un-namespace.h" - -static char *OPSYS = "unix"; -#ifdef YP -static char *NETID = "netid.byname"; -#endif -static char *NETIDFILE = "/etc/netid"; - -static int getnetid( char *, char * ); -static int _getgroups( char *, gid_t * ); - -/* - * 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)) { - char *res = val; - - p = strsep(&res, ":"); - if (p == NULL) - return (0); - *uidp = (uid_t) atol(p); - p = strsep(&res, "\n,"); - if (p == NULL) { - return (0); - } - *gidp = (gid_t) atol(p); - for (gidlen = 0; gidlen < NGRPS; gidlen++) { - p = strsep(&res, "\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[NGRPS]; -{ - gid_t ngroups = 0; - struct group *grp; - int i; - 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 == NGRPS) { -#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 == NULL) { -#ifdef YP - res = "+"; - goto getnetidyp; -#else - return (0); -#endif - } - for (;;) { - if (fd == NULL) - return (0); /* getnetidyp brings us here */ - res = fgets(buf, sizeof(buf), fd); - if (res == NULL) { - 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 = strsep(&res, "\t "); - if (mkey == NULL) { - fprintf(stderr, - "Bad record in %s -- %s", NETIDFILE, buf); - continue; - } - do { - mval = strsep(&res, " \t#\n"); - } while (mval != NULL && !*mval); - 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/lib/libc/rpc/pmap_clnt.c b/lib/libc/rpc/pmap_clnt.c deleted file mode 100644 index a0db013..0000000 --- a/lib/libc/rpc/pmap_clnt.c +++ /dev/null @@ -1,120 +0,0 @@ -/* $NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * pmap_clnt.c - * Client interface to pmap rpc service. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <rpc/rpc.h> -#include <rpc/pmap_prot.h> -#include <rpc/pmap_clnt.h> -#include <rpc/nettype.h> -#include <netinet/in.h> -#include "un-namespace.h" - -#include <stdio.h> -#include <stdlib.h> - -#include "rpc_com.h" - -bool_t -pmap_set(u_long program, u_long version, int protocol, int port) -{ - bool_t rslt; - struct netbuf *na; - struct netconfig *nconf; - char buf[32]; - - if ((protocol != IPPROTO_UDP) && (protocol != IPPROTO_TCP)) { - return (FALSE); - } - nconf = __rpc_getconfip(protocol == IPPROTO_UDP ? "udp" : "tcp"); - if (nconf == NULL) { - return (FALSE); - } - snprintf(buf, sizeof buf, "0.0.0.0.%d.%d", - (((u_int32_t)port) >> 8) & 0xff, port & 0xff); - na = uaddr2taddr(nconf, buf); - if (na == NULL) { - freenetconfigent(nconf); - return (FALSE); - } - rslt = rpcb_set((rpcprog_t)program, (rpcvers_t)version, nconf, na); - free(na); - freenetconfigent(nconf); - return (rslt); -} - -/* - * Remove the mapping between program, version and port. - * Calls the pmap service remotely to do the un-mapping. - */ -bool_t -pmap_unset(u_long program, u_long version) -{ - struct netconfig *nconf; - bool_t udp_rslt = FALSE; - bool_t tcp_rslt = FALSE; - - nconf = __rpc_getconfip("udp"); - if (nconf != NULL) { - udp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version, - nconf); - freenetconfigent(nconf); - } - nconf = __rpc_getconfip("tcp"); - if (nconf != NULL) { - tcp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version, - nconf); - freenetconfigent(nconf); - } - /* - * XXX: The call may still succeed even if only one of the - * calls succeeded. This was the best that could be - * done for backward compatibility. - */ - return (tcp_rslt || udp_rslt); -} diff --git a/lib/libc/rpc/pmap_getmaps.c b/lib/libc/rpc/pmap_getmaps.c deleted file mode 100644 index 42d3720..0000000 --- a/lib/libc/rpc/pmap_getmaps.c +++ /dev/null @@ -1,100 +0,0 @@ -/* $NetBSD: pmap_getmaps.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include <arpa/inet.h> -#include <net/if.h> - -#include <assert.h> -#include <errno.h> -#include <netdb.h> -#include <stdio.h> -#include <unistd.h> - -#include <rpc/rpc.h> -#include <rpc/pmap_prot.h> -#include <rpc/pmap_clnt.h> -#include "un-namespace.h" - -#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 = NULL; - int sock = -1; - struct timeval minutetimeout; - CLIENT *client; - - assert(address != NULL); - - minutetimeout.tv_sec = 60; - minutetimeout.tv_usec = 0; - address->sin_port = htons(PMAPPORT); - client = clnttcp_create(address, PMAPPROG, - PMAPVERS, &sock, 50, 500); - if (client != NULL) { - if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_DUMP, - (xdrproc_t)xdr_void, NULL, - (xdrproc_t)xdr_pmaplist, &head, minutetimeout) != - RPC_SUCCESS) { - clnt_perror(client, "pmap_getmaps rpc problem"); - } - CLNT_DESTROY(client); - } - address->sin_port = 0; - return (head); -} diff --git a/lib/libc/rpc/pmap_getport.c b/lib/libc/rpc/pmap_getport.c deleted file mode 100644 index ca0aafd..0000000 --- a/lib/libc/rpc/pmap_getport.c +++ /dev/null @@ -1,104 +0,0 @@ -/* $NetBSD: pmap_getport.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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 *sccsid2 = "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"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * pmap_getport.c - * Client interface to pmap rpc service. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/socket.h> - -#include <arpa/inet.h> -#include <net/if.h> - -#include <assert.h> -#include <unistd.h> - -#include <rpc/rpc.h> -#include <rpc/pmap_prot.h> -#include <rpc/pmap_clnt.h> -#include "un-namespace.h" - -static const struct timeval timeout = { 5, 0 }; -static const 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 sock = -1; - CLIENT *client; - struct pmap parms; - - assert(address != NULL); - - address->sin_port = htons(PMAPPORT); - client = clntudp_bufcreate(address, PMAPPROG, - PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); - if (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, (rpcproc_t)PMAPPROC_GETPORT, - (xdrproc_t)xdr_pmap, - &parms, (xdrproc_t)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); - } - address->sin_port = 0; - return (port); -} diff --git a/lib/libc/rpc/pmap_prot.c b/lib/libc/rpc/pmap_prot.c deleted file mode 100644 index 2c01311..0000000 --- a/lib/libc/rpc/pmap_prot.c +++ /dev/null @@ -1,69 +0,0 @@ -/* $NetBSD: pmap_prot.c,v 1.10 2000/01/22 22:19:18 mycroft Exp $ */ - -/* - * 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 *sccsid2 = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * pmap_prot.c - * Protocol for the local binder service, or pmap. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <assert.h> - -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/pmap_prot.h> -#include "un-namespace.h" - - -bool_t -xdr_pmap(xdrs, regs) - XDR *xdrs; - struct pmap *regs; -{ - - assert(xdrs != NULL); - assert(regs != NULL); - - 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/lib/libc/rpc/pmap_prot2.c b/lib/libc/rpc/pmap_prot2.c deleted file mode 100644 index ae7c7c6..0000000 --- a/lib/libc/rpc/pmap_prot2.c +++ /dev/null @@ -1,143 +0,0 @@ -/* $NetBSD: pmap_prot2.c,v 1.14 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * pmap_prot2.c - * Protocol for the local binder service, or pmap. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <assert.h> - -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/pmap_prot.h> -#include "un-namespace.h" - - -/* - * 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) - XDR *xdrs; - 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; - int freeing; - struct pmaplist **next = NULL; /* pacify gcc */ - - assert(xdrs != NULL); - assert(rp != NULL); - - freeing = (xdrs->x_op == XDR_FREE); - - for (;;) { - 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), (xdrproc_t)xdr_pmap)) - return (FALSE); - rp = (freeing) ? next : &((*rp)->pml_next); - } -} - - -/* - * xdr_pmaplist_ptr() is specified to take a PMAPLIST *, but is identical in - * functionality to xdr_pmaplist(). - */ -bool_t -xdr_pmaplist_ptr(xdrs, rp) - XDR *xdrs; - struct pmaplist *rp; -{ - return xdr_pmaplist(xdrs, (struct pmaplist **)(void *)rp); -} diff --git a/lib/libc/rpc/pmap_rmt.c b/lib/libc/rpc/pmap_rmt.c deleted file mode 100644 index ddcde2e..0000000 --- a/lib/libc/rpc/pmap_rmt.c +++ /dev/null @@ -1,176 +0,0 @@ -/* $NetBSD: pmap_rmt.c,v 1.29 2000/07/06 03:10:34 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * pmap_rmt.c - * Client interface to pmap rpc service. - * remote call and broadcast service - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/poll.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <assert.h> -#include <err.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include <rpc/rpc.h> -#include <rpc/pmap_prot.h> -#include <rpc/pmap_clnt.h> -#include <rpc/pmap_rmt.h> -#include "un-namespace.h" - -static const 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 sock = -1; - CLIENT *client; - struct rmtcallargs a; - struct rmtcallres r; - enum clnt_stat stat; - - assert(addr != NULL); - assert(port_ptr != NULL); - - addr->sin_port = htons(PMAPPORT); - client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock); - if (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, (rpcproc_t)PMAPPROC_CALLIT, - (xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres, - &r, tout); - CLNT_DESTROY(client); - } else { - stat = RPC_FAILED; - } - addr->sin_port = 0; - return (stat); -} - - -/* - * XDR remote call arguments - * written for XDR_ENCODE direction only - */ -bool_t -xdr_rmtcall_args(xdrs, cap) - XDR *xdrs; - struct rmtcallargs *cap; -{ - u_int lenposition, argposition, position; - - assert(xdrs != NULL); - assert(cap != NULL); - - 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) - XDR *xdrs; - struct rmtcallres *crp; -{ - caddr_t port_ptr; - - assert(xdrs != NULL); - assert(crp != NULL); - - port_ptr = (caddr_t)(void *)crp->port_ptr; - if (xdr_reference(xdrs, &port_ptr, sizeof (u_long), - (xdrproc_t)xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { - crp->port_ptr = (u_long *)(void *)port_ptr; - return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); - } - return (FALSE); -} diff --git a/lib/libc/rpc/publickey.3 b/lib/libc/rpc/publickey.3 deleted file mode 100644 index 64fe080..0000000 --- a/lib/libc/rpc/publickey.3 +++ /dev/null @@ -1,53 +0,0 @@ -.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC -.\" $FreeBSD$ -.\" -.Dd October 6, 1987 -.Dt PUBLICKEY 3 -.Os -.Sh NAME -.Nm publickey , getpublickey , getsecretkey -.Nd "get public or secret key" -.Sh LIBRARY -.Lb librpcsvc -.Sh SYNOPSIS -.In rpc/rpc.h -.In rpc/key_prot.h -.Ft int -.Fo getpublickey -.Fa "const char netname[MAXNETNAMELEN+1]" -.Fa "char publickey[HEXKEYBYTES+1]" -.Fc -.Ft int -.Fo getsecretkey -.Fa "char netname[MAXNETNAMELEN+1]" -.Fa "char secretkey[HEXKEYBYTES+1]" -.Fa "char *passwd" -.Fc -.Sh DESCRIPTION -These routines are used to get public and secret keys from the -.Tn YP -database. -The -.Fn getsecretkey -function -has an extra argument, -.Fa 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 -.Dv NULL Ns \-terminated , -hexadecimal strings. -If the password supplied to -.Fn getsecretkey -fails to decrypt the secret key, the routine will return 1 but the -.Fa secretkey -argument will be a -.Dv NULL -string -.Pq Dq \& . -.Sh SEE ALSO -.Xr publickey 5 -.Pp -.%T "RPC Programmer's Manual" -in -.Pa /usr/share/doc/psd/23.rpc . diff --git a/lib/libc/rpc/publickey.5 b/lib/libc/rpc/publickey.5 deleted file mode 100644 index 71f4ef6..0000000 --- a/lib/libc/rpc/publickey.5 +++ /dev/null @@ -1,42 +0,0 @@ -.\" $FreeBSD$ -.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI; -.Dd October 19, 1987 -.Dt PUBLICKEY 5 -.Os -.Sh NAME -.Nm publickey -.Nd "public key database" -.Sh SYNOPSIS -.Pa /etc/publickey -.Sh DESCRIPTION -.Pa /etc/publickey -is the public key database used for secure -RPC (Remote Procedure Calls). -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). -.Pp -This file is altered either by the user through the -.Xr chkey 1 -command or by the system administrator through the -.Xr newkey 8 -command. -The file -.Pa /etc/publickey -should only contain data on the -.Tn NIS -master machine, where it -is converted into the -.Tn NIS -database -.Pa publickey.byname . -.Sh SEE ALSO -.Xr chkey 1 , -.Xr publickey 3 , -.Xr newkey 8 , -.Xr ypupdated 8 diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3 deleted file mode 100644 index 81a24ca..0000000 --- a/lib/libc/rpc/rpc.3 +++ /dev/null @@ -1,517 +0,0 @@ -.\" @(#)rpc.3n 1.31 93/08/31 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" $NetBSD: rpc.3,v 1.10 2000/06/02 23:11:12 fvdl Exp $ -.\" $FreeBSD$ -.Dd May 7, 1993 -.Dt RPC 3 -.Os -.Sh NAME -.Nm rpc -.Nd library routines for remote procedure calls -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.In netconfig.h -.Sh DESCRIPTION -These -routines allow C language programs to make procedure -calls on other machines across a network. -First, the client sends a request to the server. -On receipt of the request, the server calls a dispatch routine -to perform the requested service, and then sends back a reply. -.Pp -All -RPC routines require the header -.In rpc/rpc.h . -Routines that take a -.Vt "struct netconfig" -also require that -.In netconfig.h -be included. -.Sh Nettype -Some of the high-level -RPC interface routines take a -.Fa nettype -string as one of the arguments -(for example, -.Fn clnt_create , -.Fn svc_create , -.Fn rpc_reg , -.Fn rpc_call ) . -This string defines a class of transports which can be used -for a particular application. -.Pp -The -.Fa nettype -argument -can be one of the following: -.Bl -tag -width datagram_v -.It netpath -Choose from the transports which have been -indicated by their token names in the -.Ev NETPATH -environment variable. -.Ev NETPATH -is unset or -.Dv NULL , -it defaults to -.Qq visible . -.Qq netpath -is the default -.Fa nettype . -.It visible -Choose the transports which have the visible flag (v) -set in the -.Pa /etc/netconfig -file. -.It circuit_v -This is same as -.Qq visible -except that it chooses only the connection oriented transports -(semantics -.Qq tpi_cots -or -.Qq tpi_cots_ord ) -from the entries in the -.Pa /etc/netconfig -file. -.It datagram_v -This is same as -.Qq visible -except that it chooses only the connectionless datagram transports -(semantics -.Qq tpi_clts ) -from the entries in the -.Pa /etc/netconfig -file. -.It circuit_n -This is same as -.Qq netpath -except that it chooses only the connection oriented datagram transports -(semantics -.Qq tpi_cots -or -.Qq tpi_cots_ord ) . -.It datagram_n -This is same as -.Qq netpath -except that it chooses only the connectionless datagram transports -(semantics -.Qq tpi_clts ) . -.It udp -This refers to Internet UDP, both version 4 and 6. -.It tcp -This refers to Internet TCP, both version 4 and 6. -.El -.Pp -If -.Fa nettype -is -.Dv NULL , -it defaults to -.Qq netpath . -The transports are tried in left to right order in the -.Ev NETPATH -variable or in top to down order in the -.Pa /etc/netconfig -file. -.Sh Derived Types -The derived types used in the RPC interfaces are defined as follows: -.Bd -literal - typedef u_int32_t rpcprog_t; - typedef u_int32_t rpcvers_t; - typedef u_int32_t rpcproc_t; - typedef u_int32_t rpcprot_t; - typedef u_int32_t rpcport_t; - typedef int32_t rpc_inline_t; -.Ed -.Sh "Data Structures" -Some of the data structures used by the -RPC package are shown below. -.Sh "The AUTH Structure" -.Bd -literal -/* - * Authentication info. Opaque to client. - */ -struct opaque_auth { - enum_t oa_flavor; /* flavor of auth */ - caddr_t oa_base; /* address of more auth stuff */ - u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ -}; - -/* - * Auth handle, interface to client side authenticators. - */ -typedef struct { - struct opaque_auth ah_cred; - struct opaque_auth ah_verf; - struct auth_ops { - void (*ah_nextverf)(\|); - int (*ah_marshal)(\|); /* nextverf & serialize */ - int (*ah_validate)(\|); /* validate verifier */ - int (*ah_refresh)(\|); /* refresh credentials */ - void (*ah_destroy)(\|); /* destroy this structure */ - } *ah_ops; - caddr_t ah_private; -} AUTH; -.Ed -.Sh "The CLIENT Structure" -.Bd -literal -/* - * Client rpc handle. - * Created by individual implementations. - * Client is responsible for initializing auth. - */ - -typedef struct { - AUTH *cl_auth; /* authenticator */ - struct clnt_ops { - enum clnt_stat (*cl_call)(); /* call remote procedure */ - void (*cl_abort)(); /* abort a call */ - void (*cl_geterr)(); /* get specific error code */ - bool_t (*cl_freeres)(); /* frees results */ - void (*cl_destroy)(); /* destroy this structure */ - bool_t (*cl_control)(); /* the ioctl() of rpc */ - } *cl_ops; - caddr_t cl_private; /* private stuff */ - char *cl_netid; /* network identifier */ - char *cl_tp; /* device name */ -} CLIENT; -.Ed -.Sh "The SVCXPRT structure" -.Bd -literal -enum xprt_stat { - XPRT_DIED, - XPRT_MOREREQS, - XPRT_IDLE -}; - -/* - * Server side transport handle - */ -typedef struct { - int xp_fd; /* file descriptor for the server handle */ - u_short xp_port; /* obsolete */ - const struct xp_ops { - bool_t (*xp_recv)(); /* receive incoming requests */ - enum xprt_stat (*xp_stat)(); /* get transport status */ - bool_t (*xp_getargs)(); /* get arguments */ - bool_t (*xp_reply)(); /* send reply */ - bool_t (*xp_freeargs)(); /* free mem allocated for args */ - void (*xp_destroy)(); /* destroy this struct */ - } *xp_ops; - int xp_addrlen; /* length of remote addr. Obsolete */ - struct sockaddr_in xp_raddr; /* Obsolete */ - const struct xp_ops2 { - bool_t (*xp_control)(); /* catch-all function */ - } *xp_ops2; - char *xp_tp; /* transport provider device name */ - char *xp_netid; /* network identifier */ - struct netbuf xp_ltaddr; /* local transport address */ - struct netbuf xp_rtaddr; /* remote transport address */ - struct opaque_auth xp_verf; /* raw response verifier */ - caddr_t xp_p1; /* private: for use by svc ops */ - caddr_t xp_p2; /* private: for use by svc ops */ - caddr_t xp_p3; /* private: for use by svc lib */ - int xp_type /* transport type */ -} SVCXPRT; -.Ed -.Sh "The svc_reg structure" -.Bd -literal -struct svc_req { - rpcprog_t rq_prog; /* service program number */ - rpcvers_t rq_vers; /* service protocol version */ - rpcproc_t rq_proc; /* the desired procedure */ - struct opaque_auth rq_cred; /* raw creds from the wire */ - caddr_t rq_clntcred; /* read only cooked cred */ - SVCXPRT *rq_xprt; /* associated transport */ -}; -.Ed -.Sh "The XDR structure" -.Bd -literal -/* - * XDR operations. - * XDR_ENCODE causes the type to be encoded into the stream. - * XDR_DECODE causes the type to be extracted from the stream. - * XDR_FREE can be used to release the space allocated by an XDR_DECODE - * request. - */ -enum xdr_op { - XDR_ENCODE=0, - XDR_DECODE=1, - XDR_FREE=2 -}; -/* - * This is the number of bytes per unit of external data. - */ -#define BYTES_PER_XDR_UNIT (4) -#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / - BYTES_PER_XDR_UNIT) \e * BYTES_PER_XDR_UNIT) - -/* - * A xdrproc_t exists for each data type which is to be encoded or - * decoded. The second argument to the xdrproc_t is a pointer to - * an opaque pointer. The opaque pointer generally points to a - * structure of the data type to be decoded. If this points to 0, - * then the type routines should allocate dynamic storage of the - * appropriate size and return it. - * bool_t (*xdrproc_t)(XDR *, caddr_t *); - */ -typedef bool_t (*xdrproc_t)(); - -/* - * The XDR handle. - * Contains operation which is being applied to the stream, - * an operations vector for the particular implementation - */ -typedef struct { - enum xdr_op x_op; /* operation; fast additional param */ - struct xdr_ops { - bool_t (*x_getlong)(); /* get a long from underlying stream */ - bool_t (*x_putlong)(); /* put a long to underlying stream */ - bool_t (*x_getbytes)(); /* get bytes from underlying stream */ - bool_t (*x_putbytes)(); /* put bytes to underlying stream */ - u_int (*x_getpostn)(); /* returns bytes off from beginning */ - bool_t (*x_setpostn)(); /* lets you reposition the stream */ - long * (*x_inline)(); /* buf quick ptr to buffered data */ - void (*x_destroy)(); /* free privates of this xdr_stream */ - } *x_ops; - caddr_t x_public; /* users' data */ - caddr_t x_private; /* pointer to private data */ - caddr_t x_base; /* private used for position info */ - u_int x_handy; /* extra private word */ -} XDR; - -/* - * The netbuf structure. This structure is defined in <xti.h> on SysV - * systems, but NetBSD / FreeBSD do not use XTI. - * - * Usually, buf will point to a struct sockaddr, and len and maxlen - * will contain the length and maximum length of that socket address, - * respectively. - */ -struct netbuf { - unsigned int maxlen; - unsigned int len; - void *buf; -}; - -/* - * The format of the address and options arguments of the XTI t_bind call. - * Only provided for compatibility, it should not be used other than - * as an argument to svc_tli_create(). - */ - -struct t_bind { - struct netbuf addr; - unsigned int qlen; -}; -.Ed -.Sh "Index to Routines" -The following table lists RPC routines and the manual reference -pages on which they are described: -.Pp -.Bl -tag -width "authunix_create_default()" -compact -.It Em "RPC Routine" -.Em "Manual Reference Page" -.Pp -.It Fn auth_destroy -.Xr rpc_clnt_auth 3 -.It Fn authdes_create -.Xr rpc_soc 3 -.It Fn authnone_create -.Xr rpc_clnt_auth 3 -.It Fn authsys_create -.Xr rpc_clnt_auth 3 -.It Fn authsys_create_default -.Xr rpc_clnt_auth 3 -.It Fn authunix_create -.Xr rpc_soc 3 -.It Fn authunix_create_default -.Xr rpc_soc 3 -.It Fn callrpc -.Xr rpc_soc 3 -.It Fn clnt_broadcast -.Xr rpc_soc 3 -.It Fn clnt_call -.Xr rpc_clnt_calls 3 -.It Fn clnt_control -.Xr rpc_clnt_create 3 -.It Fn clnt_create -.Xr rpc_clnt_create 3 -.It Fn clnt_create_timed -.Xr rpc_clnt_create 3 -.It Fn clnt_create_vers -.Xr rpc_clnt_create 3 -.It Fn clnt_create_vers_timed -.Xr rpc_clnt_create 3 -.It Fn clnt_destroy -.Xr rpc_clnt_create 3 -.It Fn clnt_dg_create -.Xr rpc_clnt_create 3 -.It Fn clnt_freeres -.Xr rpc_clnt_calls 3 -.It Fn clnt_geterr -.Xr rpc_clnt_calls 3 -.It Fn clnt_pcreateerror -.Xr rpc_clnt_create 3 -.It Fn clnt_perrno -.Xr rpc_clnt_calls 3 -.It Fn clnt_perror -.Xr rpc_clnt_calls 3 -.It Fn clnt_raw_create -.Xr rpc_clnt_create 3 -.It Fn clnt_spcreateerror -.Xr rpc_clnt_create 3 -.It Fn clnt_sperrno -.Xr rpc_clnt_calls 3 -.It Fn clnt_sperror -.Xr rpc_clnt_calls 3 -.It Fn clnt_tli_create -.Xr rpc_clnt_create 3 -.It Fn clnt_tp_create -.Xr rpc_clnt_create 3 -.It Fn clnt_tp_create_timed -.Xr rpc_clnt_create 3 -.It Fn clnt_udpcreate -.Xr rpc_soc 3 -.It Fn clnt_vc_create -.Xr rpc_clnt_create 3 -.It Fn clntraw_create -.Xr rpc_soc 3 -.It Fn clnttcp_create -.Xr rpc_soc 3 -.It Fn clntudp_bufcreate -.Xr rpc_soc 3 -.It Fn get_myaddress -.Xr rpc_soc 3 -.It Fn pmap_getmaps -.Xr rpc_soc 3 -.It Fn pmap_getport -.Xr rpc_soc 3 -.It Fn pmap_rmtcall -.Xr rpc_soc 3 -.It Fn pmap_set -.Xr rpc_soc 3 -.It Fn pmap_unset -.Xr rpc_soc 3 -.It Fn registerrpc -.Xr rpc_soc 3 -.It Fn rpc_broadcast -.Xr rpc_clnt_calls 3 -.It Fn rpc_broadcast_exp -.Xr rpc_clnt_calls 3 -.It Fn rpc_call -.Xr rpc_clnt_calls 3 -.It Fn rpc_reg -.Xr rpc_svc_calls 3 -.It Fn svc_create -.Xr rpc_svc_create 3 -.It Fn svc_destroy -.Xr rpc_svc_create 3 -.It Fn svc_dg_create -.Xr rpc_svc_create 3 -.It Fn svc_dg_enablecache -.Xr rpc_svc_calls 3 -.It Fn svc_fd_create -.Xr rpc_svc_create 3 -.It Fn svc_fds -.Xr rpc_soc 3 -.It Fn svc_freeargs -.Xr rpc_svc_reg 3 -.It Fn svc_getargs -.Xr rpc_svc_reg 3 -.It Fn svc_getcaller -.Xr rpc_soc 3 -.It Fn svc_getreq -.Xr rpc_soc 3 -.It Fn svc_getreqset -.Xr rpc_svc_calls 3 -.It Fn svc_getrpccaller -.Xr rpc_svc_calls 3 -.It Fn svc_kerb_reg -.Xr kerberos_rpc 3 -.It Fn svc_raw_create -.Xr rpc_svc_create 3 -.It Fn svc_reg -.Xr rpc_svc_calls 3 -.It Fn svc_register -.Xr rpc_soc 3 -.It Fn svc_run -.Xr rpc_svc_reg 3 -.It Fn svc_sendreply -.Xr rpc_svc_reg 3 -.It Fn svc_tli_create -.Xr rpc_svc_create 3 -.It Fn svc_tp_create -.Xr rpc_svc_create 3 -.It Fn svc_unreg -.Xr rpc_svc_calls 3 -.It Fn svc_unregister -.Xr rpc_soc 3 -.It Fn svc_vc_create -.Xr rpc_svc_create 3 -.It Fn svcerr_auth -.Xr rpc_svc_err 3 -.It Fn svcerr_decode -.Xr rpc_svc_err 3 -.It Fn svcerr_noproc -.Xr rpc_svc_err 3 -.It Fn svcerr_noprog -.Xr rpc_svc_err 3 -.It Fn svcerr_progvers -.Xr rpc_svc_err 3 -.It Fn svcerr_systemerr -.Xr rpc_svc_err 3 -.It Fn svcerr_weakauth -.Xr rpc_svc_err 3 -.It Fn svcfd_create -.Xr rpc_soc 3 -.It Fn svcraw_create -.Xr rpc_soc 3 -.It Fn svctcp_create -.Xr rpc_soc 3 -.It Fn svcudp_bufcreate -.Xr rpc_soc 3 -.It Fn svcudp_create -.Xr rpc_soc 3 -.It Fn xdr_accepted_reply -.Xr rpc_xdr 3 -.It Fn xdr_authsys_parms -.Xr rpc_xdr 3 -.It Fn xdr_authunix_parms -.Xr rpc_soc 3 -.It Fn xdr_callhdr -.Xr rpc_xdr 3 -.It Fn xdr_callmsg -.Xr rpc_xdr 3 -.It Fn xdr_opaque_auth -.Xr rpc_xdr 3 -.It Fn xdr_rejected_reply -.Xr rpc_xdr 3 -.It Fn xdr_replymsg -.Xr rpc_xdr 3 -.It Fn xprt_register -.Xr rpc_svc_calls 3 -.It Fn xprt_unregister -.Xr rpc_svc_calls 3 -.El -.Sh FILES -.Bl -tag -width /etc/netconfig -.It Pa /etc/netconfig -.El -.Sh SEE ALSO -.Xr getnetconfig 3 , -.Xr getnetpath 3 , -.Xr rpcbind 3 , -.Xr rpc_clnt_auth 3 , -.Xr rpc_clnt_calls 3 , -.Xr rpc_clnt_create 3 , -.Xr rpc_svc_calls 3 , -.Xr rpc_svc_create 3 , -.Xr rpc_svc_err 3 , -.Xr rpc_svc_reg 3 , -.Xr rpc_xdr 3 , -.Xr xdr 3 , -.Xr netconfig 5 diff --git a/lib/libc/rpc/rpc.5 b/lib/libc/rpc/rpc.5 deleted file mode 100644 index 398d9aa..0000000 --- a/lib/libc/rpc/rpc.5 +++ /dev/null @@ -1,59 +0,0 @@ -.\" $NetBSD: rpc.5,v 1.3 2000/06/15 20:05:54 fvdl Exp $ -.\" $FreeBSD$ -.\" @(#)rpc.4 1.17 93/08/30 SMI; from SVr4 -.\" Copyright 1989 AT&T -.Dd December 10, 1991 -.Dt RPC 5 -.Os -.Sh NAME -.Nm rpc -.Nd rpc program number data base -.Sh SYNOPSIS -.Pa /etc/rpc -.Sh DESCRIPTION -The -.Nm -file contains user readable names that -can be used in place of RPC program numbers. -For each RPC program a single line should be present -with the following information: -.Pp -.Bl -enum -compact -.It -name of the RPC program -.It -RPC program number -.It -aliases -.El -.Pp -Items are separated by any number of blanks and/or -tab characters. -A hash -.Pq Dq Li # -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 -width /etc/nsswitch.conf -compact -.It Pa /etc/nsswitch.conf -.El -.Sh EXAMPLES -Below is an example of an RPC database: -.Bd -literal -# -# rpc -# -rpcbind 100000 portmap sunrpc portmapper -rusersd 100002 rusers -nfs 100003 nfsprog -mountd 100005 mount showmount -walld 100008 rwall shutdown -sprayd 100012 spray -llockmgr 100020 -nlockmgr 100021 -status 100024 -bootparam 100026 -keyserv 100029 keyserver -.Ed -.Sh SEE ALSO -.Xr getrpcent 3 diff --git a/lib/libc/rpc/rpc_callmsg.c b/lib/libc/rpc/rpc_callmsg.c deleted file mode 100644 index ad1bdb3..0000000 --- a/lib/libc/rpc/rpc_callmsg.c +++ /dev/null @@ -1,207 +0,0 @@ -/* $NetBSD: rpc_callmsg.c,v 1.16 2000/07/14 08:40:42 fvdl Exp $ */ - -/* - * 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 *sccsid2 = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * rpc_callmsg.c - * - * Copyright (C) 1984, Sun Microsystems, Inc. - * - */ - -#include "namespace.h" -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <rpc/rpc.h> -#include "un-namespace.h" - -/* - * XDR a call message - */ -bool_t -xdr_callmsg(xdrs, cmsg) - XDR *xdrs; - struct rpc_msg *cmsg; -{ - enum msg_type *prm_direction; - int32_t *buf; - struct opaque_auth *oa; - - assert(xdrs != NULL); - assert(cmsg != NULL); - - 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_INT32(buf, cmsg->rm_xid); - IXDR_PUT_ENUM(buf, cmsg->rm_direction); - if (cmsg->rm_direction != CALL) { - return (FALSE); - } - IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers); - if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { - return (FALSE); - } - IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog); - IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers); - IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc); - oa = &cmsg->rm_call.cb_cred; - IXDR_PUT_ENUM(buf, oa->oa_flavor); - IXDR_PUT_INT32(buf, oa->oa_length); - if (oa->oa_length) { - memmove(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_INT32(buf, oa->oa_length); - if (oa->oa_length) { - memmove(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_U_INT32(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_U_INT32(buf); - if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { - return (FALSE); - } - cmsg->rm_call.cb_prog = IXDR_GET_U_INT32(buf); - cmsg->rm_call.cb_vers = IXDR_GET_U_INT32(buf); - cmsg->rm_call.cb_proc = IXDR_GET_U_INT32(buf); - oa = &cmsg->rm_call.cb_cred; - oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); - oa->oa_length = (u_int)IXDR_GET_U_INT32(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); - if (oa->oa_base == NULL) - return (FALSE); - } - 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 { - memmove(oa->oa_base, 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 = (u_int)IXDR_GET_U_INT32(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); - if (oa->oa_base == NULL) - return (FALSE); - } - 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 { - memmove(oa->oa_base, buf, - oa->oa_length); - /* no real need... - buf += RNDUP(oa->oa_length) / - sizeof (int32_t); - */ - } - } - return (TRUE); - } - } - prm_direction = &cmsg->rm_direction; - if ( - xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) && - xdr_enum(xdrs, (enum_t *) prm_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/lib/libc/rpc/rpc_clnt_auth.3 b/lib/libc/rpc/rpc_clnt_auth.3 deleted file mode 100644 index 863707e..0000000 --- a/lib/libc/rpc/rpc_clnt_auth.3 +++ /dev/null @@ -1,96 +0,0 @@ -.\" @(#)rpc_clnt_auth.3n 1.21 93/05/07 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_clnt_auth 1.4 89/07/20 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $NetBSD: rpc_clnt_auth.3,v 1.1 2000/06/03 09:29:50 fvdl Exp $ -.\" $FreeBSD$ -.Dd May 7, 1993 -.Dt RPC_CLNT_AUTH 3 -.Os -.Sh NAME -.Nm auth_destroy , -.Nm authnone_create , -.Nm authsys_create , -.Nm authsys_create_default -.Nd library routines for client side remote procedure call authentication -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft "void" -.Fn auth_destroy "AUTH *auth" -.Ft "AUTH *" -.Fn authnone_create "void" -.Ft "AUTH *" -.Fn authsys_create "const char *host" "const uid_t uid" "const gid_t gid" "const int len" "const gid_t *aup_gids" -.Ft "AUTH *" -.Fn authsys_create_default "void" -.Sh DESCRIPTION -These routines are part of the -RPC library that allows C language programs to make procedure -calls on other machines across the network, -with desired authentication. -.Pp -These routines are normally called after creating the -.Vt CLIENT -handle. -The -.Va cl_auth -field of the -.Vt CLIENT -structure should be initialized by the -.Vt AUTH -structure returned by some of the following routines. -The client's authentication information -is passed to the server when the -RPC -call is made. -.Pp -Only the -.Dv NULL -and the -.Dv SYS -style of authentication is discussed here. -.Sh Routines -.Bl -tag -width authsys_create_default() -.It Fn auth_destroy -A function macro that destroys the authentication -information associated with -.Fa auth . -Destruction usually involves deallocation -of private data structures. -The use of -.Fa auth -is undefined after calling -.Fn auth_destroy . -.It Fn authnone_create -Create and return an RPC -authentication handle that passes nonusable -authentication information with each remote procedure call. -This is the default authentication used by RPC. -.It Fn authsys_create -Create and return an RPC authentication handle that contains -.Dv AUTH_SYS -authentication information. -The -.Fa host -argument -is the name of the machine on which the information was -created; -.Fa uid -is the user's user ID; -.Fa gid -is the user's current group ID; -.Fa len -and -.Fa aup_gids -refer to a counted array of groups to which the user belongs. -.It Fn authsys_create_default -Call -.Fn authsys_create -with the appropriate arguments. -.El -.Sh SEE ALSO -.Xr rpc 3 , -.Xr rpc_clnt_calls 3 , -.Xr rpc_clnt_create 3 diff --git a/lib/libc/rpc/rpc_clnt_calls.3 b/lib/libc/rpc/rpc_clnt_calls.3 deleted file mode 100644 index 213a7d1..0000000 --- a/lib/libc/rpc/rpc_clnt_calls.3 +++ /dev/null @@ -1,316 +0,0 @@ -.\" @(#)rpc_clnt_calls.3n 1.30 93/08/31 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_clnt_calls 1.4 89/07/20 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $FreeBSD$ -.Dd May 7, 1993 -.Dt RPC_CLNT_CALLS 3 -.Os -.Sh NAME -.Nm rpc_clnt_calls , -.Nm clnt_call , -.Nm clnt_freeres , -.Nm clnt_geterr , -.Nm clnt_perrno , -.Nm clnt_perror , -.Nm clnt_sperrno , -.Nm clnt_sperror , -.Nm rpc_broadcast , -.Nm rpc_broadcast_exp , -.Nm rpc_call -.Nd library routines for client side calls -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft "enum clnt_stat" -.Fn clnt_call "CLIENT *clnt" "const rpcproc_t procnum" "const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "caddr_t out" "const struct timeval tout" -.Ft bool_t -.Fn clnt_freeres "CLIENT *clnt" "const xdrproc_t outproc" "caddr_t out" -.Ft void -.Fn clnt_geterr "const CLIENT * clnt" "struct rpc_err * errp" -.Ft void -.Fn clnt_perrno "const enum clnt_stat stat" -.Ft void -.Fn clnt_perror "CLIENT *clnt" "const char *s" -.Ft "char *" -.Fn clnt_sperrno "const enum clnt_stat stat" -.Ft "char *" -.Fn clnt_sperror "CLIENT *clnt" "const char * s" -.Ft "enum clnt_stat" -.Fo rpc_broadcast -.Fa "const rpcprog_t prognum" "const rpcvers_t versnum" -.Fa "const rpcproc_t procnum" "const xdrproc_t inproc" -.Fa "const caddr_t in" "const xdrproc_t outproc" "caddr_t out" -.Fa "const resultproc_t eachresult" "const char *nettype" -.Fc -.Ft "enum clnt_stat" -.Fo rpc_broadcast_exp -.Fa "const rpcprog_t prognum" "const rpcvers_t versnum" -.Fa "const rpcproc_t procnum" "const xdrproc_t xargs" -.Fa "caddr_t argsp" "const xdrproc_t xresults" -.Fa "caddr_t resultsp" "const resultproc_t eachresult" -.Fa "const int inittime" "const int waittime" -.Fa "const char * nettype" -.Fc -.Ft "enum clnt_stat" -.Fo rpc_call -.Fa "const char *host" "const rpcprog_t prognum" -.Fa "const rpcvers_t versnum" "const rpcproc_t procnum" -.Fa "const xdrproc_t inproc" "const char *in" -.Fa "const xdrproc_t outproc" "char *out" "const char *nettype" -.Fc -.Sh DESCRIPTION -RPC library routines allow C language programs to make procedure -calls on other machines across the network. -First, the client calls a procedure to send a request to the server. -Upon receipt of the request, the server calls a dispatch routine -to perform the requested service, and then sends back a reply. -.Pp -The -.Fn clnt_call , -.Fn rpc_call , -and -.Fn rpc_broadcast -routines handle the client side of the procedure call. -The remaining routines deal with error handling in the case of errors. -.Pp -Some of the routines take a -.Vt CLIENT -handle as one of the arguments. -A -.Vt CLIENT -handle can be created by an RPC creation routine such as -.Fn clnt_create -(see -.Xr rpc_clnt_create 3 ) . -.Pp -These routines are safe for use in multithreaded applications. -.Vt CLIENT -handles can be shared between threads, however in this implementation -requests by different threads are serialized (that is, the first request will -receive its results before the second request is sent). -.Sh Routines -See -.Xr rpc 3 -for the definition of the -.Vt CLIENT -data structure. -.Bl -tag -width XXXXX -.It Fn clnt_call -A function macro that calls the remote procedure -.Fa procnum -associated with the client handle, -.Fa clnt , -which is obtained with an RPC -client creation routine such as -.Fn clnt_create -(see -.Xr rpc_clnt_create 3 ) . -The -.Fa inproc -argument -is the XDR function used to encode the procedure's arguments, and -.Fa outproc -is the XDR function used to decode the procedure's results; -.Fa in -is the address of the procedure's argument(s), and -.Fa out -is the address of where to place the result(s). -The -.Fa tout -argument -is the time allowed for results to be returned, which is overridden by -a time-out set explicitly through -.Fn clnt_control , -see -.Xr rpc_clnt_create 3 . -If the remote call succeeds, the status returned is -.Dv RPC_SUCCESS , -otherwise an appropriate status is returned. -.It Fn clnt_freeres -A function macro that frees any data allocated by the -RPC/XDR system when it decoded the results of an RPC call. -The -.Fa out -argument -is the address of the results, and -.Fa outproc -is the XDR routine describing the results. -This routine returns 1 if the results were successfully freed, -and 0 otherwise. -.It Fn clnt_geterr -A function macro that copies the error structure out of the client -handle to the structure at address -.Fa errp . -.It Fn clnt_perrno -Print a message to standard error corresponding -to the condition indicated by -.Fa stat . -A newline is appended. -Normally used after a procedure call fails for a routine -for which a client handle is not needed, for instance -.Fn rpc_call . -.It Fn clnt_perror -Print a message to the standard error indicating why an -RPC call failed; -.Fa clnt -is the handle used to do the call. -The message is prepended with string -.Fa s -and a colon. -A newline is appended. -Normally used after a remote procedure call fails -for a routine which requires a client handle, -for instance -.Fn clnt_call . -.It Fn clnt_sperrno -Take the same arguments as -.Fn clnt_perrno , -but instead of sending a message to the standard error -indicating why an RPC -call failed, return a pointer to a string which contains the message. -The -.Fn clnt_sperrno -function -is normally used instead of -.Fn clnt_perrno -when 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 -.Fn printf -(see -.Xr printf 3 ) , -or if a message format different than that supported by -.Fn clnt_perrno -is to be used. -Note: -unlike -.Fn clnt_sperror -and -.Fn clnt_spcreateerror -(see -.Xr rpc_clnt_create 3 ) , -.Fn clnt_sperrno -does not return pointer to static data so the -result will not get overwritten on each call. -.It Fn clnt_sperror -Like -.Fn clnt_perror , -except that (like -.Fn clnt_sperrno ) -it returns a string instead of printing to standard error. -However, -.Fn clnt_sperror -does not append a newline at the end of the message. -Warning: -returns pointer to a buffer that is overwritten -on each call. -.It Fn rpc_broadcast -Like -.Fn rpc_call , -except the call message is broadcast to -all the connectionless transports specified by -.Fa nettype . -If -.Fa nettype -is -.Dv NULL , -it defaults to -.Qq netpath . -Each time it receives a response, -this routine calls -.Fn eachresult , -whose form is: -.Ft bool_t -.Fn eachresult "caddr_t out" "const struct netbuf * addr" "const struct netconfig * netconf" -where -.Fa out -is the same as -.Fa out -passed to -.Fn rpc_broadcast , -except that the remote procedure's output is decoded there; -.Fa addr -points to the address of the machine that sent the results, and -.Fa netconf -is the netconfig structure of the transport on which the remote -server responded. -If -.Fn eachresult -returns 0, -.Fn rpc_broadcast -waits for more replies; -otherwise it returns with appropriate status. -Warning: -broadcast file descriptors are limited in size to the -maximum transfer size of that transport. -For Ethernet, this value is 1500 bytes. -The -.Fn rpc_broadcast -function -uses -.Dv AUTH_SYS -credentials by default (see -.Xr rpc_clnt_auth 3 ) . -.It Fn rpc_broadcast_exp -Like -.Fn rpc_broadcast , -except that the initial timeout, -.Fa inittime -and the maximum timeout, -.Fa waittime -are specified in milliseconds. -The -.Fa inittime -argument -is the initial time that -.Fn rpc_broadcast_exp -waits before resending the request. -After the first resend, the re-transmission interval -increases exponentially until it exceeds -.Fa waittime . -.It Fn rpc_call -Call the remote procedure associated with -.Fa prognum , -.Fa versnum , -and -.Fa procnum -on the machine, -.Fa host . -The -.Fa inproc -argument -is used to encode the procedure's arguments, and -.Fa outproc -is used to decode the procedure's results; -.Fa in -is the address of the procedure's argument(s), and -.Fa out -is the address of where to place the result(s). -The -.Fa nettype -argument -can be any of the values listed on -.Xr rpc 3 . -This routine returns -.Dv RPC_SUCCESS -if it succeeds, -or an appropriate status is returned. -Use the -.Fn clnt_perrno -routine to translate failure status into error messages. -Warning: -.Fn rpc_call -uses the first available transport belonging -to the class -.Fa nettype , -on which it can create a connection. -You do not have control of timeouts or authentication -using this routine. -.El -.Sh SEE ALSO -.Xr printf 3 , -.Xr rpc 3 , -.Xr rpc_clnt_auth 3 , -.Xr rpc_clnt_create 3 diff --git a/lib/libc/rpc/rpc_clnt_create.3 b/lib/libc/rpc/rpc_clnt_create.3 deleted file mode 100644 index 34c90ed..0000000 --- a/lib/libc/rpc/rpc_clnt_create.3 +++ /dev/null @@ -1,514 +0,0 @@ -.\" @(#)rpc_clnt_create.3n 1.36 93/08/31 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_clnt_create 1.5 89/07/24 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $NetBSD: rpc_clnt_create.3,v 1.2 2000/06/20 00:53:08 fvdl Exp $ -.\" $FreeBSD$ -.Dd May 7, 1993 -.Dt RPC_CLNT_CREATE 3 -.Os -.Sh NAME -.Nm rpc_clnt_create , -.Nm clnt_control , -.Nm clnt_create , -.Nm clnt_create_timed , -.Nm clnt_create_vers , -.Nm clnt_create_vers_timed , -.Nm clnt_destroy , -.Nm clnt_dg_create , -.Nm clnt_pcreateerror , -.Nm clnt_raw_create , -.Nm clnt_spcreateerror , -.Nm clnt_tli_create , -.Nm clnt_tp_create , -.Nm clnt_tp_create_timed , -.Nm clnt_vc_create , -.Nm rpc_createerr -.Nd "library routines for dealing with creation and manipulation of" -.Vt CLIENT -handles -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft bool_t -.Fn clnt_control "CLIENT *clnt" "const u_int req" "char *info" -.Ft "CLIENT *" -.Fn clnt_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype" -.Ft "CLIENT *" -.Fn clnt_create_timed "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype" "const struct timeval *timeout" -.Ft "CLIENT *" -.Fn clnt_create_vers "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "const char *nettype" -.Ft "CLIENT *" -.Fn clnt_create_vers_timed "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "const char *nettype" "const struct timeval *timeout" -.Ft void -.Fn clnt_destroy "CLIENT *clnt" -.Ft "CLIENT *" -.Fn clnt_dg_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz" -.Ft void -.Fn clnt_pcreateerror "const char *s" -.Ft "char *" -.Fn clnt_spcreateerror "const char *s" -.Ft "CLIENT *" -.Fn clnt_raw_create "const rpcprog_t prognum" "const rpcvers_t versnum" -.Ft "CLIENT *" -.Fn clnt_tli_create "const int fildes" "const struct netconfig *netconf" "struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz" -.Ft "CLIENT *" -.Fn clnt_tp_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" -.Ft "CLIENT *" -.Fn clnt_tp_create_timed "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "const struct timeval *timeout" -.Ft "CLIENT *" -.Fn clnt_vc_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "u_int sendsz" "u_int recvsz" -.Sh DESCRIPTION -RPC library routines allow C language programs to make procedure -calls on other machines across the network. -First a -.Vt CLIENT -handle is created and then the client calls a procedure to send a -request to the server. -On receipt of the request, the server calls a dispatch routine -to perform the requested service, and then sends a reply. -.Sh Routines -.Bl -tag -width YYYYYYY -.It Fn clnt_control -A function macro to change or retrieve various information -about a client object. -The -.Fa req -argument -indicates the type of operation, and -.Fa info -is a pointer to the information. -For both connectionless and connection-oriented transports, -the supported values of -.Fa req -and their argument types and what they do are: -.Bl -column "CLSET_FD_NCLOSE" "struct timeval *" "set total timeout" -.It Dv CLSET_TIMEOUT Ta "struct timeval *" Ta "set total timeout" -.It Dv CLGET_TIMEOUT Ta "struct timeval *" Ta "get total timeout" -.El -.Pp -Note: -if you set the timeout using -.Fn clnt_control , -the timeout argument passed by -.Fn clnt_call -is ignored in all subsequent calls. -.Pp -Note: -If you set the timeout value to 0, -.Fn clnt_control -immediately returns an error -.Pq Dv RPC_TIMEDOUT . -Set the timeout argument to 0 for batching calls. -.Bl -column CLSET_FD_NCLOSE "struct timeval *" -.It Dv CLGET_SVC_ADDR Ta "struct netbuf *" Ta "get servers address" -.It Dv CLGET_FD Ta "int *" Ta "get fd from handle" -.It Dv CLSET_FD_CLOSE Ta "void" Ta "close fd on destroy" -.It Dv CLSET_FD_NCLOSE Ta void Ta "do not close fd on destroy" -.It Dv CLGET_VERS Ta "u_int32_t *" Ta "get RPC program version" -.It Dv CLSET_VERS Ta "u_int32_t *" Ta "set RPC program version" -.It Dv CLGET_XID Ta "u_int32_t *" Ta "get XID of previous call" -.It Dv CLSET_XID Ta "u_int32_t *" Ta "set XID of next call" -.El -.Pp -The following operations are valid for connectionless transports only: -.Bl -column CLSET_RETRY_TIMEOUT "struct timeval *" "set total timeout" -.It Dv CLSET_RETRY_TIMEOUT Ta "struct timeval *" Ta "set the retry timeout" -.It Dv CLGET_RETRY_TIMEOUT Ta "struct timeval *" Ta "get the retry timeout" -.It Dv CLSET_CONNECT Ta Vt "int *" Ta use Xr connect 2 -.El -.Pp -The retry timeout is the time that RPC -waits for the server to reply before retransmitting the request. -The -.Fn clnt_control -function -returns -.Dv TRUE -on success and -.Dv FALSE -on failure. -.It Fn clnt_create -Generic client creation routine for program -.Fa prognum -and version -.Fa versnum . -The -.Fa host -argument -identifies the name of the remote host where the server -is located. -The -.Fa nettype -argument -indicates the class of transport protocol to use. -The transports are tried in left to right order in -.Ev NETPATH -environment variable or in top to bottom order in -the netconfig database. -The -.Fn clnt_create -function -tries all the transports of the -.Fa nettype -class available from the -.Ev NETPATH -environment variable and the netconfig database, -and chooses the first successful one. -A default timeout is set and can be modified using -.Fn clnt_control . -This routine returns -.Dv NULL -if it fails. -The -.Fn clnt_pcreateerror -routine can be used to print the reason for failure. -.Pp -Note: -.Fn clnt_create -returns a valid client handle even -if the particular version number supplied to -.Fn clnt_create -is not registered with the -.Xr rpcbind 8 -service. -This mismatch will be discovered by a -.Fn clnt_call -later (see -.Xr rpc_clnt_calls 3 ) . -.It Fn clnt_create_timed -Generic client creation routine which is similar to -.Fn clnt_create -but which also has the additional argument -.Fa timeout -that specifies the maximum amount of time allowed for -each transport class tried. -In all other respects, the -.Fn clnt_create_timed -call behaves exactly like the -.Fn clnt_create -call. -.It Fn clnt_create_vers -Generic client creation routine which is similar to -.Fn clnt_create -but which also checks for the -version availability. -The -.Fa host -argument -identifies the name of the remote host where the server -is located. -The -.Fa nettype -argument -indicates the class transport protocols to be used. -If the routine is successful it returns a client handle created for -the highest version between -.Fa vers_low -and -.Fa vers_high -that is supported by the server. -The -.Fa vers_outp -argument -is set to this value. -That is, after a successful return -.Fa vers_low -<= -.Fa *vers_outp -<= -.Fa vers_high . -If no version between -.Fa vers_low -and -.Fa vers_high -is supported by the server then the routine fails and returns -.Dv NULL . -A default timeout is set and can be modified using -.Fn clnt_control . -This routine returns -.Dv NULL -if it fails. -The -.Fn clnt_pcreateerror -routine can be used to print the reason for failure. -Note: -.Fn clnt_create -returns a valid client handle even -if the particular version number supplied to -.Fn clnt_create -is not registered with the -.Xr rpcbind 8 -service. -This mismatch will be discovered by a -.Fn clnt_call -later (see -.Xr rpc_clnt_calls 3 ) . -However, -.Fn clnt_create_vers -does this for you and returns a valid handle -only if a version within -the range supplied is supported by the server. -.It Fn clnt_create_vers_timed -Generic client creation routine which is similar to -.Fn clnt_create_vers -but which also has the additional argument -.Fa timeout -that specifies the maximum amount of time allowed for -each transport class tried. -In all other respects, the -.Fn clnt_create_vers_timed -call behaves exactly like the -.Fn clnt_create_vers -call. -.It Fn clnt_destroy -A function macro that destroys the client's RPC handle. -Destruction usually involves deallocation -of private data structures, including -.Fa clnt -itself. -Use of -.Fa clnt -is undefined after calling -.Fn clnt_destroy . -If the RPC library opened the associated file descriptor, or -.Dv CLSET_FD_CLOSE -was set using -.Fn clnt_control , -the file descriptor will be closed. -The caller should call -.Fn auth_destroy "clnt->cl_auth" -(before calling -.Fn clnt_destroy ) -to destroy the associated -.Vt AUTH -structure (see -.Xr rpc_clnt_auth 3 ) . -.It Fn clnt_dg_create -This routine creates an RPC client for the remote program -.Fa prognum -and version -.Fa versnum ; -the client uses a connectionless transport. -The remote program is located at address -.Fa svcaddr . -The -.Fa fildes -argument -is an open and bound file descriptor. -This routine will resend the call message in intervals of -15 seconds until a response is received or until the -call times out. -The total time for the call to time out is specified by -.Fn clnt_call -(see -.Fn clnt_call -in -.Xr rpc_clnt_calls 3 ) . -The retry time out and the total time out periods can -be changed using -.Fn clnt_control . -The user may set the size of the send and receive -buffers with the -.Fa sendsz -and -.Fa recvsz -arguments; -values of 0 choose suitable defaults. -This routine returns -.Dv NULL -if it fails. -.It Fn clnt_pcreateerror -Print a message to standard error indicating -why a client RPC handle could not be created. -The message is prepended with the string -.Fa s -and a colon, and appended with a newline. -.It Fn clnt_spcreateerror -Like -.Fn clnt_pcreateerror , -except that it returns a string -instead of printing to the standard error. -A newline is not appended to the message in this case. -Warning: -returns a pointer to a buffer that is overwritten -on each call. -.It Fn clnt_raw_create -This routine creates an RPC -client handle for the remote program -.Fa prognum -and version -.Fa versnum . -The transport used to pass messages to the service is -a buffer within the process's address space, -so the corresponding RPC -server should live in the same address space; -(see -.Fn svc_raw_create -in -.Xr rpc_svc_create 3 ) . -This allows simulation of RPC and measurement of -RPC overheads, such as round trip times, -without any kernel or networking interference. -This routine returns -.Dv NULL -if it fails. -The -.Fn clnt_raw_create -function -should be called after -.Fn svc_raw_create . -.It Fn clnt_tli_create -This routine creates an RPC -client handle for the remote program -.Fa prognum -and version -.Fa versnum . -The remote program is located at address -.Fa svcaddr . -If -.Fa svcaddr -is -.Dv NULL -and it is connection-oriented, it is assumed that the file descriptor -is connected. -For connectionless transports, if -.Fa svcaddr -is -.Dv NULL , -.Dv RPC_UNKNOWNADDR -error is set. -The -.Fa fildes -argument -is a file descriptor which may be open, bound and connected. -If it is -.Dv RPC_ANYFD , -it opens a file descriptor on the transport specified by -.Fa netconf . -If -.Fa fildes -is -.Dv RPC_ANYFD -and -.Fa netconf -is -.Dv NULL , -a -.Dv RPC_UNKNOWNPROTO -error is set. -If -.Fa fildes -is unbound, then it will attempt to bind the descriptor. -The user may specify the size of the buffers with the -.Fa sendsz -and -.Fa recvsz -arguments; -values of 0 choose suitable defaults. -Depending upon the type of the transport (connection-oriented -or connectionless), -.Fn clnt_tli_create -calls appropriate client creation routines. -This routine returns -.Dv NULL -if it fails. -The -.Fn clnt_pcreateerror -routine can be used to print the reason for failure. -The remote rpcbind -service (see -.Xr rpcbind 8 ) -is not consulted for the address of the remote -service. -.It Fn clnt_tp_create -Like -.Fn clnt_create -except -.Fn clnt_tp_create -tries only one transport specified through -.Fa netconf . -The -.Fn clnt_tp_create -function -creates a client handle for the program -.Fa prognum , -the version -.Fa versnum , -and for the transport specified by -.Fa netconf . -Default options are set, -which can be changed using -.Fn clnt_control -calls. -The remote rpcbind service on the host -.Fa host -is consulted for the address of the remote service. -This routine returns -.Dv NULL -if it fails. -The -.Fn clnt_pcreateerror -routine can be used to print the reason for failure. -.It Fn clnt_tp_create_timed -Like -.Fn clnt_tp_create -except -.Fn clnt_tp_create_timed -has the extra argument -.Fa timeout -which specifies the maximum time allowed for -the creation attempt to succeed. -In all other respects, the -.Fn clnt_tp_create_timed -call behaves exactly like the -.Fn clnt_tp_create -call. -.It Fn clnt_vc_create -This routine creates an RPC -client for the remote program -.Fa prognum -and version -.Fa versnum ; -the client uses a connection-oriented transport. -The remote program is located at address -.Fa svcaddr . -The -.Fa fildes -argument -is an open and bound file descriptor. -The user may specify the size of the send and receive buffers -with the -.Fa sendsz -and -.Fa recvsz -arguments; -values of 0 choose suitable defaults. -This routine returns -.Dv NULL -if it fails. -The address -.Fa svcaddr -should not be -.Dv NULL -and should point to the actual address of the remote program. -The -.Fn clnt_vc_create -function -does not consult the remote rpcbind service for this information. -.It Xo -.Vt "struct rpc_createerr" Va rpc_createerr ; -.Xc -A global variable whose value is set by any RPC -client handle creation routine -that fails. -It is used by the routine -.Fn clnt_pcreateerror -to print the reason for the failure. -.El -.Sh SEE ALSO -.Xr rpc 3 , -.Xr rpc_clnt_auth 3 , -.Xr rpc_clnt_calls 3 , -.Xr rpcbind 8 diff --git a/lib/libc/rpc/rpc_com.h b/lib/libc/rpc/rpc_com.h deleted file mode 100644 index f2bf11f..0000000 --- a/lib/libc/rpc/rpc_com.h +++ /dev/null @@ -1,95 +0,0 @@ -/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */ - -/* - * 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 - * - * $FreeBSD$ - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* - * rpc_com.h, Common definitions for both the server and client side. - * All for the topmost layer of rpc - * - * In Sun's tirpc distribution, this was installed as <rpc/rpc_com.h>, - * but as it contains only non-exported interfaces, it was moved here. - */ - -#ifndef _RPC_RPCCOM_H -#define _RPC_RPCCOM_H - -#include <sys/cdefs.h> - -/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */ - -/* - * The max size of the transport, if the size cannot be determined - * by other means. - */ -#define RPC_MAXDATASIZE 9000 -#define RPC_MAXADDRSIZE 1024 - -#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ - (u_int32_t)(now)->tv_usec) - -__BEGIN_DECLS -extern u_int __rpc_get_a_size(int); -extern int __rpc_dtbsize(void); -extern struct netconfig * __rpcgettp(int); -extern int __rpc_get_default_domain(char **); - -char *__rpc_taddr2uaddr_af(int, const struct netbuf *); -struct netbuf *__rpc_uaddr2taddr_af(int, const char *); -int __rpc_fixup_addr(struct netbuf *, const struct netbuf *); -int __rpc_sockinfo2netid(struct __rpc_sockinfo *, const char **); -int __rpc_seman2socktype(int); -int __rpc_socktype2seman(int); -void *rpc_nullproc(CLIENT *); -int __rpc_sockisbound(int); - -struct netbuf *__rpcb_findaddr_timed(rpcprog_t, rpcvers_t, - const struct netconfig *, const char *host, CLIENT **clpp, - struct timeval *tp); - -bool_t __rpc_control(int,void *); - -char *_get_next_token(char *, int); - -bool_t __svc_clean_idle(fd_set *, int, bool_t); -bool_t __xdrrec_setnonblock(XDR *, int); -bool_t __xdrrec_getrec(XDR *, enum xprt_stat *, bool_t); -void __xprt_unregister_unlocked(SVCXPRT *); - -SVCXPRT **__svc_xports; -int __svc_maxrec; - -__END_DECLS - -#endif /* _RPC_RPCCOM_H */ diff --git a/lib/libc/rpc/rpc_commondata.c b/lib/libc/rpc/rpc_commondata.c deleted file mode 100644 index 679233a..0000000 --- a/lib/libc/rpc/rpc_commondata.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: rpc_commondata.c,v 1.7 2000/06/02 23:11:13 fvdl Exp $ */ - -/* - * 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 = "@(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <rpc/rpc.h> -#include "un-namespace.h" - -/* - * This file should only contain common data (global data) that is exported - * by public interfaces - */ -struct opaque_auth _null_auth; -fd_set svc_fdset; -int svc_maxfd = -1; diff --git a/lib/libc/rpc/rpc_dtablesize.c b/lib/libc/rpc/rpc_dtablesize.c deleted file mode 100644 index 5e50ba8..0000000 --- a/lib/libc/rpc/rpc_dtablesize.c +++ /dev/null @@ -1,67 +0,0 @@ -/* $NetBSD: rpc_dtablesize.c,v 1.14 1998/11/15 17:32:43 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro"; -static char *sccsid = "@(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <unistd.h> -#include "un-namespace.h" - -int _rpc_dtablesize(void); /* XXX */ - -/* - * 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/lib/libc/rpc/rpc_generic.c b/lib/libc/rpc/rpc_generic.c deleted file mode 100644 index ab259d5..0000000 --- a/lib/libc/rpc/rpc_generic.c +++ /dev/null @@ -1,845 +0,0 @@ -/* $NetBSD: rpc_generic.c,v 1.4 2000/09/28 09:07:04 kleink Exp $ */ - -/* - * 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. - */ - -/* #pragma ident "@(#)rpc_generic.c 1.17 94/04/24 SMI" */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * rpc_generic.c, Miscl routines for RPC. - * - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/un.h> -#include <sys/resource.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <rpc/rpc.h> -#include <ctype.h> -#include <stddef.h> -#include <stdio.h> -#include <netdb.h> -#include <netconfig.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <rpc/nettype.h> -#include "un-namespace.h" -#include "rpc_com.h" -#include "mt_misc.h" - -struct handle { - NCONF_HANDLE *nhandle; - int nflag; /* Whether NETPATH or NETCONFIG */ - int nettype; -}; - -static const struct _rpcnettype { - const char *name; - const int type; -} _rpctypelist[] = { - { "netpath", _RPC_NETPATH }, - { "visible", _RPC_VISIBLE }, - { "circuit_v", _RPC_CIRCUIT_V }, - { "datagram_v", _RPC_DATAGRAM_V }, - { "circuit_n", _RPC_CIRCUIT_N }, - { "datagram_n", _RPC_DATAGRAM_N }, - { "tcp", _RPC_TCP }, - { "udp", _RPC_UDP }, - { 0, _RPC_NONE } -}; - -struct netid_af { - const char *netid; - int af; - int protocol; -}; - -static const struct netid_af na_cvt[] = { - { "udp", AF_INET, IPPROTO_UDP }, - { "tcp", AF_INET, IPPROTO_TCP }, -#ifdef INET6 - { "udp6", AF_INET6, IPPROTO_UDP }, - { "tcp6", AF_INET6, IPPROTO_TCP }, -#endif - { "local", AF_LOCAL, 0 } -}; - -#if 0 -static char *strlocase(char *); -#endif -static int getnettype(const char *); - -/* - * Cache the result of getrlimit(), so we don't have to do an - * expensive call every time. - */ -int -__rpc_dtbsize() -{ - static int tbsize; - struct rlimit rl; - - if (tbsize) { - return (tbsize); - } - if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { - return (tbsize = (int)rl.rlim_max); - } - /* - * Something wrong. I'll try to save face by returning a - * pessimistic number. - */ - return (32); -} - - -/* - * Find the appropriate buffer size - */ -u_int -/*ARGSUSED*/ -__rpc_get_t_size(af, proto, size) - int af, proto; - int size; /* Size requested */ -{ - int maxsize, defsize; - - maxsize = 256 * 1024; /* XXX */ - switch (proto) { - case IPPROTO_TCP: - defsize = 64 * 1024; /* XXX */ - break; - case IPPROTO_UDP: - defsize = UDPMSGSIZE; - break; - default: - defsize = RPC_MAXDATASIZE; - break; - } - if (size == 0) - return defsize; - - /* Check whether the value is within the upper max limit */ - return (size > maxsize ? (u_int)maxsize : (u_int)size); -} - -/* - * Find the appropriate address buffer size - */ -u_int -__rpc_get_a_size(af) - int af; -{ - switch (af) { - case AF_INET: - return sizeof (struct sockaddr_in); -#ifdef INET6 - case AF_INET6: - return sizeof (struct sockaddr_in6); -#endif - case AF_LOCAL: - return sizeof (struct sockaddr_un); - default: - break; - } - return ((u_int)RPC_MAXADDRSIZE); -} - -#if 0 -static char * -strlocase(p) - char *p; -{ - char *t = p; - - for (; *p; p++) - if (isupper(*p)) - *p = tolower(*p); - return (t); -} -#endif - -/* - * Returns the type of the network as defined in <rpc/nettype.h> - * If nettype is NULL, it defaults to NETPATH. - */ -static int -getnettype(nettype) - const char *nettype; -{ - int i; - - if ((nettype == NULL) || (nettype[0] == 0)) { - return (_RPC_NETPATH); /* Default */ - } - -#if 0 - nettype = strlocase(nettype); -#endif - for (i = 0; _rpctypelist[i].name; i++) - if (strcasecmp(nettype, _rpctypelist[i].name) == 0) { - return (_rpctypelist[i].type); - } - return (_rpctypelist[i].type); -} - -static thread_key_t tcp_key, udp_key; -static once_t keys_once = ONCE_INITIALIZER; -static int tcp_key_error, udp_key_error; - -static void -keys_init(void) -{ - - tcp_key_error = thr_keycreate(&tcp_key, free); - udp_key_error = thr_keycreate(&udp_key, free); -} - -/* - * For the given nettype (tcp or udp only), return the first structure found. - * This should be freed by calling freenetconfigent() - */ -struct netconfig * -__rpc_getconfip(nettype) - const char *nettype; -{ - char *netid; - char *netid_tcp = (char *) NULL; - char *netid_udp = (char *) NULL; - static char *netid_tcp_main; - static char *netid_udp_main; - struct netconfig *dummy; - int main_thread; - - if ((main_thread = thr_main())) { - netid_udp = netid_udp_main; - netid_tcp = netid_tcp_main; - } else { - if (thr_once(&keys_once, keys_init) != 0 || - tcp_key_error != 0 || udp_key_error != 0) - return (NULL); - netid_tcp = (char *)thr_getspecific(tcp_key); - netid_udp = (char *)thr_getspecific(udp_key); - } - if (!netid_udp && !netid_tcp) { - struct netconfig *nconf; - void *confighandle; - - if (!(confighandle = setnetconfig())) { - syslog (LOG_ERR, "rpc: failed to open " NETCONFIG); - return (NULL); - } - while ((nconf = getnetconfig(confighandle)) != NULL) { - if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { - if (strcmp(nconf->nc_proto, NC_TCP) == 0) { - netid_tcp = strdup(nconf->nc_netid); - if (main_thread) - netid_tcp_main = netid_tcp; - else - thr_setspecific(tcp_key, - (void *) netid_tcp); - } else - if (strcmp(nconf->nc_proto, NC_UDP) == 0) { - netid_udp = strdup(nconf->nc_netid); - if (main_thread) - netid_udp_main = netid_udp; - else - thr_setspecific(udp_key, - (void *) netid_udp); - } - } - } - endnetconfig(confighandle); - } - if (strcmp(nettype, "udp") == 0) - netid = netid_udp; - else if (strcmp(nettype, "tcp") == 0) - netid = netid_tcp; - else { - return (NULL); - } - if ((netid == NULL) || (netid[0] == 0)) { - return (NULL); - } - dummy = getnetconfigent(netid); - return (dummy); -} - -/* - * Returns the type of the nettype, which should then be used with - * __rpc_getconf(). - */ -void * -__rpc_setconf(nettype) - const char *nettype; -{ - struct handle *handle; - - handle = (struct handle *) malloc(sizeof (struct handle)); - if (handle == NULL) { - return (NULL); - } - switch (handle->nettype = getnettype(nettype)) { - case _RPC_NETPATH: - case _RPC_CIRCUIT_N: - case _RPC_DATAGRAM_N: - if (!(handle->nhandle = setnetpath())) - goto failed; - handle->nflag = TRUE; - break; - case _RPC_VISIBLE: - case _RPC_CIRCUIT_V: - case _RPC_DATAGRAM_V: - case _RPC_TCP: - case _RPC_UDP: - if (!(handle->nhandle = setnetconfig())) { - syslog (LOG_ERR, "rpc: failed to open " NETCONFIG); - goto failed; - } - handle->nflag = FALSE; - break; - default: - goto failed; - } - - return (handle); - -failed: - free(handle); - return (NULL); -} - -/* - * Returns the next netconfig struct for the given "net" type. - * __rpc_setconf() should have been called previously. - */ -struct netconfig * -__rpc_getconf(vhandle) - void *vhandle; -{ - struct handle *handle; - struct netconfig *nconf; - - handle = (struct handle *)vhandle; - if (handle == NULL) { - return (NULL); - } - for (;;) { - if (handle->nflag) - nconf = getnetpath(handle->nhandle); - else - nconf = getnetconfig(handle->nhandle); - if (nconf == NULL) - break; - if ((nconf->nc_semantics != NC_TPI_CLTS) && - (nconf->nc_semantics != NC_TPI_COTS) && - (nconf->nc_semantics != NC_TPI_COTS_ORD)) - continue; - switch (handle->nettype) { - case _RPC_VISIBLE: - if (!(nconf->nc_flag & NC_VISIBLE)) - continue; - /* FALLTHROUGH */ - case _RPC_NETPATH: /* Be happy */ - break; - case _RPC_CIRCUIT_V: - if (!(nconf->nc_flag & NC_VISIBLE)) - continue; - /* FALLTHROUGH */ - case _RPC_CIRCUIT_N: - if ((nconf->nc_semantics != NC_TPI_COTS) && - (nconf->nc_semantics != NC_TPI_COTS_ORD)) - continue; - break; - case _RPC_DATAGRAM_V: - if (!(nconf->nc_flag & NC_VISIBLE)) - continue; - /* FALLTHROUGH */ - case _RPC_DATAGRAM_N: - if (nconf->nc_semantics != NC_TPI_CLTS) - continue; - break; - case _RPC_TCP: - if (((nconf->nc_semantics != NC_TPI_COTS) && - (nconf->nc_semantics != NC_TPI_COTS_ORD)) || - (strcmp(nconf->nc_protofmly, NC_INET) -#ifdef INET6 - && strcmp(nconf->nc_protofmly, NC_INET6)) -#else - ) -#endif - || - strcmp(nconf->nc_proto, NC_TCP)) - continue; - break; - case _RPC_UDP: - if ((nconf->nc_semantics != NC_TPI_CLTS) || - (strcmp(nconf->nc_protofmly, NC_INET) -#ifdef INET6 - && strcmp(nconf->nc_protofmly, NC_INET6)) -#else - ) -#endif - || - strcmp(nconf->nc_proto, NC_UDP)) - continue; - break; - } - break; - } - return (nconf); -} - -void -__rpc_endconf(vhandle) - void * vhandle; -{ - struct handle *handle; - - handle = (struct handle *) vhandle; - if (handle == NULL) { - return; - } - if (handle->nflag) { - endnetpath(handle->nhandle); - } else { - endnetconfig(handle->nhandle); - } - free(handle); -} - -/* - * Used to ping the NULL procedure for clnt handle. - * Returns NULL if fails, else a non-NULL pointer. - */ -void * -rpc_nullproc(clnt) - CLIENT *clnt; -{ - struct timeval TIMEOUT = {25, 0}; - - if (clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) { - return (NULL); - } - return ((void *) clnt); -} - -/* - * Try all possible transports until - * one succeeds in finding the netconf for the given fd. - */ -struct netconfig * -__rpcgettp(fd) - int fd; -{ - const char *netid; - struct __rpc_sockinfo si; - - if (!__rpc_fd2sockinfo(fd, &si)) - return NULL; - - if (!__rpc_sockinfo2netid(&si, &netid)) - return NULL; - - /*LINTED const castaway*/ - return getnetconfigent((char *)netid); -} - -int -__rpc_fd2sockinfo(int fd, struct __rpc_sockinfo *sip) -{ - socklen_t len; - int type, proto; - struct sockaddr_storage ss; - - len = sizeof ss; - if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &len) < 0) - return 0; - sip->si_alen = len; - - len = sizeof type; - if (_getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len) < 0) - return 0; - - /* XXX */ - if (ss.ss_family != AF_LOCAL) { - if (type == SOCK_STREAM) - proto = IPPROTO_TCP; - else if (type == SOCK_DGRAM) - proto = IPPROTO_UDP; - else - return 0; - } else - proto = 0; - - sip->si_af = ss.ss_family; - sip->si_proto = proto; - sip->si_socktype = type; - - return 1; -} - -/* - * Linear search, but the number of entries is small. - */ -int -__rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip) -{ - int i; - - for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++) - if (strcmp(na_cvt[i].netid, nconf->nc_netid) == 0 || ( - strcmp(nconf->nc_netid, "unix") == 0 && - strcmp(na_cvt[i].netid, "local") == 0)) { - sip->si_af = na_cvt[i].af; - sip->si_proto = na_cvt[i].protocol; - sip->si_socktype = - __rpc_seman2socktype((int)nconf->nc_semantics); - if (sip->si_socktype == -1) - return 0; - sip->si_alen = __rpc_get_a_size(sip->si_af); - return 1; - } - - return 0; -} - -int -__rpc_nconf2fd(const struct netconfig *nconf) -{ - struct __rpc_sockinfo si; - - if (!__rpc_nconf2sockinfo(nconf, &si)) - return 0; - - return _socket(si.si_af, si.si_socktype, si.si_proto); -} - -int -__rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid) -{ - int i; - struct netconfig *nconf; - - nconf = getnetconfigent("local"); - - for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++) { - if (na_cvt[i].af == sip->si_af && - na_cvt[i].protocol == sip->si_proto) { - if (strcmp(na_cvt[i].netid, "local") == 0 && nconf == NULL) { - if (netid) - *netid = "unix"; - } else { - if (netid) - *netid = na_cvt[i].netid; - } - if (nconf != NULL) - freenetconfigent(nconf); - return 1; - } - } - if (nconf != NULL) - freenetconfigent(nconf); - - return 0; -} - -char * -taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf) -{ - struct __rpc_sockinfo si; - - if (!__rpc_nconf2sockinfo(nconf, &si)) - return NULL; - return __rpc_taddr2uaddr_af(si.si_af, nbuf); -} - -struct netbuf * -uaddr2taddr(const struct netconfig *nconf, const char *uaddr) -{ - struct __rpc_sockinfo si; - - if (!__rpc_nconf2sockinfo(nconf, &si)) - return NULL; - return __rpc_uaddr2taddr_af(si.si_af, uaddr); -} - -char * -__rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf) -{ - char *ret; - struct sockaddr_in *sin; - struct sockaddr_un *sun; - char namebuf[INET_ADDRSTRLEN]; -#ifdef INET6 - struct sockaddr_in6 *sin6; - char namebuf6[INET6_ADDRSTRLEN]; -#endif - u_int16_t port; - - switch (af) { - case AF_INET: - sin = nbuf->buf; - if (inet_ntop(af, &sin->sin_addr, namebuf, sizeof namebuf) - == NULL) - return NULL; - port = ntohs(sin->sin_port); - if (asprintf(&ret, "%s.%u.%u", namebuf, ((u_int32_t)port) >> 8, - port & 0xff) < 0) - return NULL; - break; -#ifdef INET6 - case AF_INET6: - sin6 = nbuf->buf; - if (inet_ntop(af, &sin6->sin6_addr, namebuf6, sizeof namebuf6) - == NULL) - return NULL; - port = ntohs(sin6->sin6_port); - if (asprintf(&ret, "%s.%u.%u", namebuf6, ((u_int32_t)port) >> 8, - port & 0xff) < 0) - return NULL; - break; -#endif - case AF_LOCAL: - sun = nbuf->buf; - if (asprintf(&ret, "%.*s", (int)(sun->sun_len - - offsetof(struct sockaddr_un, sun_path)), - sun->sun_path) < 0) - return (NULL); - break; - default: - return NULL; - } - - return ret; -} - -struct netbuf * -__rpc_uaddr2taddr_af(int af, const char *uaddr) -{ - struct netbuf *ret = NULL; - char *addrstr, *p; - unsigned port, portlo, porthi; - struct sockaddr_in *sin; -#ifdef INET6 - struct sockaddr_in6 *sin6; -#endif - struct sockaddr_un *sun; - - port = 0; - sin = NULL; - addrstr = strdup(uaddr); - if (addrstr == NULL) - return NULL; - - /* - * AF_LOCAL addresses are expected to be absolute - * pathnames, anything else will be AF_INET or AF_INET6. - */ - if (*addrstr != '/') { - p = strrchr(addrstr, '.'); - if (p == NULL) - goto out; - portlo = (unsigned)atoi(p + 1); - *p = '\0'; - - p = strrchr(addrstr, '.'); - if (p == NULL) - goto out; - porthi = (unsigned)atoi(p + 1); - *p = '\0'; - port = (porthi << 8) | portlo; - } - - ret = (struct netbuf *)malloc(sizeof *ret); - if (ret == NULL) - goto out; - - switch (af) { - case AF_INET: - sin = (struct sockaddr_in *)malloc(sizeof *sin); - if (sin == NULL) - goto out; - memset(sin, 0, sizeof *sin); - sin->sin_family = AF_INET; - sin->sin_port = htons(port); - if (inet_pton(AF_INET, addrstr, &sin->sin_addr) <= 0) { - free(sin); - free(ret); - ret = NULL; - goto out; - } - sin->sin_len = ret->maxlen = ret->len = sizeof *sin; - ret->buf = sin; - break; -#ifdef INET6 - case AF_INET6: - sin6 = (struct sockaddr_in6 *)malloc(sizeof *sin6); - if (sin6 == NULL) - goto out; - memset(sin6, 0, sizeof *sin6); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons(port); - if (inet_pton(AF_INET6, addrstr, &sin6->sin6_addr) <= 0) { - free(sin6); - free(ret); - ret = NULL; - goto out; - } - sin6->sin6_len = ret->maxlen = ret->len = sizeof *sin6; - ret->buf = sin6; - break; -#endif - case AF_LOCAL: - sun = (struct sockaddr_un *)malloc(sizeof *sun); - if (sun == NULL) - goto out; - memset(sun, 0, sizeof *sun); - sun->sun_family = AF_LOCAL; - strncpy(sun->sun_path, addrstr, sizeof(sun->sun_path) - 1); - ret->len = ret->maxlen = sun->sun_len = SUN_LEN(sun); - ret->buf = sun; - break; - default: - break; - } -out: - free(addrstr); - return ret; -} - -int -__rpc_seman2socktype(int semantics) -{ - switch (semantics) { - case NC_TPI_CLTS: - return SOCK_DGRAM; - case NC_TPI_COTS_ORD: - return SOCK_STREAM; - case NC_TPI_RAW: - return SOCK_RAW; - default: - break; - } - - return -1; -} - -int -__rpc_socktype2seman(int socktype) -{ - switch (socktype) { - case SOCK_DGRAM: - return NC_TPI_CLTS; - case SOCK_STREAM: - return NC_TPI_COTS_ORD; - case SOCK_RAW: - return NC_TPI_RAW; - default: - break; - } - - return -1; -} - -/* - * XXXX - IPv6 scope IDs can't be handled in universal addresses. - * Here, we compare the original server address to that of the RPC - * service we just received back from a call to rpcbind on the remote - * machine. If they are both "link local" or "site local", copy - * the scope id of the server address over to the service address. - */ -int -__rpc_fixup_addr(struct netbuf *new, const struct netbuf *svc) -{ -#ifdef INET6 - struct sockaddr *sa_new, *sa_svc; - struct sockaddr_in6 *sin6_new, *sin6_svc; - - sa_svc = (struct sockaddr *)svc->buf; - sa_new = (struct sockaddr *)new->buf; - - if (sa_new->sa_family == sa_svc->sa_family && - sa_new->sa_family == AF_INET6) { - sin6_new = (struct sockaddr_in6 *)new->buf; - sin6_svc = (struct sockaddr_in6 *)svc->buf; - - if ((IN6_IS_ADDR_LINKLOCAL(&sin6_new->sin6_addr) && - IN6_IS_ADDR_LINKLOCAL(&sin6_svc->sin6_addr)) || - (IN6_IS_ADDR_SITELOCAL(&sin6_new->sin6_addr) && - IN6_IS_ADDR_SITELOCAL(&sin6_svc->sin6_addr))) { - sin6_new->sin6_scope_id = sin6_svc->sin6_scope_id; - } - } -#endif - return 1; -} - -int -__rpc_sockisbound(int fd) -{ - struct sockaddr_storage ss; - socklen_t slen; - - slen = sizeof (struct sockaddr_storage); - if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) - return 0; - - switch (ss.ss_family) { - case AF_INET: - return (((struct sockaddr_in *) - (void *)&ss)->sin_port != 0); -#ifdef INET6 - case AF_INET6: - return (((struct sockaddr_in6 *) - (void *)&ss)->sin6_port != 0); -#endif - case AF_LOCAL: - /* XXX check this */ - return (((struct sockaddr_un *) - (void *)&ss)->sun_path[0] != '\0'); - default: - break; - } - - return 0; -} diff --git a/lib/libc/rpc/rpc_prot.c b/lib/libc/rpc/rpc_prot.c deleted file mode 100644 index 2a4b575..0000000 --- a/lib/libc/rpc/rpc_prot.c +++ /dev/null @@ -1,372 +0,0 @@ -/* $NetBSD: rpc_prot.c,v 1.16 2000/06/02 23:11:13 fvdl Exp $ */ - -/* - * 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 *sccsid2 = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include <sys/param.h> - -#include <assert.h> - -#include <rpc/rpc.h> -#include "un-namespace.h" - -static void accepted(enum accept_stat, struct rpc_err *); -static void rejected(enum reject_stat, struct rpc_err *); - -/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ - -extern struct opaque_auth _null_auth; - -/* - * XDR an opaque authentication struct - * (see auth.h) - */ -bool_t -xdr_opaque_auth(xdrs, ap) - XDR *xdrs; - struct opaque_auth *ap; -{ - - assert(xdrs != NULL); - assert(ap != NULL); - - 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) - XDR *xdrs; - des_block *blkp; -{ - - assert(xdrs != NULL); - assert(blkp != NULL); - - return (xdr_opaque(xdrs, (caddr_t)(void *)blkp, sizeof(des_block))); -} - -/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ - -/* - * XDR the MSG_ACCEPTED part of a reply message union - */ -bool_t -xdr_accepted_reply(xdrs, ar) - XDR *xdrs; - struct accepted_reply *ar; -{ - enum accept_stat *par_stat; - - assert(xdrs != NULL); - assert(ar != NULL); - - par_stat = &ar->ar_stat; - - /* personalized union, rather than calling xdr_union */ - if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) - return (FALSE); - if (! xdr_enum(xdrs, (enum_t *) par_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))); - - case GARBAGE_ARGS: - case SYSTEM_ERR: - case PROC_UNAVAIL: - case PROG_UNAVAIL: - 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) - XDR *xdrs; - struct rejected_reply *rr; -{ - enum reject_stat *prj_stat; - enum auth_stat *prj_why; - - assert(xdrs != NULL); - assert(rr != NULL); - - prj_stat = &rr->rj_stat; - - /* personalized union, rather than calling xdr_union */ - if (! xdr_enum(xdrs, (enum_t *) prj_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: - prj_why = &rr->rj_why; - return (xdr_enum(xdrs, (enum_t *) prj_why)); - } - /* NOTREACHED */ - assert(0); - return (FALSE); -} - -static const struct xdr_discrim reply_dscrm[3] = { - { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply }, - { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply }, - { __dontcare__, NULL_xdrproc_t } }; - -/* - * XDR a reply message - */ -bool_t -xdr_replymsg(xdrs, rmsg) - XDR *xdrs; - struct rpc_msg *rmsg; -{ - enum msg_type *prm_direction; - enum reply_stat *prp_stat; - - assert(xdrs != NULL); - assert(rmsg != NULL); - - prm_direction = &rmsg->rm_direction; - prp_stat = &rmsg->rm_reply.rp_stat; - - if ( - xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) && - xdr_enum(xdrs, (enum_t *) prm_direction) && - (rmsg->rm_direction == REPLY) ) - return (xdr_union(xdrs, (enum_t *) prp_stat, - (caddr_t)(void *)&(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) - XDR *xdrs; - struct rpc_msg *cmsg; -{ - enum msg_type *prm_direction; - - assert(xdrs != NULL); - assert(cmsg != NULL); - - prm_direction = &cmsg->rm_direction; - - 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 *) prm_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) - enum accept_stat acpt_stat; - struct rpc_err *error; -{ - - assert(error != NULL); - - 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; - } - /* NOTREACHED */ - /* something's wrong, but we don't know what ... */ - error->re_status = RPC_FAILED; - error->re_lb.s1 = (int32_t)MSG_ACCEPTED; - error->re_lb.s2 = (int32_t)acpt_stat; -} - -static void -rejected(rjct_stat, error) - enum reject_stat rjct_stat; - struct rpc_err *error; -{ - - assert(error != NULL); - - switch (rjct_stat) { - case RPC_MISMATCH: - error->re_status = RPC_VERSMISMATCH; - return; - - case AUTH_ERROR: - error->re_status = RPC_AUTHERROR; - return; - } - /* something's wrong, but we don't know what ... */ - /* NOTREACHED */ - error->re_status = RPC_FAILED; - error->re_lb.s1 = (int32_t)MSG_DENIED; - error->re_lb.s2 = (int32_t)rjct_stat; -} - -/* - * given a reply message, fills in the error - */ -void -_seterr_reply(msg, error) - struct rpc_msg *msg; - struct rpc_err *error; -{ - - assert(msg != NULL); - assert(error != NULL); - - /* 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 = (int32_t)(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; - - case RPC_FAILED: - case RPC_SUCCESS: - case RPC_PROGNOTREGISTERED: - case RPC_PMAPFAILURE: - case RPC_UNKNOWNPROTO: - case RPC_UNKNOWNHOST: - case RPC_SYSTEMERROR: - case RPC_CANTDECODEARGS: - case RPC_PROCUNAVAIL: - case RPC_PROGUNAVAIL: - case RPC_TIMEDOUT: - case RPC_CANTRECV: - case RPC_CANTSEND: - case RPC_CANTDECODERES: - case RPC_CANTENCODEARGS: - default: - break; - } -} diff --git a/lib/libc/rpc/rpc_secure.3 b/lib/libc/rpc/rpc_secure.3 deleted file mode 100644 index 07c6314..0000000 --- a/lib/libc/rpc/rpc_secure.3 +++ /dev/null @@ -1,287 +0,0 @@ -.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI -.\" $FreeBSD$ -.\" -.Dd February 16, 1988 -.Dt RPC 3 -.Os -.Sh NAME -.Nm rpc_secure -.Nd library routines for secure remote procedure calls -.Sh SYNOPSIS -.In rpc/rpc.h -.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" "const char *host" "const 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" "const uid_t uid" "const 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 -The -.Fn authdes_create -function, -used on the client side, returns an authentication handle that -will enable the use of the secure authentication system. -The first argument -.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 -argument -.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 argument is usually the -address of the -.Tn RPC -server itself. -The final argument -.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 -The -.Fn authdes_getucred -function, -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 -The -.Fn getnetname -function -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 -The -.Fn host2netname -function -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 -The -.Fn key_decryptsession -function -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 -The -.Fn key_decryptsession -function -takes a server netname and a -.Tn DES -key, and decrypts the key by -using the public key of the server and the secret key -associated with the effective uid of the calling process. -It -is the inverse of -.Fn key_encryptsession . -.Pp -The -.Fn key_encryptsession -function -is a keyserver interface routine. -It -takes a server netname and a des key, and encrypts -it using the public key of the server and the secret key -associated with the effective uid of the calling process. -It -is the inverse of -.Fn key_decryptsession . -.Pp -The -.Fn key_gendes -function -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 -The -.Fn key_setsecret -function -is a keyserver interface routine. -It is used to set the key for -the effective -.Fa uid -of the calling process. -.Pp -The -.Fn netname2host -function -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 -The -.Fn netname2user -function -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 -The -.Fn user2netname -function -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/lib/libc/rpc/rpc_soc.3 b/lib/libc/rpc/rpc_soc.3 deleted file mode 100644 index ebc666b..0000000 --- a/lib/libc/rpc/rpc_soc.3 +++ /dev/null @@ -1,1726 +0,0 @@ -.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI -.\" $NetBSD: rpc_soc.3,v 1.2 2000/06/07 13:39:43 simonb Exp $ -.\" $FreeBSD$ -.\" -.Dd February 16, 1988 -.Dt RPC_SOC 3 -.Os -.Sh NAME -.Nm rpc_soc , -.Nm auth_destroy , -.Nm authnone_create , -.Nm authunix_create , -.Nm authunix_create_default , -.Nm callrpc , -.Nm clnt_broadcast , -.Nm clnt_call , -.Nm clnt_control , -.Nm clnt_create , -.Nm clnt_destroy , -.Nm clnt_freeres , -.Nm clnt_geterr , -.Nm clnt_pcreateerror , -.Nm clnt_perrno , -.Nm clnt_perror , -.Nm clnt_spcreateerror , -.Nm clnt_sperrno , -.Nm clnt_sperror , -.Nm clntraw_create , -.Nm clnttcp_create , -.Nm clntudp_bufcreate , -.Nm clntudp_create , -.Nm clntunix_create , -.Nm get_myaddress , -.Nm pmap_getmaps , -.Nm pmap_getport , -.Nm pmap_rmtcall , -.Nm pmap_set , -.Nm pmap_unset , -.Nm registerrpc , -.Nm rpc_createerr , -.Nm svc_destroy , -.Nm svc_fds , -.Nm svc_fdset , -.Nm svc_getargs , -.Nm svc_getcaller , -.Nm svc_getreq , -.Nm svc_getreqset , -.Nm svc_register , -.Nm svc_run , -.Nm svc_sendreply , -.Nm svc_unregister , -.Nm svcerr_auth , -.Nm svcerr_decode , -.Nm svcerr_noproc , -.Nm svcerr_noprog , -.Nm svcerr_progvers , -.Nm svcerr_systemerr , -.Nm svcerr_weakauth , -.Nm svcfd_create , -.Nm svcunixfd_create , -.Nm svcraw_create , -.Nm svcunix_create , -.Nm xdr_accepted_reply , -.Nm xdr_authunix_parms , -.Nm xdr_callhdr , -.Nm xdr_callmsg , -.Nm xdr_opaque_auth , -.Nm xdr_pmap , -.Nm xdr_pmaplist , -.Nm xdr_rejected_reply , -.Nm xdr_replymsg , -.Nm xprt_register , -.Nm xprt_unregister -.Nd "library routines for remote procedure calls" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Pp -See -.Sx DESCRIPTION -for function declarations. -.Sh DESCRIPTION -.Bf -symbolic -The -.Fn svc_* -and -.Fn clnt_* -functions described in this page are the old, TS-RPC -interface to the XDR and RPC library, and exist for backward compatibility. -The new interface is described in the pages -referenced from -.Xr rpc 3 . -.Ef -.Pp -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. -.Pp -Routines that are used for Secure -.Tn RPC ( DES -authentication) are described in -.Xr rpc_secure 3 . -Secure -.Tn RPC -can be used only if -.Tn DES -encryption is available. -.Bl -tag -width indent -compact -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn auth_destroy "AUTH *auth" -.Xc -.Pp -A macro that destroys the authentication information associated with -.Fa auth . -Destruction usually involves deallocation of private data -structures. -The use of -.Fa auth -is undefined after calling -.Fn auth_destroy . -.Pp -.It Xo -.Ft "AUTH *" -.Xc -.It Xo -.Fn authnone_create -.Xc -.Pp -Create and return an -.Tn RPC -authentication handle that passes nonusable authentication -information with each remote procedure call. -This is the -default authentication used by -.Tn RPC . -.Pp -.It Xo -.Ft "AUTH *" -.Xc -.It Xo -.Fn authunix_create "char *host" "int uid" "int gid" "int len" "int *aup_gids" -.Xc -.Pp -Create and return an -.Tn RPC -authentication handle that contains -.Ux -authentication information. -The -.Fa host -argument -is the name of the machine on which the information was -created; -.Fa uid -is the user's user ID; -.Fa gid -is the user's current group ID; -.Fa len -and -.Fa aup_gids -refer to a counted array of groups to which the user belongs. -It is easy to impersonate a user. -.Pp -.It Xo -.Ft "AUTH *" -.Xc -.It Xo -.Fn authunix_create_default -.Xc -.Pp -Calls -.Fn authunix_create -with the appropriate arguments. -.Pp -.It Xo -.Ft int -.Fo callrpc -.Fa "char *host" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "u_long procnum" -.Fa "xdrproc_t inproc" -.Fa "void *in" -.Fa "xdrproc_t outproc" -.Fa "void *out" -.Fc -.Xc -.Pp -Call the remote procedure associated with -.Fa prognum , -.Fa versnum , -and -.Fa procnum -on the machine -.Fa host . -The -.Fa in -argument -is the address of the procedure's argument(s), and -.Fa out -is the address of where to place the result(s); -.Fa inproc -is used to encode the procedure's arguments, and -.Fa outproc -is used to decode the procedure's results. -This routine returns zero if it succeeds, or the value of -.Vt "enum clnt_stat" -cast to an integer if it fails. -The routine -.Fn clnt_perrno -is handy for translating failure statuses into messages. -.Pp -Warning: calling remote procedures with this routine -uses -.Tn UDP/IP -as a transport; see -.Fn clntudp_create -for restrictions. -You do not have control of timeouts or authentication using -this routine. -.Pp -.It Xo -.Ft "enum clnt_stat" -.Xc -.It Xo -.Fo clnt_broadcast -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "u_long procnum" -.Fa "xdrproc_t inproc" -.Fa "char *in" -.Fa "xdrproc_t outproc" -.Fa "char *out" -.Fa "bool_t (*eachresult)(caddr_t, struct sockaddr_in *)" -.Fc -.Xc -.Pp -Like -.Fn callrpc , -except the call message is broadcast to all locally -connected broadcast nets. -Each time it receives a -response, this routine calls -.Fn eachresult , -whose form is: -.Bd -ragged -offset indent -.Ft bool_t -.Fn eachresult "caddr_t out" "struct sockaddr_in *addr" -.Ed -.Pp -where -.Fa out -is the same as -.Fa out -passed to -.Fn clnt_broadcast , -except that the remote procedure's output is decoded there; -.Fa addr -points to the address of the machine that sent the results. -If -.Fn eachresult -returns zero, -.Fn clnt_broadcast -waits for more replies; otherwise it returns with appropriate -status. -.Pp -Warning: broadcast sockets are limited in size to the -maximum transfer unit of the data link. -For ethernet, -this value is 1500 bytes. -.Pp -.It Xo -.Ft "enum clnt_stat" -.Xc -.It Xo -.Fo clnt_call -.Fa "CLIENT *clnt" -.Fa "u_long procnum" -.Fa "xdrproc_t inproc" -.Fa "char *in" -.Fa "xdrproc_t outproc" -.Fa "char *out" -.Fa "struct timeval tout" -.Fc -.Xc -.Pp -A macro that calls the remote procedure -.Fa procnum -associated with the client handle, -.Fa clnt , -which is obtained with an -.Tn RPC -client creation routine such as -.Fn clnt_create . -The -.Fa in -argument -is the address of the procedure's argument(s), and -.Fa out -is the address of where to place the result(s); -.Fa inproc -is used to encode the procedure's arguments, and -.Fa outproc -is used to decode the procedure's results; -.Fa tout -is the time allowed for results to come back. -.Pp -.It Xo -.Ft void -.Fn clnt_destroy "CLIENT *clnt" -.Xc -.Pp -A macro that destroys the client's -.Tn RPC -handle. -Destruction usually involves deallocation -of private data structures, including -.Fa clnt -itself. -Use of -.Fa clnt -is undefined after calling -.Fn clnt_destroy . -If the -.Tn RPC -library opened the associated socket, it will close it also. -Otherwise, the socket remains open. -.Pp -.It Xo -.Ft CLIENT * -.Xc -.It Xo -.Fn clnt_create "char *host" "u_long prog" "u_long vers" "char *proto" -.Xc -.Pp -Generic client creation routine. -The -.Fa host -argument -identifies the name of the remote host where the server -is located. -The -.Fa proto -argument -indicates which kind of transport protocol to use. -The -currently supported values for this field are -.Qq Li udp -and -.Qq Li tcp . -Default timeouts are set, but can be modified using -.Fn clnt_control . -.Pp -Warning: Using -.Tn UDP -has its shortcomings. -Since -.Tn UDP Ns \-based -.Tn 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. -.Pp -.It Xo -.Ft bool_t -.Xc -.It Xo -.Fn clnt_control "CLIENT *cl" "u_int req" "char *info" -.Xc -.Pp -A macro used to change or retrieve various information -about a client object. -The -.Fa req -argument -indicates the type of operation, and -.Fa info -is a pointer to the information. -For both -.Tn UDP -and -.Tn TCP , -the supported values of -.Fa req -and their argument types and what they do are: -.Bl -column "CLSET_RETRY_TIMEOUT" "struct sockaddr_in" -.It Dv CLSET_TIMEOUT Ta Xo -.Vt "struct timeval" Ta "set total timeout" -.Xc -.It Dv CLGET_TIMEOUT Ta Xo -.Vt "struct timeval" Ta "get total timeout" -.Xc -.El -.Pp -Note: if you set the timeout using -.Fn clnt_control , -the timeout argument passed to -.Fn clnt_call -will be ignored in all future calls. -.Bl -column "CLSET_RETRY_TIMEOUT" "struct sockaddr_in" -.It Dv CLGET_SERVER_ADDR Ta Xo -.Vt "struct sockaddr_in" Ta "get server's address" -.Xc -.El -.Pp -The following operations are valid for -.Tn UDP -only: -.Bl -column "CLSET_RETRY_TIMEOUT" "struct sockaddr_in" -.It Dv CLSET_RETRY_TIMEOUT Ta Xo -.Vt "struct timeval" Ta "set the retry timeout" -.Xc -.It Dv CLGET_RETRY_TIMEOUT Ta Xo -.Vt "struct timeval" Ta "get the retry timeout" -.Xc -.El -.Pp -The retry timeout is the time that -.Tn "UDP RPC" -waits for the server to reply before -retransmitting the request. -.Pp -.It Xo -.Ft bool_t -.Fn clnt_freeres "CLIENT *clnt" "xdrproc_t outproc" "char *out" -.Xc -.Pp -A macro that frees any data allocated by the -.Tn RPC/XDR -system when it decoded the results of an -.Tn RPC -call. -The -.Fa out -argument -is the address of the results, and -.Fa outproc -is the -.Tn XDR -routine describing the results. -This routine returns one if the results were successfully -freed, -and zero otherwise. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn clnt_geterr "CLIENT *clnt" "struct rpc_err *errp" -.Xc -.Pp -A macro that copies the error structure out of the client -handle -to the structure at address -.Fa errp . -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn clnt_pcreateerror "char *s" -.Xc -.Pp -prints a message to standard error indicating -why a client -.Tn RPC -handle could not be created. -The message is prepended with string -.Fa s -and a colon. -A newline is appended at the end of the message. -Used when a -.Fn clnt_create , -.Fn clntraw_create , -.Fn clnttcp_create , -or -.Fn clntudp_create -call fails. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn clnt_perrno "enum clnt_stat stat" -.Xc -.Pp -Print a message to standard error corresponding -to the condition indicated by -.Fa stat . -A newline is appended at the end of the message. -Used after -.Fn callrpc . -.Pp -.It Xo -.Ft void -.Fn clnt_perror "CLIENT *clnt" "char *s" -.Xc -.Pp -Print a message to standard error indicating why an -.Tn RPC -call failed; -.Fa clnt -is the handle used to do the call. -The message is prepended with string -.Fa s -and a colon. -A newline is appended at the end of the message. -Used after -.Fn clnt_call . -.Pp -.It Xo -.Ft "char *" -.Xc -.It Xo -.Fn clnt_spcreateerror "char *s" -.Xc -.Pp -Like -.Fn clnt_pcreateerror , -except that it returns a string -instead of printing to the standard error. -.Pp -Bugs: returns pointer to static data that is overwritten -on each call. -.Pp -.It Xo -.Ft "char *" -.Xc -.It Xo -.Fn clnt_sperrno "enum clnt_stat stat" -.Xc -.Pp -Take the same arguments as -.Fn clnt_perrno , -but instead of sending a message to the standard error -indicating why an -.Tn RPC -call failed, return a pointer to a string which contains -the message. -.Pp -The -.Fn clnt_sperrno -function -is used instead of -.Fn 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 -.Fn printf , -or if a message format different from that supported by -.Fn clnt_perrno -is to be used. -.Pp -Note: unlike -.Fn clnt_sperror -and -.Fn clnt_spcreateerror , -.Fn clnt_sperrno -returns pointer to static data, but the -result will not get overwritten on each call. -.Pp -.It Xo -.Ft "char *" -.Xc -.It Xo -.Fn clnt_sperror "CLIENT *rpch" "char *s" -.Xc -.Pp -Like -.Fn clnt_perror , -except that (like -.Fn clnt_sperrno ) -it returns a string instead of printing to standard error. -.Pp -Bugs: returns pointer to static data that is overwritten -on each call. -.Pp -.It Xo -.Ft "CLIENT *" -.Xc -.It Xo -.Fn clntraw_create "u_long prognum" "u_long versnum" -.Xc -.Pp -This routine creates a toy -.Tn RPC -client for the remote program -.Fa prognum , -version -.Fa versnum . -The transport used to pass messages to the service is -actually a buffer within the process's address space, so the -corresponding -.Tn RPC -server should live in the same address space; see -.Fn svcraw_create . -This allows simulation of -.Tn RPC -and acquisition of -.Tn RPC -overheads, such as round trip times, without any -kernel interference. -This routine returns -.Dv NULL -if it fails. -.Pp -.It Xo -.Ft "CLIENT *" -.Xc -.It Xo -.Fo clnttcp_create -.Fa "struct sockaddr_in *addr" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "int *sockp" -.Fa "u_int sendsz" -.Fa "u_int recvsz" -.Fc -.Xc -.Pp -This routine creates an -.Tn RPC -client for the remote program -.Fa prognum , -version -.Fa versnum ; -the client uses -.Tn TCP/IP -as a transport. -The remote program is located at Internet -address -.Fa addr . -If -.Fa addr\->sin_port -is zero, then it is set to the actual port that the remote -program is listening on (the remote -.Xr rpcbind 8 -service is consulted for this information). -The -.Fa sockp -argument -is a socket; if it is -.Dv RPC_ANYSOCK , -then this routine opens a new one and sets -.Fa sockp . -Since -.Tn TCP Ns \-based -.Tn RPC -uses buffered -.Tn I/O , -the user may specify the size of the send and receive buffers -with the -.Fa sendsz -and -.Fa recvsz -arguments; -values of zero choose suitable defaults. -This routine returns -.Dv NULL -if it fails. -.Pp -.It Xo -.Ft "CLIENT *" -.Xc -.It Xo -.Fo clntudp_create -.Fa "struct sockaddr_in *addr" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "struct timeval wait" -.Fa "int *sockp" -.Fc -.Xc -.Pp -This routine creates an -.Tn RPC -client for the remote program -.Fa prognum , -version -.Fa versnum ; -the client uses -.Tn UDP/IP -as a transport. -The remote program is located at Internet -address -.Fa addr . -If -.Fa addr\->sin_port -is zero, then it is set to actual port that the remote -program is listening on (the remote -.Xr rpcbind 8 -service is consulted for this information). -The -.Fa sockp -argument -is a socket; if it is -.Dv RPC_ANYSOCK , -then this routine opens a new one and sets -.Fa sockp . -The -.Tn UDP -transport resends the call message in intervals of -.Fa 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 -.Fn clnt_call . -.Pp -Warning: since -.Tn UDP Ns \-based -.Tn 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. -.Pp -.It Xo -.Ft "CLIENT *" -.Xc -.It Xo -.Fo clntudp_bufcreate -.Fa "struct sockaddr_in *addr" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "struct timeval wait" -.Fa "int *sockp" -.Fa "unsigned int sendsize" -.Fa "unsigned int recosize" -.Fc -.Xc -.Pp -This routine creates an -.Tn RPC -client for the remote program -.Fa prognum , -on -.Fa versnum ; -the client uses -.Tn UDP/IP -as a transport. -The remote program is located at Internet -address -.Fa addr . -If -.Fa addr\->sin_port -is zero, then it is set to actual port that the remote -program is listening on (the remote -.Xr rpcbind 8 -service is consulted for this information). -The -.Fa sockp -argument -is a socket; if it is -.Dv RPC_ANYSOCK , -then this routine opens a new one and sets -.Fa sockp . -The -.Tn UDP -transport resends the call message in intervals of -.Fa 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 -.Fn clnt_call . -.Pp -This allows the user to specify the maximum packet size -for sending and receiving -.Tn UDP Ns \-based -.Tn RPC -messages. -.Pp -.It Xo -.Ft "CLIENT *" -.Xc -.It Xo -.Fo clntunix_create -.Fa "struct sockaddr_un *raddr" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "int *sockp" -.Fa "u_int sendsz" -.Fa "u_int recvsz" -.Fc -.Xc -.Pp -This routine creates an -.Tn RPC -client for the local -program -.Fa prognum , -version -.Fa versnum ; -the client uses -.Ux Ns -domain -sockets as a transport. -The local program is located at the -.Fa *raddr . -The -.Fa sockp -argument -is a socket; if it is -.Dv RPC_ANYSOCK , -then this routine opens a new one and sets -.Fa sockp . -Since -.Ux Ns -based -.Tn RPC -uses buffered -.Tn I/O , -the user may specify the size of the send and receive buffers -with the -.Fa sendsz -and -.Fa recvsz -arguments; -values of zero choose suitable defaults. -This routine returns -.Dv NULL -if it fails. -.Pp -.It Xo -.Ft int -.Xc -.It Xo -.Fn get_myaddress "struct sockaddr_in *addr" -.Xc -.Pp -Stuff the machine's -.Tn IP -address into -.Fa addr , -without consulting the library routines that deal with -.Pa /etc/hosts . -The port number is always set to -.Fn htons PMAPPORT . -Returns zero on success, non-zero on failure. -.Pp -.It Xo -.Ft "struct pmaplist *" -.Xc -.It Xo -.Fn pmap_getmaps "struct sockaddr_in *addr" -.Xc -.Pp -A user interface to the -.Xr rpcbind 8 -service, which returns a list of the current -.Tn RPC -program\-to\-port mappings -on the host located at -.Tn IP -address -.Fa addr . -This routine can return -.Dv NULL . -The command -.Dq Nm rpcinfo Fl p -uses this routine. -.Pp -.It Xo -.Ft u_short -.Xc -.It Xo -.Fo pmap_getport -.Fa "struct sockaddr_in *addr" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "u_long protocol" -.Fc -.Xc -.Pp -A user interface to the -.Xr rpcbind 8 -service, which returns the port number -on which waits a service that supports program number -.Fa prognum , -version -.Fa versnum , -and speaks the transport protocol associated with -.Fa protocol . -The value of -.Fa protocol -is most likely -.Dv IPPROTO_UDP -or -.Dv IPPROTO_TCP . -A return value of zero means that the mapping does not exist -or that -the -.Tn RPC -system failed to contact the remote -.Xr rpcbind 8 -service. -In the latter case, the global variable -.Va rpc_createerr -contains the -.Tn RPC -status. -.Pp -.It Xo -.Ft "enum clnt_stat" -.Xc -.It Xo -.Fo pmap_rmtcall -.Fa "struct sockaddr_in *addr" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "u_long procnum" -.Fa "xdrproc_t inproc" -.Fa "char *in" -.Fa "xdrproc_t outproc" -.Fa "char *out" -.Fa "struct timeval tout" -.Fa "u_long *portp" -.Fc -.Xc -.Pp -A user interface to the -.Xr rpcbind 8 -service, which instructs -.Xr rpcbind 8 -on the host at -.Tn IP -address -.Fa addr -to make an -.Tn RPC -call on your behalf to a procedure on that host. -The -.Fa portp -argument -will be modified to the program's port number if the -procedure -succeeds. -The definitions of other arguments are discussed -in -.Fn callrpc -and -.Fn clnt_call . -This procedure should be used for a -.Dq ping -and nothing -else. -See also -.Fn clnt_broadcast . -.Pp -.It Xo -.Ft bool_t -.Fn pmap_set "u_long prognum" "u_long versnum" "u_long protocol" "u_short port" -.Xc -.Pp -A user interface to the -.Xr rpcbind 8 -service, which establishes a mapping between the triple -.Pq Fa prognum , versnum , protocol -and -.Fa port -on the machine's -.Xr rpcbind 8 -service. -The value of -.Fa protocol -is most likely -.Dv IPPROTO_UDP -or -.Dv IPPROTO_TCP . -This routine returns one if it succeeds, zero otherwise. -Automatically done by -.Fn svc_register . -.Pp -.It Xo -.Ft bool_t -.Fn pmap_unset "u_long prognum" "u_long versnum" -.Xc -.Pp -A user interface to the -.Xr rpcbind 8 -service, which destroys all mapping between the triple -.Pq Fa prognum , versnum , * -and -.Fa ports -on the machine's -.Xr rpcbind 8 -service. -This routine returns one if it succeeds, zero -otherwise. -.Pp -.It Xo -.Ft bool_t -.Fo registerrpc -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "u_long procnum" -.Fa "char *(*procname)(void)" -.Fa "xdrproc_t inproc" -.Fa "xdrproc_t outproc" -.Fc -.Xc -.Pp -Register procedure -.Fa procname -with the -.Tn RPC -service package. -If a request arrives for program -.Fa prognum , -version -.Fa versnum , -and procedure -.Fa procnum , -.Fa procname -is called with a pointer to its argument(s); -.Fa progname -should return a pointer to its static result(s); -.Fa inproc -is used to decode the arguments while -.Fa outproc -is used to encode the results. -This routine returns zero if the registration succeeded, \-1 -otherwise. -.Pp -Warning: remote procedures registered in this form -are accessed using the -.Tn UDP/IP -transport; see -.Fn svcudp_create -for restrictions. -.Pp -.It Xo -.Vt "struct rpc_createerr" rpc_createerr ; -.Xc -.Pp -A global variable whose value is set by any -.Tn RPC -client creation routine -that does not succeed. -Use the routine -.Fn clnt_pcreateerror -to print the reason why. -.Pp -.It Xo -.Ft bool_t -.Fn svc_destroy "SVCXPRT * xprt" -.Xc -.Pp -A macro that destroys the -.Tn RPC -service transport handle, -.Fa xprt . -Destruction usually involves deallocation -of private data structures, including -.Fa xprt -itself. -Use of -.Fa xprt -is undefined after calling this routine. -.Pp -.It Xo -.Vt fd_set svc_fdset ; -.Xc -.Pp -A global variable reflecting the -.Tn RPC -service side's -read file descriptor bit mask; it is suitable as a template argument -to the -.Xr select 2 -system call. -This is only of interest -if a service implementor does not call -.Fn svc_run , -but rather does his own asynchronous event processing. -This variable is read\-only (do not pass its address to -.Xr select 2 ! ) , -yet it may change after calls to -.Fn svc_getreqset -or any creation routines. -As well, note that if the process has descriptor limits -which are extended beyond -.Dv FD_SETSIZE , -this variable will only be usable for the first -.Dv FD_SETSIZE -descriptors. -.Pp -.It Xo -.Vt int svc_fds ; -.Xc -.Pp -Similar to -.Va svc_fdset , -but limited to 32 descriptors. -This -interface is obsoleted by -.Va svc_fdset . -.Pp -.It Xo -.Ft bool_t -.Fn svc_freeargs "SVCXPRT *xprt" "xdrproc_t inproc" "char *in" -.Xc -.Pp -A macro that frees any data allocated by the -.Tn RPC/XDR -system when it decoded the arguments to a service procedure -using -.Fn svc_getargs . -This routine returns 1 if the results were successfully -freed, -and zero otherwise. -.Pp -.It Xo -.Ft bool_t -.Fn svc_getargs "SVCXPRT *xprt" "xdrproc_t inproc" "char *in" -.Xc -.Pp -A macro that decodes the arguments of an -.Tn RPC -request -associated with the -.Tn RPC -service transport handle, -.Fa xprt . -The -.Fa in -argument -is the address where the arguments will be placed; -.Fa inproc -is the -.Tn XDR -routine used to decode the arguments. -This routine returns one if decoding succeeds, and zero -otherwise. -.Pp -.It Xo -.Ft "struct sockaddr_in *" -.Xc -.It Xo -.Fn svc_getcaller "SVCXPRT *xprt" -.Xc -.Pp -The approved way of getting the network address of the caller -of a procedure associated with the -.Tn RPC -service transport handle, -.Fa xprt . -.Pp -.It Xo -.Ft void -.Fn svc_getreqset "fd_set *rdfds" -.Xc -.Pp -This routine is only of interest if a service implementor -does not call -.Fn svc_run , -but instead implements custom asynchronous event processing. -It is called when the -.Xr select 2 -system call has determined that an -.Tn RPC -request has arrived on some -.Tn RPC -socket(s); -.Fa rdfds -is the resultant read file descriptor bit mask. -The routine returns when all sockets associated with the -value of -.Fa rdfds -have been serviced. -.Pp -.It Xo -.Ft void -.Fn svc_getreq "int rdfds" -.Xc -.Pp -Similar to -.Fn svc_getreqset , -but limited to 32 descriptors. -This interface is obsoleted by -.Fn svc_getreqset . -.Pp -.It Xo -.Ft bool_t -.Fo svc_register -.Fa "SVCXPRT *xprt" -.Fa "u_long prognum" -.Fa "u_long versnum" -.Fa "void (*dispatch)(struct svc_req *, SVCXPRT *)" -.Fa "int protocol" -.Fc -.Xc -.Pp -Associates -.Fa prognum -and -.Fa versnum -with the service dispatch procedure, -.Fn dispatch . -If -.Fa protocol -is zero, the service is not registered with the -.Xr rpcbind 8 -service. -If -.Fa protocol -is non-zero, then a mapping of the triple -.Pq Fa prognum , versnum , protocol -to -.Fa xprt\->xp_port -is established with the local -.Xr rpcbind 8 -service (generally -.Fa protocol -is zero, -.Dv IPPROTO_UDP -or -.Dv IPPROTO_TCP ) . -The procedure -.Fn dispatch -has the following form: -.Bd -ragged -offset indent -.Ft bool_t -.Fn dispatch "struct svc_req *request" "SVCXPRT *xprt" -.Ed -.Pp -The -.Fn svc_register -routine returns one if it succeeds, and zero otherwise. -.Pp -.It Xo -.Fn svc_run -.Xc -.Pp -This routine never returns. -It waits for -.Tn RPC -requests to arrive, and calls the appropriate service -procedure using -.Fn svc_getreq -when one arrives. -This procedure is usually waiting for a -.Xr select 2 -system call to return. -.Pp -.It Xo -.Ft bool_t -.Fn svc_sendreply "SVCXPRT *xprt" "xdrproc_t outproc" "char *out" -.Xc -.Pp -Called by an -.Tn RPC -service's dispatch routine to send the results of a -remote procedure call. -The -.Fa xprt -argument -is the request's associated transport handle; -.Fa outproc -is the -.Tn XDR -routine which is used to encode the results; and -.Fa out -is the address of the results. -This routine returns one if it succeeds, zero otherwise. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svc_unregister "u_long prognum" "u_long versnum" -.Xc -.Pp -Remove all mapping of the double -.Pq Fa prognum , versnum -to dispatch routines, and of the triple -.Pq Fa prognum , versnum , * -to port number. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svcerr_auth "SVCXPRT *xprt" "enum auth_stat why" -.Xc -.Pp -Called by a service dispatch routine that refuses to perform -a remote procedure call due to an authentication error. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svcerr_decode "SVCXPRT *xprt" -.Xc -.Pp -Called by a service dispatch routine that cannot successfully -decode its arguments. -See also -.Fn svc_getargs . -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svcerr_noproc "SVCXPRT *xprt" -.Xc -.Pp -Called by a service dispatch routine that does not implement -the procedure number that the caller requests. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svcerr_noprog "SVCXPRT *xprt" -.Xc -.Pp -Called when the desired program is not registered with the -.Tn RPC -package. -Service implementors usually do not need this routine. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svcerr_progvers "SVCXPRT *xprt" "u_long low_vers" "u_long high_vers" -.Xc -.Pp -Called when the desired version of a program is not registered -with the -.Tn RPC -package. -Service implementors usually do not need this routine. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svcerr_systemerr "SVCXPRT *xprt" -.Xc -.Pp -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. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn svcerr_weakauth "SVCXPRT *xprt" -.Xc -.Pp -Called by a service dispatch routine that refuses to perform -a remote procedure call due to insufficient -authentication arguments. -The routine calls -.Fn svcerr_auth xprt AUTH_TOOWEAK . -.Pp -.It Xo -.Ft "SVCXPRT *" -.Xc -.It Xo -.Fn svcraw_create void -.Xc -.Pp -This routine creates a toy -.Tn RPC -service transport, to which it returns a pointer. -The transport -is really a buffer within the process's address space, -so the corresponding -.Tn RPC -client should live in the same -address space; -see -.Fn clntraw_create . -This routine allows simulation of -.Tn RPC -and acquisition of -.Tn RPC -overheads (such as round trip times), without any kernel -interference. -This routine returns -.Dv NULL -if it fails. -.Pp -.It Xo -.Ft "SVCXPRT *" -.Xc -.It Xo -.Fn svctcp_create "int sock" "u_int send_buf_size" "u_int recv_buf_size" -.Xc -.Pp -This routine creates a -.Tn TCP/IP Ns \-based -.Tn RPC -service transport, to which it returns a pointer. -The transport is associated with the socket -.Fa sock , -which may be -.Dv RPC_ANYSOCK , -in which case a new socket is created. -If the socket is not bound to a local -.Tn TCP -port, then this routine binds it to an arbitrary port. -Upon completion, -.Fa xprt\->xp_fd -is the transport's socket descriptor, and -.Fa xprt\->xp_port -is the transport's port number. -This routine returns -.Dv NULL -if it fails. -Since -.Tn TCP Ns \-based -.Tn RPC -uses buffered -.Tn I/O , -users may specify the size of buffers; values of zero -choose suitable defaults. -.Pp -.It Xo -.Ft "SVCXPRT *" -.Xc -.It Xo -.Fn svcunix_create "int sock" "u_int send_buf_size" "u_int recv_buf_size" "char *path" -.Xc -.Pp -This routine creates a -.Ux Ns -based -.Tn RPC -service transport, to which it returns a pointer. -The transport is associated with the socket -.Fa sock , -which may be -.Dv RPC_ANYSOCK , -in which case a new socket is created. -The -.Fa *path -argument -is a variable-length file system pathname of -at most 104 characters. -This file is -.Em not -removed when the socket is closed. -The -.Xr unlink 2 -system call must be used to remove the file. -Upon completion, -.Fa xprt\->xp_fd -is the transport's socket descriptor. -This routine returns -.Dv NULL -if it fails. -Since -.Ux Ns -based -.Tn RPC -uses buffered -.Tn I/O , -users may specify the size of buffers; values of zero -choose suitable defaults. -.Pp -.It Xo -.Ft "SVCXPRT *" -.Xc -.It Xo -.Fn svcunixfd_create "int fd" "u_int sendsize" "u_int recvsize" -.Xc -.Pp -Create a service on top of any open descriptor. -The -.Fa sendsize -and -.Fa recvsize -arguments -indicate sizes for the send and receive buffers. -If they are -zero, a reasonable default is chosen. -.Pp -.It Xo -.Ft "SVCXPRT *" -.Xc -.It Xo -.Fn svcfd_create "int fd" "u_int sendsize" "u_int recvsize" -.Xc -.Pp -Create a service on top of any open descriptor. -Typically, -this -descriptor is a connected socket for a stream protocol such -as -.Tn TCP . -The -.Fa sendsize -and -.Fa recvsize -arguments -indicate sizes for the send and receive buffers. -If they are -zero, a reasonable default is chosen. -.Pp -.It Xo -.Ft "SVCXPRT *" -.Xc -.It Xo -.Fn svcudp_bufcreate "int sock" "u_int sendsize" "u_int recvsize" -.Xc -.Pp -This routine creates a -.Tn UDP/IP Ns \-based -.Tn RPC -service transport, to which it returns a pointer. -The transport is associated with the socket -.Fa sock , -which may be -.Dv RPC_ANYSOCK , -in which case a new socket is created. -If the socket is not bound to a local -.Tn UDP -port, then this routine binds it to an arbitrary port. -Upon -completion, -.Fa xprt\->xp_fd -is the transport's socket descriptor, and -.Fa xprt\->xp_port -is the transport's port number. -This routine returns -.Dv NULL -if it fails. -.Pp -This allows the user to specify the maximum packet size for sending and -receiving -.Tn UDP Ns \-based -.Tn RPC -messages. -.Pp -.It Xo -.Ft bool_t -.Fn xdr_accepted_reply "XDR *xdrs" "struct accepted_reply *ar" -.Xc -.Pp -Used for encoding -.Tn RPC -reply messages. -This routine is useful for users who -wish to generate -.Tn RPC Ns \-style -messages without using the -.Tn RPC -package. -.Pp -.It Xo -.Ft bool_t -.Fn xdr_authunix_parms "XDR *xdrs" "struct authunix_parms *aupp" -.Xc -.Pp -Used for describing -.Ux -credentials. -This routine is useful for users -who wish to generate these credentials without using the -.Tn RPC -authentication package. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Ft bool_t -.Fn xdr_callhdr "XDR *xdrs" "struct rpc_msg *chdr" -.Xc -.Pp -Used for describing -.Tn RPC -call header messages. -This routine is useful for users who wish to generate -.Tn RPC Ns \-style -messages without using the -.Tn RPC -package. -.Pp -.It Xo -.Ft bool_t -.Fn xdr_callmsg "XDR *xdrs" "struct rpc_msg *cmsg" -.Xc -.Pp -Used for describing -.Tn RPC -call messages. -This routine is useful for users who wish to generate -.Tn RPC Ns \-style -messages without using the -.Tn RPC -package. -.Pp -.It Xo -.Ft bool_t -.Fn xdr_opaque_auth "XDR *xdrs" "struct opaque_auth *ap" -.Xc -.Pp -Used for describing -.Tn RPC -authentication information messages. -This routine is useful for users who wish to generate -.Tn RPC Ns \-style -messages without using the -.Tn RPC -package. -.Pp -.It Xo -.Vt struct pmap ; -.Xc -.It Xo -.Ft bool_t -.Fn xdr_pmap "XDR *xdrs" "struct pmap *regs" -.Xc -.Pp -Used for describing arguments to various -.Xr rpcbind 8 -procedures, externally. -This routine is useful for users who wish to generate -these arguments without using the -.Fn pmap_* -interface. -.Pp -.It Xo -.Ft bool_t -.Fn xdr_pmaplist "XDR *xdrs" "struct pmaplist **rp" -.Xc -.Pp -Used for describing a list of port mappings, externally. -This routine is useful for users who wish to generate -these arguments without using the -.Fn pmap_* -interface. -.Pp -.It Xo -.Ft bool_t -.Fn xdr_rejected_reply "XDR *xdrs" "struct rejected_reply *rr" -.Xc -.Pp -Used for describing -.Tn RPC -reply messages. -This routine is useful for users who wish to generate -.Tn RPC Ns \-style -messages without using the -.Tn RPC -package. -.Pp -.It Xo -.Ft bool_t -.Fn xdr_replymsg "XDR *xdrs" "struct rpc_msg *rmsg" -.Xc -.Pp -Used for describing -.Tn RPC -reply messages. -This routine is useful for users who wish to generate -.Tn RPC -style messages without using the -.Tn RPC -package. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn xprt_register "SVCXPRT *xprt" -.Xc -.Pp -After -.Tn RPC -service transport handles are created, -they should register themselves with the -.Tn RPC -service package. -This routine modifies the global variable -.Va svc_fds . -Service implementors usually do not need this routine. -.Pp -.It Xo -.Ft void -.Xc -.It Xo -.Fn xprt_unregister "SVCXPRT *xprt" -.Xc -.Pp -Before an -.Tn RPC -service transport handle is destroyed, -it should unregister itself with the -.Tn RPC -service package. -This routine modifies the global variable -.Va svc_fds . -Service implementors usually do not need this routine. -.El -.Sh SEE ALSO -.Xr rpc_secure 3 , -.Xr xdr 3 -.Rs -.%T "Remote Procedure Calls: Protocol Specification" -.Re -.Rs -.%T "Remote Procedure Call Programming Guide" -.Re -.Rs -.%T "rpcgen Programming Guide" -.Re -.Rs -.%T "RPC: Remote Procedure Call Protocol Specification" -.%O RFC1050 -.%Q "Sun Microsystems, Inc., USC-ISI" -.Re diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c deleted file mode 100644 index 2568d43..0000000 --- a/lib/libc/rpc/rpc_soc.c +++ /dev/null @@ -1,582 +0,0 @@ -/* $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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 - */ - -/* #ident "@(#)rpc_soc.c 1.17 94/04/24 SMI" */ - -/* - * Copyright (c) 1986-1991 by Sun Microsystems Inc. - * In addition, portions of such source code were derived from Berkeley - * 4.3 BSD under license from the Regents of the University of - * California. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rpc_soc.c 1.41 89/05/02 Copyr 1988 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#ifdef PORTMAP -/* - * rpc_soc.c - * - * The backward compatibility routines for the earlier implementation - * of RPC, where the only transports supported were tcp/ip and udp/ip. - * Based on berkeley socket abstraction, now implemented on the top - * of TLI/Streams - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <stdio.h> -#include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> -#include <rpc/pmap_prot.h> -#include <rpc/nettype.h> -#include <syslog.h> -#include <netinet/in.h> -#include <netdb.h> -#include <errno.h> -#include <syslog.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "un-namespace.h" - -#include "rpc_com.h" -#include "mt_misc.h" - -static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, - int *, u_int, u_int, char *); -static SVCXPRT *svc_com_create(int, u_int, u_int, char *); -static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); - -/* XXX */ -#define IN4_LOCALHOST_STRING "127.0.0.1" -#define IN6_LOCALHOST_STRING "::1" - -/* - * A common clnt create routine - */ -static CLIENT * -clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp) - struct sockaddr_in *raddr; - rpcprog_t prog; - rpcvers_t vers; - int *sockp; - u_int sendsz; - u_int recvsz; - char *tp; -{ - CLIENT *cl; - int madefd = FALSE; - int fd = *sockp; - struct netconfig *nconf; - struct netbuf bindaddr; - - mutex_lock(&rpcsoc_lock); - if ((nconf = __rpc_getconfip(tp)) == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - mutex_unlock(&rpcsoc_lock); - return (NULL); - } - if (fd == RPC_ANYSOCK) { - fd = __rpc_nconf2fd(nconf); - if (fd == -1) - goto syserror; - madefd = TRUE; - } - - if (raddr->sin_port == 0) { - u_int proto; - u_short sport; - - mutex_unlock(&rpcsoc_lock); /* pmap_getport is recursive */ - proto = strcmp(tp, "udp") == 0 ? IPPROTO_UDP : IPPROTO_TCP; - sport = pmap_getport(raddr, (u_long)prog, (u_long)vers, - proto); - if (sport == 0) { - goto err; - } - raddr->sin_port = htons(sport); - mutex_lock(&rpcsoc_lock); /* pmap_getport is recursive */ - } - - /* Transform sockaddr_in to netbuf */ - bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); - bindaddr.buf = raddr; - - bindresvport(fd, NULL); - cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, - sendsz, recvsz); - if (cl) { - if (madefd == TRUE) { - /* - * The fd should be closed while destroying the handle. - */ - (void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); - *sockp = fd; - } - (void) freenetconfigent(nconf); - mutex_unlock(&rpcsoc_lock); - return (cl); - } - goto err; - -syserror: - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - -err: if (madefd == TRUE) - (void)_close(fd); - (void) freenetconfigent(nconf); - mutex_unlock(&rpcsoc_lock); - return (NULL); -} - -CLIENT * -clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz) - struct sockaddr_in *raddr; - u_long prog; - u_long vers; - struct timeval wait; - int *sockp; - u_int sendsz; - u_int recvsz; -{ - CLIENT *cl; - - cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, - sendsz, recvsz, "udp"); - if (cl == NULL) { - return (NULL); - } - (void) CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait); - return (cl); -} - -CLIENT * -clntudp_create(raddr, program, version, wait, sockp) - struct sockaddr_in *raddr; - u_long program; - u_long version; - struct timeval wait; - int *sockp; -{ - - return clntudp_bufcreate(raddr, program, version, wait, sockp, - UDPMSGSIZE, UDPMSGSIZE); -} - -CLIENT * -clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) - struct sockaddr_in *raddr; - u_long prog; - u_long vers; - int *sockp; - u_int sendsz; - u_int recvsz; -{ - - return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, - sendsz, recvsz, "tcp"); -} - -CLIENT * -clntraw_create(prog, vers) - u_long prog; - u_long vers; -{ - - return clnt_raw_create((rpcprog_t)prog, (rpcvers_t)vers); -} - -/* - * A common server create routine - */ -static SVCXPRT * -svc_com_create(fd, sendsize, recvsize, netid) - int fd; - u_int sendsize; - u_int recvsize; - char *netid; -{ - struct netconfig *nconf; - SVCXPRT *svc; - int madefd = FALSE; - int port; - struct sockaddr_in sin; - - if ((nconf = __rpc_getconfip(netid)) == NULL) { - (void) syslog(LOG_ERR, "Could not get %s transport", netid); - return (NULL); - } - if (fd == RPC_ANYSOCK) { - fd = __rpc_nconf2fd(nconf); - if (fd == -1) { - (void) freenetconfigent(nconf); - (void) syslog(LOG_ERR, - "svc%s_create: could not open connection", netid); - return (NULL); - } - madefd = TRUE; - } - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - bindresvport(fd, &sin); - _listen(fd, SOMAXCONN); - svc = svc_tli_create(fd, nconf, NULL, sendsize, recvsize); - (void) freenetconfigent(nconf); - if (svc == NULL) { - if (madefd) - (void)_close(fd); - return (NULL); - } - port = (((struct sockaddr_in *)svc->xp_ltaddr.buf)->sin_port); - svc->xp_port = ntohs(port); - return (svc); -} - -SVCXPRT * -svctcp_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - - return svc_com_create(fd, sendsize, recvsize, "tcp"); -} - -SVCXPRT * -svcudp_bufcreate(fd, sendsz, recvsz) - int fd; - u_int sendsz, recvsz; -{ - - return svc_com_create(fd, sendsz, recvsz, "udp"); -} - -SVCXPRT * -svcfd_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - - return svc_fd_create(fd, sendsize, recvsize); -} - - -SVCXPRT * -svcudp_create(fd) - int fd; -{ - - return svc_com_create(fd, UDPMSGSIZE, UDPMSGSIZE, "udp"); -} - -SVCXPRT * -svcraw_create() -{ - - return svc_raw_create(); -} - -int -get_myaddress(addr) - struct sockaddr_in *addr; -{ - - memset((void *) addr, 0, sizeof(*addr)); - addr->sin_family = AF_INET; - addr->sin_port = htons(PMAPPORT); - addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - return (0); -} - -/* - * For connectionless "udp" transport. Obsoleted by rpc_call(). - */ -int -callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) - const char *host; - int prognum, versnum, procnum; - xdrproc_t inproc, outproc; - void *in, *out; -{ - - return (int)rpc_call(host, (rpcprog_t)prognum, (rpcvers_t)versnum, - (rpcproc_t)procnum, inproc, in, outproc, out, "udp"); -} - -/* - * For connectionless kind of transport. Obsoleted by rpc_reg() - */ -int -registerrpc(prognum, versnum, procnum, progname, inproc, outproc) - int prognum, versnum, procnum; - char *(*progname)(char [UDPMSGSIZE]); - xdrproc_t inproc, outproc; -{ - - return rpc_reg((rpcprog_t)prognum, (rpcvers_t)versnum, - (rpcproc_t)procnum, progname, inproc, outproc, "udp"); -} - -/* - * All the following clnt_broadcast stuff is convulated; it supports - * the earlier calling style of the callback function - */ -static thread_key_t clnt_broadcast_key; -static resultproc_t clnt_broadcast_result_main; -static once_t clnt_broadcast_once = ONCE_INITIALIZER; - -static void -clnt_broadcast_key_init(void) -{ - - thr_keycreate(&clnt_broadcast_key, free); -} - -/* - * Need to translate the netbuf address into sockaddr_in address. - * Dont care about netid here. - */ -/* ARGSUSED */ -static bool_t -rpc_wrap_bcast(resultp, addr, nconf) - char *resultp; /* results of the call */ - struct netbuf *addr; /* address of the guy who responded */ - struct netconfig *nconf; /* Netconf of the transport */ -{ - resultproc_t clnt_broadcast_result; - - if (strcmp(nconf->nc_netid, "udp")) - return (FALSE); - if (thr_main()) - clnt_broadcast_result = clnt_broadcast_result_main; - else - clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); - return (*clnt_broadcast_result)(resultp, - (struct sockaddr_in *)addr->buf); -} - -/* - * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). - */ -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 */ - void *argsp; /* pointer to args */ - xdrproc_t xresults; /* xdr routine for results */ - void *resultsp; /* pointer to results */ - resultproc_t eachresult; /* call with each result obtained */ -{ - - if (thr_main()) - clnt_broadcast_result_main = eachresult; - else { - thr_once(&clnt_broadcast_once, clnt_broadcast_key_init); - thr_setspecific(clnt_broadcast_key, (void *) eachresult); - } - return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, - (rpcproc_t)proc, xargs, argsp, xresults, resultsp, - (resultproc_t) rpc_wrap_bcast, "udp"); -} - -/* - * Create the client des authentication object. Obsoleted by - * authdes_seccreate(). - */ -AUTH * -authdes_create(servername, window, syncaddr, ckey) - char *servername; /* network name of server */ - u_int window; /* time to live */ - struct sockaddr *syncaddr; /* optional hostaddr to sync with */ - des_block *ckey; /* optional conversation key to use */ -{ - AUTH *dummy; - AUTH *nauth; - char hostname[NI_MAXHOST]; - - if (syncaddr) { - /* - * Change addr to hostname, because that is the way - * new interface takes it. - */ - if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, - sizeof hostname, NULL, 0, 0) != 0) - goto fallback; - - nauth = authdes_seccreate(servername, window, hostname, ckey); - return (nauth); - } -fallback: - dummy = authdes_seccreate(servername, window, NULL, ckey); - return (dummy); -} - -/* - * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() - */ -CLIENT * -clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz) - struct sockaddr_un *raddr; - u_long prog; - u_long vers; - int *sockp; - u_int sendsz; - u_int recvsz; -{ - struct netbuf *svcaddr; - struct netconfig *nconf; - CLIENT *cl; - int len; - - cl = NULL; - nconf = NULL; - svcaddr = NULL; - if ((raddr->sun_len == 0) || - ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || - ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { - if (svcaddr != NULL) - free(svcaddr); - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = errno; - return(cl); - } - if (*sockp < 0) { - *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); - len = raddr->sun_len = SUN_LEN(raddr); - 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)_close(*sockp); - goto done; - } - } - svcaddr->buf = raddr; - svcaddr->len = raddr->sun_len; - svcaddr->maxlen = sizeof (struct sockaddr_un); - cl = clnt_vc_create(*sockp, svcaddr, prog, - vers, sendsz, recvsz); -done: - free(svcaddr->buf); - free(svcaddr); - return(cl); -} - -/* - * Creates, registers, and returns a (rpc) unix based transporter. - * Obsoleted by svc_vc_create(). - */ -SVCXPRT * -svcunix_create(sock, sendsize, recvsize, path) - int sock; - u_int sendsize; - u_int recvsize; - char *path; -{ - struct netconfig *nconf; - void *localhandle; - struct sockaddr_un sun; - struct sockaddr *sa; - struct t_bind taddr; - SVCXPRT *xprt; - int addrlen; - - xprt = (SVCXPRT *)NULL; - localhandle = setnetconfig(); - while ((nconf = getnetconfig(localhandle)) != NULL) { - if (nconf->nc_protofmly != NULL && - strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) - break; - } - if (nconf == NULL) - return(xprt); - - if ((sock = __rpc_nconf2fd(nconf)) < 0) - goto done; - - memset(&sun, 0, sizeof sun); - sun.sun_family = AF_LOCAL; - if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= - sizeof(sun.sun_path)) - goto done; - sun.sun_len = SUN_LEN(&sun); - addrlen = sizeof (struct sockaddr_un); - sa = (struct sockaddr *)&sun; - - if (_bind(sock, sa, addrlen) < 0) - goto done; - - taddr.addr.len = taddr.addr.maxlen = addrlen; - taddr.addr.buf = malloc(addrlen); - if (taddr.addr.buf == NULL) - goto done; - memcpy(taddr.addr.buf, sa, addrlen); - - if (nconf->nc_semantics != NC_TPI_CLTS) { - if (_listen(sock, SOMAXCONN) < 0) { - free(taddr.addr.buf); - goto done; - } - } - - xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); - -done: - endnetconfig(localhandle); - return(xprt); -} - -/* - * Like svunix_create(), except the routine takes any *open* UNIX file - * descriptor as its first input. Obsoleted by svc_fd_create(); - */ -SVCXPRT * -svcunixfd_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - return (svc_fd_create(fd, sendsize, recvsize)); -} - -#endif /* PORTMAP */ diff --git a/lib/libc/rpc/rpc_svc_calls.3 b/lib/libc/rpc/rpc_svc_calls.3 deleted file mode 100644 index 8732962..0000000 --- a/lib/libc/rpc/rpc_svc_calls.3 +++ /dev/null @@ -1,267 +0,0 @@ -.\" @(#)rpc_svc_calls.3n 1.28 93/05/10 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_svc_calls 1.5 89/07/25 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $NetBSD: rpc_svc_calls.3,v 1.1 2000/06/02 23:11:13 fvdl Exp $ -.\" $FreeBSD$ -.Dd May 3, 1993 -.Dt RPC_SVC_CALLS 3 -.Os -.Sh NAME -.Nm svc_dg_enablecache , -.Nm svc_exit , -.Nm svc_fdset , -.Nm svc_freeargs , -.Nm svc_getargs , -.Nm svc_getreq_common , -.Nm svc_getreq_poll , -.Nm svc_getreqset , -.Nm svc_getrpccaller , -.Nm svc_pollset , -.Nm svc_run , -.Nm svc_sendreply -.Nd library routines for RPC servers -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft int -.Fn svc_dg_enablecache "SVCXPRT *xprt" "const unsigned cache_size" -.Ft void -.Fn svc_exit "void" -.Ft bool_t -.Fn svc_freeargs "const SVCXPRT *xprt" "const xdrproc_t inproc" "caddr_t in" -.Ft bool_t -.Fn svc_getargs "const SVCXPRT *xprt" "const xdrproc_t inproc" "caddr_t in" -.Ft void -.Fn svc_getreq_common "const int fd" -.Ft void -.Fn svc_getreq_poll "struct pollfd *pfdp" "const int pollretval" -.Ft void -.Fn svc_getreqset "fd_set * rdfds" -.Ft "struct netbuf *" -.Fn svc_getrpccaller "const SVCXPRT *xprt" -.Ft "struct cmsgcred *" -.Fn __svc_getcallercreds "const SVCXPRT *xprt" -.Vt struct pollfd svc_pollset[FD_SETSIZE]; -.Ft void -.Fn svc_run "void" -.Ft bool_t -.Fn svc_sendreply "SVCXPRT *xprt" "xdrproc_t outproc" "void *out" -.Sh DESCRIPTION -These routines are part of the -RPC -library which allows C language programs to make procedure -calls on other machines across the network. -.Pp -These routines are associated with the server side of the -RPC mechanism. -Some of them are called by the server side dispatch function, -while others -(such as -.Fn svc_run ) -are called when the server is initiated. -.\" .Pp -.\" In the current implementation, the service transport handle, -.\" .Dv SVCXPRT , -.\" contains a single data area for decoding arguments and encoding results. -.\" Therefore, this structure cannot be freely shared between threads that call -.\" functions that do this. -.\" Routines on this page that are affected by this -.\" restriction are marked as unsafe for MT applications. -.Sh Routines -See -.Xr rpc 3 -for the definition of the -.Vt SVCXPRT -data structure. -.Bl -tag -width __svc_getcallercreds() -.It Fn svc_dg_enablecache -This function allocates a duplicate request cache for the -service endpoint -.Fa xprt , -large enough to hold -.Fa cache_size -entries. -Once enabled, there is no way to disable caching. -This routine returns 0 if space necessary for a cache of the given size -was successfully allocated, and 1 otherwise. -.It Fn svc_exit -This function, when called by any of the RPC server procedure or -otherwise, causes -.Fn svc_run -to return. -.Pp -As currently implemented, -.Fn svc_exit -zeroes the -.Va svc_fdset -global variable. -If RPC server activity is to be resumed, -services must be reregistered with the RPC library -either through one of the -.Xr rpc_svc_create 3 -functions, or using -.Fn xprt_register . -The -.Fn svc_exit -function -has global scope and ends all RPC server activity. -.It Xo -.Vt fd_set Va svc_fdset -.Xc -A global variable reflecting the -RPC server's read file descriptor bit mask; it is suitable as an argument -to the -.Xr select 2 -system call. -This is only of interest -if service implementors do not call -.Fn svc_run , -but rather do their own asynchronous event processing. -This variable is read-only (do not pass its address to -.Xr select 2 ! ) , -yet it may change after calls to -.Fn svc_getreqset -or any creation routines. -.It Fn svc_freeargs -A function macro that frees any data allocated by the -RPC/XDR system when it decoded the arguments to a service procedure -using -.Fn svc_getargs . -This routine returns -.Dv TRUE -if the results were successfully -freed, and -.Dv FALSE -otherwise. -.It Fn svc_getargs -A function macro that decodes the arguments of an -RPC request associated with the RPC -service transport handle -.Fa xprt . -The -.Fa in -argument -is the address where the arguments will be placed; -.Fa inproc -is the XDR -routine used to decode the arguments. -This routine returns -.Dv TRUE -if decoding succeeds, and -.Dv FALSE -otherwise. -.It Fn svc_getreq_common -This routine is called to handle a request on the given -file descriptor. -.It Fn svc_getreq_poll -This routine is only of interest if a service implementor -does not call -.Fn svc_run , -but instead implements custom asynchronous event processing. -It is called when -.Xr poll 2 -has determined that an RPC request has arrived on some RPC -file descriptors; -.Fa pollretval -is the return value from -.Xr poll 2 -and -.Fa pfdp -is the array of -.Vt pollfd -structures on which the -.Xr poll 2 -was done. -It is assumed to be an array large enough to -contain the maximal number of descriptors allowed. -.It Fn svc_getreqset -This routine is only of interest if a service implementor -does not call -.Fn svc_run , -but instead implements custom asynchronous event processing. -It is called when -.Xr poll 2 -has determined that an RPC -request has arrived on some RPC file descriptors; -.Fa rdfds -is the resultant read file descriptor bit mask. -The routine returns when all file descriptors -associated with the value of -.Fa rdfds -have been serviced. -.It Fn svc_getrpccaller -The approved way of getting the network address of the caller -of a procedure associated with the -RPC service transport handle -.Fa xprt . -.It Fn __svc_getcallercreds -.Em Warning : -this macro is specific to -.Fx -and thus not portable. -This macro returns a pointer to a -.Vt cmsgcred -structure, defined in -.In sys/socket.h , -identifying the calling client. -This only works if the client is -calling the server over an -.Dv AF_LOCAL -socket. -.It Xo -.Vt struct pollfd Va svc_pollset[FD_SETSIZE] ; -.Xc -.Va svc_pollset -is an array of -.Vt pollfd -structures derived from -.Va svc_fdset[] . -It is suitable as an argument to the -.Xr poll 2 -system call. -The derivation of -.Va svc_pollset -from -.Va svc_fdset -is made in the current implementation in -.Fn svc_run . -Service implementors who do not call -.Fn svc_run -and who wish to use this array must perform this derivation themselves. -.It Fn svc_run -This routine never returns. -It waits for RPC -requests to arrive, and calls the appropriate service -procedure using -.Fn svc_getreq_poll -when one arrives. -This procedure is usually waiting for the -.Xr poll 2 -system call to return. -.It Fn svc_sendreply -Called by an RPC service's dispatch routine to send the results of a -remote procedure call. -The -.Fa xprt -argument -is the request's associated transport handle; -.Fa outproc -is the XDR -routine which is used to encode the results; and -.Fa out -is the address of the results. -This routine returns -.Dv TRUE -if it succeeds, -.Dv FALSE -otherwise. -.El -.Sh SEE ALSO -.Xr poll 2 , -.Xr select 2 , -.Xr rpc 3 , -.Xr rpc_svc_create 3 , -.Xr rpc_svc_err 3 , -.Xr rpc_svc_reg 3 diff --git a/lib/libc/rpc/rpc_svc_create.3 b/lib/libc/rpc/rpc_svc_create.3 deleted file mode 100644 index 4016a6c..0000000 --- a/lib/libc/rpc/rpc_svc_create.3 +++ /dev/null @@ -1,337 +0,0 @@ -.\" @(#)rpc_svc_create.3n 1.26 93/08/26 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_svc_create 1.3 89/06/28 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $FreeBSD$ -.Dd May 3, 1993 -.Dt RPC_SVC_CREATE 3 -.Os -.Sh NAME -.Nm rpc_svc_create , -.Nm svc_control , -.Nm svc_create , -.Nm svc_destroy , -.Nm svc_dg_create , -.Nm svc_fd_create , -.Nm svc_raw_create , -.Nm svc_tli_create , -.Nm svc_tp_create , -.Nm svc_vc_create -.Nd library routines for the creation of server handles -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft bool_t -.Fn svc_control "SVCXPRT *svc" "const u_int req" "void *info" -.Ft int -.Fn svc_create "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype" -.Ft SVCXPRT * -.Fn svc_dg_create "const int fildes" "const u_int sendsz" "const u_int recvsz" -.Ft void -.Fn svc_destroy "SVCXPRT *xprt" -.Ft "SVCXPRT *" -.Fn svc_fd_create "const int fildes" "const u_int sendsz" "const u_int recvsz" -.Ft "SVCXPRT *" -.Fn svc_raw_create "void" -.Ft "SVCXPRT *" -.Fn svc_tli_create "const int fildes" "const struct netconfig *netconf" "const struct t_bind *bindaddr" "const u_int sendsz" "const u_int recvsz" -.Ft "SVCXPRT *" -.Fn svc_tp_create "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" -.Ft "SVCXPRT *" -.Fn svc_vc_create "const int fildes" "const u_int sendsz" "const u_int recvsz" -.Sh DESCRIPTION -These routines are part of the RPC -library which allows C language programs to make procedure -calls on servers across the network. -These routines deal with the creation of service handles. -Once the handle is created, the server can be invoked by calling -.Fn svc_run . -.Sh Routines -See -.Xr rpc 3 -for the definition of the -.Vt SVCXPRT -data structure. -.Bl -tag -width XXXXX -.It Fn svc_control -A function to change or retrieve various information -about a service object. -The -.Fa req -argument -indicates the type of operation and -.Fa info -is a pointer to the information. -The supported values of -.Fa req , -their argument types, and what they do are: -.Bl -tag -width SVCGET_XID -.It Dv SVCGET_VERSQUIET -If a request is received for a program number -served by this server but the version number -is outside the range registered with the server, -an -.Dv RPC_PROGVERSMISMATCH -error will normally -be returned. -The -.Fa info -argument -should be a pointer to an -integer. -Upon successful completion of the -.Dv SVCGET_VERSQUIET -request, -.Fa *info -contains an -integer which describes the server's current -behavior: 0 indicates normal server behavior -(that is, an -.Dv RPC_PROGVERSMISMATCH -error -will be returned); 1 indicates that the out of -range request will be silently ignored. -.It Dv SVCSET_VERSQUIET -If a request is received for a program number -served by this server but the version number -is outside the range registered with the server, -an -.Dv RPC_PROGVERSMISMATCH -error will normally -be returned. -It is sometimes desirable to -change this behavior. -The -.Fa info -argument -should be a -pointer to an integer which is either 0 -(indicating normal server behavior - an -.Dv RPC_PROGVERSMISMATCH -error will be returned), -or 1 (indicating that the out of range request -should be silently ignored). -.El -.It Fn svc_create -The -.Fn svc_create -function -creates server handles for all the transports -belonging to the class -.Fa nettype . -The -.Fa nettype -argument -defines a class of transports which can be used -for a particular application. -The transports are tried in left to right order in -.Ev NETPATH -variable or in top to bottom order in the netconfig database. -If -.Fa nettype -is -.Dv NULL , -it defaults to -.Qq netpath . -.Pp -The -.Fn svc_create -function -registers itself with the rpcbind -service (see -.Xr rpcbind 8 ) . -The -.Fa dispatch -function -is called when there is a remote procedure call for the given -.Fa prognum -and -.Fa versnum ; -this requires calling -.Fn svc_run -(see -.Fn svc_run -in -.Xr rpc_svc_reg 3 ) . -If -.Fn svc_create -succeeds, it returns the number of server -handles it created, -otherwise it returns 0 and an error message is logged. -.It Fn svc_destroy -A function macro that destroys the RPC -service handle -.Fa xprt . -Destruction usually involves deallocation -of private data structures, -including -.Fa xprt -itself. -Use of -.Fa xprt -is undefined after calling this routine. -.It Fn svc_dg_create -This routine creates a connectionless RPC -service handle, and returns a pointer to it. -This routine returns -.Dv NULL -if it fails, and an error message is logged. -The -.Fa sendsz -and -.Fa recvsz -arguments -are arguments used to specify the size of the buffers. -If they are 0, suitable defaults are chosen. -The file descriptor -.Fa fildes -should be open and bound. -The server is not registered with -.Xr rpcbind 8 . -.Pp -Warning: -since connectionless-based RPC -messages can only hold limited amount of encoded data, -this transport cannot be used for procedures -that take large arguments or return huge results. -.It Fn svc_fd_create -This routine creates a service on top of an open and bound file descriptor, -and returns the handle to it. -Typically, this descriptor is a connected file descriptor for a -connection-oriented transport. -The -.Fa sendsz -and -.Fa recvsz -arguments -indicate sizes for the send and receive buffers. -If they are 0, reasonable defaults are chosen. -This routine returns -.Dv NULL -if it fails, and an error message is logged. -.It Fn svc_raw_create -This routine creates an RPC -service handle and returns a pointer to it. -The transport is really a buffer within the process's -address space, so the corresponding RPC -client should live in the same address space; -(see -.Fn clnt_raw_create -in -.Xr rpc_clnt_create 3 ) . -This routine allows simulation of RPC and acquisition of -RPC overheads (such as round trip times), -without any kernel and networking interference. -This routine returns -.Dv NULL -if it fails, and an error message is logged. -.Pp -Note: -.Fn svc_run -should not be called when the raw interface is being used. -.It Fn svc_tli_create -This routine creates an RPC -server handle, and returns a pointer to it. -The -.Fa fildes -argument -is the file descriptor on which the service is listening. -If -.Fa fildes -is -.Dv RPC_ANYFD , -it opens a file descriptor on the transport specified by -.Fa netconf . -If the file descriptor is unbound and -.Fa bindaddr -is not -.Dv NULL , -.Fa fildes -is bound to the address specified by -.Fa bindaddr , -otherwise -.Fa fildes -is bound to a default address chosen by the transport. -.Pp -Note: the -.Vt t_bind -structure comes from the TLI/XTI SysV interface, which -.Nx -does not use. -The structure is defined in -.In rpc/types.h -for compatibility as: -.Bd -literal -struct t_bind { - struct netbuf addr; /* network address, see rpc(3) */ - unsigned int qlen; /* queue length (for listen(2)) */ -}; -.Ed -.Pp -In the case where the default address is chosen, -the number of outstanding connect requests is set to 8 -for connection-oriented transports. -The user may specify the size of the send and receive buffers -with the arguments -.Fa sendsz -and -.Fa recvsz ; -values of 0 choose suitable defaults. -This routine returns -.Dv NULL -if it fails, -and an error message is logged. -The server is not registered with the -.Xr rpcbind 8 -service. -.It Fn svc_tp_create -The -.Fn svc_tp_create -function -creates a server handle for the network -specified by -.Fa netconf , -and registers itself with the rpcbind service. -The -.Fa dispatch -function -is called when there is a remote procedure call -for the given -.Fa prognum -and -.Fa versnum ; -this requires calling -.Fn svc_run . -The -.Fn svc_tp_create -function -returns the service handle if it succeeds, -otherwise a -.Dv NULL -is returned and an error message is logged. -.It Fn svc_vc_create -This routine creates a connection-oriented RPC -service and returns a pointer to it. -This routine returns -.Dv NULL -if it fails, and an error message is logged. -The users may specify the size of the send and receive buffers -with the arguments -.Fa sendsz -and -.Fa recvsz ; -values of 0 choose suitable defaults. -The file descriptor -.Fa fildes -should be open and bound. -The server is not registered with the -.Xr rpcbind 8 -service. -.El -.Sh SEE ALSO -.Xr rpc 3 , -.Xr rpc_svc_calls 3 , -.Xr rpc_svc_err 3 , -.Xr rpc_svc_reg 3 , -.Xr rpcbind 8 diff --git a/lib/libc/rpc/rpc_svc_err.3 b/lib/libc/rpc/rpc_svc_err.3 deleted file mode 100644 index 7a6b1f1..0000000 --- a/lib/libc/rpc/rpc_svc_err.3 +++ /dev/null @@ -1,97 +0,0 @@ -.\" @(#)rpc_svc_err.3n 1.23 93/08/31 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_svc_err 1.4 89/06/28 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $NetBSD: rpc_svc_err.3,v 1.1 2000/06/02 23:11:14 fvdl Exp $ -.\" $FreeBSD$ -.Dd May 3, 1993 -.Dt RPC_SVC_ERR 3 -.Os -.Sh NAME -.Nm rpc_svc_err , -.Nm svcerr_auth , -.Nm svcerr_decode , -.Nm svcerr_noproc , -.Nm svcerr_noprog , -.Nm svcerr_progvers , -.Nm svcerr_systemerr , -.Nm svcerr_weakauth -.Nd library routines for server side remote procedure call errors -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft void -.Fn svcerr_auth "SVCXPRT *xprt" "enum auth_stat why" -.Ft void -.Fn svcerr_decode "SVCXPRT *xprt" -.Ft void -.Fn svcerr_noproc "SVCXPRT *xprt" -.Ft void -.Fn svcerr_noprog "SVCXPRT *xprt" -.Ft void -.Fn svcerr_progvers "SVCXPRT *xprt" "rpcvers_t low_vers" "rpcvers_t high_vers" -.Ft void -.Fn svcerr_systemerr "SVCXPRT *xprt" -.Ft void -.Fn svcerr_weakauth "SVCXPRT *xprt" -.Sh DESCRIPTION -These routines are part of the RPC -library which allows C language programs to make procedure -calls on other machines across the network. -.Pp -These routines can be called by the server side -dispatch function if there is any error in the -transaction with the client. -.Sh Routines -See -.Xr rpc 3 -for the definition of the -.Vt SVCXPRT -data structure. -.Bl -tag -width XXXXX -.It Fn svcerr_auth -Called by a service dispatch routine that refuses to perform -a remote procedure call due to an authentication error. -.It Fn svcerr_decode -Called by a service dispatch routine that cannot successfully -decode the remote arguments -(see -.Fn svc_getargs -in -.Xr rpc_svc_reg 3 ) . -.It Fn svcerr_noproc -Called by a service dispatch routine that does not implement -the procedure number that the caller requests. -.It Fn svcerr_noprog -Called when the desired program is not registered with the -RPC package. -Service implementors usually do not need this routine. -.It Fn svcerr_progvers -Called when the desired version of a program is not registered with the -RPC package. -The -.Fa low_vers -argument -is the lowest version number, -and -.Fa high_vers -is the highest version number. -Service implementors usually do not need this routine. -.It Fn svcerr_systemerr -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. -.It Fn svcerr_weakauth -Called by a service dispatch routine that refuses to perform -a remote procedure call due to insufficient (but correct) -authentication arguments. -The routine calls -.Fn svcerr_auth "xprt" "AUTH_TOOWEAK" . -.El -.Sh SEE ALSO -.Xr rpc 3 , -.Xr rpc_svc_calls 3 , -.Xr rpc_svc_create 3 , -.Xr rpc_svc_reg 3 diff --git a/lib/libc/rpc/rpc_svc_reg.3 b/lib/libc/rpc/rpc_svc_reg.3 deleted file mode 100644 index aed2ba1..0000000 --- a/lib/libc/rpc/rpc_svc_reg.3 +++ /dev/null @@ -1,183 +0,0 @@ -.\" @(#)rpc_svc_reg.3n 1.32 93/08/31 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_svc_call 1.6 89/07/20 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $NetBSD: rpc_svc_reg.3,v 1.1 2000/06/02 23:11:14 fvdl Exp $ -.\" $FreeBSD$ -.Dd May 3, 1993 -.Dt RPC_SVC_REG 3 -.Os -.Sh NAME -.Nm rpc_svc_reg , -.Nm rpc_reg , -.Nm svc_reg , -.Nm svc_unreg , -.Nm svc_auth_reg , -.Nm xprt_register , -.Nm xprt_unregister -.Nd library routines for registering servers -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft int -.Fn rpc_reg "rpcprog_t prognum" "rpcvers_t versnum" "rpcproc_t procnum" "char *(*procname)()" "xdrproc_t inproc" "xdrproc_t outproc" "char *nettype" -.Ft bool_t -.Fn svc_reg "SVCXPRT *xprt" "const rpcprog_t prognum" "const rpcvers_t versnum" "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const struct netconfig *netconf" -.Ft void -.Fn svc_unreg "const rpcprog_t prognum" "const rpcvers_t versnum" -.Ft int -.Fn svc_auth_reg "int cred_flavor" "enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *)" -.Ft void -.Fn xprt_register "SVCXPRT *xprt" -.Ft void -.Fn xprt_unregister "SVCXPRT *xprt" -.Sh DESCRIPTION -These routines are a part of the RPC -library which allows the RPC -servers to register themselves with rpcbind -(see -.Xr rpcbind 8 ) , -and associate the given program and version -number with the dispatch function. -When the RPC server receives a RPC request, the library invokes the -dispatch routine with the appropriate arguments. -.Sh Routines -See -.Xr rpc 3 -for the definition of the -.Vt SVCXPRT -data structure. -.Bl -tag -width XXXXX -.It Fn rpc_reg -Register program -.Fa prognum , -procedure -.Fa procname , -and version -.Fa versnum -with the RPC -service package. -If a request arrives for program -.Fa prognum , -version -.Fa versnum , -and procedure -.Fa procnum , -.Fa procname -is called with a pointer to its argument(s); -.Fa procname -should return a pointer to its static result(s); -.Fa inproc -is the XDR function used to decode the arguments while -.Fa outproc -is the XDR function used to encode the results. -Procedures are registered on all available transports of the class -.Fa nettype . -See -.Xr rpc 3 . -This routine returns 0 if the registration succeeded, -\-1 otherwise. -.It Fn svc_reg -Associates -.Fa prognum -and -.Fa versnum -with the service dispatch procedure, -.Fa dispatch . -If -.Fa netconf -is -.Dv NULL , -the service is not registered with the -.Xr rpcbind 8 -service. -If -.Fa netconf -is non-zero, -then a mapping of the triple -.Bq Fa prognum , versnum , netconf->nc_netid -to -.Fa xprt->xp_ltaddr -is established with the local rpcbind -service. -.Pp -The -.Fn svc_reg -routine returns 1 if it succeeds, -and 0 otherwise. -.It Fn svc_unreg -Remove from the rpcbind -service, all mappings of the triple -.Bq Fa prognum , versnum , No all-transports -to network address -and all mappings within the RPC service package -of the double -.Bq Fa prognum , versnum -to dispatch routines. -.It Fn svc_auth_reg -Registers the service authentication routine -.Fa handler -with the dispatch mechanism so that it can be -invoked to authenticate RPC requests received -with authentication type -.Fa cred_flavor . -This interface allows developers to add new authentication -types to their RPC applications without needing to modify -the libraries. -Service implementors usually do not need this routine. -.Pp -Typical service application would call -.Fn svc_auth_reg -after registering the service and prior to calling -.Fn svc_run . -When needed to process an RPC credential of type -.Fa cred_flavor , -the -.Fa handler -procedure will be called with two arguments, -.Fa "struct svc_req *rqst" -and -.Fa "struct rpc_msg *msg" , -and is expected to return a valid -.Vt "enum auth_stat" -value. -There is no provision to change or delete an authentication handler -once registered. -.Pp -The -.Fn svc_auth_reg -routine returns 0 if the registration is successful, -1 if -.Fa cred_flavor -already has an authentication handler registered for it, -and \-1 otherwise. -.It Fn xprt_register -After RPC service transport handle -.Fa xprt -is created, it is registered with the RPC -service package. -This routine modifies the global variable -.Va svc_fdset -(see -.Xr rpc_svc_calls 3 ) . -Service implementors usually do not need this routine. -.It Fn xprt_unregister -Before an RPC service transport handle -.Fa xprt -is destroyed, it unregisters itself with the -RPC service package. -This routine modifies the global variable -.Va svc_fdset -(see -.Xr rpc_svc_calls 3 ) . -Service implementors usually do not need this routine. -.El -.Sh SEE ALSO -.Xr select 2 , -.Xr rpc 3 , -.Xr rpcbind 3 , -.Xr rpc_svc_calls 3 , -.Xr rpc_svc_create 3 , -.Xr rpc_svc_err 3 , -.Xr rpcbind 8 diff --git a/lib/libc/rpc/rpc_xdr.3 b/lib/libc/rpc/rpc_xdr.3 deleted file mode 100644 index 62754fe..0000000 --- a/lib/libc/rpc/rpc_xdr.3 +++ /dev/null @@ -1,101 +0,0 @@ -.\" @(#)rpc_xdr.3n 1.24 93/08/31 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" @(#)rpc_xdr.new 1.1 89/04/06 SMI; -.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $FreeBSD$ -.Dd May 3, 1993 -.Dt RPC_XDR 3 -.Os -.Sh NAME -.Nm xdr_accepted_reply , -.Nm xdr_authsys_parms , -.Nm xdr_callhdr , -.Nm xdr_callmsg , -.Nm xdr_opaque_auth , -.Nm xdr_rejected_reply , -.Nm xdr_replymsg -.Nd XDR library routines for remote procedure calls -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft bool_t -.Fn xdr_accepted_reply "XDR *xdrs" "struct accepted_reply *ar" -.Ft bool_t -.Fn xdr_authsys_parms "XDR *xdrs" "struct authsys_parms *aupp" -.Ft bool_t -.Fn xdr_callhdr "XDR *xdrs" "struct rpc_msg *chdr" -.Ft bool_t -.Fn xdr_callmsg "XDR *xdrs" "struct rpc_msg *cmsg" -.Ft bool_t -.Fn xdr_opaque_auth "XDR *xdrs" "struct opaque_auth *ap" -.Ft bool_t -.Fn xdr_rejected_reply "XDR *xdrs" "struct rejected_reply *rr" -.Ft bool_t -.Fn xdr_replymsg "XDR *xdrs" "struct rpc_msg *rmsg" -.Sh DESCRIPTION -These routines are used for describing the -RPC messages in XDR language. -They should normally be used by those who do not -want to use the RPC -package directly. -These routines return -.Dv TRUE -if they succeed, -.Dv FALSE -otherwise. -.Sh Routines -See -.Xr rpc 3 -for the definition of the -.Vt XDR -data structure. -.Bl -tag -width XXXXX -.It Fn xdr_accepted_reply -Used to translate between RPC -reply messages and their external representation. -It includes the status of the RPC -call in the XDR language format. -In the case of success, it also includes the call results. -.It Fn xdr_authsys_parms -Used for describing -.Ux -operating system credentials. -It includes machine-name, uid, gid list, etc. -.It Fn xdr_callhdr -Used for describing -RPC -call header messages. -It encodes the static part of the call message header in the -XDR language format. -It includes information such as transaction -ID, RPC version number, program and version number. -.It Fn xdr_callmsg -Used for describing -RPC call messages. -This includes all the RPC -call information such as transaction -ID, RPC version number, program number, version number, -authentication information, etc. -This is normally used by servers to determine information about the client -RPC call. -.It Fn xdr_opaque_auth -Used for describing RPC -opaque authentication information messages. -.It Fn xdr_rejected_reply -Used for describing RPC reply messages. -It encodes the rejected RPC message in the XDR language format. -The message could be rejected either because of version -number mis-match or because of authentication errors. -.It Fn xdr_replymsg -Used for describing RPC -reply messages. -It translates between the -RPC reply message and its external representation. -This reply could be either an acceptance, -rejection or -.Dv NULL . -.El -.Sh SEE ALSO -.Xr rpc 3 , -.Xr xdr 3 diff --git a/lib/libc/rpc/rpcb_clnt.c b/lib/libc/rpc/rpcb_clnt.c deleted file mode 100644 index afef806..0000000 --- a/lib/libc/rpc/rpcb_clnt.c +++ /dev/null @@ -1,1363 +0,0 @@ -/* $NetBSD: rpcb_clnt.c,v 1.6 2000/07/16 06:41:43 itojun Exp $ */ - -/* - * The contents of this file are subject to the Sun Standards - * License Version 1.0 the (the "License";) You may not use - * this file except in compliance with the License. You may - * obtain a copy of the License at lib/libc/rpc/LICENSE - * - * Software distributed under the License is distributed on - * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for the specific - * language governing rights and limitations under the License. - * - * The Original Code is Copyright 1998 by Sun Microsystems, Inc - * - * The Initial Developer of the Original Code is: Sun - * Microsystems, Inc. - * - * All Rights Reserved. - * - * 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 "@(#)rpcb_clnt.c 1.27 94/04/24 SMI" */ - - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rpcb_clnt.c 1.30 89/06/21 Copyr 1988 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * rpcb_clnt.c - * interface to rpcbind rpc service. - * - * Copyright (C) 1988, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/utsname.h> -#include <rpc/rpc.h> -#include <rpc/rpcb_prot.h> -#include <rpc/nettype.h> -#include <netconfig.h> -#ifdef PORTMAP -#include <netinet/in.h> /* FOR IPPROTO_TCP/UDP definitions */ -#include <rpc/pmap_prot.h> -#endif /* PORTMAP */ -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <netdb.h> -#include <syslog.h> -#include "un-namespace.h" - -#include "rpc_com.h" -#include "mt_misc.h" - -static struct timeval tottimeout = { 60, 0 }; -static const struct timeval rmttimeout = { 3, 0 }; -static struct timeval rpcbrmttime = { 15, 0 }; - -extern bool_t xdr_wrapstring(XDR *, char **); - -static const char nullstring[] = "\000"; - -#define CACHESIZE 6 - -struct address_cache { - char *ac_host; - char *ac_netid; - char *ac_uaddr; - struct netbuf *ac_taddr; - struct address_cache *ac_next; -}; - -static struct address_cache *front; -static int cachesize; - -#define CLCR_GET_RPCB_TIMEOUT 1 -#define CLCR_SET_RPCB_TIMEOUT 2 - - -extern int __rpc_lowvers; - -static struct address_cache *check_cache(const char *, const char *); -static void delete_cache(struct netbuf *); -static void add_cache(const char *, const char *, struct netbuf *, char *); -static CLIENT *getclnthandle(const char *, const struct netconfig *, char **); -static CLIENT *local_rpcb(void); -static struct netbuf *got_entry(rpcb_entry_list_ptr, const struct netconfig *); - -/* - * This routine adjusts the timeout used for calls to the remote rpcbind. - * Also, this routine can be used to set the use of portmapper version 2 - * only when doing rpc_broadcasts - * These are private routines that may not be provided in future releases. - */ -bool_t -__rpc_control(request, info) - int request; - void *info; -{ - switch (request) { - case CLCR_GET_RPCB_TIMEOUT: - *(struct timeval *)info = tottimeout; - break; - case CLCR_SET_RPCB_TIMEOUT: - tottimeout = *(struct timeval *)info; - break; - case CLCR_SET_LOWVERS: - __rpc_lowvers = *(int *)info; - break; - case CLCR_GET_LOWVERS: - *(int *)info = __rpc_lowvers; - break; - default: - return (FALSE); - } - return (TRUE); -} - -/* - * It might seem that a reader/writer lock would be more reasonable here. - * However because getclnthandle(), the only user of the cache functions, - * may do a delete_cache() operation if a check_cache() fails to return an - * address useful to clnt_tli_create(), we may as well use a mutex. - */ -/* - * As it turns out, if the cache lock is *not* a reader/writer lock, we will - * block all clnt_create's if we are trying to connect to a host that's down, - * since the lock will be held all during that time. - */ - -/* - * The routines check_cache(), add_cache(), delete_cache() manage the - * cache of rpcbind addresses for (host, netid). - */ - -static struct address_cache * -check_cache(host, netid) - const char *host, *netid; -{ - struct address_cache *cptr; - - /* READ LOCK HELD ON ENTRY: rpcbaddr_cache_lock */ - - for (cptr = front; cptr != NULL; cptr = cptr->ac_next) { - if (!strcmp(cptr->ac_host, host) && - !strcmp(cptr->ac_netid, netid)) { -#ifdef ND_DEBUG - fprintf(stderr, "Found cache entry for %s: %s\n", - host, netid); -#endif - return (cptr); - } - } - return ((struct address_cache *) NULL); -} - -static void -delete_cache(addr) - struct netbuf *addr; -{ - struct address_cache *cptr, *prevptr = NULL; - - /* WRITE LOCK HELD ON ENTRY: rpcbaddr_cache_lock */ - for (cptr = front; cptr != NULL; cptr = cptr->ac_next) { - if (!memcmp(cptr->ac_taddr->buf, addr->buf, addr->len)) { - free(cptr->ac_host); - free(cptr->ac_netid); - free(cptr->ac_taddr->buf); - free(cptr->ac_taddr); - if (cptr->ac_uaddr) - free(cptr->ac_uaddr); - if (prevptr) - prevptr->ac_next = cptr->ac_next; - else - front = cptr->ac_next; - free(cptr); - cachesize--; - break; - } - prevptr = cptr; - } -} - -static void -add_cache(host, netid, taddr, uaddr) - const char *host, *netid; - char *uaddr; - struct netbuf *taddr; -{ - struct address_cache *ad_cache, *cptr, *prevptr; - - ad_cache = (struct address_cache *) - malloc(sizeof (struct address_cache)); - if (!ad_cache) { - return; - } - ad_cache->ac_host = strdup(host); - ad_cache->ac_netid = strdup(netid); - ad_cache->ac_uaddr = uaddr ? strdup(uaddr) : NULL; - ad_cache->ac_taddr = (struct netbuf *)malloc(sizeof (struct netbuf)); - if (!ad_cache->ac_host || !ad_cache->ac_netid || !ad_cache->ac_taddr || - (uaddr && !ad_cache->ac_uaddr)) { - goto out; - } - ad_cache->ac_taddr->len = ad_cache->ac_taddr->maxlen = taddr->len; - ad_cache->ac_taddr->buf = (char *) malloc(taddr->len); - if (ad_cache->ac_taddr->buf == NULL) { -out: - if (ad_cache->ac_host) - free(ad_cache->ac_host); - if (ad_cache->ac_netid) - free(ad_cache->ac_netid); - if (ad_cache->ac_uaddr) - free(ad_cache->ac_uaddr); - if (ad_cache->ac_taddr) - free(ad_cache->ac_taddr); - free(ad_cache); - return; - } - memcpy(ad_cache->ac_taddr->buf, taddr->buf, taddr->len); -#ifdef ND_DEBUG - fprintf(stderr, "Added to cache: %s : %s\n", host, netid); -#endif - -/* VARIABLES PROTECTED BY rpcbaddr_cache_lock: cptr */ - - rwlock_wrlock(&rpcbaddr_cache_lock); - if (cachesize < CACHESIZE) { - ad_cache->ac_next = front; - front = ad_cache; - cachesize++; - } else { - /* Free the last entry */ - cptr = front; - prevptr = NULL; - while (cptr->ac_next) { - prevptr = cptr; - cptr = cptr->ac_next; - } - -#ifdef ND_DEBUG - fprintf(stderr, "Deleted from cache: %s : %s\n", - cptr->ac_host, cptr->ac_netid); -#endif - free(cptr->ac_host); - free(cptr->ac_netid); - free(cptr->ac_taddr->buf); - free(cptr->ac_taddr); - if (cptr->ac_uaddr) - free(cptr->ac_uaddr); - - if (prevptr) { - prevptr->ac_next = NULL; - ad_cache->ac_next = front; - front = ad_cache; - } else { - front = ad_cache; - ad_cache->ac_next = NULL; - } - free(cptr); - } - rwlock_unlock(&rpcbaddr_cache_lock); -} - -/* - * This routine will return a client handle that is connected to the - * rpcbind. If targaddr is non-NULL, the "universal address" of the - * host will be stored in *targaddr; the caller is responsible for - * freeing this string. - * On error, returns NULL and free's everything. - */ -static CLIENT * -getclnthandle(host, nconf, targaddr) - const char *host; - const struct netconfig *nconf; - char **targaddr; -{ - CLIENT *client; - struct netbuf *addr, taddr; - struct netbuf addr_to_delete; - struct __rpc_sockinfo si; - struct addrinfo hints, *res, *tres; - struct address_cache *ad_cache; - char *tmpaddr; - -/* VARIABLES PROTECTED BY rpcbaddr_cache_lock: ad_cache */ - - /* Get the address of the rpcbind. Check cache first */ - client = NULL; - addr_to_delete.len = 0; - rwlock_rdlock(&rpcbaddr_cache_lock); - ad_cache = NULL; - if (host != NULL) - ad_cache = check_cache(host, nconf->nc_netid); - if (ad_cache != NULL) { - addr = ad_cache->ac_taddr; - client = clnt_tli_create(RPC_ANYFD, nconf, addr, - (rpcprog_t)RPCBPROG, (rpcvers_t)RPCBVERS4, 0, 0); - if (client != NULL) { - if (targaddr) - *targaddr = strdup(ad_cache->ac_uaddr); - rwlock_unlock(&rpcbaddr_cache_lock); - return (client); - } - addr_to_delete.len = addr->len; - addr_to_delete.buf = (char *)malloc(addr->len); - if (addr_to_delete.buf == NULL) { - addr_to_delete.len = 0; - } else { - memcpy(addr_to_delete.buf, addr->buf, addr->len); - } - } - rwlock_unlock(&rpcbaddr_cache_lock); - if (addr_to_delete.len != 0) { - /* - * Assume this may be due to cache data being - * outdated - */ - rwlock_wrlock(&rpcbaddr_cache_lock); - delete_cache(&addr_to_delete); - rwlock_unlock(&rpcbaddr_cache_lock); - free(addr_to_delete.buf); - } - if (!__rpc_nconf2sockinfo(nconf, &si)) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return NULL; - } - - memset(&hints, 0, sizeof hints); - hints.ai_family = si.si_af; - hints.ai_socktype = si.si_socktype; - hints.ai_protocol = si.si_proto; - -#ifdef CLNT_DEBUG - printf("trying netid %s family %d proto %d socktype %d\n", - nconf->nc_netid, si.si_af, si.si_proto, si.si_socktype); -#endif - - if (nconf->nc_protofmly != NULL && strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { - client = local_rpcb(); - if (! client) { -#ifdef ND_DEBUG - clnt_pcreateerror("rpcbind clnt interface"); -#endif - return (NULL); - } else { - struct sockaddr_un sun; - if (targaddr) { - *targaddr = malloc(sizeof(sun.sun_path)); - if (*targaddr == NULL) { - CLNT_DESTROY(client); - return (NULL); - } - strncpy(*targaddr, _PATH_RPCBINDSOCK, - sizeof(sun.sun_path)); - } - return (client); - } - } else { - if (getaddrinfo(host, "sunrpc", &hints, &res) != 0) { - rpc_createerr.cf_stat = RPC_UNKNOWNHOST; - return NULL; - } - } - - for (tres = res; tres != NULL; tres = tres->ai_next) { - taddr.buf = tres->ai_addr; - taddr.len = taddr.maxlen = tres->ai_addrlen; - -#ifdef ND_DEBUG - { - char *ua; - - ua = taddr2uaddr(nconf, &taddr); - fprintf(stderr, "Got it [%s]\n", ua); - free(ua); - } -#endif - -#ifdef ND_DEBUG - { - int i; - - fprintf(stderr, "\tnetbuf len = %d, maxlen = %d\n", - taddr.len, taddr.maxlen); - fprintf(stderr, "\tAddress is "); - for (i = 0; i < taddr.len; i++) - fprintf(stderr, "%u.", ((char *)(taddr.buf))[i]); - fprintf(stderr, "\n"); - } -#endif - client = clnt_tli_create(RPC_ANYFD, nconf, &taddr, - (rpcprog_t)RPCBPROG, (rpcvers_t)RPCBVERS4, 0, 0); -#ifdef ND_DEBUG - if (! client) { - clnt_pcreateerror("rpcbind clnt interface"); - } -#endif - - if (client) { - tmpaddr = targaddr ? taddr2uaddr(nconf, &taddr) : NULL; - add_cache(host, nconf->nc_netid, &taddr, tmpaddr); - if (targaddr) - *targaddr = tmpaddr; - break; - } - } - if (res) - freeaddrinfo(res); - return (client); -} - -/* XXX */ -#define IN4_LOCALHOST_STRING "127.0.0.1" -#define IN6_LOCALHOST_STRING "::1" - -/* - * This routine will return a client handle that is connected to the local - * rpcbind. Returns NULL on error and free's everything. - */ -static CLIENT * -local_rpcb() -{ - CLIENT *client; - static struct netconfig *loopnconf; - static char *hostname; - int sock; - size_t tsize; - struct netbuf nbuf; - struct sockaddr_un sun; - - /* - * Try connecting to the local rpcbind through a local socket - * first. If this doesn't work, try all transports defined in - * the netconfig file. - */ - memset(&sun, 0, sizeof sun); - sock = _socket(AF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) - goto try_nconf; - sun.sun_family = AF_LOCAL; - strcpy(sun.sun_path, _PATH_RPCBINDSOCK); - nbuf.len = sun.sun_len = SUN_LEN(&sun); - nbuf.maxlen = sizeof (struct sockaddr_un); - nbuf.buf = &sun; - - tsize = __rpc_get_t_size(AF_LOCAL, 0, 0); - client = clnt_vc_create(sock, &nbuf, (rpcprog_t)RPCBPROG, - (rpcvers_t)RPCBVERS, tsize, tsize); - - if (client != NULL) { - /* Mark the socket to be closed in destructor */ - (void) CLNT_CONTROL(client, CLSET_FD_CLOSE, NULL); - return client; - } - - /* Nobody needs this socket anymore; free the descriptor. */ - _close(sock); - -try_nconf: - -/* VARIABLES PROTECTED BY loopnconf_lock: loopnconf */ - mutex_lock(&loopnconf_lock); - if (loopnconf == NULL) { - struct netconfig *nconf, *tmpnconf = NULL; - void *nc_handle; - int fd; - - nc_handle = setnetconfig(); - if (nc_handle == NULL) { - /* fails to open netconfig file */ - syslog (LOG_ERR, "rpc: failed to open " NETCONFIG); - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - mutex_unlock(&loopnconf_lock); - return (NULL); - } - while ((nconf = getnetconfig(nc_handle)) != NULL) { -#ifdef INET6 - if ((strcmp(nconf->nc_protofmly, NC_INET6) == 0 || -#else - if (( -#endif - strcmp(nconf->nc_protofmly, NC_INET) == 0) && - (nconf->nc_semantics == NC_TPI_COTS || - nconf->nc_semantics == NC_TPI_COTS_ORD)) { - fd = __rpc_nconf2fd(nconf); - /* - * Can't create a socket, assume that - * this family isn't configured in the kernel. - */ - if (fd < 0) - continue; - _close(fd); - tmpnconf = nconf; - if (!strcmp(nconf->nc_protofmly, NC_INET)) - hostname = IN4_LOCALHOST_STRING; - else - hostname = IN6_LOCALHOST_STRING; - } - } - if (tmpnconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - mutex_unlock(&loopnconf_lock); - return (NULL); - } - loopnconf = getnetconfigent(tmpnconf->nc_netid); - /* loopnconf is never freed */ - endnetconfig(nc_handle); - } - mutex_unlock(&loopnconf_lock); - client = getclnthandle(hostname, loopnconf, NULL); - return (client); -} - -/* - * Set a mapping between program, version and address. - * Calls the rpcbind service to do the mapping. - */ -bool_t -rpcb_set(program, version, nconf, address) - rpcprog_t program; - rpcvers_t version; - const struct netconfig *nconf; /* Network structure of transport */ - const struct netbuf *address; /* Services netconfig address */ -{ - CLIENT *client; - bool_t rslt = FALSE; - RPCB parms; - char uidbuf[32]; - - /* parameter checking */ - if (nconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (FALSE); - } - if (address == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNADDR; - return (FALSE); - } - client = local_rpcb(); - if (! client) { - return (FALSE); - } - - /* convert to universal */ - /*LINTED const castaway*/ - parms.r_addr = taddr2uaddr((struct netconfig *) nconf, - (struct netbuf *)address); - if (!parms.r_addr) { - CLNT_DESTROY(client); - rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; - return (FALSE); /* no universal address */ - } - parms.r_prog = program; - parms.r_vers = version; - parms.r_netid = nconf->nc_netid; - /* - * Though uid is not being used directly, we still send it for - * completeness. For non-unix platforms, perhaps some other - * string or an empty string can be sent. - */ - (void) snprintf(uidbuf, sizeof uidbuf, "%d", geteuid()); - parms.r_owner = uidbuf; - - CLNT_CALL(client, (rpcproc_t)RPCBPROC_SET, (xdrproc_t) xdr_rpcb, - (char *)(void *)&parms, (xdrproc_t) xdr_bool, - (char *)(void *)&rslt, tottimeout); - - CLNT_DESTROY(client); - free(parms.r_addr); - return (rslt); -} - -/* - * Remove the mapping between program, version and netbuf address. - * Calls the rpcbind service to do the un-mapping. - * If netbuf is NULL, unset for all the transports, otherwise unset - * only for the given transport. - */ -bool_t -rpcb_unset(program, version, nconf) - rpcprog_t program; - rpcvers_t version; - const struct netconfig *nconf; -{ - CLIENT *client; - bool_t rslt = FALSE; - RPCB parms; - char uidbuf[32]; - - client = local_rpcb(); - if (! client) { - return (FALSE); - } - - parms.r_prog = program; - parms.r_vers = version; - if (nconf) - parms.r_netid = nconf->nc_netid; - else { - /*LINTED const castaway*/ - parms.r_netid = (char *) &nullstring[0]; /* unsets all */ - } - /*LINTED const castaway*/ - parms.r_addr = (char *) &nullstring[0]; - (void) snprintf(uidbuf, sizeof uidbuf, "%d", geteuid()); - parms.r_owner = uidbuf; - - CLNT_CALL(client, (rpcproc_t)RPCBPROC_UNSET, (xdrproc_t) xdr_rpcb, - (char *)(void *)&parms, (xdrproc_t) xdr_bool, - (char *)(void *)&rslt, tottimeout); - - CLNT_DESTROY(client); - return (rslt); -} - -/* - * From the merged list, find the appropriate entry - */ -static struct netbuf * -got_entry(relp, nconf) - rpcb_entry_list_ptr relp; - const struct netconfig *nconf; -{ - struct netbuf *na = NULL; - rpcb_entry_list_ptr sp; - rpcb_entry *rmap; - - for (sp = relp; sp != NULL; sp = sp->rpcb_entry_next) { - rmap = &sp->rpcb_entry_map; - if ((strcmp(nconf->nc_proto, rmap->r_nc_proto) == 0) && - (strcmp(nconf->nc_protofmly, rmap->r_nc_protofmly) == 0) && - (nconf->nc_semantics == rmap->r_nc_semantics) && - (rmap->r_maddr != NULL) && (rmap->r_maddr[0] != 0)) { - na = uaddr2taddr(nconf, rmap->r_maddr); -#ifdef ND_DEBUG - fprintf(stderr, "\tRemote address is [%s].\n", - rmap->r_maddr); - if (!na) - fprintf(stderr, - "\tCouldn't resolve remote address!\n"); -#endif - break; - } - } - return (na); -} - -/* - * Quick check to see if rpcbind is up. Tries to connect over - * local transport. - */ -static bool_t -__rpcbind_is_up() -{ - struct netconfig *nconf; - struct sockaddr_un sun; - void *localhandle; - int sock; - - nconf = NULL; - localhandle = setnetconfig(); - while ((nconf = getnetconfig(localhandle)) != NULL) { - if (nconf->nc_protofmly != NULL && - strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) - break; - } - if (nconf == NULL) - return (FALSE); - - endnetconfig(localhandle); - - memset(&sun, 0, sizeof sun); - sock = _socket(AF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) - return (FALSE); - sun.sun_family = AF_LOCAL; - strncpy(sun.sun_path, _PATH_RPCBINDSOCK, sizeof(sun.sun_path)); - sun.sun_len = SUN_LEN(&sun); - - if (_connect(sock, (struct sockaddr *)&sun, sun.sun_len) < 0) { - _close(sock); - return (FALSE); - } - - _close(sock); - return (TRUE); -} - -/* - * An internal function which optimizes rpcb_getaddr function. It also - * returns the client handle that it uses to contact the remote rpcbind. - * - * The algorithm used: If the transports is TCP or UDP, it first tries - * version 2 (portmap), 4 and then 3 (svr4). This order should be - * changed in the next OS release to 4, 2 and 3. We are assuming that by - * that time, version 4 would be available on many machines on the network. - * With this algorithm, we get performance as well as a plan for - * obsoleting version 2. - * - * For all other transports, the algorithm remains as 4 and then 3. - * - * XXX: Due to some problems with t_connect(), we do not reuse the same client - * handle for COTS cases and hence in these cases we do not return the - * client handle. This code will change if t_connect() ever - * starts working properly. Also look under clnt_vc.c. - */ -struct netbuf * -__rpcb_findaddr_timed(program, version, nconf, host, clpp, tp) - rpcprog_t program; - rpcvers_t version; - const struct netconfig *nconf; - const char *host; - CLIENT **clpp; - struct timeval *tp; -{ - static bool_t check_rpcbind = TRUE; - CLIENT *client = NULL; - RPCB parms; - enum clnt_stat clnt_st; - char *ua = NULL; - rpcvers_t vers; - struct netbuf *address = NULL; - rpcvers_t start_vers = RPCBVERS4; - struct netbuf servaddr; - - /* parameter checking */ - if (nconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - - parms.r_addr = NULL; - - /* - * Use default total timeout if no timeout is specified. - */ - if (tp == NULL) - tp = &tottimeout; - -#ifdef PORTMAP - /* Try version 2 for TCP or UDP */ - if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { - u_short port = 0; - struct netbuf remote; - rpcvers_t pmapvers = 2; - struct pmap pmapparms; - - /* - * Try UDP only - there are some portmappers out - * there that use UDP only. - */ - if (strcmp(nconf->nc_proto, NC_TCP) == 0) { - struct netconfig *newnconf; - - if ((newnconf = getnetconfigent("udp")) == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - client = getclnthandle(host, newnconf, &parms.r_addr); - freenetconfigent(newnconf); - } else { - client = getclnthandle(host, nconf, &parms.r_addr); - } - if (client == NULL) - return (NULL); - - /* - * Set version and retry timeout. - */ - CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime); - CLNT_CONTROL(client, CLSET_VERS, (char *)&pmapvers); - - pmapparms.pm_prog = program; - pmapparms.pm_vers = version; - pmapparms.pm_prot = strcmp(nconf->nc_proto, NC_TCP) ? - IPPROTO_UDP : IPPROTO_TCP; - pmapparms.pm_port = 0; /* not needed */ - clnt_st = CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT, - (xdrproc_t) xdr_pmap, (caddr_t)(void *)&pmapparms, - (xdrproc_t) xdr_u_short, (caddr_t)(void *)&port, - *tp); - if (clnt_st != RPC_SUCCESS) { - if ((clnt_st == RPC_PROGVERSMISMATCH) || - (clnt_st == RPC_PROGUNAVAIL)) - goto try_rpcbind; /* Try different versions */ - rpc_createerr.cf_stat = RPC_PMAPFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - goto error; - } else if (port == 0) { - address = NULL; - rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - goto error; - } - port = htons(port); - CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote); - if (((address = (struct netbuf *) - malloc(sizeof (struct netbuf))) == NULL) || - ((address->buf = (char *) - malloc(remote.len)) == NULL)) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - clnt_geterr(client, &rpc_createerr.cf_error); - if (address) { - free(address); - address = NULL; - } - goto error; - } - memcpy(address->buf, remote.buf, remote.len); - memcpy(&((char *)address->buf)[sizeof (short)], - (char *)(void *)&port, sizeof (short)); - address->len = address->maxlen = remote.len; - goto done; - } -#endif /* PORTMAP */ - -try_rpcbind: - /* - * Check if rpcbind is up. This prevents needless delays when - * accessing applications such as the keyserver while booting - * disklessly. - */ - if (check_rpcbind && strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { - if (!__rpcbind_is_up()) { - rpc_createerr.cf_stat = RPC_PMAPFAILURE; - rpc_createerr.cf_error.re_errno = 0; - goto error; - } - check_rpcbind = FALSE; - } - - /* - * Now we try version 4 and then 3. - * We also send the remote system the address we used to - * contact it in case it can help to connect back with us - */ - parms.r_prog = program; - parms.r_vers = version; - /*LINTED const castaway*/ - parms.r_owner = (char *) &nullstring[0]; /* not needed; */ - /* just for xdring */ - parms.r_netid = nconf->nc_netid; /* not really needed */ - - /* - * If a COTS transport is being used, try getting address via CLTS - * transport. This works only with version 4. - */ - if (nconf->nc_semantics == NC_TPI_COTS_ORD || - nconf->nc_semantics == NC_TPI_COTS) { - - void *handle; - struct netconfig *nconf_clts; - rpcb_entry_list_ptr relp = NULL; - - if (client == NULL) { - /* This did not go through the above PORTMAP/TCP code */ - if ((handle = __rpc_setconf("datagram_v")) != NULL) { - while ((nconf_clts = __rpc_getconf(handle)) - != NULL) { - if (strcmp(nconf_clts->nc_protofmly, - nconf->nc_protofmly) != 0) { - continue; - } - client = getclnthandle(host, nconf_clts, - &parms.r_addr); - break; - } - __rpc_endconf(handle); - } - if (client == NULL) - goto regular_rpcbind; /* Go the regular way */ - } else { - /* This is a UDP PORTMAP handle. Change to version 4 */ - vers = RPCBVERS4; - CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&vers); - } - /* - * We also send the remote system the address we used to - * contact it in case it can help it connect back with us - */ - if (parms.r_addr == NULL) { - /*LINTED const castaway*/ - parms.r_addr = (char *) &nullstring[0]; /* for XDRing */ - } - - CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime); - - clnt_st = CLNT_CALL(client, (rpcproc_t)RPCBPROC_GETADDRLIST, - (xdrproc_t) xdr_rpcb, (char *)(void *)&parms, - (xdrproc_t) xdr_rpcb_entry_list_ptr, - (char *)(void *)&relp, *tp); - if (clnt_st == RPC_SUCCESS) { - if ((address = got_entry(relp, nconf)) != NULL) { - xdr_free((xdrproc_t) xdr_rpcb_entry_list_ptr, - (char *)(void *)&relp); - CLNT_CONTROL(client, CLGET_SVC_ADDR, - (char *)(void *)&servaddr); - __rpc_fixup_addr(address, &servaddr); - goto done; - } - /* Entry not found for this transport */ - xdr_free((xdrproc_t) xdr_rpcb_entry_list_ptr, - (char *)(void *)&relp); - /* - * XXX: should have perhaps returned with error but - * since the remote machine might not always be able - * to send the address on all transports, we try the - * regular way with regular_rpcbind - */ - goto regular_rpcbind; - } else if ((clnt_st == RPC_PROGVERSMISMATCH) || - (clnt_st == RPC_PROGUNAVAIL)) { - start_vers = RPCBVERS; /* Try version 3 now */ - goto regular_rpcbind; /* Try different versions */ - } else { - rpc_createerr.cf_stat = RPC_PMAPFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - goto error; - } - } - -regular_rpcbind: - - /* Now the same transport is to be used to get the address */ - if (client && ((nconf->nc_semantics == NC_TPI_COTS_ORD) || - (nconf->nc_semantics == NC_TPI_COTS))) { - /* A CLTS type of client - destroy it */ - CLNT_DESTROY(client); - client = NULL; - } - - if (client == NULL) { - client = getclnthandle(host, nconf, &parms.r_addr); - if (client == NULL) { - goto error; - } - } - if (parms.r_addr == NULL) { - /*LINTED const castaway*/ - parms.r_addr = (char *) &nullstring[0]; - } - - /* First try from start_vers and then version 3 (RPCBVERS) */ - - CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *) &rpcbrmttime); - for (vers = start_vers; vers >= RPCBVERS; vers--) { - /* Set the version */ - CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&vers); - clnt_st = CLNT_CALL(client, (rpcproc_t)RPCBPROC_GETADDR, - (xdrproc_t) xdr_rpcb, (char *)(void *)&parms, - (xdrproc_t) xdr_wrapstring, (char *)(void *) &ua, *tp); - if (clnt_st == RPC_SUCCESS) { - if ((ua == NULL) || (ua[0] == 0)) { - /* address unknown */ - rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - goto error; - } - address = uaddr2taddr(nconf, ua); -#ifdef ND_DEBUG - fprintf(stderr, "\tRemote address is [%s]\n", ua); - if (!address) - fprintf(stderr, - "\tCouldn't resolve remote address!\n"); -#endif - xdr_free((xdrproc_t)xdr_wrapstring, - (char *)(void *)&ua); - - if (! address) { - /* We don't know about your universal address */ - rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; - goto error; - } - CLNT_CONTROL(client, CLGET_SVC_ADDR, - (char *)(void *)&servaddr); - __rpc_fixup_addr(address, &servaddr); - goto done; - } else if (clnt_st == RPC_PROGVERSMISMATCH) { - struct rpc_err rpcerr; - - clnt_geterr(client, &rpcerr); - if (rpcerr.re_vers.low > RPCBVERS4) - goto error; /* a new version, can't handle */ - } else if (clnt_st != RPC_PROGUNAVAIL) { - /* Cant handle this error */ - rpc_createerr.cf_stat = clnt_st; - clnt_geterr(client, &rpc_createerr.cf_error); - goto error; - } - } - -error: - if (client) { - CLNT_DESTROY(client); - client = NULL; - } -done: - if (nconf->nc_semantics != NC_TPI_CLTS) { - /* This client is the connectionless one */ - if (client) { - CLNT_DESTROY(client); - client = NULL; - } - } - if (clpp) { - *clpp = client; - } else if (client) { - CLNT_DESTROY(client); - } - if (parms.r_addr != NULL && parms.r_addr != nullstring) - free(parms.r_addr); - return (address); -} - - -/* - * Find the mapped address for program, version. - * Calls the rpcbind service remotely to do the lookup. - * Uses the transport specified in nconf. - * Returns FALSE (0) if no map exists, else returns 1. - * - * Assuming that the address is all properly allocated - */ -int -rpcb_getaddr(program, version, nconf, address, host) - rpcprog_t program; - rpcvers_t version; - const struct netconfig *nconf; - struct netbuf *address; - const char *host; -{ - struct netbuf *na; - - if ((na = __rpcb_findaddr_timed(program, version, - (struct netconfig *) nconf, (char *) host, - (CLIENT **) NULL, (struct timeval *) NULL)) == NULL) - return (FALSE); - - if (na->len > address->maxlen) { - /* Too long address */ - free(na->buf); - free(na); - rpc_createerr.cf_stat = RPC_FAILED; - return (FALSE); - } - memcpy(address->buf, na->buf, (size_t)na->len); - address->len = na->len; - free(na->buf); - free(na); - return (TRUE); -} - -/* - * Get a copy of the current maps. - * Calls the rpcbind service remotely to get the maps. - * - * It returns only a list of the services - * It returns NULL on failure. - */ -rpcblist * -rpcb_getmaps(nconf, host) - const struct netconfig *nconf; - const char *host; -{ - rpcblist_ptr head = NULL; - CLIENT *client; - enum clnt_stat clnt_st; - rpcvers_t vers = 0; - - client = getclnthandle(host, nconf, NULL); - if (client == NULL) { - return (head); - } - clnt_st = CLNT_CALL(client, (rpcproc_t)RPCBPROC_DUMP, - (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_rpcblist_ptr, - (char *)(void *)&head, tottimeout); - if (clnt_st == RPC_SUCCESS) - goto done; - - if ((clnt_st != RPC_PROGVERSMISMATCH) && - (clnt_st != RPC_PROGUNAVAIL)) { - rpc_createerr.cf_stat = RPC_RPCBFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - goto done; - } - - /* fall back to earlier version */ - CLNT_CONTROL(client, CLGET_VERS, (char *)(void *)&vers); - if (vers == RPCBVERS4) { - vers = RPCBVERS; - CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&vers); - if (CLNT_CALL(client, (rpcproc_t)RPCBPROC_DUMP, - (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_rpcblist_ptr, - (char *)(void *)&head, tottimeout) == RPC_SUCCESS) - goto done; - } - rpc_createerr.cf_stat = RPC_RPCBFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - -done: - CLNT_DESTROY(client); - return (head); -} - -/* - * rpcbinder remote-call-service interface. - * This routine is used to call the rpcbind remote call service - * which will look up a service program in the address 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 -rpcb_rmtcall(nconf, host, prog, vers, proc, xdrargs, argsp, - xdrres, resp, tout, addr_ptr) - const struct netconfig *nconf; /* Netconfig structure */ - const char *host; /* Remote host name */ - rpcprog_t prog; - rpcvers_t vers; - rpcproc_t proc; /* Remote proc identifiers */ - xdrproc_t xdrargs, xdrres; /* XDR routines */ - caddr_t argsp, resp; /* Argument and Result */ - struct timeval tout; /* Timeout value for this call */ - const struct netbuf *addr_ptr; /* Preallocated netbuf address */ -{ - CLIENT *client; - enum clnt_stat stat; - struct r_rpcb_rmtcallargs a; - struct r_rpcb_rmtcallres r; - rpcvers_t rpcb_vers; - - stat = 0; - client = getclnthandle(host, nconf, NULL); - if (client == NULL) { - return (RPC_FAILED); - } - /*LINTED const castaway*/ - CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)(void *)&rmttimeout); - a.prog = prog; - a.vers = vers; - a.proc = proc; - a.args.args_val = argsp; - a.xdr_args = xdrargs; - r.addr = NULL; - r.results.results_val = resp; - r.xdr_res = xdrres; - - for (rpcb_vers = RPCBVERS4; rpcb_vers >= RPCBVERS; rpcb_vers--) { - CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&rpcb_vers); - stat = CLNT_CALL(client, (rpcproc_t)RPCBPROC_CALLIT, - (xdrproc_t) xdr_rpcb_rmtcallargs, (char *)(void *)&a, - (xdrproc_t) xdr_rpcb_rmtcallres, (char *)(void *)&r, tout); - if ((stat == RPC_SUCCESS) && (addr_ptr != NULL)) { - struct netbuf *na; - /*LINTED const castaway*/ - na = uaddr2taddr((struct netconfig *) nconf, r.addr); - if (!na) { - stat = RPC_N2AXLATEFAILURE; - /*LINTED const castaway*/ - ((struct netbuf *) addr_ptr)->len = 0; - goto error; - } - if (na->len > addr_ptr->maxlen) { - /* Too long address */ - stat = RPC_FAILED; /* XXX A better error no */ - free(na->buf); - free(na); - /*LINTED const castaway*/ - ((struct netbuf *) addr_ptr)->len = 0; - goto error; - } - memcpy(addr_ptr->buf, na->buf, (size_t)na->len); - /*LINTED const castaway*/ - ((struct netbuf *)addr_ptr)->len = na->len; - free(na->buf); - free(na); - break; - } else if ((stat != RPC_PROGVERSMISMATCH) && - (stat != RPC_PROGUNAVAIL)) { - goto error; - } - } -error: - CLNT_DESTROY(client); - if (r.addr) - xdr_free((xdrproc_t) xdr_wrapstring, (char *)(void *)&r.addr); - return (stat); -} - -/* - * Gets the time on the remote host. - * Returns 1 if succeeds else 0. - */ -bool_t -rpcb_gettime(host, timep) - const char *host; - time_t *timep; -{ - CLIENT *client = NULL; - void *handle; - struct netconfig *nconf; - rpcvers_t vers; - enum clnt_stat st; - - - if ((host == NULL) || (host[0] == 0)) { - time(timep); - return (TRUE); - } - - if ((handle = __rpc_setconf("netpath")) == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (FALSE); - } - rpc_createerr.cf_stat = RPC_SUCCESS; - while (client == NULL) { - if ((nconf = __rpc_getconf(handle)) == NULL) { - if (rpc_createerr.cf_stat == RPC_SUCCESS) - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - break; - } - client = getclnthandle(host, nconf, NULL); - if (client) - break; - } - __rpc_endconf(handle); - if (client == (CLIENT *) NULL) { - return (FALSE); - } - - st = CLNT_CALL(client, (rpcproc_t)RPCBPROC_GETTIME, - (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_int, (char *)(void *)timep, tottimeout); - - if ((st == RPC_PROGVERSMISMATCH) || (st == RPC_PROGUNAVAIL)) { - CLNT_CONTROL(client, CLGET_VERS, (char *)(void *)&vers); - if (vers == RPCBVERS4) { - /* fall back to earlier version */ - vers = RPCBVERS; - CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&vers); - st = CLNT_CALL(client, (rpcproc_t)RPCBPROC_GETTIME, - (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_int, (char *)(void *)timep, - tottimeout); - } - } - CLNT_DESTROY(client); - return (st == RPC_SUCCESS? TRUE: FALSE); -} - -/* - * Converts taddr to universal address. This routine should never - * really be called because local n2a libraries are always provided. - */ -char * -rpcb_taddr2uaddr(nconf, taddr) - struct netconfig *nconf; - struct netbuf *taddr; -{ - CLIENT *client; - char *uaddr = NULL; - - - /* parameter checking */ - if (nconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - if (taddr == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNADDR; - return (NULL); - } - client = local_rpcb(); - if (! client) { - return (NULL); - } - - CLNT_CALL(client, (rpcproc_t)RPCBPROC_TADDR2UADDR, - (xdrproc_t) xdr_netbuf, (char *)(void *)taddr, - (xdrproc_t) xdr_wrapstring, (char *)(void *)&uaddr, tottimeout); - CLNT_DESTROY(client); - return (uaddr); -} - -/* - * Converts universal address to netbuf. This routine should never - * really be called because local n2a libraries are always provided. - */ -struct netbuf * -rpcb_uaddr2taddr(nconf, uaddr) - struct netconfig *nconf; - char *uaddr; -{ - CLIENT *client; - struct netbuf *taddr; - - - /* parameter checking */ - if (nconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - return (NULL); - } - if (uaddr == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNADDR; - return (NULL); - } - client = local_rpcb(); - if (! client) { - return (NULL); - } - - taddr = (struct netbuf *)calloc(1, sizeof (struct netbuf)); - if (taddr == NULL) { - CLNT_DESTROY(client); - return (NULL); - } - if (CLNT_CALL(client, (rpcproc_t)RPCBPROC_UADDR2TADDR, - (xdrproc_t) xdr_wrapstring, (char *)(void *)&uaddr, - (xdrproc_t) xdr_netbuf, (char *)(void *)taddr, - tottimeout) != RPC_SUCCESS) { - free(taddr); - taddr = NULL; - } - CLNT_DESTROY(client); - return (taddr); -} diff --git a/lib/libc/rpc/rpcb_prot.c b/lib/libc/rpc/rpcb_prot.c deleted file mode 100644 index f766749..0000000 --- a/lib/libc/rpc/rpcb_prot.c +++ /dev/null @@ -1,332 +0,0 @@ -/* $NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ - -/* - * 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 "@(#)rpcb_prot.c 1.13 94/04/24 SMI" */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * rpcb_prot.c - * XDR routines for the rpcbinder version 3. - * - * Copyright (C) 1984, 1988, Sun Microsystems, Inc. - */ - -#include "namespace.h" -#include <rpc/rpc.h> -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/rpcb_prot.h> -#include "un-namespace.h" - -bool_t -xdr_rpcb(xdrs, objp) - XDR *xdrs; - RPCB *objp; -{ - if (!xdr_u_int32_t(xdrs, &objp->r_prog)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->r_vers)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->r_netid, (u_int)~0)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->r_addr, (u_int)~0)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->r_owner, (u_int)~0)) { - return (FALSE); - } - return (TRUE); -} - -/* - * rpcblist_ptr implements a linked list. The RPCL definition from - * rpcb_prot.x is: - * - * struct rpcblist { - * rpcb rpcb_map; - * struct rpcblist *rpcb_next; - * }; - * typedef rpcblist *rpcblist_ptr; - * - * Recall that "pointers" in XDR are encoded as a boolean, indicating whether - * there's any data behind the pointer, followed by the data (if any exists). - * The boolean can be interpreted as ``more data follows me''; if FALSE then - * nothing follows the boolean; if TRUE then the boolean is followed by an - * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct - * rpcblist *"). - * - * This could be implemented via the xdr_pointer type, though this would - * result in one recursive call per element in the list. Rather than do that - * we can ``unwind'' the recursion into a while loop and use xdr_reference to - * serialize the rpcb elements. - */ - -bool_t -xdr_rpcblist_ptr(xdrs, rp) - XDR *xdrs; - rpcblist_ptr *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; - int freeing = (xdrs->x_op == XDR_FREE); - rpcblist_ptr next; - rpcblist_ptr next_copy; - - next = NULL; - for (;;) { - 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 && *rp) - next = (*rp)->rpcb_next; - if (! xdr_reference(xdrs, (caddr_t *)rp, - (u_int)sizeof (rpcblist), (xdrproc_t)xdr_rpcb)) { - return (FALSE); - } - if (freeing) { - next_copy = next; - rp = &next_copy; - /* - * Note that in the subsequent iteration, next_copy - * gets nulled out by the xdr_reference - * but next itself survives. - */ - } else if (*rp) { - rp = &((*rp)->rpcb_next); - } - } - /*NOTREACHED*/ -} - -/* - * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in - * functionality to xdr_rpcblist_ptr(). - */ -bool_t -xdr_rpcblist(xdrs, rp) - XDR *xdrs; - RPCBLIST **rp; -{ - bool_t dummy; - - dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp); - return (dummy); -} - - -bool_t -xdr_rpcb_entry(xdrs, objp) - XDR *xdrs; - rpcb_entry *objp; -{ - if (!xdr_string(xdrs, &objp->r_maddr, (u_int)~0)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->r_nc_netid, (u_int)~0)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->r_nc_semantics)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->r_nc_protofmly, (u_int)~0)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->r_nc_proto, (u_int)~0)) { - return (FALSE); - } - return (TRUE); -} - -bool_t -xdr_rpcb_entry_list_ptr(xdrs, rp) - XDR *xdrs; - rpcb_entry_list_ptr *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; - int freeing = (xdrs->x_op == XDR_FREE); - rpcb_entry_list_ptr next; - rpcb_entry_list_ptr next_copy; - - next = NULL; - for (;;) { - 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)->rpcb_entry_next; - if (! xdr_reference(xdrs, (caddr_t *)rp, - (u_int)sizeof (rpcb_entry_list), - (xdrproc_t)xdr_rpcb_entry)) { - return (FALSE); - } - if (freeing && *rp) { - next_copy = next; - rp = &next_copy; - /* - * Note that in the subsequent iteration, next_copy - * gets nulled out by the xdr_reference - * but next itself survives. - */ - } else if (*rp) { - rp = &((*rp)->rpcb_entry_next); - } - } - /*NOTREACHED*/ -} - -/* - * XDR remote call arguments - * written for XDR_ENCODE direction only - */ -bool_t -xdr_rpcb_rmtcallargs(xdrs, p) - XDR *xdrs; - struct rpcb_rmtcallargs *p; -{ - struct r_rpcb_rmtcallargs *objp = - (struct r_rpcb_rmtcallargs *)(void *)p; - u_int lenposition, argposition, position; - int32_t *buf; - - buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_u_int32_t(xdrs, &objp->prog)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->vers)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->proc)) { - return (FALSE); - } - } else { - IXDR_PUT_U_INT32(buf, objp->prog); - IXDR_PUT_U_INT32(buf, objp->vers); - IXDR_PUT_U_INT32(buf, objp->proc); - } - - /* - * All the jugglery for just getting the size of the arguments - */ - lenposition = XDR_GETPOS(xdrs); - if (! xdr_u_int(xdrs, &(objp->args.args_len))) { - return (FALSE); - } - argposition = XDR_GETPOS(xdrs); - if (! (*objp->xdr_args)(xdrs, objp->args.args_val)) { - return (FALSE); - } - position = XDR_GETPOS(xdrs); - objp->args.args_len = (u_int)((u_long)position - (u_long)argposition); - XDR_SETPOS(xdrs, lenposition); - if (! xdr_u_int(xdrs, &(objp->args.args_len))) { - return (FALSE); - } - XDR_SETPOS(xdrs, position); - return (TRUE); -} - -/* - * XDR remote call results - * written for XDR_DECODE direction only - */ -bool_t -xdr_rpcb_rmtcallres(xdrs, p) - XDR *xdrs; - struct rpcb_rmtcallres *p; -{ - bool_t dummy; - struct r_rpcb_rmtcallres *objp = (struct r_rpcb_rmtcallres *)(void *)p; - - if (!xdr_string(xdrs, &objp->addr, (u_int)~0)) { - return (FALSE); - } - if (!xdr_u_int(xdrs, &objp->results.results_len)) { - return (FALSE); - } - dummy = (*(objp->xdr_res))(xdrs, objp->results.results_val); - return (dummy); -} - -bool_t -xdr_netbuf(xdrs, objp) - XDR *xdrs; - struct netbuf *objp; -{ - bool_t dummy; - void **pp; - - if (!xdr_u_int32_t(xdrs, (u_int32_t *) &objp->maxlen)) { - return (FALSE); - } - pp = &objp->buf; - dummy = xdr_bytes(xdrs, (char **) pp, - (u_int *)&(objp->len), objp->maxlen); - return (dummy); -} diff --git a/lib/libc/rpc/rpcb_st_xdr.c b/lib/libc/rpc/rpcb_st_xdr.c deleted file mode 100644 index cf1e227..0000000 --- a/lib/libc/rpc/rpcb_st_xdr.c +++ /dev/null @@ -1,275 +0,0 @@ -/* $NetBSD: rpcb_st_xdr.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ - -/* - * 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 1991 Sun Microsystems, Inc. - * rpcb_stat_xdr.c - */ - -/* - * This file was generated from rpcb_prot.x, but includes only those - * routines used with the rpcbind stats facility. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include <rpc/rpc.h> -#include "un-namespace.h" - -/* Link list of all the stats about getport and getaddr */ - -bool_t -xdr_rpcbs_addrlist(xdrs, objp) - XDR *xdrs; - rpcbs_addrlist *objp; -{ - struct rpcbs_addrlist **pnext; - - if (!xdr_u_int32_t(xdrs, &objp->prog)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->vers)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->success)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->failure)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) { - return (FALSE); - } - - pnext = &objp->next; - - if (!xdr_pointer(xdrs, (char **) pnext, - sizeof (rpcbs_addrlist), - (xdrproc_t)xdr_rpcbs_addrlist)) { - return (FALSE); - } - - return (TRUE); -} - -/* Link list of all the stats about rmtcall */ - -bool_t -xdr_rpcbs_rmtcalllist(xdrs, objp) - XDR *xdrs; - rpcbs_rmtcalllist *objp; -{ - int32_t *buf; - struct rpcbs_rmtcalllist **pnext; - - if (xdrs->x_op == XDR_ENCODE) { - buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_u_int32_t(xdrs, &objp->prog)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->vers)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->proc)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->success)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->failure)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->indirect)) { - return (FALSE); - } - } else { - IXDR_PUT_U_INT32(buf, objp->prog); - IXDR_PUT_U_INT32(buf, objp->vers); - IXDR_PUT_U_INT32(buf, objp->proc); - IXDR_PUT_INT32(buf, objp->success); - IXDR_PUT_INT32(buf, objp->failure); - IXDR_PUT_INT32(buf, objp->indirect); - } - if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) { - return (FALSE); - } - pnext = &objp->next; - if (!xdr_pointer(xdrs, (char **) pnext, - sizeof (rpcbs_rmtcalllist), - (xdrproc_t)xdr_rpcbs_rmtcalllist)) { - return (FALSE); - } - return (TRUE); - } else if (xdrs->x_op == XDR_DECODE) { - buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_u_int32_t(xdrs, &objp->prog)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->vers)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->proc)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->success)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->failure)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->indirect)) { - return (FALSE); - } - } else { - objp->prog = (rpcprog_t)IXDR_GET_U_INT32(buf); - objp->vers = (rpcvers_t)IXDR_GET_U_INT32(buf); - objp->proc = (rpcproc_t)IXDR_GET_U_INT32(buf); - objp->success = (int)IXDR_GET_INT32(buf); - objp->failure = (int)IXDR_GET_INT32(buf); - objp->indirect = (int)IXDR_GET_INT32(buf); - } - if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) { - return (FALSE); - } - if (!xdr_pointer(xdrs, (char **) pnext, - sizeof (rpcbs_rmtcalllist), - (xdrproc_t)xdr_rpcbs_rmtcalllist)) { - return (FALSE); - } - return (TRUE); - } - if (!xdr_u_int32_t(xdrs, &objp->prog)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->vers)) { - return (FALSE); - } - if (!xdr_u_int32_t(xdrs, &objp->proc)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->success)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->failure)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->indirect)) { - return (FALSE); - } - if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) { - return (FALSE); - } - if (!xdr_pointer(xdrs, (char **) pnext, - sizeof (rpcbs_rmtcalllist), - (xdrproc_t)xdr_rpcbs_rmtcalllist)) { - return (FALSE); - } - return (TRUE); -} - -bool_t -xdr_rpcbs_proc(xdrs, objp) - XDR *xdrs; - rpcbs_proc objp; -{ - if (!xdr_vector(xdrs, (char *)(void *)objp, RPCBSTAT_HIGHPROC, - sizeof (int), (xdrproc_t)xdr_int)) { - return (FALSE); - } - return (TRUE); -} - -bool_t -xdr_rpcbs_addrlist_ptr(xdrs, objp) - XDR *xdrs; - rpcbs_addrlist_ptr *objp; -{ - if (!xdr_pointer(xdrs, (char **)objp, sizeof (rpcbs_addrlist), - (xdrproc_t)xdr_rpcbs_addrlist)) { - return (FALSE); - } - return (TRUE); -} - -bool_t -xdr_rpcbs_rmtcalllist_ptr(xdrs, objp) - XDR *xdrs; - rpcbs_rmtcalllist_ptr *objp; -{ - if (!xdr_pointer(xdrs, (char **)objp, sizeof (rpcbs_rmtcalllist), - (xdrproc_t)xdr_rpcbs_rmtcalllist)) { - return (FALSE); - } - return (TRUE); -} - -bool_t -xdr_rpcb_stat(xdrs, objp) - XDR *xdrs; - rpcb_stat *objp; -{ - - if (!xdr_rpcbs_proc(xdrs, objp->info)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->setinfo)) { - return (FALSE); - } - if (!xdr_int(xdrs, &objp->unsetinfo)) { - return (FALSE); - } - if (!xdr_rpcbs_addrlist_ptr(xdrs, &objp->addrinfo)) { - return (FALSE); - } - if (!xdr_rpcbs_rmtcalllist_ptr(xdrs, &objp->rmtinfo)) { - return (FALSE); - } - return (TRUE); -} - -/* - * One rpcb_stat structure is returned for each version of rpcbind - * being monitored. - */ -bool_t -xdr_rpcb_stat_byvers(xdrs, objp) - XDR *xdrs; - rpcb_stat_byvers objp; -{ - if (!xdr_vector(xdrs, (char *)(void *)objp, RPCBVERS_STAT, - sizeof (rpcb_stat), (xdrproc_t)xdr_rpcb_stat)) { - return (FALSE); - } - return (TRUE); -} diff --git a/lib/libc/rpc/rpcbind.3 b/lib/libc/rpc/rpcbind.3 deleted file mode 100644 index 0b716ca..0000000 --- a/lib/libc/rpc/rpcbind.3 +++ /dev/null @@ -1,194 +0,0 @@ -.\" @(#)rpcbind.3n 1.25 93/05/07 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" Copyright (c) 1988 Sun Microsystem's, Inc. - All Right's Reserved. -.\" $NetBSD: rpcbind.3,v 1.2 2000/06/03 18:47:28 fvdl Exp $ -.\" $FreeBSD$ -.Dd May 7, 1993 -.Dt RPCBIND 3 -.Os -.Sh NAME -.Nm rpcb_getmaps , -.Nm rpcb_getaddr , -.Nm rpcb_gettime , -.Nm rpcb_rmtcall , -.Nm rpcb_set , -.Nm rpcb_unset -.Nd library routines for RPC bind service -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In rpc/rpc.h -.Ft "rpcblist *" -.Fn rpcb_getmaps "const struct netconfig *netconf" "const char *host" -.Ft bool_t -.Fn rpcb_getaddr "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "struct netbuf *svcaddr" "const char *host" -.Ft bool_t -.Fn rpcb_gettime "const char *host" "time_t * timep" -.Ft "enum clnt_stat" -.Fn rpcb_rmtcall "const struct netconfig *netconf" "const char *host" "const rpcprog_t prognum, const rpcvers_t versnum" "const rpcproc_t procnum, const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "const caddr_t out" "const struct timeval tout, const struct netbuf *svcaddr" -.Ft bool_t -.Fn rpcb_set "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "const struct netbuf *svcaddr" -.Ft bool_t -.Fn rpcb_unset "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" -.Sh DESCRIPTION -These routines allow client C programs to make procedure -calls to the RPC binder service. -(see -.Xr rpcbind 8 ) -maintains a list of mappings between programs -and their universal addresses. -.Sh Routines -.Bl -tag -width XXXXX -.It Fn rpcb_getmaps -An interface to the rpcbind service, -which returns a list of the current -RPC program-to-address mappings on -.Fa host . -It uses the transport specified through -.Fa netconf -to contact the remote rpcbind -service on -.Fa host . -This routine will return -.Dv NULL , -if the remote rpcbind could not be contacted. -.It Fn rpcb_getaddr -An interface to the rpcbind -service, which finds the address of the service on -.Fa host -that is registered with program number -.Fa prognum , -version -.Fa versnum , -and speaks the transport protocol associated with -.Fa netconf . -The address found is returned in -.Fa svcaddr . -The -.Fa svcaddr -argument -should be preallocated. -This routine returns -.Dv TRUE -if it succeeds. -A return value of -.Dv FALSE -means that the mapping does not exist -or that the RPC -system failed to contact the remote -rpcbind service. -In the latter case, the global variable -.Va rpc_createerr -(see -.Xr rpc_clnt_create 3 ) -contains the -RPC status. -.It Fn rpcb_gettime -This routine returns the time on -.Fa host -in -.Fa timep . -If -.Fa host -is -.Dv NULL , -.Fn rpcb_gettime -returns the time on its own machine. -This routine returns -.Dv TRUE -if it succeeds, -.Dv FALSE -if it fails. -The -.Fn rpcb_gettime -function -can be used to synchronize the time between the -client and the remote server. -.It Fn rpcb_rmtcall -An interface to the rpcbind service, which instructs -rpcbind on -.Fa host -to make an RPC -call on your behalf to a procedure on that host. -The -.Fn netconfig -structure should correspond to a connectionless transport. -The -.Fa svcaddr -argument -will be modified to the server's address if the procedure succeeds -(see -.Fn rpc_call -and -.Fn clnt_call -in -.Xr rpc_clnt_calls 3 -for the definitions of other arguments). -.Pp -This procedure should normally be used for a -.Dq ping -and nothing else. -This routine allows programs to do lookup and call, all in one step. -.Pp -Note: Even if the server is not running -.Fn rpcb_rmtcall -does not return any error messages to the caller. -In such a case, the caller times out. -.Pp -Note: -.Fn rpcb_rmtcall -is only available for connectionless transports. -.It Fn rpcb_set -An interface to the rpcbind -service, which establishes a mapping between the triple -.Bq Fa prognum , versnum , netconf->nc_netid -and -.Fa svcaddr -on the machine's rpcbind -service. -The value of -.Fa nc_netid -must correspond to a network identifier that is defined by the -netconfig database. -This routine returns -.Dv TRUE -if it succeeds, -.Dv FALSE -otherwise. -(See also -.Fn svc_reg -in -.Xr rpc_svc_calls 3 . ) -If there already exists such an entry with rpcbind, -.Fn rpcb_set -will fail. -.It Fn rpcb_unset -An interface to the rpcbind -service, which destroys the mapping between the triple -.Bq Fa prognum , versnum , netconf->nc_netid -and the address on the machine's rpcbind -service. -If -.Fa netconf -is -.Dv NULL , -.Fn rpcb_unset -destroys all mapping between the triple -.Bq Fa prognum , versnum , No all-transports -and the addresses on the machine's rpcbind service. -This routine returns -.Dv TRUE -if it succeeds, -.Dv FALSE -otherwise. -Only the owner of the service or the super-user can destroy the mapping. -(See also -.Fn svc_unreg -in -.Xr rpc_svc_calls 3 . ) -.El -.Sh SEE ALSO -.Xr rpc_clnt_calls 3 , -.Xr rpc_svc_calls 3 , -.Xr rpcbind 8 , -.Xr rpcinfo 8 diff --git a/lib/libc/rpc/rpcdname.c b/lib/libc/rpc/rpcdname.c deleted file mode 100644 index d4455f4..0000000 --- a/lib/libc/rpc/rpcdname.c +++ /dev/null @@ -1,82 +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[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * rpcdname.c - * Gets the default domain name - */ - -#include "namespace.h" -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include "un-namespace.h" - -static char *default_domain = 0; - -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/lib/libc/rpc/rpcsec_gss_stub.c b/lib/libc/rpc/rpcsec_gss_stub.c deleted file mode 100644 index 55eb106..0000000 --- a/lib/libc/rpc/rpcsec_gss_stub.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2006 Doug Rabson - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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$ - */ - -#include <rpc/rpc.h> -#include <rpc/rpcsec_gss.h> - -bool_t -__rpc_gss_wrap_stub(AUTH *auth, void *header, size_t headerlen, XDR* xdrs, - xdrproc_t xdr_args, void *args_ptr) -{ - - return (FALSE); -} - -bool_t -__rpc_gss_unwrap_stub(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args, void *args_ptr) -{ - - return (FALSE); -} - -__weak_reference(__rpc_gss_wrap_stub, __rpc_gss_wrap); -__weak_reference(__rpc_gss_unwrap_stub, __rpc_gss_unwrap); diff --git a/lib/libc/rpc/rtime.3 b/lib/libc/rpc/rtime.3 deleted file mode 100644 index 028d2be..0000000 --- a/lib/libc/rpc/rtime.3 +++ /dev/null @@ -1,50 +0,0 @@ -.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI -.\" $FreeBSD$ -.\" -.Dd November 22, 1987 -.Dt RTIME 3 -.Os -.Sh NAME -.Nm rtime -.Nd "get remote time" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/time.h -.In netinet/in.h -.Ft int -.Fo rtime -.Fa "struct sockaddr_in *addrp" -.Fa "struct timeval *timep" -.Fa "struct timeval *timeout" -.Fc -.Sh DESCRIPTION -The -.Fn rtime -function -consults the Internet Time Server at the address pointed to by -.Fa addrp -and returns the remote time in the -.Vt timeval -struct pointed to by -.Fa timep . -Normally, the -.Tn UDP -protocol is used when consulting the Time Server. -The -.Fa timeout -argument specifies how long the -routine should wait before giving -up when waiting for a reply. -If -.Fa timeout -is specified as -.Dv NULL , -however, the routine will instead use -.Tn TCP -and block until a reply is received from the time server. -.Sh RETURN VALUES -.Rv -std rtime -.Sh SEE ALSO -.Xr timed 8 diff --git a/lib/libc/rpc/rtime.c b/lib/libc/rpc/rtime.c deleted file mode 100644 index 39ac19b..0000000 --- a/lib/libc/rpc/rtime.c +++ /dev/null @@ -1,160 +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 "namespace.h" -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <stdio.h> -#include <netdb.h> -#include "un-namespace.h" - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -extern int _rpc_dtablesize( void ); - -#define NYEARS (unsigned long)(1970 - 1900) -#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) - -static void do_close( 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; - socklen_t 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 = _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)_close(s); - errno = save; -} diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c deleted file mode 100644 index 282c2be..0000000 --- a/lib/libc/rpc/svc.c +++ /dev/null @@ -1,789 +0,0 @@ -/* $NetBSD: svc.c,v 1.21 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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 *sccsid2 = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/poll.h> -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <rpc/rpc.h> -#ifdef PORTMAP -#include <rpc/pmap_clnt.h> -#endif /* PORTMAP */ -#include "un-namespace.h" - -#include "rpc_com.h" -#include "mt_misc.h" - -#define RQCRED_SIZE 400 /* this size is excessive */ - -#define SVC_VERSQUIET 0x0001 /* keep quiet about vers mismatch */ -#define version_keepquiet(xp) (SVC_EXT(xp)->xp_flags & SVC_VERSQUIET) - -#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. - */ -static struct svc_callout { - struct svc_callout *sc_next; - rpcprog_t sc_prog; - rpcvers_t sc_vers; - char *sc_netid; - void (*sc_dispatch)(struct svc_req *, SVCXPRT *); -} *svc_head; - -static struct svc_callout *svc_find(rpcprog_t, rpcvers_t, - struct svc_callout **, char *); -static void __xprt_do_unregister (SVCXPRT *xprt, bool_t dolock); - -/* *************** SVCXPRT related stuff **************** */ - -/* - * Activate a transport handle. - */ -void -xprt_register(xprt) - SVCXPRT *xprt; -{ - int sock; - - assert(xprt != NULL); - - sock = xprt->xp_fd; - - rwlock_wrlock(&svc_fd_lock); - if (__svc_xports == NULL) { - __svc_xports = (SVCXPRT **) - mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); - if (__svc_xports == NULL) - return; - memset(__svc_xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *)); - } - if (sock < FD_SETSIZE) { - __svc_xports[sock] = xprt; - FD_SET(sock, &svc_fdset); - svc_maxfd = max(svc_maxfd, sock); - } - rwlock_unlock(&svc_fd_lock); -} - -void -xprt_unregister(SVCXPRT *xprt) -{ - __xprt_do_unregister(xprt, TRUE); -} - -void -__xprt_unregister_unlocked(SVCXPRT *xprt) -{ - __xprt_do_unregister(xprt, FALSE); -} - -/* - * De-activate a transport handle. - */ -static void -__xprt_do_unregister(xprt, dolock) - SVCXPRT *xprt; - bool_t dolock; -{ - int sock; - - assert(xprt != NULL); - - sock = xprt->xp_fd; - - if (dolock) - rwlock_wrlock(&svc_fd_lock); - if ((sock < FD_SETSIZE) && (__svc_xports[sock] == xprt)) { - __svc_xports[sock] = NULL; - FD_CLR(sock, &svc_fdset); - if (sock >= svc_maxfd) { - for (svc_maxfd--; svc_maxfd>=0; svc_maxfd--) - if (__svc_xports[svc_maxfd]) - break; - } - } - if (dolock) - rwlock_unlock(&svc_fd_lock); -} - -/* - * 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_reg(xprt, prog, vers, dispatch, nconf) - SVCXPRT *xprt; - const rpcprog_t prog; - const rpcvers_t vers; - void (*dispatch)(struct svc_req *, SVCXPRT *); - const struct netconfig *nconf; -{ - bool_t dummy; - struct svc_callout *prev; - struct svc_callout *s; - struct netconfig *tnconf; - char *netid = NULL; - int flag = 0; - -/* VARIABLES PROTECTED BY svc_lock: s, prev, svc_head */ - - if (xprt->xp_netid) { - netid = strdup(xprt->xp_netid); - flag = 1; - } else if (nconf && nconf->nc_netid) { - netid = strdup(nconf->nc_netid); - flag = 1; - } else if ((tnconf = __rpcgettp(xprt->xp_fd)) != NULL) { - netid = strdup(tnconf->nc_netid); - flag = 1; - freenetconfigent(tnconf); - } /* must have been created with svc_raw_create */ - if ((netid == NULL) && (flag == 1)) { - return (FALSE); - } - - rwlock_wrlock(&svc_lock); - if ((s = svc_find(prog, vers, &prev, netid)) != NULL) { - if (netid) - free(netid); - if (s->sc_dispatch == dispatch) - goto rpcb_it; /* he is registering another xptr */ - rwlock_unlock(&svc_lock); - return (FALSE); - } - s = mem_alloc(sizeof (struct svc_callout)); - if (s == NULL) { - if (netid) - free(netid); - rwlock_unlock(&svc_lock); - return (FALSE); - } - - s->sc_prog = prog; - s->sc_vers = vers; - s->sc_dispatch = dispatch; - s->sc_netid = netid; - s->sc_next = svc_head; - svc_head = s; - - if ((xprt->xp_netid == NULL) && (flag == 1) && netid) - ((SVCXPRT *) xprt)->xp_netid = strdup(netid); - -rpcb_it: - rwlock_unlock(&svc_lock); - /* now register the information with the local binder service */ - if (nconf) { - /*LINTED const castaway*/ - dummy = rpcb_set(prog, vers, (struct netconfig *) nconf, - &((SVCXPRT *) xprt)->xp_ltaddr); - return (dummy); - } - return (TRUE); -} - -/* - * Remove a service program from the callout list. - */ -void -svc_unreg(prog, vers) - const rpcprog_t prog; - const rpcvers_t vers; -{ - struct svc_callout *prev; - struct svc_callout *s; - - /* unregister the information anyway */ - (void) rpcb_unset(prog, vers, NULL); - rwlock_wrlock(&svc_lock); - while ((s = svc_find(prog, vers, &prev, NULL)) != NULL) { - if (prev == NULL) { - svc_head = s->sc_next; - } else { - prev->sc_next = s->sc_next; - } - s->sc_next = NULL; - if (s->sc_netid) - mem_free(s->sc_netid, sizeof (s->sc_netid) + 1); - mem_free(s, sizeof (struct svc_callout)); - } - rwlock_unlock(&svc_lock); -} - -/* ********************** CALLOUT list related stuff ************* */ - -#ifdef PORTMAP -/* - * 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)(struct svc_req *, SVCXPRT *); - int protocol; -{ - struct svc_callout *prev; - struct svc_callout *s; - - assert(xprt != NULL); - assert(dispatch != NULL); - - if ((s = svc_find((rpcprog_t)prog, (rpcvers_t)vers, &prev, NULL)) != - NULL) { - if (s->sc_dispatch == dispatch) - goto pmap_it; /* he is registering another xptr */ - return (FALSE); - } - s = mem_alloc(sizeof(struct svc_callout)); - if (s == NULL) { - return (FALSE); - } - s->sc_prog = (rpcprog_t)prog; - s->sc_vers = (rpcvers_t)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; - struct svc_callout *s; - - if ((s = svc_find((rpcprog_t)prog, (rpcvers_t)vers, &prev, NULL)) == - NULL) - return; - if (prev == NULL) { - svc_head = s->sc_next; - } else { - prev->sc_next = s->sc_next; - } - s->sc_next = NULL; - mem_free(s, sizeof(struct svc_callout)); - /* now unregister the information with the local binder service */ - (void)pmap_unset(prog, vers); -} -#endif /* PORTMAP */ - -/* - * Search the callout list for a program number, return the callout - * struct. - */ -static struct svc_callout * -svc_find(prog, vers, prev, netid) - rpcprog_t prog; - rpcvers_t vers; - struct svc_callout **prev; - char *netid; -{ - struct svc_callout *s, *p; - - assert(prev != NULL); - - p = NULL; - for (s = svc_head; s != NULL; s = s->sc_next) { - if (((s->sc_prog == prog) && (s->sc_vers == vers)) && - ((netid == NULL) || (s->sc_netid == NULL) || - (strcmp(netid, s->sc_netid) == 0))) - break; - p = s; - } - *prev = p; - return (s); -} - -/* ******************* REPLY GENERATION ROUTINES ************ */ - -/* - * Send a reply to an rpc request - */ -bool_t -svc_sendreply(xprt, xdr_results, xdr_location) - SVCXPRT *xprt; - xdrproc_t xdr_results; - void * xdr_location; -{ - struct rpc_msg rply; - - assert(xprt != NULL); - - 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) - SVCXPRT *xprt; -{ - struct rpc_msg rply; - - assert(xprt != NULL); - - 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) - SVCXPRT *xprt; -{ - struct rpc_msg rply; - - assert(xprt != NULL); - - 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) - SVCXPRT *xprt; -{ - struct rpc_msg rply; - - assert(xprt != NULL); - - 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); -} - -#if 0 -/* - * Tell RPC package to not complain about version errors to the client. This - * is useful when revving broadcast protocols that sit on a fixed address. - * There is really one (or should be only one) example of this kind of - * protocol: the portmapper (or rpc binder). - */ -void -__svc_versquiet_on(xprt) - SVCXPRT *xprt; -{ - - SVC_EXT(xprt)->xp_flags |= SVC_VERSQUIET; -} - -void -__svc_versquiet_off(xprt) - SVCXPRT *xprt; -{ - - SVC_EXT(xprt)->xp_flags &= ~SVC_VERSQUIET; -} - -void -svc_versquiet(xprt) - SVCXPRT *xprt; -{ - __svc_versquiet_on(xprt); -} - -int -__svc_versquiet_get(xprt) - SVCXPRT *xprt; -{ - - return (SVC_EXT(xprt)->xp_flags & SVC_VERSQUIET); -} -#endif - -/* - * Authentication error reply - */ -void -svcerr_auth(xprt, why) - SVCXPRT *xprt; - enum auth_stat why; -{ - struct rpc_msg rply; - - assert(xprt != NULL); - - 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; -{ - - assert(xprt != NULL); - - svcerr_auth(xprt, AUTH_TOOWEAK); -} - -/* - * Program unavailable error reply - */ -void -svcerr_noprog(xprt) - SVCXPRT *xprt; -{ - struct rpc_msg rply; - - assert(xprt != NULL); - - 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) - SVCXPRT *xprt; - rpcvers_t low_vers; - rpcvers_t high_vers; -{ - struct rpc_msg rply; - - assert(xprt != NULL); - - 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 = (u_int32_t)low_vers; - rply.acpted_rply.ar_vers.high = (u_int32_t)high_vers; - SVC_REPLY(xprt, &rply); -} - -/* - * Allocate a new server transport structure. All fields are - * initialized to zero and xp_p3 is initialized to point at an - * extension structure to hold various flags and authentication - * parameters. - */ -SVCXPRT * -svc_xprt_alloc() -{ - SVCXPRT *xprt; - SVCXPRT_EXT *ext; - - xprt = mem_alloc(sizeof(SVCXPRT)); - memset(xprt, 0, sizeof(SVCXPRT)); - ext = mem_alloc(sizeof(SVCXPRT_EXT)); - memset(ext, 0, sizeof(SVCXPRT_EXT)); - xprt->xp_p3 = ext; - ext->xp_auth.svc_ah_ops = &svc_auth_null_ops; - - return (xprt); -} - -/* - * Free a server transport structure. - */ -void -svc_xprt_free(xprt) - SVCXPRT *xprt; -{ - - mem_free(xprt->xp_p3, sizeof(SVCXPRT_EXT)); - mem_free(xprt, sizeof(SVCXPRT)); -} - -/* ******************* 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; -{ - int bit, fd; - fd_mask mask, *maskp; - int sock; - - assert(readfds != NULL); - - maskp = readfds->fds_bits; - for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) { - for (mask = *maskp++; (bit = ffsl(mask)) != 0; - mask ^= (1ul << (bit - 1))) { - /* sock has input waiting */ - fd = sock + bit - 1; - svc_getreq_common(fd); - } - } -} - -void -svc_getreq_common(fd) - int fd; -{ - SVCXPRT *xprt; - struct svc_req r; - struct rpc_msg msg; - int prog_found; - rpcvers_t low_vers; - rpcvers_t high_vers; - enum xprt_stat stat; - 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]); - - rwlock_rdlock(&svc_fd_lock); - xprt = __svc_xports[fd]; - rwlock_unlock(&svc_fd_lock); - if (xprt == NULL) - /* But do we control sock? */ - return; - /* now receive msgs from xprtprt (support batch calls) */ - do { - if (SVC_RECV(xprt, &msg)) { - - /* now find the exported program and call it */ - 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) { - /* - * RPCSEC_GSS uses this return code - * for requests that form part of its - * context establishment protocol and - * should not be dispatched to the - * application. - */ - if (why != RPCSEC_GSS_NODISPATCH) - svcerr_auth(xprt, why); - goto call_done; - } - /* now match message with a registered service*/ - prog_found = FALSE; - low_vers = (rpcvers_t) -1L; - high_vers = (rpcvers_t) 0L; - for (s = svc_head; s != NULL; 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 ... */ - } - /* - * Check if the xprt has been disconnected in a - * recursive call in the service dispatch routine. - * If so, then break. - */ - rwlock_rdlock(&svc_fd_lock); - if (xprt != __svc_xports[fd]) { - rwlock_unlock(&svc_fd_lock); - break; - } - rwlock_unlock(&svc_fd_lock); -call_done: - if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ - SVC_DESTROY(xprt); - break; - } - } while (stat == XPRT_MOREREQS); -} - - -void -svc_getreq_poll(pfdp, pollretval) - struct pollfd *pfdp; - int pollretval; -{ - int i; - int fds_found; - - for (i = fds_found = 0; fds_found < pollretval; i++) { - struct pollfd *p = &pfdp[i]; - - if (p->revents) { - /* fd has input waiting */ - fds_found++; - /* - * We assume that this function is only called - * via someone _select()ing from svc_fdset or - * _poll()ing from svc_pollset[]. Thus it's safe - * to handle the POLLNVAL event by simply turning - * the corresponding bit off in svc_fdset. The - * svc_pollset[] array is derived from svc_fdset - * and so will also be updated eventually. - * - * XXX Should we do an xprt_unregister() instead? - */ - if (p->revents & POLLNVAL) { - rwlock_wrlock(&svc_fd_lock); - FD_CLR(p->fd, &svc_fdset); - rwlock_unlock(&svc_fd_lock); - } else - svc_getreq_common(p->fd); - } - } -} - -bool_t -rpc_control(int what, void *arg) -{ - int val; - - switch (what) { - case RPC_SVC_CONNMAXREC_SET: - val = *(int *)arg; - if (val <= 0) - return FALSE; - __svc_maxrec = val; - return TRUE; - case RPC_SVC_CONNMAXREC_GET: - *(int *)arg = __svc_maxrec; - return TRUE; - default: - break; - } - return FALSE; -} diff --git a/lib/libc/rpc/svc_auth.c b/lib/libc/rpc/svc_auth.c deleted file mode 100644 index b3894e6..0000000 --- a/lib/libc/rpc/svc_auth.c +++ /dev/null @@ -1,234 +0,0 @@ -/* $NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -#ident "@(#)svc_auth.c 1.16 94/04/24 SMI" -static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * svc_auth.c, Server-side rpc authenticator interface. - * - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <rpc/rpc.h> -#include <stdlib.h> -#include "un-namespace.h" -#include "mt_misc.h" - -/* - * 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) - * struct svc_req *rqst; - * struct rpc_msg *msg; - * - */ - -/* declarations to allow servers to specify new authentication flavors */ -struct authsvc { - int flavor; - enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); - struct authsvc *next; -}; -static struct authsvc *Auths = NULL; - -struct svc_auth_ops svc_auth_null_ops; - -/* - * 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) - struct svc_req *rqst; - struct rpc_msg *msg; -{ - int cred_flavor; - struct authsvc *asp; - enum auth_stat dummy; - -/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */ - - rqst->rq_cred = msg->rm_call.cb_cred; - SVC_AUTH(rqst->rq_xprt).svc_ah_ops = &svc_auth_null_ops; - SVC_AUTH(rqst->rq_xprt).svc_ah_private = NULL; - 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: - dummy = _svcauth_null(rqst, msg); - return (dummy); - case AUTH_SYS: - dummy = _svcauth_unix(rqst, msg); - return (dummy); - case AUTH_SHORT: - dummy = _svcauth_short(rqst, msg); - return (dummy); -#ifdef DES_BUILTIN - case AUTH_DES: - dummy = _svcauth_des(rqst, msg); - return (dummy); -#endif - default: - break; - } - - /* flavor doesn't match any of the builtin types, so try new ones */ - mutex_lock(&authsvc_lock); - for (asp = Auths; asp; asp = asp->next) { - if (asp->flavor == cred_flavor) { - enum auth_stat as; - - as = (*asp->handler)(rqst, msg); - mutex_unlock(&authsvc_lock); - return (as); - } - } - mutex_unlock(&authsvc_lock); - - return (AUTH_REJECTEDCRED); -} - -/* - * A set of null auth methods used by any authentication protocols - * that don't need to inspect or modify the message body. - */ -static bool_t -svcauth_null_wrap(auth, xdrs, xdr_func, xdr_ptr) - SVCAUTH *auth; - XDR *xdrs; - xdrproc_t xdr_func; - caddr_t xdr_ptr; -{ - - return (xdr_func(xdrs, xdr_ptr)); -} - -struct svc_auth_ops svc_auth_null_ops = { - svcauth_null_wrap, - svcauth_null_wrap, -}; - -/*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) - int cred_flavor; - enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); -{ - struct authsvc *asp; - - switch (cred_flavor) { - case AUTH_NULL: - case AUTH_SYS: - case AUTH_SHORT: -#ifdef DES_BUILTIN - case AUTH_DES: -#endif - /* already registered */ - return (1); - - default: - mutex_lock(&authsvc_lock); - for (asp = Auths; asp; asp = asp->next) { - if (asp->flavor == cred_flavor) { - /* already registered */ - mutex_unlock(&authsvc_lock); - return (1); - } - } - - /* this is a new one, so go ahead and register it */ - asp = mem_alloc(sizeof (*asp)); - if (asp == NULL) { - mutex_unlock(&authsvc_lock); - return (-1); - } - asp->flavor = cred_flavor; - asp->handler = handler; - asp->next = Auths; - Auths = asp; - mutex_unlock(&authsvc_lock); - break; - } - return (0); -} diff --git a/lib/libc/rpc/svc_auth_des.c b/lib/libc/rpc/svc_auth_des.c deleted file mode 100644 index de4d1b4..0000000 --- a/lib/libc/rpc/svc_auth_des.c +++ /dev/null @@ -1,538 +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 "namespace.h" -#include "reentrant.h" -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <rpc/des_crypt.h> -#include <sys/param.h> -#include <netinet/in.h> -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/auth.h> -#include <rpc/auth_des.h> -#include <rpc/svc.h> -#include <rpc/rpc_msg.h> -#include <rpc/svc_auth.h> -#include "libc_private.h" - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)svcauth_des.c 2.3 89/07/11 4.0 RPCSRC; from 1.15 88/02/08 SMI"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -extern int key_decryptsession_pk(const char *, netobj *, des_block *); - -#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) - struct svc_req *rqst; - struct rpc_msg *msg; -{ - - long *ixdr; - des_block cryptbuf[2]; - struct authdes_cred *cred; - struct authdes_verf verf; - int status; - 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 < 0 || 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() -{ - 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) - short sid; -{ - int i; - short curr; - 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) - des_block *key; - char *name; - struct timeval *timestamp; -{ - struct cache_entry *cp; - int i; - 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 { - uid_t uid; /* cached uid */ - gid_t gid; /* cached gid */ - int grouplen; /* length of cached groups */ - gid_t groups[NGRPS]; /* 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; - gid_t *groups; -{ - unsigned sid; - 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/lib/libc/rpc/svc_auth_unix.c b/lib/libc/rpc/svc_auth_unix.c deleted file mode 100644 index 4d6f102..0000000 --- a/lib/libc/rpc/svc_auth_unix.c +++ /dev/null @@ -1,156 +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 *sccsid2 = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 "namespace.h" -#include <assert.h> -#include <stdio.h> -#include <string.h> - -#include <rpc/rpc.h> -#include "un-namespace.h" - -/* - * Unix longhand authenticator - */ -enum auth_stat -_svcauth_unix(rqst, msg) - struct svc_req *rqst; - struct rpc_msg *msg; -{ - enum auth_stat stat; - XDR xdrs; - struct authunix_parms *aup; - 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; - size_t str_len, gid_len; - u_int i; - - assert(rqst != NULL); - assert(msg != NULL); - - 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_INT32(buf); - str_len = (size_t)IXDR_GET_U_INT32(buf); - if (str_len > MAX_MACHINE_NAME) { - stat = AUTH_BADCRED; - goto done; - } - memmove(aup->aup_machname, buf, str_len); - aup->aup_machname[str_len] = 0; - str_len = RNDUP(str_len); - buf += str_len / sizeof (int32_t); - aup->aup_uid = (int)IXDR_GET_INT32(buf); - aup->aup_gid = (int)IXDR_GET_INT32(buf); - gid_len = (size_t)IXDR_GET_U_INT32(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] = (int)IXDR_GET_INT32(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 %ld str %ld auth %u\n", - (long)gid_len, (long)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/lib/libc/rpc/svc_dg.c b/lib/libc/rpc/svc_dg.c deleted file mode 100644 index a78b160..0000000 --- a/lib/libc/rpc/svc_dg.c +++ /dev/null @@ -1,739 +0,0 @@ -/* $NetBSD: svc_dg.c,v 1.4 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -#ident "@(#)svc_dg.c 1.17 94/04/24 SMI" -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * svc_dg.c, Server side for connectionless RPC. - * - * Does some caching in the hopes of achieving execute-at-most-once semantics. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <rpc/rpc.h> -#include <rpc/svc_dg.h> -#include <assert.h> -#include <errno.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef RPC_CACHE_DEBUG -#include <netconfig.h> -#include <netdir.h> -#endif -#include <err.h> -#include "un-namespace.h" - -#include "rpc_com.h" -#include "mt_misc.h" - -#define su_data(xprt) ((struct svc_dg_data *)(xprt->xp_p2)) -#define rpc_buffer(xprt) ((xprt)->xp_p1) - -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -static void svc_dg_ops(SVCXPRT *); -static enum xprt_stat svc_dg_stat(SVCXPRT *); -static bool_t svc_dg_recv(SVCXPRT *, struct rpc_msg *); -static bool_t svc_dg_reply(SVCXPRT *, struct rpc_msg *); -static bool_t svc_dg_getargs(SVCXPRT *, xdrproc_t, void *); -static bool_t svc_dg_freeargs(SVCXPRT *, xdrproc_t, void *); -static void svc_dg_destroy(SVCXPRT *); -static bool_t svc_dg_control(SVCXPRT *, const u_int, void *); -static int cache_get(SVCXPRT *, struct rpc_msg *, char **, size_t *); -static void cache_set(SVCXPRT *, size_t); -int svc_dg_enablecache(SVCXPRT *, u_int); - -/* - * Usage: - * xprt = svc_dg_create(sock, sendsize, recvsize); - * Does other connectionless specific initializations. - * Once *xprt is initialized, it is registered. - * see (svc.h, xprt_register). If recvsize or sendsize are 0 suitable - * system defaults are chosen. - * The routines returns NULL if a problem occurred. - */ -static const char svc_dg_str[] = "svc_dg_create: %s"; -static const char svc_dg_err1[] = "could not get transport information"; -static const char svc_dg_err2[] = "transport does not support data transfer"; -static const char svc_dg_err3[] = "getsockname failed"; -static const char svc_dg_err4[] = "cannot set IP_RECVDSTADDR"; -static const char __no_mem_str[] = "out of memory"; - -SVCXPRT * -svc_dg_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - SVCXPRT *xprt; - struct svc_dg_data *su = NULL; - struct __rpc_sockinfo si; - struct sockaddr_storage ss; - socklen_t slen; - - if (!__rpc_fd2sockinfo(fd, &si)) { - warnx(svc_dg_str, svc_dg_err1); - return (NULL); - } - /* - * Find the receive and the send size - */ - sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize); - recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize); - if ((sendsize == 0) || (recvsize == 0)) { - warnx(svc_dg_str, svc_dg_err2); - return (NULL); - } - - xprt = svc_xprt_alloc(); - if (xprt == NULL) - goto freedata; - - su = mem_alloc(sizeof (*su)); - if (su == NULL) - goto freedata; - su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4; - if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) - goto freedata; - xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, - XDR_DECODE); - su->su_cache = NULL; - xprt->xp_fd = fd; - xprt->xp_p2 = su; - xprt->xp_verf.oa_base = su->su_verfbody; - svc_dg_ops(xprt); - xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage); - - slen = sizeof ss; - if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) { - warnx(svc_dg_str, svc_dg_err3); - goto freedata_nowarn; - } - xprt->xp_ltaddr.buf = mem_alloc(sizeof (struct sockaddr_storage)); - xprt->xp_ltaddr.maxlen = sizeof (struct sockaddr_storage); - xprt->xp_ltaddr.len = slen; - memcpy(xprt->xp_ltaddr.buf, &ss, slen); - - if (ss.ss_family == AF_INET) { - struct sockaddr_in *sin; - static const int true_value = 1; - - sin = (struct sockaddr_in *)(void *)&ss; - if (sin->sin_addr.s_addr == INADDR_ANY) { - su->su_srcaddr.buf = mem_alloc(sizeof (ss)); - su->su_srcaddr.maxlen = sizeof (ss); - - if (_setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, - &true_value, sizeof(true_value))) { - warnx(svc_dg_str, svc_dg_err4); - goto freedata_nowarn; - } - } - } - - xprt_register(xprt); - return (xprt); -freedata: - (void) warnx(svc_dg_str, __no_mem_str); -freedata_nowarn: - if (xprt) { - if (su) - (void) mem_free(su, sizeof (*su)); - svc_xprt_free(xprt); - } - return (NULL); -} - -/*ARGSUSED*/ -static enum xprt_stat -svc_dg_stat(xprt) - SVCXPRT *xprt; -{ - return (XPRT_IDLE); -} - -static int -svc_dg_recvfrom(int fd, char *buf, int buflen, - struct sockaddr *raddr, socklen_t *raddrlen, - struct sockaddr *laddr, socklen_t *laddrlen) -{ - struct msghdr msg; - struct iovec msg_iov[1]; - struct sockaddr_in *lin = (struct sockaddr_in *)laddr; - int rlen; - bool_t have_lin = FALSE; - char tmp[CMSG_LEN(sizeof(*lin))]; - struct cmsghdr *cmsg; - - memset((char *)&msg, 0, sizeof(msg)); - msg_iov[0].iov_base = buf; - msg_iov[0].iov_len = buflen; - msg.msg_iov = msg_iov; - msg.msg_iovlen = 1; - msg.msg_namelen = *raddrlen; - msg.msg_name = (char *)raddr; - if (laddr != NULL) { - msg.msg_control = (caddr_t)tmp; - msg.msg_controllen = CMSG_LEN(sizeof(*lin)); - } - rlen = _recvmsg(fd, &msg, 0); - if (rlen >= 0) - *raddrlen = msg.msg_namelen; - - if (rlen == -1 || laddr == NULL || - msg.msg_controllen < sizeof(struct cmsghdr) || - msg.msg_flags & MSG_CTRUNC) - return rlen; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == IPPROTO_IP && - cmsg->cmsg_type == IP_RECVDSTADDR) { - have_lin = TRUE; - memcpy(&lin->sin_addr, - (struct in_addr *)CMSG_DATA(cmsg), - sizeof(struct in_addr)); - break; - } - } - - lin->sin_family = AF_INET; - lin->sin_port = 0; - *laddrlen = sizeof(struct sockaddr_in); - - if (!have_lin) - lin->sin_addr.s_addr = INADDR_ANY; - - return rlen; -} - -static bool_t -svc_dg_recv(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct svc_dg_data *su = su_data(xprt); - XDR *xdrs = &(su->su_xdrs); - char *reply; - struct sockaddr_storage ss; - socklen_t alen; - size_t replylen; - ssize_t rlen; - -again: - alen = sizeof (struct sockaddr_storage); - rlen = svc_dg_recvfrom(xprt->xp_fd, rpc_buffer(xprt), su->su_iosz, - (struct sockaddr *)(void *)&ss, &alen, - (struct sockaddr *)su->su_srcaddr.buf, &su->su_srcaddr.len); - if (rlen == -1 && errno == EINTR) - goto again; - if (rlen == -1 || (rlen < (ssize_t)(4 * sizeof (u_int32_t)))) - return (FALSE); - if (xprt->xp_rtaddr.len < alen) { - if (xprt->xp_rtaddr.len != 0) - mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.len); - xprt->xp_rtaddr.buf = mem_alloc(alen); - xprt->xp_rtaddr.len = alen; - } - memcpy(xprt->xp_rtaddr.buf, &ss, alen); -#ifdef PORTMAP - if (ss.ss_family == AF_INET) { - xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; - xprt->xp_addrlen = sizeof (struct sockaddr_in); - } -#endif /* PORTMAP */ - 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_fd, reply, replylen, 0, - (struct sockaddr *)(void *)&ss, alen); - return (FALSE); - } - } - return (TRUE); -} - -static int -svc_dg_sendto(int fd, char *buf, int buflen, - const struct sockaddr *raddr, socklen_t raddrlen, - const struct sockaddr *laddr, socklen_t laddrlen) -{ - struct msghdr msg; - struct iovec msg_iov[1]; - struct sockaddr_in *laddr_in = (struct sockaddr_in *)laddr; - struct in_addr *lin = &laddr_in->sin_addr; - char tmp[CMSG_SPACE(sizeof(*lin))]; - struct cmsghdr *cmsg; - - memset((char *)&msg, 0, sizeof(msg)); - msg_iov[0].iov_base = buf; - msg_iov[0].iov_len = buflen; - msg.msg_iov = msg_iov; - msg.msg_iovlen = 1; - msg.msg_namelen = raddrlen; - msg.msg_name = (char *)raddr; - - if (laddr != NULL && laddr->sa_family == AF_INET && - lin->s_addr != INADDR_ANY) { - msg.msg_control = (caddr_t)tmp; - msg.msg_controllen = CMSG_LEN(sizeof(*lin)); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(sizeof(*lin)); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_SENDSRCADDR; - memcpy(CMSG_DATA(cmsg), lin, sizeof(*lin)); - } - - return _sendmsg(fd, &msg, 0); -} - -static bool_t -svc_dg_reply(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct svc_dg_data *su = su_data(xprt); - XDR *xdrs = &(su->su_xdrs); - bool_t stat = TRUE; - size_t slen; - xdrproc_t xdr_proc; - caddr_t xdr_where; - - xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, 0); - msg->rm_xid = su->su_xid; - if (msg->rm_reply.rp_stat == MSG_ACCEPTED && - msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { - xdr_proc = msg->acpted_rply.ar_results.proc; - xdr_where = msg->acpted_rply.ar_results.where; - msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; - msg->acpted_rply.ar_results.where = NULL; - - if (!xdr_replymsg(xdrs, msg) || - !SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where)) - stat = FALSE; - } else { - stat = xdr_replymsg(xdrs, msg); - } - if (stat) { - slen = XDR_GETPOS(xdrs); - if (svc_dg_sendto(xprt->xp_fd, rpc_buffer(xprt), slen, - (struct sockaddr *)xprt->xp_rtaddr.buf, - (socklen_t)xprt->xp_rtaddr.len, - (struct sockaddr *)su->su_srcaddr.buf, - (socklen_t)su->su_srcaddr.len) == (ssize_t) slen) { - stat = TRUE; - if (su->su_cache) - cache_set(xprt, slen); - } - } - return (stat); -} - -static bool_t -svc_dg_getargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - void *args_ptr; -{ - struct svc_dg_data *su; - - assert(xprt != NULL); - su = su_data(xprt); - return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), - &su->su_xdrs, xdr_args, args_ptr)); -} - -static bool_t -svc_dg_freeargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - void *args_ptr; -{ - XDR *xdrs = &(su_data(xprt)->su_xdrs); - - xdrs->x_op = XDR_FREE; - return (*xdr_args)(xdrs, args_ptr); -} - -static void -svc_dg_destroy(xprt) - SVCXPRT *xprt; -{ - struct svc_dg_data *su = su_data(xprt); - - xprt_unregister(xprt); - if (xprt->xp_fd != -1) - (void)_close(xprt->xp_fd); - XDR_DESTROY(&(su->su_xdrs)); - (void) mem_free(rpc_buffer(xprt), su->su_iosz); - if (su->su_srcaddr.buf) - (void) mem_free(su->su_srcaddr.buf, su->su_srcaddr.maxlen); - (void) mem_free(su, sizeof (*su)); - if (xprt->xp_rtaddr.buf) - (void) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen); - if (xprt->xp_ltaddr.buf) - (void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); - if (xprt->xp_tp) - (void) free(xprt->xp_tp); - svc_xprt_free(xprt); -} - -static bool_t -/*ARGSUSED*/ -svc_dg_control(xprt, rq, in) - SVCXPRT *xprt; - const u_int rq; - void *in; -{ - return (FALSE); -} - -static void -svc_dg_ops(xprt) - SVCXPRT *xprt; -{ - static struct xp_ops ops; - static struct xp_ops2 ops2; - -/* VARIABLES PROTECTED BY ops_lock: ops */ - - mutex_lock(&ops_lock); - if (ops.xp_recv == NULL) { - ops.xp_recv = svc_dg_recv; - ops.xp_stat = svc_dg_stat; - ops.xp_getargs = svc_dg_getargs; - ops.xp_reply = svc_dg_reply; - ops.xp_freeargs = svc_dg_freeargs; - ops.xp_destroy = svc_dg_destroy; - ops2.xp_control = svc_dg_control; - } - xprt->xp_ops = &ops; - xprt->xp_ops2 = &ops2; - mutex_unlock(&ops_lock); -} - -/* The CACHING COMPONENT */ - -/* - * Could have been a separate file, but some part of it depends upon the - * private structure of the client handle. - * - * Fifo cache for cl server - * Copies pointers to reply buffers into fifo cache - * Buffers are sent again if retransmissions are detected. - */ - -#define SPARSENESS 4 /* 75% sparse */ - -#define ALLOC(type, size) \ - (type *) mem_alloc((sizeof (type) * (size))) - -#define MEMZERO(addr, type, size) \ - (void) memset((void *) (addr), 0, sizeof (type) * (int) (size)) - -#define FREE(addr, type, size) \ - mem_free((addr), (sizeof (type) * (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_int32_t cache_xid; - rpcproc_t cache_proc; - rpcvers_t cache_vers; - rpcprog_t cache_prog; - struct netbuf cache_addr; - /* - * The cached reply and length - */ - char *cache_reply; - size_t cache_replylen; - /* - * Next node on the list, if there is a collision - */ - cache_ptr cache_next; -}; - -/* - * The entire cache - */ -struct cl_cache { - u_int 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_int uc_nextvictim; /* points to next victim in fifo list */ - rpcprog_t uc_prog; /* saved program number */ - rpcvers_t uc_vers; /* saved version number */ - rpcproc_t uc_proc; /* saved procedure number */ -}; - - -/* - * the hashing function - */ -#define CACHE_LOC(transp, xid) \ - (xid % (SPARSENESS * ((struct cl_cache *) \ - su_data(transp)->su_cache)->uc_size)) - -/* - * Enable use of the cache. Returns 1 on success, 0 on failure. - * Note: there is no disable. - */ -static const char cache_enable_str[] = "svc_enablecache: %s %s"; -static const char alloc_err[] = "could not allocate cache "; -static const char enable_err[] = "cache already enabled"; - -int -svc_dg_enablecache(transp, size) - SVCXPRT *transp; - u_int size; -{ - struct svc_dg_data *su = su_data(transp); - struct cl_cache *uc; - - mutex_lock(&dupreq_lock); - if (su->su_cache != NULL) { - (void) warnx(cache_enable_str, enable_err, " "); - mutex_unlock(&dupreq_lock); - return (0); - } - uc = ALLOC(struct cl_cache, 1); - if (uc == NULL) { - warnx(cache_enable_str, alloc_err, " "); - mutex_unlock(&dupreq_lock); - return (0); - } - uc->uc_size = size; - uc->uc_nextvictim = 0; - uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS); - if (uc->uc_entries == NULL) { - warnx(cache_enable_str, alloc_err, "data"); - FREE(uc, struct cl_cache, 1); - mutex_unlock(&dupreq_lock); - return (0); - } - MEMZERO(uc->uc_entries, cache_ptr, size * SPARSENESS); - uc->uc_fifo = ALLOC(cache_ptr, size); - if (uc->uc_fifo == NULL) { - warnx(cache_enable_str, alloc_err, "fifo"); - FREE(uc->uc_entries, cache_ptr, size * SPARSENESS); - FREE(uc, struct cl_cache, 1); - mutex_unlock(&dupreq_lock); - return (0); - } - MEMZERO(uc->uc_fifo, cache_ptr, size); - su->su_cache = (char *)(void *)uc; - mutex_unlock(&dupreq_lock); - return (1); -} - -/* - * Set an entry in the cache. It assumes that the uc entry is set from - * the earlier call to cache_get() for the same procedure. This will always - * happen because cache_get() is calle by svc_dg_recv and cache_set() is called - * by svc_dg_reply(). All this hoopla because the right RPC parameters are - * not available at svc_dg_reply time. - */ - -static const char cache_set_str[] = "cache_set: %s"; -static const char cache_set_err1[] = "victim not found"; -static const char cache_set_err2[] = "victim alloc failed"; -static const char cache_set_err3[] = "could not allocate new rpc buffer"; - -static void -cache_set(xprt, replylen) - SVCXPRT *xprt; - size_t replylen; -{ - cache_ptr victim; - cache_ptr *vicp; - struct svc_dg_data *su = su_data(xprt); - struct cl_cache *uc = (struct cl_cache *) su->su_cache; - u_int loc; - char *newbuf; -#ifdef RPC_CACHE_DEBUG - struct netconfig *nconf; - char *uaddr; -#endif - - mutex_lock(&dupreq_lock); - /* - * 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) { - warnx(cache_set_str, cache_set_err1); - mutex_unlock(&dupreq_lock); - return; - } - *vicp = victim->cache_next; /* remove from cache */ - newbuf = victim->cache_reply; - } else { - victim = ALLOC(struct cache_node, 1); - if (victim == NULL) { - warnx(cache_set_str, cache_set_err2); - mutex_unlock(&dupreq_lock); - return; - } - newbuf = mem_alloc(su->su_iosz); - if (newbuf == NULL) { - warnx(cache_set_str, cache_set_err3); - FREE(victim, struct cache_node, 1); - mutex_unlock(&dupreq_lock); - return; - } - } - - /* - * Store it away - */ -#ifdef RPC_CACHE_DEBUG - if (nconf = getnetconfigent(xprt->xp_netid)) { - uaddr = taddr2uaddr(nconf, &xprt->xp_rtaddr); - freenetconfigent(nconf); - printf( - "cache set for xid= %x prog=%d vers=%d proc=%d for rmtaddr=%s\n", - su->su_xid, uc->uc_prog, uc->uc_vers, - uc->uc_proc, uaddr); - free(uaddr); - } -#endif - 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 = xprt->xp_rtaddr; - victim->cache_addr.buf = ALLOC(char, xprt->xp_rtaddr.len); - (void) memcpy(victim->cache_addr.buf, xprt->xp_rtaddr.buf, - (size_t)xprt->xp_rtaddr.len); - 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; - mutex_unlock(&dupreq_lock); -} - -/* - * Try to get an entry from the cache - * return 1 if found, 0 if not found and set the stage for cache_set() - */ -static int -cache_get(xprt, msg, replyp, replylenp) - SVCXPRT *xprt; - struct rpc_msg *msg; - char **replyp; - size_t *replylenp; -{ - u_int loc; - cache_ptr ent; - struct svc_dg_data *su = su_data(xprt); - struct cl_cache *uc = (struct cl_cache *) su->su_cache; -#ifdef RPC_CACHE_DEBUG - struct netconfig *nconf; - char *uaddr; -#endif - - mutex_lock(&dupreq_lock); - 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 == msg->rm_call.cb_proc && - ent->cache_vers == msg->rm_call.cb_vers && - ent->cache_prog == msg->rm_call.cb_prog && - ent->cache_addr.len == xprt->xp_rtaddr.len && - (memcmp(ent->cache_addr.buf, xprt->xp_rtaddr.buf, - xprt->xp_rtaddr.len) == 0)) { -#ifdef RPC_CACHE_DEBUG - if (nconf = getnetconfigent(xprt->xp_netid)) { - uaddr = taddr2uaddr(nconf, &xprt->xp_rtaddr); - freenetconfigent(nconf); - printf( - "cache entry found for xid=%x prog=%d vers=%d proc=%d for rmtaddr=%s\n", - su->su_xid, msg->rm_call.cb_prog, - msg->rm_call.cb_vers, - msg->rm_call.cb_proc, uaddr); - free(uaddr); - } -#endif - *replyp = ent->cache_reply; - *replylenp = ent->cache_replylen; - mutex_unlock(&dupreq_lock); - 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; - mutex_unlock(&dupreq_lock); - return (0); -} diff --git a/lib/libc/rpc/svc_generic.c b/lib/libc/rpc/svc_generic.c deleted file mode 100644 index 7f6cfb8..0000000 --- a/lib/libc/rpc/svc_generic.c +++ /dev/null @@ -1,311 +0,0 @@ -/* $NetBSD: svc_generic.c,v 1.3 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -#ident "@(#)svc_generic.c 1.19 94/04/24 SMI" -static char sccsid[] = "@(#)svc_generic.c 1.21 89/02/28 Copyr 1988 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * svc_generic.c, Server side for RPC. - * - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <rpc/rpc.h> -#include <rpc/nettype.h> -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <err.h> -#include "un-namespace.h" - -#include "rpc_com.h" -#include "mt_misc.h" - -extern int __svc_vc_setflag(SVCXPRT *, int); - -/* - * The highest level interface for server creation. - * It tries for all the nettokens in that particular class of token - * and returns the number of handles it can create and/or find. - * - * It creates a link list of all the handles it could create. - * If svc_create() is called multiple times, it uses the handle - * created earlier instead of creating a new handle every time. - */ -int -svc_create(dispatch, prognum, versnum, nettype) - void (*dispatch)(struct svc_req *, SVCXPRT *); - rpcprog_t prognum; /* Program number */ - rpcvers_t versnum; /* Version number */ - const char *nettype; /* Networktype token */ -{ - struct xlist { - SVCXPRT *xprt; /* Server handle */ - struct xlist *next; /* Next item */ - } *l; - static struct xlist *xprtlist; /* A link list of all the handles */ - int num = 0; - SVCXPRT *xprt; - struct netconfig *nconf; - void *handle; - -/* VARIABLES PROTECTED BY xprtlist_lock: xprtlist */ - - if ((handle = __rpc_setconf(nettype)) == NULL) { - warnx("svc_create: unknown protocol"); - return (0); - } - while ((nconf = __rpc_getconf(handle)) != NULL) { - mutex_lock(&xprtlist_lock); - for (l = xprtlist; l; l = l->next) { - if (strcmp(l->xprt->xp_netid, nconf->nc_netid) == 0) { - /* Found an old one, use it */ - (void) rpcb_unset(prognum, versnum, nconf); - if (svc_reg(l->xprt, prognum, versnum, - dispatch, nconf) == FALSE) - warnx( - "svc_create: could not register prog %u vers %u on %s", - (unsigned)prognum, (unsigned)versnum, - nconf->nc_netid); - else - num++; - break; - } - } - if (l == NULL) { - /* It was not found. Now create a new one */ - xprt = svc_tp_create(dispatch, prognum, versnum, nconf); - if (xprt) { - l = (struct xlist *)malloc(sizeof (*l)); - if (l == NULL) { - warnx("svc_create: no memory"); - mutex_unlock(&xprtlist_lock); - return (0); - } - l->xprt = xprt; - l->next = xprtlist; - xprtlist = l; - num++; - } - } - mutex_unlock(&xprtlist_lock); - } - __rpc_endconf(handle); - /* - * In case of num == 0; the error messages are generated by the - * underlying layers; and hence not needed here. - */ - return (num); -} - -/* - * The high level interface to svc_tli_create(). - * It tries to create a server for "nconf" and registers the service - * with the rpcbind. It calls svc_tli_create(); - */ -SVCXPRT * -svc_tp_create(dispatch, prognum, versnum, nconf) - void (*dispatch)(struct svc_req *, SVCXPRT *); - rpcprog_t prognum; /* Program number */ - rpcvers_t versnum; /* Version number */ - const struct netconfig *nconf; /* Netconfig structure for the network */ -{ - SVCXPRT *xprt; - - if (nconf == NULL) { - warnx( - "svc_tp_create: invalid netconfig structure for prog %u vers %u", - (unsigned)prognum, (unsigned)versnum); - return (NULL); - } - xprt = svc_tli_create(RPC_ANYFD, nconf, NULL, 0, 0); - if (xprt == NULL) { - return (NULL); - } - /*LINTED const castaway*/ - (void) rpcb_unset(prognum, versnum, (struct netconfig *) nconf); - if (svc_reg(xprt, prognum, versnum, dispatch, nconf) == FALSE) { - warnx( - "svc_tp_create: Could not register prog %u vers %u on %s", - (unsigned)prognum, (unsigned)versnum, - nconf->nc_netid); - SVC_DESTROY(xprt); - return (NULL); - } - return (xprt); -} - -/* - * If fd is RPC_ANYFD, then it opens a fd for the given transport - * provider (nconf cannot be NULL then). If the t_state is T_UNBND and - * bindaddr is NON-NULL, it performs a t_bind using the bindaddr. For - * NULL bindadr and Connection oriented transports, the value of qlen - * is set to 8. - * - * If sendsz or recvsz are zero, their default values are chosen. - */ -SVCXPRT * -svc_tli_create(fd, nconf, bindaddr, sendsz, recvsz) - int fd; /* Connection end point */ - const struct netconfig *nconf; /* Netconfig struct for nettoken */ - const struct t_bind *bindaddr; /* Local bind address */ - u_int sendsz; /* Max sendsize */ - u_int recvsz; /* Max recvsize */ -{ - SVCXPRT *xprt = NULL; /* service handle */ - bool_t madefd = FALSE; /* whether fd opened here */ - struct __rpc_sockinfo si; - struct sockaddr_storage ss; - socklen_t slen; - - if (fd == RPC_ANYFD) { - if (nconf == NULL) { - warnx("svc_tli_create: invalid netconfig"); - return (NULL); - } - fd = __rpc_nconf2fd(nconf); - if (fd == -1) { - warnx( - "svc_tli_create: could not open connection for %s", - nconf->nc_netid); - return (NULL); - } - __rpc_nconf2sockinfo(nconf, &si); - madefd = TRUE; - } else { - /* - * It is an open descriptor. Get the transport info. - */ - if (!__rpc_fd2sockinfo(fd, &si)) { - warnx( - "svc_tli_create: could not get transport information"); - return (NULL); - } - } - - /* - * If the fd is unbound, try to bind it. - */ - if (madefd || !__rpc_sockisbound(fd)) { - if (bindaddr == NULL) { - if (bindresvport(fd, NULL) < 0) { - memset(&ss, 0, sizeof ss); - ss.ss_family = si.si_af; - ss.ss_len = si.si_alen; - if (_bind(fd, (struct sockaddr *)(void *)&ss, - (socklen_t)si.si_alen) < 0) { - warnx( - "svc_tli_create: could not bind to anonymous port"); - goto freedata; - } - } - _listen(fd, SOMAXCONN); - } else { - if (_bind(fd, - (struct sockaddr *)bindaddr->addr.buf, - (socklen_t)si.si_alen) < 0) { - warnx( - "svc_tli_create: could not bind to requested address"); - goto freedata; - } - _listen(fd, (int)bindaddr->qlen); - } - - } - /* - * call transport specific function. - */ - switch (si.si_socktype) { - case SOCK_STREAM: - slen = sizeof ss; - if (_getpeername(fd, (struct sockaddr *)(void *)&ss, &slen) - == 0) { - /* accepted socket */ - xprt = svc_fd_create(fd, sendsz, recvsz); - } else - xprt = svc_vc_create(fd, sendsz, recvsz); - if (!nconf || !xprt) - break; -#if 0 - /* XXX fvdl */ - if (strcmp(nconf->nc_protofmly, "inet") == 0 || - strcmp(nconf->nc_protofmly, "inet6") == 0) - (void) __svc_vc_setflag(xprt, TRUE); -#endif - break; - case SOCK_DGRAM: - xprt = svc_dg_create(fd, sendsz, recvsz); - break; - default: - warnx("svc_tli_create: bad service type"); - goto freedata; - } - - if (xprt == NULL) - /* - * The error messages here are spitted out by the lower layers: - * svc_vc_create(), svc_fd_create() and svc_dg_create(). - */ - goto freedata; - - /* Fill in type of service */ - xprt->xp_type = __rpc_socktype2seman(si.si_socktype); - - if (nconf) { - xprt->xp_netid = strdup(nconf->nc_netid); - xprt->xp_tp = strdup(nconf->nc_device); - } - return (xprt); - -freedata: - if (madefd) - (void)_close(fd); - if (xprt) { - if (!madefd) /* so that svc_destroy doesnt close fd */ - xprt->xp_fd = RPC_ANYFD; - SVC_DESTROY(xprt); - } - return (NULL); -} diff --git a/lib/libc/rpc/svc_raw.c b/lib/libc/rpc/svc_raw.c deleted file mode 100644 index 67bcba1..0000000 --- a/lib/libc/rpc/svc_raw.c +++ /dev/null @@ -1,274 +0,0 @@ -/* $NetBSD: svc_raw.c,v 1.14 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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_raw.c 1.16 94/04/24 SMI" */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)svc_raw.c 1.25 89/01/31 Copyr 1984 Sun Micro"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * 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 kernel. - * - */ - -#include "namespace.h" -#include "reentrant.h" -#include <rpc/rpc.h> -#include <sys/types.h> -#include <rpc/raw.h> -#include <stdlib.h> -#include "un-namespace.h" -#include "mt_misc.h" - -#ifndef UDPMSGSIZE -#define UDPMSGSIZE 8800 -#endif - -/* - * This is the "network" that we will be moving data over - */ -static struct svc_raw_private { - char *raw_buf; /* should be shared with the cl handle */ - SVCXPRT *server; - XDR xdr_stream; - char verf_body[MAX_AUTH_BYTES]; -} *svc_raw_private; - -static enum xprt_stat svc_raw_stat(SVCXPRT *); -static bool_t svc_raw_recv(SVCXPRT *, struct rpc_msg *); -static bool_t svc_raw_reply(SVCXPRT *, struct rpc_msg *); -static bool_t svc_raw_getargs(SVCXPRT *, xdrproc_t, void *); -static bool_t svc_raw_freeargs(SVCXPRT *, xdrproc_t, void *); -static void svc_raw_destroy(SVCXPRT *); -static void svc_raw_ops(SVCXPRT *); -static bool_t svc_raw_control(SVCXPRT *, const u_int, void *); - -char *__rpc_rawcombuf = NULL; - -SVCXPRT * -svc_raw_create() -{ - struct svc_raw_private *srp; -/* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */ - - mutex_lock(&svcraw_lock); - srp = svc_raw_private; - if (srp == NULL) { - srp = (struct svc_raw_private *)calloc(1, sizeof (*srp)); - if (srp == NULL) { - mutex_unlock(&svcraw_lock); - return (NULL); - } - if (__rpc_rawcombuf == NULL) - __rpc_rawcombuf = calloc(UDPMSGSIZE, sizeof (char)); - srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */ - srp->server = svc_xprt_alloc(); - svc_raw_private = srp; - } - srp->server->xp_fd = FD_SETSIZE; - srp->server->xp_port = 0; - svc_raw_ops(srp->server); - srp->server->xp_verf.oa_base = srp->verf_body; - xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE); - xprt_register(srp->server); - mutex_unlock(&svcraw_lock); - return (srp->server); -} - -/*ARGSUSED*/ -static enum xprt_stat -svc_raw_stat(xprt) -SVCXPRT *xprt; /* args needed to satisfy ANSI-C typechecking */ -{ - return (XPRT_IDLE); -} - -/*ARGSUSED*/ -static bool_t -svc_raw_recv(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct svc_raw_private *srp; - XDR *xdrs; - - mutex_lock(&svcraw_lock); - srp = svc_raw_private; - if (srp == NULL) { - mutex_unlock(&svcraw_lock); - return (FALSE); - } - mutex_unlock(&svcraw_lock); - - xdrs = &srp->xdr_stream; - xdrs->x_op = XDR_DECODE; - (void) XDR_SETPOS(xdrs, 0); - if (! xdr_callmsg(xdrs, msg)) { - return (FALSE); - } - return (TRUE); -} - -/*ARGSUSED*/ -static bool_t -svc_raw_reply(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct svc_raw_private *srp; - XDR *xdrs; - bool_t stat; - xdrproc_t xdr_proc; - caddr_t xdr_where; - - mutex_lock(&svcraw_lock); - srp = svc_raw_private; - if (srp == NULL) { - mutex_unlock(&svcraw_lock); - return (FALSE); - } - mutex_unlock(&svcraw_lock); - - xdrs = &srp->xdr_stream; - xdrs->x_op = XDR_ENCODE; - (void) XDR_SETPOS(xdrs, 0); - if (msg->rm_reply.rp_stat == MSG_ACCEPTED && - msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { - xdr_proc = msg->acpted_rply.ar_results.proc; - xdr_where = msg->acpted_rply.ar_results.where; - msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; - msg->acpted_rply.ar_results.where = NULL; - - stat = xdr_replymsg(xdrs, msg) && - SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where); - } else { - stat = xdr_replymsg(xdrs, msg); - } - if (!stat) { - return (FALSE); - } - (void) XDR_GETPOS(xdrs); /* called just for overhead */ - return (TRUE); -} - -/*ARGSUSED*/ -static bool_t -svc_raw_getargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - void *args_ptr; -{ - struct svc_raw_private *srp; - - mutex_lock(&svcraw_lock); - srp = svc_raw_private; - if (srp == NULL) { - mutex_unlock(&svcraw_lock); - return (FALSE); - } - mutex_unlock(&svcraw_lock); - - return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), &srp->xdr_stream, - xdr_args, args_ptr)); -} - -/*ARGSUSED*/ -static bool_t -svc_raw_freeargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - void *args_ptr; -{ - struct svc_raw_private *srp; - XDR *xdrs; - - mutex_lock(&svcraw_lock); - srp = svc_raw_private; - if (srp == NULL) { - mutex_unlock(&svcraw_lock); - return (FALSE); - } - mutex_unlock(&svcraw_lock); - - xdrs = &srp->xdr_stream; - xdrs->x_op = XDR_FREE; - return (*xdr_args)(xdrs, args_ptr); -} - -/*ARGSUSED*/ -static void -svc_raw_destroy(xprt) -SVCXPRT *xprt; -{ -} - -/*ARGSUSED*/ -static bool_t -svc_raw_control(xprt, rq, in) - SVCXPRT *xprt; - const u_int rq; - void *in; -{ - return (FALSE); -} - -static void -svc_raw_ops(xprt) - SVCXPRT *xprt; -{ - static struct xp_ops ops; - static struct xp_ops2 ops2; - -/* VARIABLES PROTECTED BY ops_lock: ops */ - - mutex_lock(&ops_lock); - if (ops.xp_recv == NULL) { - ops.xp_recv = svc_raw_recv; - ops.xp_stat = svc_raw_stat; - ops.xp_getargs = svc_raw_getargs; - ops.xp_reply = svc_raw_reply; - ops.xp_freeargs = svc_raw_freeargs; - ops.xp_destroy = svc_raw_destroy; - ops2.xp_control = svc_raw_control; - } - xprt->xp_ops = &ops; - xprt->xp_ops2 = &ops2; - mutex_unlock(&ops_lock); -} diff --git a/lib/libc/rpc/svc_run.c b/lib/libc/rpc/svc_run.c deleted file mode 100644 index b4627d6..0000000 --- a/lib/libc/rpc/svc_run.c +++ /dev/null @@ -1,98 +0,0 @@ -/* $NetBSD: svc_run.c,v 1.17 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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 *sccsid2 = "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"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * This is the rpc server side idle loop - * Wait for input, call server program. - */ -#include "namespace.h" -#include "reentrant.h" -#include <err.h> -#include <errno.h> -#include <rpc/rpc.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include "un-namespace.h" - -#include <rpc/rpc.h> -#include "rpc_com.h" -#include "mt_misc.h" - -void -svc_run() -{ - fd_set readfds, cleanfds; - struct timeval timeout; - - timeout.tv_sec = 30; - timeout.tv_usec = 0; - - for (;;) { - rwlock_rdlock(&svc_fd_lock); - readfds = svc_fdset; - cleanfds = svc_fdset; - rwlock_unlock(&svc_fd_lock); - switch (_select(svc_maxfd+1, &readfds, NULL, NULL, &timeout)) { - case -1: - FD_ZERO(&readfds); - if (errno == EINTR) { - continue; - } - _warn("svc_run: - select failed"); - return; - case 0: - __svc_clean_idle(&cleanfds, 30, FALSE); - continue; - default: - svc_getreqset(&readfds); - } - } -} - -/* - * This function causes svc_run() to exit by telling it that it has no - * more work to do. - */ -void -svc_exit() -{ - rwlock_wrlock(&svc_fd_lock); - FD_ZERO(&svc_fdset); - rwlock_unlock(&svc_fd_lock); -} diff --git a/lib/libc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c deleted file mode 100644 index cf00727..0000000 --- a/lib/libc/rpc/svc_simple.c +++ /dev/null @@ -1,313 +0,0 @@ -/* $NetBSD: svc_simple.c,v 1.20 2000/07/06 03:10:35 christos Exp $ */ - -/* - * 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. - */ - -/* #pragma ident "@(#)svc_simple.c 1.18 94/04/24 SMI" */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * svc_simple.c - * Simplified front end to rpc. - */ - -/* - * This interface creates a virtual listener for all the services - * started thru rpc_reg(). It listens on the same endpoint for - * all the services and then executes the corresponding service - * for the given prognum and procnum. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <rpc/rpc.h> -#include <rpc/nettype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <err.h> -#include "un-namespace.h" - -#include "rpc_com.h" -#include "mt_misc.h" - -static void universal(struct svc_req *, SVCXPRT *); - -static struct proglst { - char *(*p_progname)(char *); - rpcprog_t p_prognum; - rpcvers_t p_versnum; - rpcproc_t p_procnum; - SVCXPRT *p_transp; - char *p_netid; - char *p_xdrbuf; - int p_recvsz; - xdrproc_t p_inproc, p_outproc; - struct proglst *p_nxt; -} *proglst; - -static const char rpc_reg_err[] = "%s: %s"; -static const char rpc_reg_msg[] = "rpc_reg: "; -static const char __reg_err1[] = "can't find appropriate transport"; -static const char __reg_err2[] = "can't get protocol info"; -static const char __reg_err3[] = "unsupported transport size"; -static const char __no_mem_str[] = "out of memory"; - -/* - * For simplified, easy to use kind of rpc interfaces. - * nettype indicates the type of transport on which the service will be - * listening. Used for conservation of the system resource. Only one - * handle is created for all the services (actually one of each netid) - * and same xdrbuf is used for same netid. The size of the arguments - * is also limited by the recvsize for that transport, even if it is - * a COTS transport. This may be wrong, but for cases like these, they - * should not use the simplified interfaces like this. - */ - -int -rpc_reg(prognum, versnum, procnum, progname, inproc, outproc, nettype) - rpcprog_t prognum; /* program number */ - rpcvers_t versnum; /* version number */ - rpcproc_t procnum; /* procedure number */ - char *(*progname)(char *); /* Server routine */ - xdrproc_t inproc, outproc; /* in/out XDR procedures */ - char *nettype; /* nettype */ -{ - struct netconfig *nconf; - int done = FALSE; - void *handle; - - - if (procnum == NULLPROC) { - warnx("%s can't reassign procedure number %u", rpc_reg_msg, - NULLPROC); - return (-1); - } - - if (nettype == NULL) - nettype = "netpath"; /* The default behavior */ - if ((handle = __rpc_setconf(nettype)) == NULL) { - warnx(rpc_reg_err, rpc_reg_msg, __reg_err1); - return (-1); - } -/* VARIABLES PROTECTED BY proglst_lock: proglst */ - mutex_lock(&proglst_lock); - while ((nconf = __rpc_getconf(handle)) != NULL) { - struct proglst *pl; - SVCXPRT *svcxprt; - int madenow; - u_int recvsz; - char *xdrbuf; - char *netid; - - madenow = FALSE; - svcxprt = NULL; - recvsz = 0; - xdrbuf = netid = NULL; - for (pl = proglst; pl; pl = pl->p_nxt) { - if (strcmp(pl->p_netid, nconf->nc_netid) == 0) { - svcxprt = pl->p_transp; - xdrbuf = pl->p_xdrbuf; - recvsz = pl->p_recvsz; - netid = pl->p_netid; - break; - } - } - - if (svcxprt == NULL) { - struct __rpc_sockinfo si; - - svcxprt = svc_tli_create(RPC_ANYFD, nconf, NULL, 0, 0); - if (svcxprt == NULL) - continue; - if (!__rpc_fd2sockinfo(svcxprt->xp_fd, &si)) { - warnx(rpc_reg_err, rpc_reg_msg, __reg_err2); - SVC_DESTROY(svcxprt); - continue; - } - recvsz = __rpc_get_t_size(si.si_af, si.si_proto, 0); - if (recvsz == 0) { - warnx(rpc_reg_err, rpc_reg_msg, __reg_err3); - SVC_DESTROY(svcxprt); - continue; - } - if (((xdrbuf = malloc((unsigned)recvsz)) == NULL) || - ((netid = strdup(nconf->nc_netid)) == NULL)) { - warnx(rpc_reg_err, rpc_reg_msg, __no_mem_str); - if (xdrbuf != NULL) - free(xdrbuf); - if (netid != NULL) - free(netid); - SVC_DESTROY(svcxprt); - break; - } - madenow = TRUE; - } - /* - * Check if this (program, version, netid) had already been - * registered. The check may save a few RPC calls to rpcbind - */ - for (pl = proglst; pl; pl = pl->p_nxt) - if ((pl->p_prognum == prognum) && - (pl->p_versnum == versnum) && - (strcmp(pl->p_netid, netid) == 0)) - break; - if (pl == NULL) { /* Not yet */ - (void) rpcb_unset(prognum, versnum, nconf); - } else { - /* so that svc_reg does not call rpcb_set() */ - nconf = NULL; - } - - if (!svc_reg(svcxprt, prognum, versnum, universal, nconf)) { - warnx("%s couldn't register prog %u vers %u for %s", - rpc_reg_msg, (unsigned)prognum, - (unsigned)versnum, netid); - if (madenow) { - SVC_DESTROY(svcxprt); - free(xdrbuf); - free(netid); - } - continue; - } - - pl = malloc(sizeof (struct proglst)); - if (pl == NULL) { - warnx(rpc_reg_err, rpc_reg_msg, __no_mem_str); - if (madenow) { - SVC_DESTROY(svcxprt); - free(xdrbuf); - free(netid); - } - break; - } - pl->p_progname = progname; - pl->p_prognum = prognum; - pl->p_versnum = versnum; - pl->p_procnum = procnum; - pl->p_inproc = inproc; - pl->p_outproc = outproc; - pl->p_transp = svcxprt; - pl->p_xdrbuf = xdrbuf; - pl->p_recvsz = recvsz; - pl->p_netid = netid; - pl->p_nxt = proglst; - proglst = pl; - done = TRUE; - } - __rpc_endconf(handle); - mutex_unlock(&proglst_lock); - - if (done == FALSE) { - warnx("%s cant find suitable transport for %s", - rpc_reg_msg, nettype); - return (-1); - } - return (0); -} - -/* - * The universal handler for the services registered using registerrpc. - * It handles both the connectionless and the connection oriented cases. - */ - -static void -universal(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; -{ - rpcprog_t prog; - rpcvers_t vers; - rpcproc_t proc; - char *outdata; - char *xdrbuf; - struct proglst *pl; - - /* - * enforce "procnum 0 is echo" convention - */ - if (rqstp->rq_proc == NULLPROC) { - if (svc_sendreply(transp, (xdrproc_t) xdr_void, NULL) == - FALSE) { - warnx("svc_sendreply failed"); - } - return; - } - prog = rqstp->rq_prog; - vers = rqstp->rq_vers; - proc = rqstp->rq_proc; - mutex_lock(&proglst_lock); - for (pl = proglst; pl; pl = pl->p_nxt) - if (pl->p_prognum == prog && pl->p_procnum == proc && - pl->p_versnum == vers && - (strcmp(pl->p_netid, transp->xp_netid) == 0)) { - /* decode arguments into a CLEAN buffer */ - xdrbuf = pl->p_xdrbuf; - /* Zero the arguments: reqd ! */ - (void) memset(xdrbuf, 0, sizeof (pl->p_recvsz)); - /* - * Assuming that sizeof (xdrbuf) would be enough - * for the arguments; if not then the program - * may bomb. BEWARE! - */ - if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { - svcerr_decode(transp); - mutex_unlock(&proglst_lock); - return; - } - outdata = (*(pl->p_progname))(xdrbuf); - if (outdata == NULL && - pl->p_outproc != (xdrproc_t) xdr_void){ - /* there was an error */ - mutex_unlock(&proglst_lock); - return; - } - if (!svc_sendreply(transp, pl->p_outproc, outdata)) { - warnx( - "rpc: rpc_reg trouble replying to prog %u vers %u", - (unsigned)prog, (unsigned)vers); - mutex_unlock(&proglst_lock); - return; - } - /* free the decoded arguments */ - (void)svc_freeargs(transp, pl->p_inproc, xdrbuf); - mutex_unlock(&proglst_lock); - return; - } - mutex_unlock(&proglst_lock); - /* This should never happen */ - warnx("rpc: rpc_reg: never registered prog %u vers %u", - (unsigned)prog, (unsigned)vers); - return; -} diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c deleted file mode 100644 index 3fd8b7e..0000000 --- a/lib/libc/rpc/svc_vc.c +++ /dev/null @@ -1,810 +0,0 @@ -/* $NetBSD: svc_vc.c,v 1.7 2000/08/03 00:01:53 fvdl Exp $ */ - -/* - * 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 *sccsid2 = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * svc_vc.c, Server side for Connection Oriented based RPC. - * - * Actually implements two flavors of transporter - - * a tcp rendezvouser (a listner and connection establisher) - * and a record/tcp stream. - */ - -#include "namespace.h" -#include "reentrant.h" -#include <sys/types.h> -#include <sys/param.h> -#include <sys/poll.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/time.h> -#include <sys/uio.h> -#include <netinet/in.h> -#include <netinet/tcp.h> - -#include <assert.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <rpc/rpc.h> - -#include "rpc_com.h" -#include "mt_misc.h" -#include "un-namespace.h" - -static SVCXPRT *makefd_xprt(int, u_int, u_int); -static bool_t rendezvous_request(SVCXPRT *, struct rpc_msg *); -static enum xprt_stat rendezvous_stat(SVCXPRT *); -static void svc_vc_destroy(SVCXPRT *); -static void __svc_vc_dodestroy (SVCXPRT *); -static int read_vc(void *, void *, int); -static int write_vc(void *, void *, int); -static enum xprt_stat svc_vc_stat(SVCXPRT *); -static bool_t svc_vc_recv(SVCXPRT *, struct rpc_msg *); -static bool_t svc_vc_getargs(SVCXPRT *, xdrproc_t, void *); -static bool_t svc_vc_freeargs(SVCXPRT *, xdrproc_t, void *); -static bool_t svc_vc_reply(SVCXPRT *, struct rpc_msg *); -static void svc_vc_rendezvous_ops(SVCXPRT *); -static void svc_vc_ops(SVCXPRT *); -static bool_t svc_vc_control(SVCXPRT *xprt, const u_int rq, void *in); -static bool_t svc_vc_rendezvous_control (SVCXPRT *xprt, const u_int rq, - void *in); - -struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */ - u_int sendsize; - u_int recvsize; - int maxrec; -}; - -struct cf_conn { /* kept in xprt->xp_p1 for actual connection */ - enum xprt_stat strm_stat; - u_int32_t x_id; - XDR xdrs; - char verf_body[MAX_AUTH_BYTES]; - u_int sendsize; - u_int recvsize; - int maxrec; - bool_t nonblock; - struct timeval last_recv_time; -}; - -/* - * Usage: - * xprt = svc_vc_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. - * - * The filedescriptor passed in is expected to refer to a bound, but - * not yet connected socket. - * - * Since 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 * -svc_vc_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - SVCXPRT *xprt; - struct cf_rendezvous *r = NULL; - struct __rpc_sockinfo si; - struct sockaddr_storage sslocal; - socklen_t slen; - - if (!__rpc_fd2sockinfo(fd, &si)) - return NULL; - - r = mem_alloc(sizeof(*r)); - if (r == NULL) { - warnx("svc_vc_create: out of memory"); - goto cleanup_svc_vc_create; - } - r->sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize); - r->recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize); - r->maxrec = __svc_maxrec; - xprt = svc_xprt_alloc(); - if (xprt == NULL) { - warnx("svc_vc_create: out of memory"); - goto cleanup_svc_vc_create; - } - xprt->xp_p1 = r; - xprt->xp_verf = _null_auth; - svc_vc_rendezvous_ops(xprt); - xprt->xp_port = (u_short)-1; /* It is the rendezvouser */ - xprt->xp_fd = fd; - - slen = sizeof (struct sockaddr_storage); - if (_getsockname(fd, (struct sockaddr *)(void *)&sslocal, &slen) < 0) { - warnx("svc_vc_create: could not retrieve local addr"); - goto cleanup_svc_vc_create; - } - - xprt->xp_ltaddr.maxlen = xprt->xp_ltaddr.len = sslocal.ss_len; - xprt->xp_ltaddr.buf = mem_alloc((size_t)sslocal.ss_len); - if (xprt->xp_ltaddr.buf == NULL) { - warnx("svc_vc_create: no mem for local addr"); - goto cleanup_svc_vc_create; - } - memcpy(xprt->xp_ltaddr.buf, &sslocal, (size_t)sslocal.ss_len); - - xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage); - xprt_register(xprt); - return (xprt); -cleanup_svc_vc_create: - if (xprt) - mem_free(xprt, sizeof(*xprt)); - if (r != NULL) - mem_free(r, sizeof(*r)); - return (NULL); -} - -/* - * Like svtcp_create(), except the routine takes any *open* UNIX file - * descriptor as its first input. - */ -SVCXPRT * -svc_fd_create(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - struct sockaddr_storage ss; - socklen_t slen; - SVCXPRT *ret; - - assert(fd != -1); - - ret = makefd_xprt(fd, sendsize, recvsize); - if (ret == NULL) - return NULL; - - slen = sizeof (struct sockaddr_storage); - if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) { - warnx("svc_fd_create: could not retrieve local addr"); - goto freedata; - } - ret->xp_ltaddr.maxlen = ret->xp_ltaddr.len = ss.ss_len; - ret->xp_ltaddr.buf = mem_alloc((size_t)ss.ss_len); - if (ret->xp_ltaddr.buf == NULL) { - warnx("svc_fd_create: no mem for local addr"); - goto freedata; - } - memcpy(ret->xp_ltaddr.buf, &ss, (size_t)ss.ss_len); - - slen = sizeof (struct sockaddr_storage); - if (_getpeername(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) { - warnx("svc_fd_create: could not retrieve remote addr"); - goto freedata; - } - ret->xp_rtaddr.maxlen = ret->xp_rtaddr.len = ss.ss_len; - ret->xp_rtaddr.buf = mem_alloc((size_t)ss.ss_len); - if (ret->xp_rtaddr.buf == NULL) { - warnx("svc_fd_create: no mem for local addr"); - goto freedata; - } - memcpy(ret->xp_rtaddr.buf, &ss, (size_t)ss.ss_len); -#ifdef PORTMAP - if (ss.ss_family == AF_INET || ss.ss_family == AF_LOCAL) { - ret->xp_raddr = *(struct sockaddr_in *)ret->xp_rtaddr.buf; - ret->xp_addrlen = sizeof (struct sockaddr_in); - } -#endif /* PORTMAP */ - - return ret; - -freedata: - if (ret->xp_ltaddr.buf != NULL) - mem_free(ret->xp_ltaddr.buf, rep->xp_ltaddr.maxlen); - - return NULL; -} - -static SVCXPRT * -makefd_xprt(fd, sendsize, recvsize) - int fd; - u_int sendsize; - u_int recvsize; -{ - SVCXPRT *xprt; - struct cf_conn *cd; - const char *netid; - struct __rpc_sockinfo si; - - assert(fd != -1); - - xprt = svc_xprt_alloc(); - if (xprt == NULL) { - warnx("svc_vc: makefd_xprt: out of memory"); - goto done; - } - cd = mem_alloc(sizeof(struct cf_conn)); - if (cd == NULL) { - warnx("svc_tcp: makefd_xprt: out of memory"); - svc_xprt_free(xprt); - xprt = NULL; - goto done; - } - cd->strm_stat = XPRT_IDLE; - xdrrec_create(&(cd->xdrs), sendsize, recvsize, - xprt, read_vc, write_vc); - xprt->xp_p1 = cd; - xprt->xp_verf.oa_base = cd->verf_body; - svc_vc_ops(xprt); /* truely deals with calls */ - xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ - xprt->xp_fd = fd; - if (__rpc_fd2sockinfo(fd, &si) && __rpc_sockinfo2netid(&si, &netid)) - xprt->xp_netid = strdup(netid); - - xprt_register(xprt); -done: - return (xprt); -} - -/*ARGSUSED*/ -static bool_t -rendezvous_request(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - int sock, flags; - struct cf_rendezvous *r; - struct cf_conn *cd; - struct sockaddr_storage addr; - socklen_t len; - struct __rpc_sockinfo si; - SVCXPRT *newxprt; - fd_set cleanfds; - - assert(xprt != NULL); - assert(msg != NULL); - - r = (struct cf_rendezvous *)xprt->xp_p1; -again: - len = sizeof addr; - if ((sock = _accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr, - &len)) < 0) { - if (errno == EINTR) - goto again; - /* - * Clean out the most idle file descriptor when we're - * running out. - */ - if (errno == EMFILE || errno == ENFILE) { - cleanfds = svc_fdset; - __svc_clean_idle(&cleanfds, 0, FALSE); - goto again; - } - return (FALSE); - } - /* - * make a new transporter (re-uses xprt) - */ - newxprt = makefd_xprt(sock, r->sendsize, r->recvsize); - newxprt->xp_rtaddr.buf = mem_alloc(len); - if (newxprt->xp_rtaddr.buf == NULL) - return (FALSE); - memcpy(newxprt->xp_rtaddr.buf, &addr, len); - newxprt->xp_rtaddr.len = len; -#ifdef PORTMAP - if (addr.ss_family == AF_INET || addr.ss_family == AF_LOCAL) { - newxprt->xp_raddr = *(struct sockaddr_in *)newxprt->xp_rtaddr.buf; - newxprt->xp_addrlen = sizeof (struct sockaddr_in); - } -#endif /* PORTMAP */ - if (__rpc_fd2sockinfo(sock, &si) && si.si_proto == IPPROTO_TCP) { - len = 1; - /* XXX fvdl - is this useful? */ - _setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &len, sizeof (len)); - } - - cd = (struct cf_conn *)newxprt->xp_p1; - - cd->recvsize = r->recvsize; - cd->sendsize = r->sendsize; - cd->maxrec = r->maxrec; - - if (cd->maxrec != 0) { - flags = _fcntl(sock, F_GETFL, 0); - if (flags == -1) - return (FALSE); - if (_fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) - return (FALSE); - if (cd->recvsize > cd->maxrec) - cd->recvsize = cd->maxrec; - cd->nonblock = TRUE; - __xdrrec_setnonblock(&cd->xdrs, cd->maxrec); - } else - cd->nonblock = FALSE; - - gettimeofday(&cd->last_recv_time, NULL); - - return (FALSE); /* there is never an rpc msg to be processed */ -} - -/*ARGSUSED*/ -static enum xprt_stat -rendezvous_stat(xprt) - SVCXPRT *xprt; -{ - - return (XPRT_IDLE); -} - -static void -svc_vc_destroy(xprt) - SVCXPRT *xprt; -{ - assert(xprt != NULL); - - xprt_unregister(xprt); - __svc_vc_dodestroy(xprt); -} - -static void -__svc_vc_dodestroy(xprt) - SVCXPRT *xprt; -{ - struct cf_conn *cd; - struct cf_rendezvous *r; - - cd = (struct cf_conn *)xprt->xp_p1; - - if (xprt->xp_fd != RPC_ANYFD) - (void)_close(xprt->xp_fd); - if (xprt->xp_port != 0) { - /* a rendezvouser socket */ - r = (struct cf_rendezvous *)xprt->xp_p1; - mem_free(r, sizeof (struct cf_rendezvous)); - xprt->xp_port = 0; - } else { - /* an actual connection socket */ - XDR_DESTROY(&(cd->xdrs)); - mem_free(cd, sizeof(struct cf_conn)); - } - if (xprt->xp_rtaddr.buf) - mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen); - if (xprt->xp_ltaddr.buf) - mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); - if (xprt->xp_tp) - free(xprt->xp_tp); - if (xprt->xp_netid) - free(xprt->xp_netid); - svc_xprt_free(xprt); -} - -/*ARGSUSED*/ -static bool_t -svc_vc_control(xprt, rq, in) - SVCXPRT *xprt; - const u_int rq; - void *in; -{ - return (FALSE); -} - -static bool_t -svc_vc_rendezvous_control(xprt, rq, in) - SVCXPRT *xprt; - const u_int rq; - void *in; -{ - struct cf_rendezvous *cfp; - - cfp = (struct cf_rendezvous *)xprt->xp_p1; - if (cfp == NULL) - return (FALSE); - switch (rq) { - case SVCGET_CONNMAXREC: - *(int *)in = cfp->maxrec; - break; - case SVCSET_CONNMAXREC: - cfp->maxrec = *(int *)in; - break; - default: - return (FALSE); - } - return (TRUE); -} - -/* - * reads data from the tcp or uip connection. - * any error is fatal and the connection is closed. - * (And a read of zero bytes is a half closed stream => error.) - * All read operations timeout after 35 seconds. A timeout is - * fatal for the connection. - */ -static int -read_vc(xprtp, buf, len) - void *xprtp; - void *buf; - int len; -{ - SVCXPRT *xprt; - int sock; - int milliseconds = 35 * 1000; - struct pollfd pollfd; - struct cf_conn *cfp; - - xprt = (SVCXPRT *)xprtp; - assert(xprt != NULL); - - sock = xprt->xp_fd; - - cfp = (struct cf_conn *)xprt->xp_p1; - - if (cfp->nonblock) { - len = _read(sock, buf, (size_t)len); - if (len < 0) { - if (errno == EAGAIN) - len = 0; - else - goto fatal_err; - } - if (len != 0) - gettimeofday(&cfp->last_recv_time, NULL); - return len; - } - - do { - pollfd.fd = sock; - pollfd.events = POLLIN; - pollfd.revents = 0; - switch (_poll(&pollfd, 1, milliseconds)) { - case -1: - if (errno == EINTR) - continue; - /*FALLTHROUGH*/ - case 0: - goto fatal_err; - - default: - break; - } - } while ((pollfd.revents & POLLIN) == 0); - - if ((len = _read(sock, buf, (size_t)len)) > 0) { - gettimeofday(&cfp->last_recv_time, NULL); - return (len); - } - -fatal_err: - ((struct cf_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; - return (-1); -} - -/* - * writes data to the tcp connection. - * Any error is fatal and the connection is closed. - */ -static int -write_vc(xprtp, buf, len) - void *xprtp; - void *buf; - int len; -{ - SVCXPRT *xprt; - int i, cnt; - struct cf_conn *cd; - struct timeval tv0, tv1; - - xprt = (SVCXPRT *)xprtp; - assert(xprt != NULL); - - cd = (struct cf_conn *)xprt->xp_p1; - - if (cd->nonblock) - gettimeofday(&tv0, NULL); - - for (cnt = len; cnt > 0; cnt -= i, buf = (char *)buf + i) { - i = _write(xprt->xp_fd, buf, (size_t)cnt); - if (i < 0) { - if (errno != EAGAIN || !cd->nonblock) { - cd->strm_stat = XPRT_DIED; - return (-1); - } - if (cd->nonblock && i != cnt) { - /* - * For non-blocking connections, do not - * take more than 2 seconds writing the - * data out. - * - * XXX 2 is an arbitrary amount. - */ - gettimeofday(&tv1, NULL); - if (tv1.tv_sec - tv0.tv_sec >= 2) { - cd->strm_stat = XPRT_DIED; - return (-1); - } - } - } - } - - return (len); -} - -static enum xprt_stat -svc_vc_stat(xprt) - SVCXPRT *xprt; -{ - struct cf_conn *cd; - - assert(xprt != NULL); - - cd = (struct cf_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 -svc_vc_recv(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct cf_conn *cd; - XDR *xdrs; - - assert(xprt != NULL); - assert(msg != NULL); - - cd = (struct cf_conn *)(xprt->xp_p1); - xdrs = &(cd->xdrs); - - if (cd->nonblock) { - if (!__xdrrec_getrec(xdrs, &cd->strm_stat, TRUE)) - return FALSE; - } else { - (void)xdrrec_skiprecord(xdrs); - } - - xdrs->x_op = XDR_DECODE; - if (xdr_callmsg(xdrs, msg)) { - cd->x_id = msg->rm_xid; - return (TRUE); - } - cd->strm_stat = XPRT_DIED; - return (FALSE); -} - -static bool_t -svc_vc_getargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - void *args_ptr; -{ - struct cf_conn *cd; - - assert(xprt != NULL); - cd = (struct cf_conn *)(xprt->xp_p1); - return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), - &cd->xdrs, xdr_args, args_ptr)); -} - -static bool_t -svc_vc_freeargs(xprt, xdr_args, args_ptr) - SVCXPRT *xprt; - xdrproc_t xdr_args; - void *args_ptr; -{ - XDR *xdrs; - - assert(xprt != NULL); - /* args_ptr may be NULL */ - - xdrs = &(((struct cf_conn *)(xprt->xp_p1))->xdrs); - - xdrs->x_op = XDR_FREE; - return ((*xdr_args)(xdrs, args_ptr)); -} - -static bool_t -svc_vc_reply(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; -{ - struct cf_conn *cd; - XDR *xdrs; - bool_t rstat; - xdrproc_t xdr_proc; - caddr_t xdr_where; - u_int pos; - - assert(xprt != NULL); - assert(msg != NULL); - - cd = (struct cf_conn *)(xprt->xp_p1); - xdrs = &(cd->xdrs); - - xdrs->x_op = XDR_ENCODE; - msg->rm_xid = cd->x_id; - rstat = TRUE; - if (msg->rm_reply.rp_stat == MSG_ACCEPTED && - msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { - xdr_proc = msg->acpted_rply.ar_results.proc; - xdr_where = msg->acpted_rply.ar_results.where; - msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; - msg->acpted_rply.ar_results.where = NULL; - - pos = XDR_GETPOS(xdrs); - if (!xdr_replymsg(xdrs, msg) || - !SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where)) { - XDR_SETPOS(xdrs, pos); - rstat = FALSE; - } - } else { - rstat = xdr_replymsg(xdrs, msg); - } - - if (rstat) - (void)xdrrec_endofrecord(xdrs, TRUE); - - return (rstat); -} - -static void -svc_vc_ops(xprt) - SVCXPRT *xprt; -{ - static struct xp_ops ops; - static struct xp_ops2 ops2; - -/* VARIABLES PROTECTED BY ops_lock: ops, ops2 */ - - mutex_lock(&ops_lock); - if (ops.xp_recv == NULL) { - ops.xp_recv = svc_vc_recv; - ops.xp_stat = svc_vc_stat; - ops.xp_getargs = svc_vc_getargs; - ops.xp_reply = svc_vc_reply; - ops.xp_freeargs = svc_vc_freeargs; - ops.xp_destroy = svc_vc_destroy; - ops2.xp_control = svc_vc_control; - } - xprt->xp_ops = &ops; - xprt->xp_ops2 = &ops2; - mutex_unlock(&ops_lock); -} - -static void -svc_vc_rendezvous_ops(xprt) - SVCXPRT *xprt; -{ - static struct xp_ops ops; - static struct xp_ops2 ops2; - - mutex_lock(&ops_lock); - if (ops.xp_recv == NULL) { - ops.xp_recv = rendezvous_request; - ops.xp_stat = rendezvous_stat; - ops.xp_getargs = - (bool_t (*)(SVCXPRT *, xdrproc_t, void *))abort; - ops.xp_reply = - (bool_t (*)(SVCXPRT *, struct rpc_msg *))abort; - ops.xp_freeargs = - (bool_t (*)(SVCXPRT *, xdrproc_t, void *))abort, - ops.xp_destroy = svc_vc_destroy; - ops2.xp_control = svc_vc_rendezvous_control; - } - xprt->xp_ops = &ops; - xprt->xp_ops2 = &ops2; - mutex_unlock(&ops_lock); -} - -/* - * Get the effective UID of the sending process. Used by rpcbind, keyserv - * and rpc.yppasswdd on AF_LOCAL. - */ -int -__rpc_get_local_uid(SVCXPRT *transp, uid_t *uid) { - int sock, ret; - gid_t egid; - uid_t euid; - struct sockaddr *sa; - - sock = transp->xp_fd; - sa = (struct sockaddr *)transp->xp_rtaddr.buf; - if (sa->sa_family == AF_LOCAL) { - ret = getpeereid(sock, &euid, &egid); - if (ret == 0) - *uid = euid; - return (ret); - } else - return (-1); -} - -/* - * Destroy xprts that have not have had any activity in 'timeout' seconds. - * If 'cleanblock' is true, blocking connections (the default) are also - * cleaned. If timeout is 0, the least active connection is picked. - */ -bool_t -__svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) -{ - int i, ncleaned; - SVCXPRT *xprt, *least_active; - struct timeval tv, tdiff, tmax; - struct cf_conn *cd; - - gettimeofday(&tv, NULL); - tmax.tv_sec = tmax.tv_usec = 0; - least_active = NULL; - rwlock_wrlock(&svc_fd_lock); - for (i = ncleaned = 0; i <= svc_maxfd; i++) { - if (FD_ISSET(i, fds)) { - xprt = __svc_xports[i]; - if (xprt == NULL || xprt->xp_ops == NULL || - xprt->xp_ops->xp_recv != svc_vc_recv) - continue; - cd = (struct cf_conn *)xprt->xp_p1; - if (!cleanblock && !cd->nonblock) - continue; - if (timeout == 0) { - timersub(&tv, &cd->last_recv_time, &tdiff); - if (timercmp(&tdiff, &tmax, >)) { - tmax = tdiff; - least_active = xprt; - } - continue; - } - if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) { - __xprt_unregister_unlocked(xprt); - __svc_vc_dodestroy(xprt); - ncleaned++; - } - } - } - if (timeout == 0 && least_active != NULL) { - __xprt_unregister_unlocked(least_active); - __svc_vc_dodestroy(least_active); - ncleaned++; - } - rwlock_unlock(&svc_fd_lock); - return ncleaned > 0 ? TRUE : FALSE; -} |