diff options
author | Roland McGrath <roland@gnu.org> | 1995-02-18 01:27:10 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1995-02-18 01:27:10 +0000 |
commit | 28f540f45bbacd939bfd07f213bcad2bf730b1bf (patch) | |
tree | 15f07c4c43d635959c6afee96bde71fb1b3614ee /sunrpc |
initial import
Diffstat (limited to 'sunrpc')
80 files changed, 16471 insertions, 0 deletions
diff --git a/sunrpc/.cvsignore b/sunrpc/.cvsignore new file mode 100644 index 0000000000..048c2371e5 --- /dev/null +++ b/sunrpc/.cvsignore @@ -0,0 +1,6 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* + +rpcsrc-4.0 diff --git a/sunrpc/Makefile b/sunrpc/Makefile new file mode 100644 index 0000000000..6a5f895722 --- /dev/null +++ b/sunrpc/Makefile @@ -0,0 +1,128 @@ +# Copyright (C) 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for sunrpc portion of the library. +# +subdir := sunrpc + +# The code in this subdirectory is taken verbatim from Sun's RPCSRC-4.0 +# distribution. A few files needed trivial modifications to compile in the +# GNU environment; these changes are marked by comments that say +# `roland@gnu'. All the code from Sun's rpc, etc, and rpcgen +# subdirectories is in this directory; the rpc subdirectory contains only +# the header files. Other than that, several files were renamed so as not +# to exceed 14-character file name limits: +# +# authunix_prot.c -> authuxprot.c +# bindresvport.c -> bindrsvprt.c +# clnt_generic.c -> clnt_gen.c +# clnt_perror.c -> clnt_perr.c +# clnt_simple.c -> clnt_simp.c +# get_myaddress.c -> get_myaddr.c +# pmap_getmaps.c -> pm_getmaps.c +# pmap_getport.c -> pm_getport.c +# rpc_callmsg.c -> rpc_cmsg.c +# rpc_commondata.c -> rpc_common.c +# rpc_dtablesize.c -> rpc_dtable.c +# svc_auth_unix.c -> svc_authux.c +# xdr_reference.c -> xdr_ref.c +# rpcsvc/bootparam_prot.x -> rpcsvc/bootparam.x + +headers = $(addprefix rpc/,auth.h auth_unix.h clnt.h netdb.h pmap_clnt.h \ + pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h \ + svc_auth.h types.h xdr.h) \ + $(rpcsvc:%=rpcsvc/%) $(rpcsvc:%.x=rpcsvc/%.h) +rpcsvc = bootparam.x nlm_prot.x rstat.x \ + yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \ + rnusers.x spray.x nfs_prot.x rquota.x yp.x +install-others = $(includedir)/rpcsvc/bootparam_prot.h \ + $(sysconfdir)/rpc +generated = $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) + +routines := auth_none auth_unix authuxprot bindrsvprt \ + clnt_gen clnt_perr clnt_raw clnt_simp clnt_tcp \ + clnt_udp rpc_dtable get_myaddr getrpcent getrpcport \ + pmap_clnt pm_getmaps pm_getport pmap_prot \ + pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg \ + svc svc_auth svc_authux svc_raw svc_run svc_simple \ + svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \ + xdr_rec xdr_ref xdr_stdio + +install-lib := librpcsvc.a +install-bin := rpcgen +install-sbin := rpcinfo portmap +rpcsvc-objs = $(rpcsvc:%.x=x%.o) +rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ + rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o +extra-objs = $(rpcgen-objs) $(rpcsvc-objs) +omit-deps = $(basename $(rpcsvc-objs)) +# These headers are part of rpcgen. +distribute := rpc_util.h rpc_parse.h rpc_scan.h $(rpcgen-objs:.o=.c) etc.rpc + +others := portmap rpcinfo + +# Sun's code is not too clean. +override +gccwarn := -w + +include ../Rules + +$(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) $(libc.a) + $(+link) + +rpcgen-cmd = $(dir $(word 2,$^))$(notdir $(word 2,$^)) + +# The proper file name is longer than 14 chars, so we install it under +# a shorter name. But if the filesystem can handle it, we want to +# install under the proper name as well. +$(includedir)/rpcsvc/bootparam_prot.h: $(includedir)/rpcsvc/bootparam.h + @echo It is safe to ignore an error here if this file name is too long. + -$(do-install) + +# Install the rpc data base file. +$(sysconfdir)/rpc: etc.rpc + $(do-install) + +defines := $(defines) -D_PATH_RPC='"$(sysconfdir)/rpc"' + +# Build the `rpcsvc' library of XDR functions. + +lib: $(objpfx)librpcsvc.a + +$(objpfx)librpcsvc.a: $(addprefix $(objpfx),$(rpcsvc-objs)) +# This library is small enough that it's simplest to recreate the archive +# from scratch each time. + rm -f $@ +ifdef objdir + cd $(objdir); $(AR) cq$(verbose) $@ $(^:$(objpfx)%=%) +else + $(AR) cq$(verbose) $@ $^ +endif + $(RANLIB) $@ + +# Generate the rpcsvc headers with rpcgen. +$(objpfx)rpcsvc/%.h: rpcsvc/%.x $(objpfx)rpcgen + $(make-target-directory) + $(rpcgen-cmd) -h $< -o $@ +# Generate the rpcsvc XDR functions with rpcgen. +$(objpfx)x%.c: rpcsvc/%.x $(objpfx)rpcgen + $(rpcgen-cmd) -c $< -o $@ +# The generated source files depend on the corresponding generated headers. +# Gratuitous dependency on generated .c file here just gets it mentioned to +# avoid being an intermediate file and getting removed. +$(rpcsvc:%.x=$(objpfx)x%.o): $(objpfx)x%.o: $(objpfx)x%.c $(objpfx)rpcsvc/%.h diff --git a/sunrpc/auth_none.c b/sunrpc/auth_none.c new file mode 100644 index 0000000000..630037fb47 --- /dev/null +++ b/sunrpc/auth_none.c @@ -0,0 +1,133 @@ +/* @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * auth_none.c + * Creates a client authentication handle for passing "null" + * credentials and verifiers to remote systems. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#define MAX_MARSHEL_SIZE 20 + +/* + * Authenticator operations routines + */ +static void authnone_verf(); +static void authnone_destroy(); +static bool_t authnone_marshal(); +static bool_t authnone_validate(); +static bool_t authnone_refresh(); + +static struct auth_ops ops = { + authnone_verf, + authnone_marshal, + authnone_validate, + authnone_refresh, + authnone_destroy +}; + +static struct authnone_private { + AUTH no_client; + char marshalled_client[MAX_MARSHEL_SIZE]; + u_int mcnt; +} *authnone_private; + +AUTH * +authnone_create() +{ + register struct authnone_private *ap = authnone_private; + XDR xdr_stream; + register XDR *xdrs; + + if (ap == 0) { + ap = (struct authnone_private *)calloc(1, sizeof (*ap)); + if (ap == 0) + return (0); + authnone_private = ap; + } + if (!ap->mcnt) { + ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth; + ap->no_client.ah_ops = &ops; + xdrs = &xdr_stream; + xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE, + XDR_ENCODE); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf); + ap->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + } + return (&ap->no_client); +} + +/*ARGSUSED*/ +static bool_t +authnone_marshal(client, xdrs) + AUTH *client; + XDR *xdrs; +{ + register struct authnone_private *ap = authnone_private; + + if (ap == 0) + return (0); + return ((*xdrs->x_ops->x_putbytes)(xdrs, + ap->marshalled_client, ap->mcnt)); +} + +static void +authnone_verf() +{ +} + +static bool_t +authnone_validate() +{ + + return (TRUE); +} + +static bool_t +authnone_refresh() +{ + + return (FALSE); +} + +static void +authnone_destroy() +{ +} diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c new file mode 100644 index 0000000000..87ff2b648b --- /dev/null +++ b/sunrpc/auth_unix.c @@ -0,0 +1,319 @@ +/* @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * auth_unix.c, Implements UNIX style authentication parameters. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The system is very weak. The client uses no encryption for it's + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + * + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> + +/* + * Unix authenticator operations vector + */ +static void authunix_nextverf(); +static bool_t authunix_marshal(); +static bool_t authunix_validate(); +static bool_t authunix_refresh(); +static void authunix_destroy(); + +static struct auth_ops auth_unix_ops = { + authunix_nextverf, + authunix_marshal, + authunix_validate, + authunix_refresh, + authunix_destroy +}; + +/* + * This struct is pointed to by the ah_private field of an auth_handle. + */ +struct audata { + struct opaque_auth au_origcred; /* original credentials */ + struct opaque_auth au_shcred; /* short hand cred */ + u_long au_shfaults; /* short hand cache faults */ + char au_marshed[MAX_AUTH_BYTES]; + u_int au_mpos; /* xdr pos at end of marshed */ +}; +#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) + +static bool_t marshal_new_auth(); + + +/* + * Create a unix style authenticator. + * Returns an auth handle with the given stuff in it. + */ +AUTH * +authunix_create(machname, uid, gid, len, aup_gids) + char *machname; + int uid; + int gid; + register int len; + int *aup_gids; +{ + struct authunix_parms aup; + char mymem[MAX_AUTH_BYTES]; + struct timeval now; + XDR xdrs; + register AUTH *auth; + register struct audata *au; + + /* + * Allocate and set up auth handle + */ + auth = (AUTH *)mem_alloc(sizeof(*auth)); +#ifndef KERNEL + if (auth == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + au = (struct audata *)mem_alloc(sizeof(*au)); +#ifndef KERNEL + if (au == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + auth->ah_ops = &auth_unix_ops; + auth->ah_private = (caddr_t)au; + auth->ah_verf = au->au_shcred = _null_auth; + au->au_shfaults = 0; + + /* + * fill in param struct from the given params + */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + aup.aup_machname = machname; + aup.aup_uid = uid; + aup.aup_gid = gid; + aup.aup_len = (u_int)len; + aup.aup_gids = aup_gids; + + /* + * Serialize the parameters into origcred + */ + xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); + if (! xdr_authunix_parms(&xdrs, &aup)) + abort(); + au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); + au->au_origcred.oa_flavor = AUTH_UNIX; +#ifdef KERNEL + au->au_origcred.oa_base = mem_alloc((u_int) len); +#else + if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + bcopy(mymem, au->au_origcred.oa_base, (u_int)len); + + /* + * set auth handle to reflect new cred. + */ + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); + return (auth); +} + +/* + * Returns an auth handle with parameters determined by doing lots of + * syscalls. + */ +AUTH * +authunix_create_default() +{ + register int len; + char machname[MAX_MACHINE_NAME + 1]; + register int uid; + register int gid; + int gids[NGRPS]; + + if (gethostname(machname, MAX_MACHINE_NAME) == -1) + abort(); + machname[MAX_MACHINE_NAME] = 0; + uid = geteuid(); + gid = getegid(); + if ((len = getgroups(NGRPS, gids)) < 0) + abort(); + return (authunix_create(machname, uid, gid, len, gids)); +} + +/* + * authunix operations + */ + +static void +authunix_nextverf(auth) + AUTH *auth; +{ + /* no action necessary */ +} + +static bool_t +authunix_marshal(auth, xdrs) + AUTH *auth; + XDR *xdrs; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); +} + +static bool_t +authunix_validate(auth, verf) + register AUTH *auth; + struct opaque_auth verf; +{ + register struct audata *au; + XDR xdrs; + + if (verf.oa_flavor == AUTH_SHORT) { + au = AUTH_PRIVATE(auth); + xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE); + + if (au->au_shcred.oa_base != NULL) { + mem_free(au->au_shcred.oa_base, + au->au_shcred.oa_length); + au->au_shcred.oa_base = NULL; + } + if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { + auth->ah_cred = au->au_shcred; + } else { + xdrs.x_op = XDR_FREE; + (void)xdr_opaque_auth(&xdrs, &au->au_shcred); + au->au_shcred.oa_base = NULL; + auth->ah_cred = au->au_origcred; + } + marshal_new_auth(auth); + } + return (TRUE); +} + +static bool_t +authunix_refresh(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + struct authunix_parms aup; + struct timeval now; + XDR xdrs; + register int stat; + + if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { + /* there is no hope. Punt */ + return (FALSE); + } + au->au_shfaults ++; + + /* first deserialize the creds back into a struct authunix_parms */ + aup.aup_machname = NULL; + aup.aup_gids = (int *)NULL; + xdrmem_create(&xdrs, au->au_origcred.oa_base, + au->au_origcred.oa_length, XDR_DECODE); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + + /* update the time and serialize in place */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + xdrs.x_op = XDR_ENCODE; + XDR_SETPOS(&xdrs, 0); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); +done: + /* free the struct authunix_parms created by deserializing */ + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, &aup); + XDR_DESTROY(&xdrs); + return (stat); +} + +static void +authunix_destroy(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); + + if (au->au_shcred.oa_base != NULL) + mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); + + mem_free(auth->ah_private, sizeof(struct audata)); + + if (auth->ah_verf.oa_base != NULL) + mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); + + mem_free((caddr_t)auth, sizeof(*auth)); +} + +/* + * Marshals (pre-serializes) an auth struct. + * sets private data, au_marshed and au_mpos + */ +static bool_t +marshal_new_auth(auth) + register AUTH *auth; +{ + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + register struct audata *au = AUTH_PRIVATE(auth); + + xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); + if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || + (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { + perror("auth_none.c - Fatal marshalling problem"); + } else { + au->au_mpos = XDR_GETPOS(xdrs); + } + XDR_DESTROY(xdrs); +} diff --git a/sunrpc/authuxprot.c b/sunrpc/authuxprot.c new file mode 100644 index 0000000000..a60d99a57b --- /dev/null +++ b/sunrpc/authuxprot.c @@ -0,0 +1,66 @@ +/* @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * authunix_prot.c + * XDR for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> + +/* + * XDR for unix authentication parameters. + */ +bool_t +xdr_authunix_parms(xdrs, p) + register XDR *xdrs; + register struct authunix_parms *p; +{ + + if (xdr_u_long(xdrs, &(p->aup_time)) + && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) + && xdr_int(xdrs, &(p->aup_uid)) + && xdr_int(xdrs, &(p->aup_gid)) + && xdr_array(xdrs, (caddr_t *)&(p->aup_gids), + &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) { + return (TRUE); + } + return (FALSE); +} + diff --git a/sunrpc/bindrsvprt.c b/sunrpc/bindrsvprt.c new file mode 100644 index 0000000000..71803dd41c --- /dev/null +++ b/sunrpc/bindrsvprt.c @@ -0,0 +1,78 @@ +static char sccsid[] = "@(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC 1.8 88/02/08 SMI"; +/* + * 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) 1987 by Sun Microsystems, Inc. + */ + +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/socket.h> +#include <netinet/in.h> + +/* + * Bind a socket to a privileged IP port + */ +bindresvport(sd, sin) + int sd; + struct sockaddr_in *sin; +{ + int res; + static short port; + struct sockaddr_in myaddr; + extern int errno; + int i; + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + + if (sin == (struct sockaddr_in *)0) { + sin = &myaddr; + bzero(sin, sizeof (*sin)); + sin->sin_family = AF_INET; + } else if (sin->sin_family != AF_INET) { + errno = EPFNOSUPPORT; + return (-1); + } + if (port == 0) { + port = (getpid() % NPORTS) + STARTPORT; + } + res = -1; + errno = EADDRINUSE; + for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { + sin->sin_port = htons(port++); + if (port > ENDPORT) { + port = STARTPORT; + } + res = bind(sd, sin, sizeof(struct sockaddr_in)); + } + return (res); +} diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c new file mode 100644 index 0000000000..e54e77828b --- /dev/null +++ b/sunrpc/clnt_gen.c @@ -0,0 +1,110 @@ +/* @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI"; +#endif +/* + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/errno.h> +#include <netdb.h> + +/* + * Generic client creation: takes (hostname, program-number, protocol) and + * returns client handle. Default options are set, which the user can + * change using the rpc equivalent of ioctl()'s. + */ +CLIENT * +clnt_create(hostname, prog, vers, proto) + char *hostname; + unsigned prog; + unsigned vers; + char *proto; +{ + struct hostent *h; + struct protoent *p; + struct sockaddr_in sin; + int sock; + struct timeval tv; + CLIENT *client; + + h = gethostbyname(hostname); + if (h == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNHOST; + return (NULL); + } + if (h->h_addrtype != AF_INET) { + /* + * Only support INET for now + */ + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; + return (NULL); + } + sin.sin_family = h->h_addrtype; + sin.sin_port = 0; + bzero(sin.sin_zero, sizeof(sin.sin_zero)); + bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length); + p = getprotobyname(proto); + if (p == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + sock = RPC_ANYSOCK; + switch (p->p_proto) { + case IPPROTO_UDP: + tv.tv_sec = 5; + tv.tv_usec = 0; + client = clntudp_create(&sin, prog, vers, tv, &sock); + if (client == NULL) { + return (NULL); + } + tv.tv_sec = 25; + clnt_control(client, CLSET_TIMEOUT, &tv); + break; + case IPPROTO_TCP: + client = clnttcp_create(&sin, prog, vers, &sock, 0, 0); + if (client == NULL) { + return (NULL); + } + tv.tv_sec = 25; + tv.tv_usec = 0; + clnt_control(client, CLSET_TIMEOUT, &tv); + break; + default: + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + return (client); +} diff --git a/sunrpc/clnt_perr.c b/sunrpc/clnt_perr.c new file mode 100644 index 0000000000..1876c7f163 --- /dev/null +++ b/sunrpc/clnt_perr.c @@ -0,0 +1,305 @@ +/* @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_perror.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/auth.h> +#include <rpc/clnt.h> + +extern char *sys_errlist[]; +/* extern char *sprintf(); --roland@gnu */ +static char *auth_errmsg(); + +extern char *strcpy(); + +static char *buf; + +static char * +_buf() +{ + + if (buf == 0) + buf = (char *)malloc(256); + return (buf); +} + +/* + * Print reply error info + */ +char * +clnt_sperror(rpch, s) + CLIENT *rpch; + char *s; +{ + struct rpc_err e; + void clnt_perrno(); + char *err; + char *str = _buf(); + char *strstart = str; + + if (str == 0) + return (0); + CLNT_GETERR(rpch, &e); + + (void) sprintf(str, "%s: ", s); + str += strlen(str); + + (void) strcpy(str, clnt_sperrno(e.re_status)); + str += strlen(str); + + switch (e.re_status) { + case RPC_SUCCESS: + case RPC_CANTENCODEARGS: + case RPC_CANTDECODERES: + case RPC_TIMEDOUT: + case RPC_PROGUNAVAIL: + case RPC_PROCUNAVAIL: + case RPC_CANTDECODEARGS: + case RPC_SYSTEMERROR: + case RPC_UNKNOWNHOST: + case RPC_UNKNOWNPROTO: + case RPC_PMAPFAILURE: + case RPC_PROGNOTREGISTERED: + case RPC_FAILED: + break; + + case RPC_CANTSEND: + case RPC_CANTRECV: + (void) sprintf(str, "; errno = %s", + sys_errlist[e.re_errno]); + str += strlen(str); + break; + + case RPC_VERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + case RPC_AUTHERROR: + err = auth_errmsg(e.re_why); + (void) sprintf(str,"; why = "); + str += strlen(str); + if (err != NULL) { + (void) sprintf(str, "%s",err); + } else { + (void) sprintf(str, + "(unknown authentication error - %d)", + (int) e.re_why); + } + str += strlen(str); + break; + + case RPC_PROGVERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + default: /* unknown */ + (void) sprintf(str, + "; s1 = %lu, s2 = %lu", + e.re_lb.s1, e.re_lb.s2); + str += strlen(str); + break; + } + (void) sprintf(str, "\n"); + return(strstart) ; +} + +void +clnt_perror(rpch, s) + CLIENT *rpch; + char *s; +{ + (void) fprintf(stderr,"%s",clnt_sperror(rpch,s)); +} + + +struct rpc_errtab { + enum clnt_stat status; + char *message; +}; + +static struct rpc_errtab rpc_errlist[] = { + { RPC_SUCCESS, + "RPC: Success" }, + { RPC_CANTENCODEARGS, + "RPC: Can't encode arguments" }, + { RPC_CANTDECODERES, + "RPC: Can't decode result" }, + { RPC_CANTSEND, + "RPC: Unable to send" }, + { RPC_CANTRECV, + "RPC: Unable to receive" }, + { RPC_TIMEDOUT, + "RPC: Timed out" }, + { RPC_VERSMISMATCH, + "RPC: Incompatible versions of RPC" }, + { RPC_AUTHERROR, + "RPC: Authentication error" }, + { RPC_PROGUNAVAIL, + "RPC: Program unavailable" }, + { RPC_PROGVERSMISMATCH, + "RPC: Program/version mismatch" }, + { RPC_PROCUNAVAIL, + "RPC: Procedure unavailable" }, + { RPC_CANTDECODEARGS, + "RPC: Server can't decode arguments" }, + { RPC_SYSTEMERROR, + "RPC: Remote system error" }, + { RPC_UNKNOWNHOST, + "RPC: Unknown host" }, + { RPC_UNKNOWNPROTO, + "RPC: Unknown protocol" }, + { RPC_PMAPFAILURE, + "RPC: Port mapper failure" }, + { RPC_PROGNOTREGISTERED, + "RPC: Program not registered"}, + { RPC_FAILED, + "RPC: Failed (unspecified error)"} +}; + + +/* + * This interface for use by clntrpc + */ +char * +clnt_sperrno(stat) + enum clnt_stat stat; +{ + int i; + + for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) { + if (rpc_errlist[i].status == stat) { + return (rpc_errlist[i].message); + } + } + return ("RPC: (unknown error code)"); +} + +void +clnt_perrno(num) + enum clnt_stat num; +{ + (void) fprintf(stderr,"%s",clnt_sperrno(num)); +} + + +char * +clnt_spcreateerror(s) + char *s; +{ + extern int sys_nerr; + extern char *sys_errlist[]; + char *str = _buf(); + + if (str == 0) + return(0); + (void) sprintf(str, "%s: ", s); + (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat)); + switch (rpc_createerr.cf_stat) { + case RPC_PMAPFAILURE: + (void) strcat(str, " - "); + (void) strcat(str, + clnt_sperrno(rpc_createerr.cf_error.re_status)); + break; + + case RPC_SYSTEMERROR: + (void) strcat(str, " - "); + if (rpc_createerr.cf_error.re_errno > 0 + && rpc_createerr.cf_error.re_errno < sys_nerr) + (void) strcat(str, + sys_errlist[rpc_createerr.cf_error.re_errno]); + else + (void) sprintf(&str[strlen(str)], "Error %d", + rpc_createerr.cf_error.re_errno); + break; + } + (void) strcat(str, "\n"); + return (str); +} + +void +clnt_pcreateerror(s) + char *s; +{ + (void) fprintf(stderr,"%s",clnt_spcreateerror(s)); +} + +struct auth_errtab { + enum auth_stat status; + char *message; +}; + +static struct auth_errtab auth_errlist[] = { + { AUTH_OK, + "Authentication OK" }, + { AUTH_BADCRED, + "Invalid client credential" }, + { AUTH_REJECTEDCRED, + "Server rejected credential" }, + { AUTH_BADVERF, + "Invalid client verifier" }, + { AUTH_REJECTEDVERF, + "Server rejected verifier" }, + { AUTH_TOOWEAK, + "Client credential too weak" }, + { AUTH_INVALIDRESP, + "Invalid server verifier" }, + { AUTH_FAILED, + "Failed (unspecified error)" }, +}; + +static char * +auth_errmsg(stat) + enum auth_stat stat; +{ + int i; + + for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) { + if (auth_errlist[i].status == stat) { + return(auth_errlist[i].message); + } + } + return(NULL); +} diff --git a/sunrpc/clnt_raw.c b/sunrpc/clnt_raw.c new file mode 100644 index 0000000000..89059ae2da --- /dev/null +++ b/sunrpc/clnt_raw.c @@ -0,0 +1,238 @@ +/* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_raw.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Memory based rpc for simple testing and timing. + * Interface to create an rpc client and server in the same process. + * This lets us similate rpc and get round trip overhead, without + * any interference from the kernal. + */ + +#include <rpc/rpc.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[UDPMSGSIZE]; + char mashl_callmsg[MCALL_MSG_SIZE]; + u_int mcnt; +} *clntraw_private; + +static enum clnt_stat clntraw_call(); +static void clntraw_abort(); +static void clntraw_geterr(); +static bool_t clntraw_freeres(); +static bool_t clntraw_control(); +static void clntraw_destroy(); + +static struct clnt_ops client_ops = { + clntraw_call, + clntraw_abort, + clntraw_geterr, + clntraw_freeres, + clntraw_destroy, + clntraw_control +}; + +void svc_getreq(); + +/* + * Create a client handle for memory based rpc. + */ +CLIENT * +clntraw_create(prog, vers) + u_long prog; + u_long vers; +{ + register struct clntraw_private *clp = clntraw_private; + struct rpc_msg call_msg; + XDR *xdrs = &clp->xdr_stream; + CLIENT *client = &clp->client_object; + + if (clp == 0) { + clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); + if (clp == 0) + return (0); + clntraw_private = clp; + } + /* + * pre-serialize the staic part of the call msg and stash it away + */ + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); + if (! xdr_callhdr(xdrs, &call_msg)) { + perror("clnt_raw.c - Fatal header serialization error."); + } + clp->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + + /* + * Set xdrmem for client/server shared buffer + */ + xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); + + /* + * create client handle + */ + client->cl_ops = &client_ops; + client->cl_auth = authnone_create(); + return (client); +} + +static enum clnt_stat +clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) + CLIENT *h; + u_long proc; + xdrproc_t xargs; + caddr_t argsp; + xdrproc_t xresults; + caddr_t resultsp; + struct timeval timeout; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + struct rpc_msg msg; + enum clnt_stat status; + struct rpc_err error; + + if (clp == 0) + return (RPC_FAILED); +call_again: + /* + * send request + */ + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ; + if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) { + return (RPC_CANTENCODEARGS); + } + (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ + + /* + * We have to call server input routine here because this is + * all going on in one process. Yuk. + */ + svc_getreq(1); + + /* + * get results + */ + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = resultsp; + msg.acpted_rply.ar_results.proc = xresults; + if (! xdr_replymsg(xdrs, &msg)) + return (RPC_CANTDECODERES); + _seterr_reply(&msg, &error); + status = error.re_status; + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + } /* end successful completion */ + else { + if (AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + if (msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); + } + } + + return (status); +} + +static void +clntraw_geterr() +{ +} + + +static bool_t +clntraw_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + bool_t rval; + + if (clp == 0) + { + rval = (bool_t) RPC_FAILED; + return (rval); + } + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntraw_abort() +{ +} + +static bool_t +clntraw_control() +{ + return (FALSE); +} + +static void +clntraw_destroy() +{ +} diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c new file mode 100644 index 0000000000..043ce0a3eb --- /dev/null +++ b/sunrpc/clnt_simp.c @@ -0,0 +1,112 @@ +/* @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> +#include <strings.h> + +static struct callrpc_private { + CLIENT *client; + int socket; + int oldprognum, oldversnum, valid; + char *oldhost; +} *callrpc_private; + +callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) + char *host; + xdrproc_t inproc, outproc; + char *in, *out; +{ + register struct callrpc_private *crp = callrpc_private; + struct sockaddr_in server_addr; + enum clnt_stat clnt_stat; + struct hostent *hp; + struct timeval timeout, tottimeout; + + if (crp == 0) { + crp = (struct callrpc_private *)calloc(1, sizeof (*crp)); + if (crp == 0) + return (0); + callrpc_private = crp; + } + if (crp->oldhost == NULL) { + crp->oldhost = malloc(256); + crp->oldhost[0] = 0; + crp->socket = RPC_ANYSOCK; + } + if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum + && strcmp(crp->oldhost, host) == 0) { + /* reuse old client */ + } else { + crp->valid = 0; + (void)close(crp->socket); + crp->socket = RPC_ANYSOCK; + if (crp->client) { + clnt_destroy(crp->client); + crp->client = NULL; + } + if ((hp = gethostbyname(host)) == NULL) + return ((int) RPC_UNKNOWNHOST); + timeout.tv_usec = 0; + timeout.tv_sec = 5; + bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length); + server_addr.sin_family = AF_INET; + server_addr.sin_port = 0; + if ((crp->client = clntudp_create(&server_addr, (u_long)prognum, + (u_long)versnum, timeout, &crp->socket)) == NULL) + return ((int) rpc_createerr.cf_stat); + crp->valid = 1; + crp->oldprognum = prognum; + crp->oldversnum = versnum; + (void) strcpy(crp->oldhost, host); + } + tottimeout.tv_sec = 25; + tottimeout.tv_usec = 0; + clnt_stat = clnt_call(crp->client, procnum, inproc, in, + outproc, out, tottimeout); + /* + * if call failed, empty cache + */ + if (clnt_stat != RPC_SUCCESS) + crp->valid = 0; + return ((int) clnt_stat); +} diff --git a/sunrpc/clnt_tcp.c b/sunrpc/clnt_tcp.c new file mode 100644 index 0000000000..2222bc6577 --- /dev/null +++ b/sunrpc/clnt_tcp.c @@ -0,0 +1,466 @@ +/* @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_tcp.c, Implements a TCP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * TCP based RPC supports 'batched calls'. + * A sequence of calls may be batched-up in a send buffer. The rpc call + * return immediately to the client even though the call was not necessarily + * sent. The batching occurs if the results' xdr routine is NULL (0) AND + * the rpc timeout value is zero (see clnt.h, rpc). + * + * Clients should NOT casually batch calls that in fact return results; that is, + * the server side should be aware that a call is batched and not produce any + * return message. Batched calls that produce many result messages can + * deadlock (netlock) the client and the server.... + * + * Now go hang yourself. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> +#include <errno.h> +#include <rpc/pmap_clnt.h> + +#define MCALL_MSG_SIZE 24 + +extern int errno; + +static int readtcp(); +static int writetcp(); + +static enum clnt_stat clnttcp_call(); +static void clnttcp_abort(); +static void clnttcp_geterr(); +static bool_t clnttcp_freeres(); +static bool_t clnttcp_control(); +static void clnttcp_destroy(); + +static struct clnt_ops tcp_ops = { + clnttcp_call, + clnttcp_abort, + clnttcp_geterr, + clnttcp_freeres, + clnttcp_destroy, + clnttcp_control +}; + +struct ct_data { + int ct_sock; + bool_t ct_closeit; + struct timeval ct_wait; + bool_t ct_waitset; /* wait set by clnt_control? */ + struct sockaddr_in ct_addr; + struct rpc_err ct_error; + char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ + u_int ct_mpos; /* pos after marshal */ + XDR ct_xdrs; +}; + +/* + * Create a client handle for a tcp/ip connection. + * If *sockp<0, *sockp is set to a newly created TCP socket and it is + * connected to raddr. If *sockp non-negative then + * raddr is ignored. The rpc/tcp package does buffering + * similar to stdio, so the client must pick send and receive buffer sizes,]; + * 0 => use the default. + * If raddr->sin_port is 0, then a binder on the remote machine is + * consulted for the right port number. + * NB: *sockp is copied into a private area. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this + * something more useful. + */ +CLIENT * +clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long prog; + u_long vers; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *h; + register struct ct_data *ct; + struct timeval now; + struct rpc_msg call_msg; + + h = (CLIENT *)mem_alloc(sizeof(*h)); + if (h == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + ct = (struct ct_data *)mem_alloc(sizeof(*ct)); + if (ct == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + + /* + * If no port number given ask the pmap for one + */ + if (raddr->sin_port == 0) { + u_short port; + if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) { + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); + } + raddr->sin_port = htons(port); + } + + /* + * If no socket given, open one + */ + if (*sockp < 0) { + *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + if ((*sockp < 0) + || (connect(*sockp, (struct sockaddr *)raddr, + sizeof(*raddr)) < 0)) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + (void)close(*sockp); + goto fooy; + } + ct->ct_closeit = TRUE; + } else { + ct->ct_closeit = FALSE; + } + + /* + * Set up private data struct + */ + ct->ct_sock = *sockp; + ct->ct_wait.tv_usec = 0; + ct->ct_waitset = FALSE; + ct->ct_addr = *raddr; + + /* + * Initialize call message + */ + (void)gettimeofday(&now, (struct timezone *)0); + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + + /* + * pre-serialize the staic part of the call msg and stash it away + */ + xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, + XDR_ENCODE); + if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { + if (ct->ct_closeit) { + (void)close(*sockp); + } + goto fooy; + } + ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); + XDR_DESTROY(&(ct->ct_xdrs)); + + /* + * Create a client handle which uses xdrrec for serialization + * and authnone for authentication. + */ + xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, + (caddr_t)ct, readtcp, writetcp); + h->cl_ops = &tcp_ops; + h->cl_private = (caddr_t) ct; + h->cl_auth = authnone_create(); + return (h); + +fooy: + /* + * Something goofed, free stuff and barf + */ + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +static enum clnt_stat +clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) + register CLIENT *h; + u_long proc; + xdrproc_t xdr_args; + caddr_t args_ptr; + xdrproc_t xdr_results; + caddr_t results_ptr; + struct timeval timeout; +{ + register struct ct_data *ct = (struct ct_data *) h->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + struct rpc_msg reply_msg; + u_long x_id; + u_long *msg_x_id = (u_long *)(ct->ct_mcall); /* yuk */ + register bool_t shipnow; + int refreshes = 2; + + if (!ct->ct_waitset) { + ct->ct_wait = timeout; + } + + shipnow = + (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 + && timeout.tv_usec == 0) ? FALSE : TRUE; + +call_again: + xdrs->x_op = XDR_ENCODE; + ct->ct_error.re_status = RPC_SUCCESS; + x_id = ntohl(--(*msg_x_id)); + if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xdr_args)(xdrs, args_ptr))) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTENCODEARGS; + (void)xdrrec_endofrecord(xdrs, TRUE); + return (ct->ct_error.re_status); + } + if (! xdrrec_endofrecord(xdrs, shipnow)) + return (ct->ct_error.re_status = RPC_CANTSEND); + if (! shipnow) + return (RPC_SUCCESS); + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return(ct->ct_error.re_status = RPC_TIMEDOUT); + } + + + /* + * Keep receiving until we get a valid transaction id + */ + xdrs->x_op = XDR_DECODE; + while (TRUE) { + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = NULL; + reply_msg.acpted_rply.ar_results.proc = xdr_void; + if (! xdrrec_skiprecord(xdrs)) + return (ct->ct_error.re_status); + /* now decode and validate the response header */ + if (! xdr_replymsg(xdrs, &reply_msg)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + continue; + return (ct->ct_error.re_status); + } + if (reply_msg.rm_xid == x_id) + break; + } + + /* + * process header + */ + _seterr_reply(&reply_msg, &(ct->ct_error)); + if (ct->ct_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { + ct->ct_error.re_status = RPC_AUTHERROR; + ct->ct_error.re_why = AUTH_INVALIDRESP; + } else if (! (*xdr_results)(xdrs, results_ptr)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTDECODERES; + } + /* free verifier ... */ + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (refreshes-- && AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + return (ct->ct_error.re_status); +} + +static void +clnttcp_geterr(h, errp) + CLIENT *h; + struct rpc_err *errp; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + *errp = ct->ct_error; +} + +static bool_t +clnttcp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clnttcp_abort() +{ +} + +static bool_t +clnttcp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + ct->ct_wait = *(struct timeval *)info; + ct->ct_waitset = TRUE; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = ct->ct_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = ct->ct_addr; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +static void +clnttcp_destroy(h) + CLIENT *h; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + if (ct->ct_closeit) { + (void)close(ct->ct_sock); + } + XDR_DESTROY(&(ct->ct_xdrs)); + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); +} + +/* + * Interface between xdr serializer and tcp connection. + * Behaves like the system calls, read & write, but keeps some error state + * around for the rpc level. + */ +static int +readtcp(ct, buf, len) + register struct ct_data *ct; + caddr_t buf; + register int len; +{ +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; + + if (len == 0) + return (0); + FD_ZERO(&mask); + FD_SET(ct->ct_sock, &mask); +#else + register int mask = 1 << (ct->ct_sock); + int readfds; + + if (len == 0) + return (0); + +#endif /* def FD_SETSIZE */ + while (TRUE) { + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, + &(ct->ct_wait))) { + 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; + } + switch (len = read(ct->ct_sock, buf, len)) { + + case 0: + /* premature eof */ + ct->ct_error.re_errno = ECONNRESET; + ct->ct_error.re_status = RPC_CANTRECV; + len = -1; /* it's really an error */ + break; + + case -1: + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTRECV; + break; + } + return (len); +} + +static int +writetcp(ct, buf, len) + struct ct_data *ct; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(ct->ct_sock, buf, cnt)) == -1) { + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTSEND; + return (-1); + } + } + return (len); +} diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c new file mode 100644 index 0000000000..815cbb4ed2 --- /dev/null +++ b/sunrpc/clnt_udp.c @@ -0,0 +1,442 @@ +/* @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_udp.c, Implements a UDP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netdb.h> +#include <errno.h> +#include <rpc/pmap_clnt.h> + +extern int errno; + +/* + * UDP bases client side rpc operations + */ +static enum clnt_stat clntudp_call(); +static void clntudp_abort(); +static void clntudp_geterr(); +static bool_t clntudp_freeres(); +static bool_t clntudp_control(); +static void clntudp_destroy(); + +static struct clnt_ops udp_ops = { + clntudp_call, + clntudp_abort, + clntudp_geterr, + clntudp_freeres, + clntudp_destroy, + clntudp_control +}; + +/* + * Private data kept per client handle + */ +struct cu_data { + int cu_sock; + bool_t cu_closeit; + struct sockaddr_in cu_raddr; + int cu_rlen; + struct timeval cu_wait; + struct timeval cu_total; + struct rpc_err cu_error; + XDR cu_outxdrs; + u_int cu_xdrpos; + u_int cu_sendsz; + char *cu_outbuf; + u_int cu_recvsz; + char cu_inbuf[1]; +}; + +/* + * Create a UDP based client handle. + * If *sockp<0, *sockp is set to a newly created UPD socket. + * If raddr->sin_port is 0 a binder on the remote machine + * is consulted for the correct port number. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is initialized to null authentication. + * Caller may wish to set this something more useful. + * + * wait is the amount of time used between retransmitting a call if + * no response has been heard; retransmition occurs until the actual + * rpc call times out. + * + * sendsz and recvsz are the maximum allowable packet sizes that can be + * sent and received. + */ +CLIENT * +clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *cl; + register struct cu_data *cu; + struct timeval now; + struct rpc_msg call_msg; + + cl = (CLIENT *)mem_alloc(sizeof(CLIENT)); + if (cl == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + sendsz = ((sendsz + 3) / 4) * 4; + recvsz = ((recvsz + 3) / 4) * 4; + cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz); + if (cu == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + cu->cu_outbuf = &cu->cu_inbuf[recvsz]; + + (void)gettimeofday(&now, (struct timezone *)0); + if (raddr->sin_port == 0) { + u_short port; + if ((port = + pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) { + goto fooy; + } + raddr->sin_port = htons(port); + } + cl->cl_ops = &udp_ops; + cl->cl_private = (caddr_t)cu; + cu->cu_raddr = *raddr; + cu->cu_rlen = sizeof (cu->cu_raddr); + cu->cu_wait = wait; + cu->cu_total.tv_sec = -1; + cu->cu_total.tv_usec = -1; + cu->cu_sendsz = sendsz; + cu->cu_recvsz = recvsz; + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = program; + call_msg.rm_call.cb_vers = version; + xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, + sendsz, XDR_ENCODE); + if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) { + goto fooy; + } + cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); + if (*sockp < 0) { + int dontblock = 1; + + *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (*sockp < 0) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + /* attempt to bind to prov port */ + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + /* the sockets rpc controls are non-blocking */ + (void)ioctl(*sockp, FIONBIO, (char *) &dontblock); + cu->cu_closeit = TRUE; + } else { + cu->cu_closeit = FALSE; + } + cu->cu_sock = *sockp; + cl->cl_auth = authnone_create(); + return (cl); +fooy: + if (cu) + mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz); + if (cl) + mem_free((caddr_t)cl, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +CLIENT * +clntudp_create(raddr, program, version, wait, sockp) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; +{ + + return(clntudp_bufcreate(raddr, program, version, wait, sockp, + UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum clnt_stat +clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) + register CLIENT *cl; /* client handle */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + struct timeval utimeout; /* seconds to wait before giving up */ +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs; + register int outlen; + register int inlen; + int fromlen; +#ifdef FD_SETSIZE + fd_set readfds; + fd_set mask; +#else + int readfds; + register int mask; +#endif /* def FD_SETSIZE */ + struct sockaddr_in from; + struct rpc_msg reply_msg; + XDR reply_xdrs; + struct timeval time_waited; + bool_t ok; + int nrefreshes = 2; /* number of times to refresh cred */ + struct timeval timeout; + + if (cu->cu_total.tv_usec == -1) { + timeout = utimeout; /* use supplied timeout */ + } else { + timeout = cu->cu_total; /* use default timeout */ + } + + time_waited.tv_sec = 0; + time_waited.tv_usec = 0; +call_again: + xdrs = &(cu->cu_outxdrs); + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, cu->cu_xdrpos); + /* + * the transaction is the first thing in the out buffer + */ + (*(u_short *)(cu->cu_outbuf))++; + if ((! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) + return (cu->cu_error.re_status = RPC_CANTENCODEARGS); + outlen = (int)XDR_GETPOS(xdrs); + +send_again: + if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0, + (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) + != outlen) { + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTSEND); + } + + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return (cu->cu_error.re_status = RPC_TIMEDOUT); + } + /* + * sub-optimal code appears here because we have + * some clock time to spare while the packets are in flight. + * (We assume that this is actually only executed once.) + */ + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = resultsp; + reply_msg.acpted_rply.ar_results.proc = xresults; +#ifdef FD_SETSIZE + FD_ZERO(&mask); + FD_SET(cu->cu_sock, &mask); +#else + mask = 1 << cu->cu_sock; +#endif /* def FD_SETSIZE */ + for (;;) { + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, + (int *)NULL, &(cu->cu_wait))) { + + case 0: + time_waited.tv_sec += cu->cu_wait.tv_sec; + time_waited.tv_usec += cu->cu_wait.tv_usec; + while (time_waited.tv_usec >= 1000000) { + time_waited.tv_sec++; + time_waited.tv_usec -= 1000000; + } + if ((time_waited.tv_sec < timeout.tv_sec) || + ((time_waited.tv_sec == timeout.tv_sec) && + (time_waited.tv_usec < timeout.tv_usec))) + goto send_again; + return (cu->cu_error.re_status = RPC_TIMEDOUT); + + /* + * buggy in other cases because time_waited is not being + * updated. + */ + case -1: + if (errno == EINTR) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + do { + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, + (int) cu->cu_recvsz, 0, + (struct sockaddr *)&from, &fromlen); + } while (inlen < 0 && errno == EINTR); + if (inlen < 0) { + if (errno == EWOULDBLOCK) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + if (inlen < sizeof(u_long)) + continue; + /* see if reply transaction id matches sent id */ + if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf))) + continue; + /* we now assume we have the proper reply */ + break; + } + + /* + * now decode and validate the response + */ + xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE); + ok = xdr_replymsg(&reply_xdrs, &reply_msg); + /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ + if (ok) { + _seterr_reply(&reply_msg, &(cu->cu_error)); + if (cu->cu_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(cl->cl_auth, + &reply_msg.acpted_rply.ar_verf)) { + cu->cu_error.re_status = RPC_AUTHERROR; + cu->cu_error.re_why = AUTH_INVALIDRESP; + } + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, + &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) { + nrefreshes--; + goto call_again; + } + } /* end of unsuccessful completion */ + } /* end of valid reply message */ + else { + cu->cu_error.re_status = RPC_CANTDECODERES; + } + return (cu->cu_error.re_status); +} + +static void +clntudp_geterr(cl, errp) + CLIENT *cl; + struct rpc_err *errp; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + *errp = cu->cu_error; +} + + +static bool_t +clntudp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs = &(cu->cu_outxdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntudp_abort(/*h*/) + /*CLIENT *h;*/ +{ +} + +static bool_t +clntudp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + cu->cu_total = *(struct timeval *)info; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = cu->cu_total; + break; + case CLSET_RETRY_TIMEOUT: + cu->cu_wait = *(struct timeval *)info; + break; + case CLGET_RETRY_TIMEOUT: + *(struct timeval *)info = cu->cu_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = cu->cu_raddr; + break; + default: + return (FALSE); + } + return (TRUE); +} + +static void +clntudp_destroy(cl) + CLIENT *cl; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + if (cu->cu_closeit) { + (void)close(cu->cu_sock); + } + XDR_DESTROY(&(cu->cu_outxdrs)); + mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); + mem_free((caddr_t)cl, sizeof(CLIENT)); +} diff --git a/sunrpc/etc.rpc b/sunrpc/etc.rpc new file mode 100644 index 0000000000..bebfb51b73 --- /dev/null +++ b/sunrpc/etc.rpc @@ -0,0 +1,33 @@ +# +# rpc 88/08/01 4.0 RPCSRC; from 1.12 88/02/07 SMI +# +portmapper 100000 portmap sunrpc +rstatd 100001 rstat rstat_svc rup perfmeter +rusersd 100002 rusers +nfs 100003 nfsprog +ypserv 100004 ypprog +mountd 100005 mount showmount +ypbind 100007 +walld 100008 rwall shutdown +yppasswdd 100009 yppasswd +etherstatd 100010 etherstat +rquotad 100011 rquotaprog quota rquota +sprayd 100012 spray +3270_mapper 100013 +rje_mapper 100014 +selection_svc 100015 selnsvc +database_svc 100016 +rexd 100017 rex +alis 100018 +sched 100019 +llockmgr 100020 +nlockmgr 100021 +x25.inr 100022 +statmon 100023 +status 100024 +bootparam 100026 +ypupdated 100028 ypupdate +keyserv 100029 keyserver +tfsd 100037 +nsed 100038 +nsemntd 100039 diff --git a/sunrpc/get_myaddr.c b/sunrpc/get_myaddr.c new file mode 100644 index 0000000000..9692f852f9 --- /dev/null +++ b/sunrpc/get_myaddr.c @@ -0,0 +1,91 @@ +/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * get_myaddress.c + * + * Get client's IP address via ioctl. This avoids using the yellowpages. + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/pmap_prot.h> +#include <sys/socket.h> +#include <stdio.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> +#include <sys/ioctl.h> +/* Order of following two #includes reversed by roland@gnu */ +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * don't use gethostbyname, which would invoke yellow pages + */ +get_myaddress(addr) + struct sockaddr_in *addr; +{ + int s; + char buf[BUFSIZ]; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + int len; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("get_myaddress: socket"); + exit(1); + } + ifc.ifc_len = sizeof (buf); + ifc.ifc_buf = buf; + if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { + perror("get_myaddress: ioctl (get interface configuration)"); + exit(1); + } + ifr = ifc.ifc_req; + for (len = ifc.ifc_len; len; len -= sizeof ifreq) { + ifreq = *ifr; + if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + perror("get_myaddress: ioctl"); + exit(1); + } + if ((ifreq.ifr_flags & IFF_UP) && + ifr->ifr_addr.sa_family == AF_INET) { + *addr = *((struct sockaddr_in *)&ifr->ifr_addr); + addr->sin_port = htons(PMAPPORT); + break; + } + ifr++; + } + (void) close(s); +} diff --git a/sunrpc/getrpcent.c b/sunrpc/getrpcent.c new file mode 100644 index 0000000000..8ef65618b0 --- /dev/null +++ b/sunrpc/getrpcent.c @@ -0,0 +1,235 @@ +/* @(#)getrpcent.c 2.2 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)getrpcent.c 1.9 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <rpc/rpc.h> +#include <netdb.h> +#include <sys/socket.h> + +/* + * Internet version. + */ +struct rpcdata { + FILE *rpcf; + char *current; + int currentlen; + int stayopen; +#define MAXALIASES 35 + char *rpc_aliases[MAXALIASES]; + struct rpcent rpc; + char line[BUFSIZ+1]; + char *domain; +} *rpcdata, *_rpcdata(); + +static struct rpcent *interpret(); +struct hostent *gethostent(); +char *inet_ntoa(); +extern char *index(); /* Changed from static by roland@gnu */ + +static char RPCDB[] = _PATH_RPC; /* Changed from "/etc/rpc" by roland@gnu */ + +static struct rpcdata * +_rpcdata() +{ + register struct rpcdata *d = rpcdata; + + if (d == 0) { + d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); + rpcdata = d; + } + return (d); +} + +struct rpcent * +getrpcbynumber(number) + register int number; +{ + register struct rpcdata *d = _rpcdata(); + register struct rpcent *p; + int reason; + char adrstr[16], *val = NULL; + int vallen; + + if (d == 0) + return (0); + setrpcent(0); + while (p = getrpcent()) { + if (p->r_number == number) + break; + } + endrpcent(); + return (p); +} + +struct rpcent * +getrpcbyname(name) + const char *name; /* const added by roland@gnu */ +{ + struct rpcent *rpc; + char **rp; + + setrpcent(0); + while(rpc = getrpcent()) { + if (strcmp(rpc->r_name, name) == 0) + return (rpc); + for (rp = rpc->r_aliases; *rp != NULL; rp++) { + if (strcmp(*rp, name) == 0) + return (rpc); + } + } + endrpcent(); + return (NULL); +} + +setrpcent(f) + int f; +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->rpcf == NULL) + d->rpcf = fopen(RPCDB, "r"); + else + rewind(d->rpcf); + if (d->current) + free(d->current); + d->current = NULL; + d->stayopen |= f; +} + +endrpcent() +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->current && !d->stayopen) { + free(d->current); + d->current = NULL; + } + if (d->rpcf && !d->stayopen) { + fclose(d->rpcf); + d->rpcf = NULL; + } +} + +struct rpcent * +getrpcent() +{ + struct rpcent *hp; + int reason; + char *key = NULL, *val = NULL; + int keylen, vallen; + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return(NULL); + if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) + return (NULL); + if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) + return (NULL); + return interpret(d->line, strlen(d->line)); +} + +static struct rpcent * +interpret(val, len) +{ + register struct rpcdata *d = _rpcdata(); + char *p; + register char *cp, **q; + + if (d == 0) + return; + strncpy(d->line, val, len); + p = d->line; + d->line[len] = '\n'; + if (*p == '#') + return (getrpcent()); + cp = index(p, '#'); + if (cp == NULL) + { + cp = index(p, '\n'); + if (cp == NULL) + return (getrpcent()); + } + *cp = '\0'; + cp = index(p, ' '); + if (cp == NULL) + { + cp = index(p, '\t'); + if (cp == NULL) + return (getrpcent()); + } + *cp++ = '\0'; + /* THIS STUFF IS INTERNET SPECIFIC */ + d->rpc.r_name = d->line; + while (*cp == ' ' || *cp == '\t') + cp++; + d->rpc.r_number = atoi(cp); + q = d->rpc.r_aliases = d->rpc_aliases; + cp = index(p, ' '); + if (cp != NULL) + *cp++ = '\0'; + else + { + cp = index(p, '\t'); + if (cp != NULL) + *cp++ = '\0'; + } + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &(d->rpc_aliases[MAXALIASES - 1])) + *q++ = cp; + cp = index(p, ' '); + if (cp != NULL) + *cp++ = '\0'; + else + { + cp = index(p, '\t'); + if (cp != NULL) + *cp++ = '\0'; + } + } + *q = NULL; + return (&d->rpc); +} diff --git a/sunrpc/getrpcport.c b/sunrpc/getrpcport.c new file mode 100644 index 0000000000..9b13bac6b0 --- /dev/null +++ b/sunrpc/getrpcport.c @@ -0,0 +1,55 @@ +/* @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)getrpcport.c 1.3 87/08/11 SMI"; +#endif +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <netdb.h> +#include <sys/socket.h> + +getrpcport(host, prognum, versnum, proto) + char *host; +{ + struct sockaddr_in addr; + struct hostent *hp; + + if ((hp = gethostbyname(host)) == NULL) + return (0); + bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length); + addr.sin_family = AF_INET; + addr.sin_port = 0; + return (pmap_getport(&addr, prognum, versnum, proto)); +} diff --git a/sunrpc/pm_getmaps.c b/sunrpc/pm_getmaps.c new file mode 100644 index 0000000000..c5f72af87b --- /dev/null +++ b/sunrpc/pm_getmaps.c @@ -0,0 +1,86 @@ +/* @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_getmap.c + * Client interface to pmap rpc service. + * contains pmap_getmaps, which is only tcp service involved + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <errno.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> +#include <sys/ioctl.h> +#define NAMELEN 255 +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; + +/* + * Get a copy of the current port maps. + * Calls the pmap service remotely to do get the maps. + */ +struct pmaplist * +pmap_getmaps(address) + struct sockaddr_in *address; +{ + struct pmaplist *head = (struct pmaplist *)NULL; + int socket = -1; + struct timeval minutetimeout; + register CLIENT *client; + + minutetimeout.tv_sec = 60; + minutetimeout.tv_usec = 0; + address->sin_port = htons(PMAPPORT); + client = clnttcp_create(address, PMAPPROG, + PMAPVERS, &socket, 50, 500); + if (client != (CLIENT *)NULL) { + if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist, + &head, minutetimeout) != RPC_SUCCESS) { + clnt_perror(client, "pmap_getmaps rpc problem"); + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (head); +} diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c new file mode 100644 index 0000000000..2e1cc5aded --- /dev/null +++ b/sunrpc/pm_getport.c @@ -0,0 +1,89 @@ +/* @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_getport.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <sys/socket.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +/* + * Find the mapped port for program,version. + * Calls the pmap service remotely to do the lookup. + * Returns 0 if no map exists. + */ +u_short +pmap_getport(address, program, version, protocol) + struct sockaddr_in *address; + u_long program; + u_long version; + u_int protocol; +{ + u_short port = 0; + int socket = -1; + register CLIENT *client; + struct pmap parms; + + address->sin_port = htons(PMAPPORT); + client = clntudp_bufcreate(address, PMAPPROG, + PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client != (CLIENT *)NULL) { + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = 0; /* not needed or used */ + if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, + xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ + rpc_createerr.cf_stat = RPC_PMAPFAILURE; + clnt_geterr(client, &rpc_createerr.cf_error); + } else if (port == 0) { + rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (port); +} diff --git a/sunrpc/pmap_clnt.c b/sunrpc/pmap_clnt.c new file mode 100644 index 0000000000..09220e77b1 --- /dev/null +++ b/sunrpc/pmap_clnt.c @@ -0,0 +1,115 @@ +/* @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_clnt.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +void clnt_perror(); + + +/* + * Set a mapping between program,version and port. + * Calls the pmap service remotely to do the mapping. + */ +bool_t +pmap_set(program, version, protocol, port) + u_long program; + u_long version; + int protocol; + u_short port; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + get_myaddress(&myaddress); + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = port; + if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout) != RPC_SUCCESS) { + clnt_perror(client, "Cannot register service"); + return (FALSE); + } + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} + +/* + * Remove the mapping between program,version and port. + * Calls the pmap service remotely to do the un-mapping. + */ +bool_t +pmap_unset(program, version) + u_long program; + u_long version; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + get_myaddress(&myaddress); + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_port = parms.pm_prot = 0; + CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout); + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} diff --git a/sunrpc/pmap_prot.c b/sunrpc/pmap_prot.c new file mode 100644 index 0000000000..643c2ff6a2 --- /dev/null +++ b/sunrpc/pmap_prot.c @@ -0,0 +1,57 @@ +/* @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_prot.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/pmap_prot.h> + + +bool_t +xdr_pmap(xdrs, regs) + XDR *xdrs; + struct pmap *regs; +{ + + if (xdr_u_long(xdrs, ®s->pm_prog) && + xdr_u_long(xdrs, ®s->pm_vers) && + xdr_u_long(xdrs, ®s->pm_prot)) + return (xdr_u_long(xdrs, ®s->pm_port)); + return (FALSE); +} diff --git a/sunrpc/pmap_prot2.c b/sunrpc/pmap_prot2.c new file mode 100644 index 0000000000..e2a8214d48 --- /dev/null +++ b/sunrpc/pmap_prot2.c @@ -0,0 +1,116 @@ +/* @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_prot2.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/pmap_prot.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) + register XDR *xdrs; + register struct pmaplist **rp; +{ + /* + * more_elements is pre-computed in case the direction is + * XDR_ENCODE or XDR_FREE. more_elements is overwritten by + * xdr_bool when the direction is XDR_DECODE. + */ + bool_t more_elements; + register int freeing = (xdrs->x_op == XDR_FREE); + register struct pmaplist **next; + + while (TRUE) { + more_elements = (bool_t)(*rp != NULL); + if (! xdr_bool(xdrs, &more_elements)) + return (FALSE); + if (! more_elements) + return (TRUE); /* we are done */ + /* + * the unfortunate side effect of non-recursion is that in + * the case of freeing we must remember the next object + * before we free the current object ... + */ + if (freeing) + next = &((*rp)->pml_next); + if (! xdr_reference(xdrs, (caddr_t *)rp, + (u_int)sizeof(struct pmaplist), xdr_pmap)) + return (FALSE); + rp = (freeing) ? next : &((*rp)->pml_next); + } +} diff --git a/sunrpc/pmap_rmt.c b/sunrpc/pmap_rmt.c new file mode 100644 index 0000000000..32c829da2d --- /dev/null +++ b/sunrpc/pmap_rmt.c @@ -0,0 +1,392 @@ +/* @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_rmt.c + * Client interface to pmap rpc service. + * remote call and broadcast service + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <rpc/pmap_rmt.h> +#include <sys/socket.h> +#include <stdio.h> +#include <errno.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; +static struct timeval timeout = { 3, 0 }; + + +/* + * pmapper remote-call-service interface. + * This routine is used to call the pmapper remote call service + * which will look up a service program in the port maps, and then + * remotely call that routine with the given parameters. This allows + * programs to do a lookup and call in one step. +*/ +enum clnt_stat +pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr) + struct sockaddr_in *addr; + u_long prog, vers, proc; + xdrproc_t xdrargs, xdrres; + caddr_t argsp, resp; + struct timeval tout; + u_long *port_ptr; +{ + int socket = -1; + register CLIENT *client; + struct rmtcallargs a; + struct rmtcallres r; + enum clnt_stat stat; + + addr->sin_port = htons(PMAPPORT); + client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket); + if (client != (CLIENT *)NULL) { + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.args_ptr = argsp; + a.xdr_args = xdrargs; + r.port_ptr = port_ptr; + r.results_ptr = resp; + r.xdr_results = xdrres; + stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a, + xdr_rmtcallres, &r, tout); + CLNT_DESTROY(client); + } else { + stat = RPC_FAILED; + } + (void)close(socket); + addr->sin_port = 0; + return (stat); +} + + +/* + * XDR remote call arguments + * written for XDR_ENCODE direction only + */ +bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + u_int lenposition, argposition, position; + + if (xdr_u_long(xdrs, &(cap->prog)) && + xdr_u_long(xdrs, &(cap->vers)) && + xdr_u_long(xdrs, &(cap->proc))) { + lenposition = XDR_GETPOS(xdrs); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + argposition = XDR_GETPOS(xdrs); + if (! (*(cap->xdr_args))(xdrs, cap->args_ptr)) + return (FALSE); + position = XDR_GETPOS(xdrs); + cap->arglen = (u_long)position - (u_long)argposition; + XDR_SETPOS(xdrs, lenposition); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + XDR_SETPOS(xdrs, position); + return (TRUE); + } + return (FALSE); +} + +/* + * XDR remote call results + * written for XDR_DECODE direction only + */ +bool_t +xdr_rmtcallres(xdrs, crp) + register XDR *xdrs; + register struct rmtcallres *crp; +{ + caddr_t port_ptr; + + port_ptr = (caddr_t)crp->port_ptr; + if (xdr_reference(xdrs, &port_ptr, sizeof (u_long), + xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { + crp->port_ptr = (u_long *)port_ptr; + return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); + } + return (FALSE); +} + + +/* + * The following is kludged-up support for simple rpc broadcasts. + * Someday a large, complicated system will replace these trivial + * routines which only support udp/ip . + */ + +static int +getbroadcastnets(addrs, sock, buf) + struct in_addr *addrs; + int sock; /* any valid socket will do */ + char *buf; /* why allocxate more when we can use existing... */ +{ + struct ifconf ifc; + struct ifreq ifreq, *ifr; + struct sockaddr_in *sin; + int n, i; + + ifc.ifc_len = UDPMSGSIZE; + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { + perror("broadcast: ioctl (get interface configuration)"); + return (0); + } + ifr = ifc.ifc_req; + for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) { + ifreq = *ifr; + if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + perror("broadcast: ioctl (get interface flags)"); + continue; + } + if ((ifreq.ifr_flags & IFF_BROADCAST) && + (ifreq.ifr_flags & IFF_UP) && + ifr->ifr_addr.sa_family == AF_INET) { + sin = (struct sockaddr_in *)&ifr->ifr_addr; +#ifdef SIOCGIFBRDADDR /* 4.3BSD */ + if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { + addrs[i++] = inet_makeaddr(inet_netof + /* Changed to pass struct instead of s_addr member + by roland@gnu. */ + (sin->sin_addr), INADDR_ANY); + } else { + addrs[i++] = ((struct sockaddr_in*) + &ifreq.ifr_addr)->sin_addr; + } +#else /* 4.2 BSD */ + addrs[i++] = inet_makeaddr(inet_netof + (sin->sin_addr.s_addr), INADDR_ANY); +#endif + } + } + return (i); +} + +typedef bool_t (*resultproc_t)(); + +enum clnt_stat +clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) + u_long prog; /* program number */ + u_long vers; /* version number */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + resultproc_t eachresult; /* call with each result obtained */ +{ + enum clnt_stat stat; + AUTH *unix_auth = authunix_create_default(); + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + int outlen, inlen, fromlen, nets; + register int sock; + int on = 1; +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; +#else + int readfds; + register int mask; +#endif /* def FD_SETSIZE */ + register int i; + bool_t done = FALSE; + register u_long xid; + u_long port; + struct in_addr addrs[20]; + struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ + struct rmtcallargs a; + struct rmtcallres r; + struct rpc_msg msg; + struct timeval t; + char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; + + /* + * initialization: create a socket, a broadcast address, and + * preserialize the arguments into a send buffer. + */ + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("Cannot create socket for broadcast rpc"); + stat = RPC_CANTSEND; + goto done_broad; + } +#ifdef SO_BROADCAST + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { + perror("Cannot set socket option SO_BROADCAST"); + stat = RPC_CANTSEND; + goto done_broad; + } +#endif /* def SO_BROADCAST */ +#ifdef FD_SETSIZE + FD_ZERO(&mask); + FD_SET(sock, &mask); +#else + mask = (1 << sock); +#endif /* def FD_SETSIZE */ + nets = getbroadcastnets(addrs, sock, inbuf); + bzero((char *)&baddr, sizeof (baddr)); + baddr.sin_family = AF_INET; + baddr.sin_port = htons(PMAPPORT); + baddr.sin_addr.s_addr = htonl(INADDR_ANY); +/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ + (void)gettimeofday(&t, (struct timezone *)0); + msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec; + t.tv_usec = 0; + msg.rm_direction = CALL; + msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + msg.rm_call.cb_prog = PMAPPROG; + msg.rm_call.cb_vers = PMAPVERS; + msg.rm_call.cb_proc = PMAPPROC_CALLIT; + msg.rm_call.cb_cred = unix_auth->ah_cred; + msg.rm_call.cb_verf = unix_auth->ah_verf; + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.xdr_args = xargs; + a.args_ptr = argsp; + r.port_ptr = &port; + r.xdr_results = xresults; + r.results_ptr = resultsp; + xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); + if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) { + stat = RPC_CANTENCODEARGS; + goto done_broad; + } + outlen = (int)xdr_getpos(xdrs); + xdr_destroy(xdrs); + /* + * Basic loop: broadcast a packet and wait a while for response(s). + * The response timeout grows larger per iteration. + */ + for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { + for (i = 0; i < nets; i++) { + baddr.sin_addr = addrs[i]; + if (sendto(sock, outbuf, outlen, 0, + (struct sockaddr *)&baddr, + sizeof (struct sockaddr)) != outlen) { + perror("Cannot send broadcast packet"); + stat = RPC_CANTSEND; + goto done_broad; + } + } + if (eachresult == NULL) { + stat = RPC_SUCCESS; + goto done_broad; + } + recv_again: + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = (caddr_t)&r; + msg.acpted_rply.ar_results.proc = xdr_rmtcallres; + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, + (int *)NULL, &t)) { + + case 0: /* timed out */ + stat = RPC_TIMEDOUT; + continue; + + case -1: /* some kind of error */ + if (errno == EINTR) + goto recv_again; + perror("Broadcast select problem"); + stat = RPC_CANTRECV; + goto done_broad; + + } /* end of select results switch */ + try_again: + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, + (struct sockaddr *)&raddr, &fromlen); + if (inlen < 0) { + if (errno == EINTR) + goto try_again; + perror("Cannot receive reply to broadcast"); + stat = RPC_CANTRECV; + goto done_broad; + } + if (inlen < sizeof(u_long)) + goto recv_again; + /* + * see if reply transaction id matches sent id. + * If so, decode the results. + */ + xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE); + if (xdr_replymsg(xdrs, &msg)) { + if ((msg.rm_xid == xid) && + (msg.rm_reply.rp_stat == MSG_ACCEPTED) && + (msg.acpted_rply.ar_stat == SUCCESS)) { + raddr.sin_port = htons((u_short)port); + done = (*eachresult)(resultsp, &raddr); + } + /* otherwise, we just ignore the errors ... */ + } else { +#ifdef notdef + /* some kind of deserialization problem ... */ + if (msg.rm_xid == xid) + fprintf(stderr, "Broadcast deserialization problem"); + /* otherwise, just random garbage */ +#endif + } + xdrs->x_op = XDR_FREE; + msg.acpted_rply.ar_results.proc = xdr_void; + (void)xdr_replymsg(xdrs, &msg); + (void)(*xresults)(xdrs, resultsp); + xdr_destroy(xdrs); + if (done) { + stat = RPC_SUCCESS; + goto done_broad; + } else { + goto recv_again; + } + } +done_broad: + (void)close(sock); + AUTH_DESTROY(unix_auth); + return (stat); +} + diff --git a/sunrpc/portmap.c b/sunrpc/portmap.c new file mode 100644 index 0000000000..adfdef955e --- /dev/null +++ b/sunrpc/portmap.c @@ -0,0 +1,481 @@ +/* @(#)portmap.c 2.3 88/08/11 4.0 RPCSRC */ +#ifndef lint +static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro"; +#endif + +/* + * Copyright (c) 1984 by Sun Microsystems, Inc. + */ + +/* + * portmap.c, Implements the program,version to port number mapping for + * rpc. + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <stdio.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/wait.h> +#include <sys/signal.h> + +char *malloc(); +int reg_service(); +void reap(); +struct pmaplist *pmaplist; +static int debugging = 0; + +main() +{ + SVCXPRT *xprt; + int sock, pid, t; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + register struct pmaplist *pml; + +#ifndef DEBUG + pid = fork(); + if (pid < 0) { + perror("portmap: fork"); + exit(1); + } + if (pid != 0) + exit(0); + for (t = 0; t < 20; t++) + close(t); + open("/", 0); + dup2(0, 1); + dup2(0, 2); + t = open("/dev/tty", 2); + if (t >= 0) { + ioctl(t, TIOCNOTTY, (char *)0); + close(t); + } +#endif + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("portmap cannot create socket"); + exit(1); + } + + addr.sin_addr.s_addr = 0; + addr.sin_family = AF_INET; + addr.sin_port = htons(PMAPPORT); + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + perror("portmap cannot bind"); + exit(1); + } + + if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) { + fprintf(stderr, "couldn't do udp_create\n"); + exit(1); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_next = 0; + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_UDP; + pml->pml_map.pm_port = PMAPPORT; + pmaplist = pml; + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("portmap cannot create socket"); + exit(1); + } + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + perror("portmap cannot bind"); + exit(1); + } + if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE)) + == (SVCXPRT *)NULL) { + fprintf(stderr, "couldn't do tcp_create\n"); + exit(1); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_TCP; + pml->pml_map.pm_port = PMAPPORT; + pml->pml_next = pmaplist; + pmaplist = pml; + + (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); + + (void)signal(SIGCHLD, reap); + svc_run(); + fprintf(stderr, "run_svc returned unexpectedly\n"); + abort(); +} + +static struct pmaplist * +find_service(prog, vers, prot) + u_long prog; + u_long vers; +{ + register struct pmaplist *hit = NULL; + register struct pmaplist *pml; + + for (pml = pmaplist; pml != NULL; pml = pml->pml_next) { + if ((pml->pml_map.pm_prog != prog) || + (pml->pml_map.pm_prot != prot)) + continue; + hit = pml; + if (pml->pml_map.pm_vers == vers) + break; + } + return (hit); +} + +/* + * 1 OK, 0 not + */ +reg_service(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct pmap reg; + struct pmaplist *pml, *prevpml, *fnd; + int ans, port; + caddr_t t; + +#ifdef DEBUG + fprintf(stderr, "server: about do a switch\n"); +#endif + switch (rqstp->rq_proc) { + + case PMAPPROC_NULL: + /* + * Null proc call + */ + if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) { + abort(); + } + break; + + case PMAPPROC_SET: + /* + * Set a program,version to port mapping + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + /* + * check to see if already used + * find_service returns a hit even if + * the versions don't match, so check for it + */ + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) { + if (fnd->pml_map.pm_port == reg.pm_port) { + ans = 1; + goto done; + } + else { + ans = 0; + goto done; + } + } else { + /* + * add to END of list + */ + pml = (struct pmaplist *) + malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map = reg; + pml->pml_next = 0; + if (pmaplist == 0) { + pmaplist = pml; + } else { + for (fnd= pmaplist; fnd->pml_next != 0; + fnd = fnd->pml_next); + fnd->pml_next = pml; + } + ans = 1; + } + done: + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_UNSET: + /* + * Remove a program,version to port mapping. + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + ans = 0; + for (prevpml = NULL, pml = pmaplist; pml != NULL; ) { + if ((pml->pml_map.pm_prog != reg.pm_prog) || + (pml->pml_map.pm_vers != reg.pm_vers)) { + /* both pml & prevpml move forwards */ + prevpml = pml; + pml = pml->pml_next; + continue; + } + /* found it; pml moves forward, prevpml stays */ + ans = 1; + t = (caddr_t)pml; + pml = pml->pml_next; + if (prevpml == NULL) + pmaplist = pml; + else + prevpml->pml_next = pml; + free(t); + } + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_GETPORT: + /* + * Lookup the mapping for a program,version and return its port + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd) + port = fnd->pml_map.pm_port; + else + port = 0; + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_DUMP: + /* + * Return the current set of mapped program,version + */ + if (!svc_getargs(xprt, xdr_void, NULL)) + svcerr_decode(xprt); + else { + if ((!svc_sendreply(xprt, xdr_pmaplist, + (caddr_t)&pmaplist)) && debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_CALLIT: + /* + * Calls a procedure on the local machine. If the requested + * procedure is not registered this procedure does not return + * error information!! + * This procedure is only supported on rpc/udp and calls via + * rpc/udp. It passes null authentication parameters. + */ + callit(rqstp, xprt); + break; + + default: + svcerr_noproc(xprt); + break; + } +} + + +/* + * Stuff for the rmtcall service + */ +#define ARGSIZE 9000 + +typedef struct encap_parms { + u_long arglen; + char *args; +}; + +static bool_t +xdr_encap_parms(xdrs, epp) + XDR *xdrs; + struct encap_parms *epp; +{ + + return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE)); +} + +typedef struct rmtcallargs { + u_long rmt_prog; + u_long rmt_vers; + u_long rmt_port; + u_long rmt_proc; + struct encap_parms rmt_args; +}; + +static bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + + /* does not get a port number */ + if (xdr_u_long(xdrs, &(cap->rmt_prog)) && + xdr_u_long(xdrs, &(cap->rmt_vers)) && + xdr_u_long(xdrs, &(cap->rmt_proc))) { + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + } + return (FALSE); +} + +static bool_t +xdr_rmtcall_result(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + if (xdr_u_long(xdrs, &(cap->rmt_port))) + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + return (FALSE); +} + +/* + * only worries about the struct encap_parms part of struct rmtcallargs. + * The arglen must already be set!! + */ +static bool_t +xdr_opaque_parms(xdrs, cap) + XDR *xdrs; + struct rmtcallargs *cap; +{ + + return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen)); +} + +/* + * This routine finds and sets the length of incoming opaque paraters + * and then calls xdr_opaque_parms. + */ +static bool_t +xdr_len_opaque_parms(xdrs, cap) + register XDR *xdrs; + struct rmtcallargs *cap; +{ + register u_int beginpos, lowpos, highpos, currpos, pos; + + beginpos = lowpos = pos = xdr_getpos(xdrs); + highpos = lowpos + ARGSIZE; + while ((int)(highpos - lowpos) >= 0) { + currpos = (lowpos + highpos) / 2; + if (xdr_setpos(xdrs, currpos)) { + pos = currpos; + lowpos = currpos + 1; + } else { + highpos = currpos - 1; + } + } + xdr_setpos(xdrs, beginpos); + cap->rmt_args.arglen = pos - beginpos; + return (xdr_opaque_parms(xdrs, cap)); +} + +/* + * Call a remote procedure service + * This procedure is very quiet when things go wrong. + * The proc is written to support broadcast rpc. In the broadcast case, + * a machine should shut-up instead of complain, less the requestor be + * overrun with complaints at the expense of not hearing a valid reply ... + * + * This now forks so that the program & process that it calls can call + * back to the portmapper. + */ +static +callit(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct rmtcallargs a; + struct pmaplist *pml; + u_short port; + struct sockaddr_in me; + int pid, socket = -1; + CLIENT *client; + struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred; + struct timeval timeout; + char buf[ARGSIZE]; + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + a.rmt_args.args = buf; + if (!svc_getargs(xprt, xdr_rmtcall_args, &a)) + return; + if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL) + return; + /* + * fork a child to do the work. Parent immediately returns. + * Child exits upon completion. + */ + if ((pid = fork()) != 0) { + if (debugging && (pid < 0)) { + fprintf(stderr, "portmap CALLIT: cannot fork.\n"); + } + return; + } + port = pml->pml_map.pm_port; + get_myaddress(&me); + me.sin_port = htons(port); + client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket); + if (client != (CLIENT *)NULL) { + if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) { + client->cl_auth = authunix_create(au->aup_machname, + au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids); + } + a.rmt_port = (u_long)port; + if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a, + xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) { + svc_sendreply(xprt, xdr_rmtcall_result, &a); + } + AUTH_DESTROY(client->cl_auth); + clnt_destroy(client); + } + (void)close(socket); + exit(0); +} + +void +reap() +{ + while (wait3(NULL, WNOHANG, NULL) > 0); +} diff --git a/sunrpc/rpc/auth.h b/sunrpc/rpc/auth.h new file mode 100644 index 0000000000..cb19555472 --- /dev/null +++ b/sunrpc/rpc/auth.h @@ -0,0 +1,166 @@ +/* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */ +/* + * 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 + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7 /* some unknown reason */ +}; + +#if 1 /* (mc68000 || sparc || vax || i386) --roland@gnu */ +typedef u_long u_int32; /* 32-bit unsigned integers */ +#endif + +union des_block { + struct { + u_int32 high; + u_int32 low; + } key; + char c[8]; +}; +typedef union des_block des_block; +extern bool_t xdr_des_block(); + +/* + * 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; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf)(); + int (*ah_marshal)(); /* nextverf & serialize */ + int (*ah_validate)(); /* validate varifier */ + int (*ah_refresh)(); /* refresh credentials */ + void (*ah_destroy)(); /* destroy this structure */ + } *ah_ops; + caddr_t ah_private; +} AUTH; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) +#define auth_refresh(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + + +extern struct opaque_auth _null_auth; + + +/* + * These are the various implementations of client side authenticators. + */ + +/* + * Unix style authentication + * AUTH *authunix_create(machname, uid, gid, len, aup_gids) + * char *machname; + * int uid; + * int gid; + * int len; + * int *aup_gids; + */ +extern AUTH *authunix_create(); +extern AUTH *authunix_create_default(); /* takes no parameters */ +extern AUTH *authnone_create(); /* takes no parameters */ +extern AUTH *authdes_create(); + +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_UNIX 1 /* unix style (uid, gids) */ +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DES 3 /* des style (encrypted timestamps) */ diff --git a/sunrpc/rpc/auth_unix.h b/sunrpc/rpc/auth_unix.h new file mode 100644 index 0000000000..705741e139 --- /dev/null +++ b/sunrpc/rpc/auth_unix.h @@ -0,0 +1,72 @@ +/* @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */ +/* + * 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 + */ +/* @(#)auth_unix.h 1.5 86/07/16 SMI */ + +/* + * auth_unix.h, Protocol for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * The system is very weak. The client uses no encryption for it + * 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. + */ + +/* The machine name is part of a credential; it may not exceed 255 bytes */ +#define MAX_MACHINE_NAME 255 + +/* gids compose part of a credential; there may not be more than 16 of them */ +#define NGRPS 16 + +/* + * Unix style credentials. + */ +struct authunix_parms { + u_long aup_time; + char *aup_machname; + int aup_uid; + int aup_gid; + u_int aup_len; + int *aup_gids; +}; + +extern bool_t xdr_authunix_parms(); + +/* + * If a response verifier has flavor AUTH_SHORT, + * then the body of the response verifier encapsulates the following structure; + * again it is serialized in the obvious fashion. + */ +struct short_hand_verf { + struct opaque_auth new_cred; +}; diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h new file mode 100644 index 0000000000..8c002a19fa --- /dev/null +++ b/sunrpc/rpc/clnt.h @@ -0,0 +1,331 @@ +/* @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/ +/* + * 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 + */ + +/* + * clnt.h - Client side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _CLNT_ +#define _CLNT_ + +/* + * Rpc calls return an enum clnt_stat. This should be looked at more, + * since each implementation is required to live with this (implementation + * independent) list of errors. + */ +enum clnt_stat { + RPC_SUCCESS=0, /* call succeeded */ + /* + * local errors + */ + RPC_CANTENCODEARGS=1, /* can't encode arguments */ + RPC_CANTDECODERES=2, /* can't decode results */ + RPC_CANTSEND=3, /* failure in sending call */ + RPC_CANTRECV=4, /* failure in receiving result */ + RPC_TIMEDOUT=5, /* call timed out */ + /* + * remote errors + */ + RPC_VERSMISMATCH=6, /* rpc versions not compatible */ + RPC_AUTHERROR=7, /* authentication error */ + RPC_PROGUNAVAIL=8, /* program not available */ + RPC_PROGVERSMISMATCH=9, /* program version mismatched */ + RPC_PROCUNAVAIL=10, /* procedure unavailable */ + RPC_CANTDECODEARGS=11, /* decode arguments error */ + RPC_SYSTEMERROR=12, /* generic "other problem" */ + + /* + * callrpc & clnt_create errors + */ + RPC_UNKNOWNHOST=13, /* unknown host name */ + RPC_UNKNOWNPROTO=17, /* unkown protocol */ + + /* + * _ create errors + */ + RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ + RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ + /* + * unspecified error + */ + RPC_FAILED=16 +}; + + +/* + * Error info. + */ +struct rpc_err { + enum clnt_stat re_status; + union { + int RE_errno; /* realated system error */ + enum auth_stat RE_why; /* why the auth error occurred */ + struct { + u_long low; /* lowest verion supported */ + u_long high; /* highest verion supported */ + } RE_vers; + struct { /* maybe meaningful if RPC_FAILED */ + long s1; + long s2; + } RE_lb; /* life boot & debugging only */ + } ru; +#define re_errno ru.RE_errno +#define re_why ru.RE_why +#define re_vers ru.RE_vers +#define re_lb ru.RE_lb +}; + + +/* + * Client rpc handle. + * Created by individual implementations, see e.g. rpc_udp.c. + * Client is responsible for initializing auth, see e.g. auth_none.c. + */ +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 */ +} CLIENT; + + +/* + * client side rpc interface ops + * + * Parameter types are: + * + */ + +/* + * enum clnt_stat + * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) + * CLIENT *rh; + * u_long proc; + * xdrproc_t xargs; + * caddr_t argsp; + * xdrproc_t xres; + * caddr_t resp; + * struct timeval timeout; + */ +#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) +#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) + +/* + * void + * CLNT_ABORT(rh); + * CLIENT *rh; + */ +#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) +#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) + +/* + * struct rpc_err + * CLNT_GETERR(rh); + * CLIENT *rh; + */ +#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) +#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) + + +/* + * bool_t + * CLNT_FREERES(rh, xres, resp); + * CLIENT *rh; + * xdrproc_t xres; + * caddr_t resp; + */ +#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) +#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) + +/* + * bool_t + * CLNT_CONTROL(cl, request, info) + * CLIENT *cl; + * u_int request; + * char *info; + */ +#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) +#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) + +/* + * control operations that apply to both udp and tcp transports + */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +/* + * udp only control operations + */ +#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ +#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ + +/* + * void + * CLNT_DESTROY(rh); + * CLIENT *rh; + */ +#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) +#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) + + +/* + * RPCTEST is a test program which is accessable on every rpc + * transport/port. It is used for testing, performance evaluation, + * and network administration. + */ + +#define RPCTEST_PROGRAM ((u_long)1) +#define RPCTEST_VERSION ((u_long)1) +#define RPCTEST_NULL_PROC ((u_long)2) +#define RPCTEST_NULL_BATCH_PROC ((u_long)3) + +/* + * By convention, procedure 0 takes null arguments and returns them + */ + +#define NULLPROC ((u_long)0) + +/* + * Below are the client handle creation routines for the various + * implementations of client side rpc. They can return NULL if a + * creation failure occurs. + */ + +/* + * Memory based rpc (for speed check and testing) + * CLIENT * + * clntraw_create(prog, vers) + * u_long prog; + * u_long vers; + */ +extern CLIENT *clntraw_create(); + + +/* + * Generic client creation routine. Supported protocols are "udp" and "tcp" + */ +extern CLIENT * +clnt_create(/*host, prog, vers, prot*/); /* + char *host; -- hostname + u_long prog; -- program number + u_long vers; -- version number + char *prot; -- protocol +*/ + + + + +/* + * TCP based rpc + * CLIENT * + * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +extern CLIENT *clnttcp_create(); + +/* + * UDP based rpc. + * CLIENT * + * clntudp_create(raddr, program, version, wait, sockp) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * + * Same as above, but you specify max packet sizes. + * CLIENT * + * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +extern CLIENT *clntudp_create(); +extern CLIENT *clntudp_bufcreate(); + +/* + * Print why creation failed + */ +void clnt_pcreateerror(/* char *msg */); /* stderr */ +char *clnt_spcreateerror(/* char *msg */); /* string */ + +/* + * Like clnt_perror(), but is more verbose in its output + */ +void clnt_perrno(/* enum clnt_stat num */); /* stderr */ + +/* + * Print an English error message, given the client error code + */ +void clnt_perror(/* CLIENT *clnt, char *msg */); /* stderr */ +char *clnt_sperror(/* CLIENT *clnt, char *msg */); /* string */ + +/* + * If a creation fails, the following allows the user to figure out why. + */ +struct rpc_createerr { + enum clnt_stat cf_stat; + struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ +}; + +extern struct rpc_createerr rpc_createerr; + + + +/* + * Copy error message to buffer. + */ +char *clnt_sperrno(/* enum clnt_stat num */); /* string */ + + + +#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ +#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ + +#endif /*!_CLNT_*/ diff --git a/sunrpc/rpc/netdb.h b/sunrpc/rpc/netdb.h new file mode 100644 index 0000000000..23413cf7ba --- /dev/null +++ b/sunrpc/rpc/netdb.h @@ -0,0 +1,52 @@ +/* @(#)netdb.h 2.1 88/07/29 3.9 RPCSRC */ +/* + * 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 + */ +/* @(#)rpc.h 1.8 87/07/24 SMI */ + +/* Cleaned up for GNU C library roland@gnu.ai.mit.edu: + added multiple inclusion protection and use of <sys/cdefs.h>. + In GNU this file is #include'd by <netdb.h>. */ + +#ifndef _RPC_NETDB_H +#define _RPC_NETDB_H +#include <sys/cdefs.h> + +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + int r_number; /* rpc program number */ +}; + +__BEGIN_DECLS +struct rpcent *getrpcbyname __P((const char *)); +struct rpcent *getrpcbynumber __P((int)); +struct rpcent *getrpcent __P((void)); +__END_DECLS + +#endif diff --git a/sunrpc/rpc/pmap_clnt.h b/sunrpc/rpc/pmap_clnt.h new file mode 100644 index 0000000000..d2ea2a88e9 --- /dev/null +++ b/sunrpc/rpc/pmap_clnt.h @@ -0,0 +1,65 @@ +/* @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */ +/* + * 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 + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +extern bool_t pmap_set(); +extern bool_t pmap_unset(); +extern struct pmaplist *pmap_getmaps(); +enum clnt_stat pmap_rmtcall(); +enum clnt_stat clnt_broadcast(); +extern u_short pmap_getport(); diff --git a/sunrpc/rpc/pmap_prot.h b/sunrpc/rpc/pmap_prot.h new file mode 100644 index 0000000000..ccf7a77b41 --- /dev/null +++ b/sunrpc/rpc/pmap_prot.h @@ -0,0 +1,94 @@ +/* @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */ +/* + * 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 + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#define PMAPPORT ((u_short)111) +#define PMAPPROG ((u_long)100000) +#define PMAPVERS ((u_long)2) +#define PMAPVERS_PROTO ((u_long)2) +#define PMAPVERS_ORIG ((u_long)1) +#define PMAPPROC_NULL ((u_long)0) +#define PMAPPROC_SET ((u_long)1) +#define PMAPPROC_UNSET ((u_long)2) +#define PMAPPROC_GETPORT ((u_long)3) +#define PMAPPROC_DUMP ((u_long)4) +#define PMAPPROC_CALLIT ((u_long)5) + +struct pmap { + long unsigned pm_prog; + long unsigned pm_vers; + long unsigned pm_prot; + long unsigned pm_port; +}; + +extern bool_t xdr_pmap(); + +struct pmaplist { + struct pmap pml_map; + struct pmaplist *pml_next; +}; + +extern bool_t xdr_pmaplist(); diff --git a/sunrpc/rpc/pmap_rmt.h b/sunrpc/rpc/pmap_rmt.h new file mode 100644 index 0000000000..ee68cebec2 --- /dev/null +++ b/sunrpc/rpc/pmap_rmt.h @@ -0,0 +1,53 @@ +/* @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */ +/* + * 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 + */ + +/* + * Structures and XDR routines for parameters to and replies from + * the portmapper remote-call-service. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +struct rmtcallargs { + u_long prog, vers, proc, arglen; + caddr_t args_ptr; + xdrproc_t xdr_args; +}; + +bool_t xdr_rmtcall_args(); + +struct rmtcallres { + u_long *port_ptr; + u_long resultslen; + caddr_t results_ptr; + xdrproc_t xdr_results; +}; + +bool_t xdr_rmtcallres(); diff --git a/sunrpc/rpc/rpc.h b/sunrpc/rpc/rpc.h new file mode 100644 index 0000000000..83a124a3ed --- /dev/null +++ b/sunrpc/rpc/rpc.h @@ -0,0 +1,73 @@ +/* @(#)rpc.h 2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */ +/* + * 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 + */ + +/* + * rpc.h, Just includes the billions of rpc header files necessary to + * do remote procedure calling. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ +#ifndef __RPC_HEADER__ +#define __RPC_HEADER__ + +#include <rpc/types.h> /* some typedefs */ +#include <netinet/in.h> + +/* external data representation interfaces */ +#include <rpc/xdr.h> /* generic (de)serializer */ + +/* Client side only authentication */ +#include <rpc/auth.h> /* generic authenticator (client side) */ + +/* Client side (mostly) remote procedure call */ +#include <rpc/clnt.h> /* generic rpc stuff */ + +/* semi-private protocol headers */ +#include <rpc/rpc_msg.h> /* protocol for rpc messages */ +#include <rpc/auth_unix.h> /* protocol for unix style cred */ +/* + * Uncomment-out the next line if you are building the rpc library with + * DES Authentication (see the README file in the secure_rpc/ directory). + */ +/*#include <rpc/auth_des.h> /* protocol for des style cred */ + +/* Server side only remote procedure callee */ +#include <rpc/svc.h> /* service manager and multiplexer */ +#include <rpc/svc_auth.h> /* service side authenticator */ + +/* + * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION + * OF UNIX BASED ON NFSSRC. These systems will already have the structures + * defined by <rpc/netdb.h> included in <netdb.h>. + */ +/* routines for parsing /etc/rpc */ +#include <rpc/netdb.h> /* structures and routines to parse /etc/rpc */ + +#endif /* ndef __RPC_HEADER__ */ diff --git a/sunrpc/rpc/rpc_msg.h b/sunrpc/rpc/rpc_msg.h new file mode 100644 index 0000000000..b78872b6a8 --- /dev/null +++ b/sunrpc/rpc/rpc_msg.h @@ -0,0 +1,187 @@ +/* @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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 + */ +/* @(#)rpc_msg.h 1.7 86/07/16 SMI */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#define RPC_MSG_VERSION ((u_long) 2) +#define RPC_SERVICE_PORT ((u_short) 2048) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum msg_type { + CALL=0, + REPLY=1 +}; + +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 +}; + +enum accept_stat { + SUCCESS=0, + PROG_UNAVAIL=1, + PROG_MISMATCH=2, + PROC_UNAVAIL=3, + GARBAGE_ARGS=4, + SYSTEM_ERR=5 +}; + +enum reject_stat { + RPC_MISMATCH=0, + AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was accepted by the server. + * Note: there could be an error even though the request was + * accepted. + */ +struct accepted_reply { + struct opaque_auth ar_verf; + enum accept_stat ar_stat; + union { + struct { + u_long low; + u_long high; + } AR_versions; + struct { + caddr_t where; + xdrproc_t proc; + } AR_results; + /* and many other null cases */ + } ru; +#define ar_results ru.AR_results +#define ar_vers ru.AR_versions +}; + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct rejected_reply { + enum reject_stat rj_stat; + union { + struct { + u_long low; + u_long high; + } RJ_versions; + enum auth_stat RJ_why; /* why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct reply_body { + enum reply_stat rp_stat; + union { + struct accepted_reply RP_ar; + struct rejected_reply RP_dr; + } ru; +#define rp_acpt ru.RP_ar +#define rp_rjct ru.RP_dr +}; + +/* + * Body of an rpc request call. + */ +struct call_body { + u_long cb_rpcvers; /* must be equal to two */ + u_long cb_prog; + u_long cb_vers; + u_long cb_proc; + struct opaque_auth cb_cred; + struct opaque_auth cb_verf; /* protocol specific - provided by client */ +}; + +/* + * The rpc message + */ +struct rpc_msg { + u_long rm_xid; + enum msg_type rm_direction; + union { + struct call_body RM_cmb; + struct reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr + + +/* + * XDR routine to handle a rpc message. + * xdr_callmsg(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callmsg(); + +/* + * XDR routine to pre-serialize the static part of a rpc message. + * xdr_callhdr(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callhdr(); + +/* + * XDR routine to handle a rpc reply. + * xdr_replymsg(xdrs, rmsg) + * XDR *xdrs; + * struct rpc_msg *rmsg; + */ +extern bool_t xdr_replymsg(); + +/* + * Fills in the error part of a reply message. + * _seterr_reply(msg, error) + * struct rpc_msg *msg; + * struct rpc_err *error; + */ +extern void _seterr_reply(); diff --git a/sunrpc/rpc/svc.h b/sunrpc/rpc/svc.h new file mode 100644 index 0000000000..3cb07ef3f3 --- /dev/null +++ b/sunrpc/rpc/svc.h @@ -0,0 +1,280 @@ +/* @(#)svc.h 2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */ +/* + * 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 + */ + +/* + * svc.h, Server-side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef __SVC_HEADER__ +#define __SVC_HEADER__ + +/* + * This interface must manage two items concerning remote procedure calling: + * + * 1) An arbitrary number of transport connections upon which rpc requests + * are received. The two most notable transports are TCP and UDP; they are + * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; + * they in turn call xprt_register and xprt_unregister. + * + * 2) An arbitrary number of locally registered services. Services are + * described by the following four data: program number, version number, + * "service dispatch" function, a transport handle, and a boolean that + * indicates whether or not the exported program should be registered with a + * local binder service; if true the program's number and version and the + * port number from the transport handle are registered with the binder. + * These data are registered with the rpc svc system via svc_register. + * + * A service's dispatch function is called whenever an rpc request comes in + * on a transport. The request's program and version numbers must match + * those of the registered service. The dispatch function is passed two + * parameters, struct svc_req * and SVCXPRT *, defined below. + */ + +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct { + int xp_sock; + u_short xp_port; /* associated port number */ + struct xp_ops { + bool_t (*xp_recv)(); /* receive incomming 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 address */ + struct sockaddr_in xp_raddr; /* remote address */ + struct opaque_auth xp_verf; /* raw response verifier */ + caddr_t xp_p1; /* private */ + caddr_t xp_p2; /* private */ +} SVCXPRT; + +/* + * Approved way of getting address of caller + */ +#define svc_getcaller(x) (&(x)->xp_raddr) + +/* + * Operations defined on an SVCXPRT handle + * + * SVCXPRT *xprt; + * struct rpc_msg *msg; + * xdrproc_t xargs; + * caddr_t argsp; + */ +#define SVC_RECV(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) +#define svc_recv(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) + +#define SVC_STAT(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) +#define svc_stat(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) + +#define SVC_GETARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) +#define svc_getargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) + +#define SVC_REPLY(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) +#define svc_reply(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) + +#define SVC_FREEARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) +#define svc_freeargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) + +#define SVC_DESTROY(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) +#define svc_destroy(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) + + +/* + * Service request + */ +struct svc_req { + u_long rq_prog; /* service program number */ + u_long rq_vers; /* service protocol version */ + u_long 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 */ +}; + + +/* + * Service registration + * + * svc_register(xprt, prog, vers, dispatch, protocol) + * SVCXPRT *xprt; + * u_long prog; + * u_long vers; + * void (*dispatch)(); + * int protocol; /* like TCP or UDP, zero means do not register + */ +extern bool_t svc_register(); + +/* + * Service un-registration + * + * svc_unregister(prog, vers) + * u_long prog; + * u_long vers; + */ +extern void svc_unregister(); + +/* + * Transport registration. + * + * xprt_register(xprt) + * SVCXPRT *xprt; + */ +extern void xprt_register(); + +/* + * Transport un-register + * + * xprt_unregister(xprt) + * SVCXPRT *xprt; + */ +extern void xprt_unregister(); + + + + +/* + * When the service routine is called, it must first check to see if it + * knows about the procedure; if not, it should call svcerr_noproc + * and return. If so, it should deserialize its arguments via + * SVC_GETARGS (defined above). If the deserialization does not work, + * svcerr_decode should be called followed by a return. Successful + * decoding of the arguments should be followed the execution of the + * procedure's code and a call to svc_sendreply. + * + * Also, if the service refuses to execute the procedure due to too- + * weak authentication parameters, svcerr_weakauth should be called. + * Note: do not confuse access-control failure with weak authentication! + * + * NB: In pure implementations of rpc, the caller always waits for a reply + * msg. This message is sent when svc_sendreply is called. + * Therefore pure service implementations should always call + * svc_sendreply even if the function logically returns void; use + * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows + * for the abuse of pure rpc via batched calling or pipelining. In the + * case of a batched call, svc_sendreply should NOT be called since + * this would send a return message, which is what batching tries to avoid. + * It is the service/protocol writer's responsibility to know which calls are + * batched and which are not. Warning: responding to batch calls may + * deadlock the caller and server processes! + */ + +extern bool_t svc_sendreply(); +extern void svcerr_decode(); +extern void svcerr_weakauth(); +extern void svcerr_noproc(); +extern void svcerr_progvers(); +extern void svcerr_auth(); +extern void svcerr_noprog(); +extern void svcerr_systemerr(); + +/* + * Lowest level dispatching -OR- who owns this process anyway. + * Somebody has to wait for incoming requests and then call the correct + * service routine. The routine svc_run does infinite waiting; i.e., + * svc_run never returns. + * Since another (co-existant) package may wish to selectively wait for + * incoming calls or other events outside of the rpc architecture, the + * routine svc_getreq is provided. It must be passed readfds, the + * "in-place" results of a select system call (see select, section 2). + */ + +/* + * Global keeper of rpc service descriptors in use + * dynamic; must be inspected before each call to select + */ +#ifdef FD_SETSIZE +extern fd_set svc_fdset; +#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +#else +extern int svc_fds; +#endif /* def FD_SETSIZE */ + +/* + * a small program implemented by the svc_rpc implementation itself; + * also see clnt.h for protocol numbers. + */ +extern void rpctest_service(); + +extern void svc_getreq(); +extern void svc_getreqset(); /* takes fdset instead of int */ +extern void svc_run(); /* never returns */ + +/* + * Socket to use on svcxxx_create call to get default socket + */ +#define RPC_ANYSOCK -1 + +/* + * These are the existing service side transport implementations + */ + +/* + * Memory based rpc for testing and timing. + */ +extern SVCXPRT *svcraw_create(); + +/* + * Udp based rpc. + */ +extern SVCXPRT *svcudp_create(); +extern SVCXPRT *svcudp_bufcreate(); + +/* + * Tcp based rpc. + */ +extern SVCXPRT *svctcp_create(); + + + +#endif !__SVC_HEADER__ diff --git a/sunrpc/rpc/svc_auth.h b/sunrpc/rpc/svc_auth.h new file mode 100644 index 0000000000..a36a01aba8 --- /dev/null +++ b/sunrpc/rpc/svc_auth.h @@ -0,0 +1,42 @@ +/* @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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 + */ +/* @(#)svc_auth.h 1.6 86/07/16 SMI */ + +/* + * svc_auth.h, Service side of rpc authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + + +/* + * Server side authenticator + */ +extern enum auth_stat _authenticate(); diff --git a/sunrpc/rpc/types.h b/sunrpc/rpc/types.h new file mode 100644 index 0000000000..1f620eff8f --- /dev/null +++ b/sunrpc/rpc/types.h @@ -0,0 +1,63 @@ +/* @(#)types.h 2.3 88/08/15 4.0 RPCSRC */ +/* + * 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 + */ +/* @(#)types.h 1.18 87/07/24 SMI */ + +/* + * Rpc additions to <sys/types.h> + */ +#ifndef __TYPES_RPC_HEADER__ +#define __TYPES_RPC_HEADER__ + +#define bool_t int +#define enum_t int +#define FALSE (0) +#define TRUE (1) +#define __dontcare__ -1 +#ifndef NULL +# define NULL 0 +#endif + +extern char *malloc(); +#define mem_alloc(bsize) malloc(bsize) +#define mem_free(ptr, bsize) free(ptr) + +#ifndef makedev /* ie, we haven't already included it */ +#include <sys/types.h> +#endif +#include <sys/time.h> + +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK (u_long)0x7F000001 +#endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#endif /* ndef __TYPES_RPC_HEADER__ */ diff --git a/sunrpc/rpc/xdr.h b/sunrpc/rpc/xdr.h new file mode 100644 index 0000000000..6cd3e6fe03 --- /dev/null +++ b/sunrpc/rpc/xdr.h @@ -0,0 +1,270 @@ +/* @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */ +/* + * 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 + */ +/* @(#)xdr.h 1.19 87/04/22 SMI */ + +/* + * xdr.h, External Data Representation Serialization Routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef __XDR_HEADER__ +#define __XDR_HEADER__ + +/* + * XDR provides a conventional way for converting between C data + * types and an external bit-string representation. Library supplied + * routines provide for the conversion on built-in C data types. These + * routines and utility routines defined here are used to help implement + * a type encode/decode routine for each user-defined type. + * + * Each data type provides a single procedure which takes two arguments: + * + * bool_t + * xdrproc(xdrs, argresp) + * XDR *xdrs; + * <type> *argresp; + * + * xdrs is an instance of a XDR handle, to which or from which the data + * type is to be converted. argresp is a pointer to the structure to be + * converted. The XDR handle contains an operation field which indicates + * which of the operations (ENCODE, DECODE * or FREE) is to be performed. + * + * XDR_DECODE may allocate space if the pointer argresp is null. This + * data can be freed with the XDR_FREE operation. + * + * We write only one procedure per data type to make it easy + * to keep the encode and decode procedures for a data type consistent. + * In many cases the same code performs all operations on a user defined type, + * because all the hard work is done in the component type routines. + * decode as a series of calls on the nested data types. + */ + +/* + * 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) \ + * 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 pointer is 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 paticular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular impelementation. + */ +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 " */ + bool_t (*x_getbytes)();/* get some bytes from " */ + bool_t (*x_putbytes)();/* put some bytes to " */ + 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 */ + int x_handy; /* extra private word */ +} XDR; + +/* + * Operations defined on a XDR handle + * + * XDR *xdrs; + * long *longp; + * caddr_t addr; + * u_int len; + * u_int pos; + */ +#define XDR_GETLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) +#define xdr_getlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) + +#define XDR_PUTLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) +#define xdr_putlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) + +#define XDR_GETBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) + +#define XDR_PUTBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) + +#define XDR_GETPOS(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) + +#define XDR_SETPOS(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) + +#define XDR_INLINE(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) + +#define XDR_DESTROY(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) +#define xdr_destroy(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) + +/* + * Support struct for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * a entry with a null procedure pointer. The xdr_union routine gets + * the discriminant value and then searches the array of structures + * for a matching value. If a match is found the associated xdr routine + * is called to handle that part of the union. If there is + * no match, then a default routine may be called. + * If there is no match and no default routine it is an error. + */ +#define NULL_xdrproc_t ((xdrproc_t)0) +struct xdr_discrim { + int value; + xdrproc_t proc; +}; + +/* + * In-line routines for fast encode/decode of primitve data types. + * Caveat emptor: these use single memory cycles to get the + * data from the underlying buffer, and will fail to operate + * properly if the data is not aligned. The standard way to use these + * is to say: + * if ((buf = XDR_INLINE(xdrs, count)) == NULL) + * return (FALSE); + * <<< macro calls >>> + * where ``count'' is the number of bytes of data occupied + * by the primitive data types. + * + * N.B. and frozen for all time: each data type here uses 4 bytes + * of external representation. + */ +#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) +#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v)) + +#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) +#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) +#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) + +#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) + +/* + * These are the "generic" xdr routines. + */ +extern bool_t xdr_void(); +extern bool_t xdr_int(); +extern bool_t xdr_u_int(); +extern bool_t xdr_long(); +extern bool_t xdr_u_long(); +extern bool_t xdr_short(); +extern bool_t xdr_u_short(); +extern bool_t xdr_bool(); +extern bool_t xdr_enum(); +extern bool_t xdr_array(); +extern bool_t xdr_bytes(); +extern bool_t xdr_opaque(); +extern bool_t xdr_string(); +extern bool_t xdr_union(); +extern bool_t xdr_char(); +extern bool_t xdr_u_char(); +extern bool_t xdr_vector(); +extern bool_t xdr_float(); +extern bool_t xdr_double(); +extern bool_t xdr_reference(); +extern bool_t xdr_pointer(); +extern bool_t xdr_wrapstring(); + +/* + * Common opaque bytes objects used by many rpc protocols; + * declared here due to commonality. + */ +#define MAX_NETOBJ_SZ 1024 +struct netobj { + u_int n_len; + char *n_bytes; +}; +typedef struct netobj netobj; +extern bool_t xdr_netobj(); + +/* + * These are the public routines for the various implementations of + * xdr streams. + */ +extern void xdrmem_create(); /* XDR using memory buffers */ +extern void xdrstdio_create(); /* XDR using stdio library */ +extern void xdrrec_create(); /* XDR pseudo records for tcp */ +extern bool_t xdrrec_endofrecord(); /* make end of xdr record */ +extern bool_t xdrrec_skiprecord(); /* move to beginning of next record */ +extern bool_t xdrrec_eof(); /* true if no more input */ + +#endif !__XDR_HEADER__ diff --git a/sunrpc/rpc_clntout.c b/sunrpc/rpc_clntout.c new file mode 100644 index 0000000000..555681bd2a --- /dev/null +++ b/sunrpc/rpc_clntout.c @@ -0,0 +1,126 @@ +/* @(#)rpc_clntout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_clntout.c 1.2 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsytsems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_parse.h" +#include "rpc_util.h" + +#define DEFAULT_TIMEOUT 25 /* in seconds */ + +void +write_stubs() +{ + list *l; + definition *def; + + f_print(fout, + "\n/* Default timeout can be changed using clnt_control() */\n"); + f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n", + DEFAULT_TIMEOUT); + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind == DEF_PROGRAM) { + write_program(def); + } + } +} + + +static +write_program(def) + definition *def; +{ + version_list *vp; + proc_list *proc; + + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + for (proc = vp->procs; proc != NULL; proc = proc->next) { + f_print(fout, "\n"); + ptype(proc->res_prefix, proc->res_type, 1); + f_print(fout, "*\n"); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "(argp, clnt)\n"); + f_print(fout, "\t"); + ptype(proc->arg_prefix, proc->arg_type, 1); + f_print(fout, "*argp;\n"); + f_print(fout, "\tCLIENT *clnt;\n"); + f_print(fout, "{\n"); + printbody(proc); + f_print(fout, "}\n\n"); + } + } +} + +static char * +ampr(type) + char *type; +{ + if (isvectordef(type, REL_ALIAS)) { + return (""); + } else { + return ("&"); + } +} + +static +printbody(proc) + proc_list *proc; +{ + f_print(fout, "\tstatic "); + if (streq(proc->res_type, "void")) { + f_print(fout, "char "); + } else { + ptype(proc->res_prefix, proc->res_type, 0); + } + f_print(fout, "res;\n"); + f_print(fout, "\n"); + f_print(fout, "\tbzero((char *)%sres, sizeof(res));\n", + ampr(proc->res_type)); + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_%s, argp, xdr_%s, %sres, TIMEOUT) != RPC_SUCCESS) {\n", + proc->proc_name, stringfix(proc->arg_type), + stringfix(proc->res_type), ampr(proc->res_type)); + f_print(fout, "\t\treturn (NULL);\n"); + f_print(fout, "\t}\n"); + if (streq(proc->res_type, "void")) { + f_print(fout, "\treturn ((void *)%sres);\n", + ampr(proc->res_type)); + } else { + f_print(fout, "\treturn (%sres);\n", ampr(proc->res_type)); + } +} diff --git a/sunrpc/rpc_cmsg.c b/sunrpc/rpc_cmsg.c new file mode 100644 index 0000000000..d9d815a6fb --- /dev/null +++ b/sunrpc/rpc_cmsg.c @@ -0,0 +1,190 @@ +/* @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * rpc_callmsg.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ + +#include <sys/param.h> + +#include <rpc/rpc.h> + +/* + * XDR a call message + */ +bool_t +xdr_callmsg(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + register long *buf; + register struct opaque_auth *oa; + + if (xdrs->x_op == XDR_ENCODE) { + if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_cred.oa_length) + + 2 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_verf.oa_length)); + if (buf != NULL) { + IXDR_PUT_LONG(buf, cmsg->rm_xid); + IXDR_PUT_ENUM(buf, cmsg->rm_direction); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc); + oa = &cmsg->rm_call.cb_cred; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + buf += RNDUP(oa->oa_length) / sizeof (long); + } + oa = &cmsg->rm_call.cb_verf; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / sizeof (long); + */ + } + return (TRUE); + } + } + if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); + if (buf != NULL) { + cmsg->rm_xid = IXDR_GET_LONG(buf); + cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); + oa = &cmsg->rm_call.cb_cred; + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + oa = &cmsg->rm_call.cb_verf; + buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || + xdr_u_int(xdrs, &oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + } + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + return (TRUE); + } + } + if ( + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + (cmsg->rm_direction == CALL) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) && + xdr_u_long(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/sunrpc/rpc_common.c b/sunrpc/rpc_common.c new file mode 100644 index 0000000000..75cead0875 --- /dev/null +++ b/sunrpc/rpc_common.c @@ -0,0 +1,41 @@ +/* @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#include <rpc/rpc.h> +/* + * This file should only contain common data (global data) that is exported + * by public interfaces + */ +struct opaque_auth _null_auth; +#ifdef FD_SETSIZE +fd_set svc_fdset; +#else +int svc_fds; +#endif /* def FD_SETSIZE */ +struct rpc_createerr rpc_createerr; diff --git a/sunrpc/rpc_cout.c b/sunrpc/rpc_cout.c new file mode 100644 index 0000000000..86d38652f5 --- /dev/null +++ b/sunrpc/rpc_cout.c @@ -0,0 +1,350 @@ +/* @(#)rpc_cout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_cout.c 1.8 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_cout.c, XDR routine outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_util.h" +#include "rpc_parse.h" + +/* + * Emit the C-routine for the given definition + */ +void +emit(def) + definition *def; +{ + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { + return; + } + print_header(def); + switch (def->def_kind) { + case DEF_UNION: + emit_union(def); + break; + case DEF_ENUM: + emit_enum(def); + break; + case DEF_STRUCT: + emit_struct(def); + break; + case DEF_TYPEDEF: + emit_typedef(def); + break; + } + print_trailer(); +} + +static +findtype(def, type) + definition *def; + char *type; +{ + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { + return (0); + } else { + return (streq(def->def_name, type)); + } +} + +static +undefined(type) + char *type; +{ + definition *def; + + def = (definition *) FINDVAL(defined, type, findtype); + return (def == NULL); +} + + +static +print_header(def) + definition *def; +{ + space(); + f_print(fout, "bool_t\n"); + f_print(fout, "xdr_%s(xdrs, objp)\n", def->def_name); + f_print(fout, "\tXDR *xdrs;\n"); + f_print(fout, "\t%s ", def->def_name); + if (def->def_kind != DEF_TYPEDEF || + !isvectordef(def->def.ty.old_type, def->def.ty.rel)) { + f_print(fout, "*"); + } + f_print(fout, "objp;\n"); + f_print(fout, "{\n"); +} + +static +print_trailer() +{ + f_print(fout, "\treturn (TRUE);\n"); + f_print(fout, "}\n"); + space(); +} + + +static +print_ifopen(indent, name) + int indent; + char *name; +{ + tabify(fout, indent); + f_print(fout, "if (!xdr_%s(xdrs", name); +} + + +static +print_ifarg(arg) + char *arg; +{ + f_print(fout, ", %s", arg); +} + + +static +print_ifsizeof(prefix, type) + char *prefix; + char *type; +{ + if (streq(type, "bool")) { + f_print(fout, ", sizeof(bool_t), xdr_bool"); + } else { + f_print(fout, ", sizeof("); + if (undefined(type) && prefix) { + f_print(fout, "%s ", prefix); + } + f_print(fout, "%s), xdr_%s", type, type); + } +} + +static +print_ifclose(indent) + int indent; +{ + f_print(fout, ")) {\n"); + tabify(fout, indent); + f_print(fout, "\treturn (FALSE);\n"); + tabify(fout, indent); + f_print(fout, "}\n"); +} + +static +space() +{ + f_print(fout, "\n\n"); +} + +static +print_ifstat(indent, prefix, type, rel, amax, objname, name) + int indent; + char *prefix; + char *type; + relation rel; + char *amax; + char *objname; + char *name; +{ + char *alt = NULL; + + switch (rel) { + case REL_POINTER: + print_ifopen(indent, "pointer"); + print_ifarg("(char **)"); + f_print(fout, "%s", objname); + print_ifsizeof(prefix, type); + break; + case REL_VECTOR: + if (streq(type, "string")) { + alt = "string"; + } else if (streq(type, "opaque")) { + alt = "opaque"; + } + if (alt) { + print_ifopen(indent, alt); + print_ifarg(objname); + } else { + print_ifopen(indent, "vector"); + print_ifarg("(char *)"); + f_print(fout, "%s", objname); + } + print_ifarg(amax); + if (!alt) { + print_ifsizeof(prefix, type); + } + break; + case REL_ARRAY: + if (streq(type, "string")) { + alt = "string"; + } else if (streq(type, "opaque")) { + alt = "bytes"; + } + if (streq(type, "string")) { + print_ifopen(indent, alt); + print_ifarg(objname); + } else { + if (alt) { + print_ifopen(indent, alt); + } else { + print_ifopen(indent, "array"); + } + print_ifarg("(char **)"); + if (*objname == '&') { + f_print(fout, "%s.%s_val, (u_int *)%s.%s_len", + objname, name, objname, name); + } else { + f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len", + objname, name, objname, name); + } + } + print_ifarg(amax); + if (!alt) { + print_ifsizeof(prefix, type); + } + break; + case REL_ALIAS: + print_ifopen(indent, type); + print_ifarg(objname); + break; + } + print_ifclose(indent); +} + + +/* ARGSUSED */ +static +emit_enum(def) + definition *def; +{ + print_ifopen(1, "enum"); + print_ifarg("(enum_t *)objp"); + print_ifclose(1); +} + + +static +emit_union(def) + definition *def; +{ + declaration *dflt; + case_list *cl; + declaration *cs; + char *object; + char *format = "&objp->%s_u.%s"; + + print_stat(&def->def.un.enum_decl); + f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); + for (cl = def->def.un.cases; cl != NULL; cl = cl->next) { + cs = &cl->case_decl; + f_print(fout, "\tcase %s:\n", cl->case_name); + if (!streq(cs->type, "void")) { + object = alloc(strlen(def->def_name) + strlen(format) + + strlen(cs->name) + 1); + s_print(object, format, def->def_name, cs->name); + print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max, + object, cs->name); + free(object); + } + f_print(fout, "\t\tbreak;\n"); + } + dflt = def->def.un.default_decl; + if (dflt != NULL) { + if (!streq(dflt->type, "void")) { + f_print(fout, "\tdefault:\n"); + object = alloc(strlen(def->def_name) + strlen(format) + + strlen(dflt->name) + 1); + s_print(object, format, def->def_name, dflt->name); + print_ifstat(2, dflt->prefix, dflt->type, dflt->rel, + dflt->array_max, object, dflt->name); + free(object); + f_print(fout, "\t\tbreak;\n"); + } + } else { + f_print(fout, "\tdefault:\n"); + f_print(fout, "\t\treturn (FALSE);\n"); + } + f_print(fout, "\t}\n"); +} + + + +static +emit_struct(def) + definition *def; +{ + decl_list *dl; + + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { + print_stat(&dl->decl); + } +} + + + + +static +emit_typedef(def) + definition *def; +{ + char *prefix = def->def.ty.old_prefix; + char *type = def->def.ty.old_type; + char *amax = def->def.ty.array_max; + relation rel = def->def.ty.rel; + + print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); +} + + + + + +static +print_stat(dec) + declaration *dec; +{ + char *prefix = dec->prefix; + char *type = dec->type; + char *amax = dec->array_max; + relation rel = dec->rel; + char name[256]; + + if (isvectordef(type, rel)) { + s_print(name, "objp->%s", dec->name); + } else { + s_print(name, "&objp->%s", dec->name); + } + print_ifstat(1, prefix, type, rel, amax, name, dec->name); +} diff --git a/sunrpc/rpc_dtable.c b/sunrpc/rpc_dtable.c new file mode 100644 index 0000000000..a8488172e4 --- /dev/null +++ b/sunrpc/rpc_dtable.c @@ -0,0 +1,46 @@ +/* @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro"; +#endif + +/* + * Cache the result of getdtablesize(), so we don't have to do an + * expensive system call every time. + */ +_rpc_dtablesize() +{ + static int size; + + if (size == 0) { + size = getdtablesize(); + } + return (size); +} diff --git a/sunrpc/rpc_hout.c b/sunrpc/rpc_hout.c new file mode 100644 index 0000000000..1bf009738d --- /dev/null +++ b/sunrpc/rpc_hout.c @@ -0,0 +1,370 @@ +/* @(#)rpc_hout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_hout.c 1.6 87/07/28 (C) 1987 SMI"; +#endif + +/* + * rpc_hout.c, Header file outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <ctype.h> +#include "rpc_util.h" +#include "rpc_parse.h" + + +/* + * Print the C-version of an xdr definition + */ +void +print_datadef(def) + definition *def; +{ + if (def->def_kind != DEF_CONST) { + f_print(fout, "\n"); + } + switch (def->def_kind) { + case DEF_STRUCT: + pstructdef(def); + break; + case DEF_UNION: + puniondef(def); + break; + case DEF_ENUM: + penumdef(def); + break; + case DEF_TYPEDEF: + ptypedef(def); + break; + case DEF_PROGRAM: + pprogramdef(def); + break; + case DEF_CONST: + pconstdef(def); + break; + } + if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { + f_print(fout, "bool_t xdr_%s();\n", def->def_name); + } + if (def->def_kind != DEF_CONST) { + f_print(fout, "\n"); + } +} + +static +pconstdef(def) + definition *def; +{ + pdefine(def->def_name, def->def.co); +} + +static +pstructdef(def) + definition *def; +{ + decl_list *l; + char *name = def->def_name; + + f_print(fout, "struct %s {\n", name); + for (l = def->def.st.decls; l != NULL; l = l->next) { + pdeclaration(name, &l->decl, 1); + } + f_print(fout, "};\n"); + f_print(fout, "typedef struct %s %s;\n", name, name); +} + +static +puniondef(def) + definition *def; +{ + case_list *l; + char *name = def->def_name; + declaration *decl; + + f_print(fout, "struct %s {\n", name); + decl = &def->def.un.enum_decl; + if (streq(decl->type, "bool")) { + f_print(fout, "\tbool_t %s;\n", decl->name); + } else { + f_print(fout, "\t%s %s;\n", decl->type, decl->name); + } + f_print(fout, "\tunion {\n"); + for (l = def->def.un.cases; l != NULL; l = l->next) { + pdeclaration(name, &l->case_decl, 2); + } + decl = def->def.un.default_decl; + if (decl && !streq(decl->type, "void")) { + pdeclaration(name, decl, 2); + } + f_print(fout, "\t} %s_u;\n", name); + f_print(fout, "};\n"); + f_print(fout, "typedef struct %s %s;\n", name, name); +} + + + +static +pdefine(name, num) + char *name; + char *num; +{ + f_print(fout, "#define %s %s\n", name, num); +} + +static +puldefine(name, num) + char *name; + char *num; +{ + f_print(fout, "#define %s ((u_long)%s)\n", name, num); +} + +static +define_printed(stop, start) + proc_list *stop; + version_list *start; +{ + version_list *vers; + proc_list *proc; + + for (vers = start; vers != NULL; vers = vers->next) { + for (proc = vers->procs; proc != NULL; proc = proc->next) { + if (proc == stop) { + return (0); + } else if (streq(proc->proc_name, stop->proc_name)) { + return (1); + } + } + } + abort(); + /* NOTREACHED */ +} + + +static +pprogramdef(def) + definition *def; +{ + version_list *vers; + proc_list *proc; + + puldefine(def->def_name, def->def.pr.prog_num); + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { + puldefine(vers->vers_name, vers->vers_num); + for (proc = vers->procs; proc != NULL; proc = proc->next) { + if (!define_printed(proc, def->def.pr.versions)) { + puldefine(proc->proc_name, proc->proc_num); + } + pprocdef(proc, vers); + } + } +} + + +pprocdef(proc, vp) + proc_list *proc; + version_list *vp; +{ + f_print(fout, "extern "); + if (proc->res_prefix) { + if (streq(proc->res_prefix, "enum")) { + f_print(fout, "enum "); + } else { + f_print(fout, "struct "); + } + } + if (streq(proc->res_type, "bool")) { + f_print(fout, "bool_t *"); + } else if (streq(proc->res_type, "string")) { + f_print(fout, "char **"); + } else { + f_print(fout, "%s *", fixtype(proc->res_type)); + } + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "();\n"); +} + +static +penumdef(def) + definition *def; +{ + char *name = def->def_name; + enumval_list *l; + char *last = NULL; + int count = 0; + + f_print(fout, "enum %s {\n", name); + for (l = def->def.en.vals; l != NULL; l = l->next) { + f_print(fout, "\t%s", l->name); + if (l->assignment) { + f_print(fout, " = %s", l->assignment); + last = l->assignment; + count = 1; + } else { + if (last == NULL) { + f_print(fout, " = %d", count++); + } else { + f_print(fout, " = %s + %d", last, count++); + } + } + f_print(fout, ",\n"); + } + f_print(fout, "};\n"); + f_print(fout, "typedef enum %s %s;\n", name, name); +} + +static +ptypedef(def) + definition *def; +{ + char *name = def->def_name; + char *old = def->def.ty.old_type; + char prefix[8]; /* enough to contain "struct ", including NUL */ + relation rel = def->def.ty.rel; + + + if (!streq(name, old)) { + if (streq(old, "string")) { + old = "char"; + rel = REL_POINTER; + } else if (streq(old, "opaque")) { + old = "char"; + } else if (streq(old, "bool")) { + old = "bool_t"; + } + if (undefined2(old, name) && def->def.ty.old_prefix) { + s_print(prefix, "%s ", def->def.ty.old_prefix); + } else { + prefix[0] = 0; + } + f_print(fout, "typedef "); + switch (rel) { + case REL_ARRAY: + f_print(fout, "struct {\n"); + f_print(fout, "\tu_int %s_len;\n", name); + f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name); + f_print(fout, "} %s", name); + break; + case REL_POINTER: + f_print(fout, "%s%s *%s", prefix, old, name); + break; + case REL_VECTOR: + f_print(fout, "%s%s %s[%s]", prefix, old, name, + def->def.ty.array_max); + break; + case REL_ALIAS: + f_print(fout, "%s%s %s", prefix, old, name); + break; + } + f_print(fout, ";\n"); + } +} + + +static +pdeclaration(name, dec, tab) + char *name; + declaration *dec; + int tab; +{ + char buf[8]; /* enough to hold "struct ", include NUL */ + char *prefix; + char *type; + + if (streq(dec->type, "void")) { + return; + } + tabify(fout, tab); + if (streq(dec->type, name) && !dec->prefix) { + f_print(fout, "struct "); + } + if (streq(dec->type, "string")) { + f_print(fout, "char *%s", dec->name); + } else { + prefix = ""; + if (streq(dec->type, "bool")) { + type = "bool_t"; + } else if (streq(dec->type, "opaque")) { + type = "char"; + } else { + if (dec->prefix) { + s_print(buf, "%s ", dec->prefix); + prefix = buf; + } + type = dec->type; + } + switch (dec->rel) { + case REL_ALIAS: + f_print(fout, "%s%s %s", prefix, type, dec->name); + break; + case REL_VECTOR: + f_print(fout, "%s%s %s[%s]", prefix, type, dec->name, + dec->array_max); + break; + case REL_POINTER: + f_print(fout, "%s%s *%s", prefix, type, dec->name); + break; + case REL_ARRAY: + f_print(fout, "struct {\n"); + tabify(fout, tab); + f_print(fout, "\tu_int %s_len;\n", dec->name); + tabify(fout, tab); + f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); + tabify(fout, tab); + f_print(fout, "} %s", dec->name); + break; + } + } + f_print(fout, ";\n"); +} + + + +static +undefined2(type, stop) + char *type; + char *stop; +{ + list *l; + definition *def; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + if (streq(def->def_name, stop)) { + return (1); + } else if (streq(def->def_name, type)) { + return (0); + } + } + } + return (1); +} diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c new file mode 100644 index 0000000000..795bf2aa57 --- /dev/null +++ b/sunrpc/rpc_main.c @@ -0,0 +1,433 @@ +/* @(#)rpc_main.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_main.c, Top level of the RPC protocol compiler. + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <strings.h> +#include <sys/file.h> +#include "rpc_util.h" +#include "rpc_parse.h" +#include "rpc_scan.h" + +#define EXTEND 1 /* alias for TRUE */ + +struct commandline { + int cflag; + int hflag; + int lflag; + int sflag; + int mflag; + char *infile; + char *outfile; +}; + +static char *cmdname; +static char CPP[] = "/lib/cpp"; +static char CPPFLAGS[] = "-C"; +static char *allv[] = { + "rpcgen", "-s", "udp", "-s", "tcp", +}; +static int allc = sizeof(allv)/sizeof(allv[0]); + +main(argc, argv) + int argc; + char *argv[]; + +{ + struct commandline cmd; + + if (!parseargs(argc, argv, &cmd)) { + f_print(stderr, + "usage: %s infile\n", cmdname); + f_print(stderr, + " %s [-c | -h | -l | -m] [-o outfile] [infile]\n", + cmdname); + f_print(stderr, + " %s [-s udp|tcp]* [-o outfile] [infile]\n", + cmdname); + exit(1); + } + if (cmd.cflag) { + c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile); + } else if (cmd.hflag) { + h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile); + } else if (cmd.lflag) { + l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile); + } else if (cmd.sflag || cmd.mflag) { + s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND, + cmd.outfile, cmd.mflag); + } else { + c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); + reinitialize(); + h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); + reinitialize(); + l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); + reinitialize(); + s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, + "_svc.c", cmd.mflag); + } + exit(0); +} + +/* + * add extension to filename + */ +static char * +extendfile(file, ext) + char *file; + char *ext; +{ + char *res; + char *p; + + res = alloc(strlen(file) + strlen(ext) + 1); + if (res == NULL) { + abort(); + } + p = rindex(file, '.'); + if (p == NULL) { + p = file + strlen(file); + } + (void) strcpy(res, file); + (void) strcpy(res + (p - file), ext); + return (res); +} + +/* + * Open output file with given extension + */ +static +open_output(infile, outfile) + char *infile; + char *outfile; +{ + if (outfile == NULL) { + fout = stdout; + return; + } + if (infile != NULL && streq(outfile, infile)) { + f_print(stderr, "%s: output would overwrite %s\n", cmdname, + infile); + crash(); + } + fout = fopen(outfile, "w"); + if (fout == NULL) { + f_print(stderr, "%s: unable to open ", cmdname); + perror(outfile); + crash(); + } + record_open(outfile); +} + +/* + * Open input file with given define for C-preprocessor + */ +static +open_input(infile, define) + char *infile; + char *define; +{ + int pd[2]; + + infilename = (infile == NULL) ? "<stdin>" : infile; + (void) pipe(pd); + switch (fork()) { + case 0: + (void) close(1); + (void) dup2(pd[1], 1); + (void) close(pd[0]); + execl(CPP, CPP, CPPFLAGS, define, infile, NULL); + perror("execl"); + exit(1); + case -1: + perror("fork"); + exit(1); + } + (void) close(pd[1]); + fin = fdopen(pd[0], "r"); + if (fin == NULL) { + f_print(stderr, "%s: ", cmdname); + perror(infilename); + crash(); + } +} + +/* + * Compile into an XDR routine output file + */ +static +c_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + definition *def; + char *include; + char *outfilename; + long tell; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + tell = ftell(fout); + while (def = get_definition()) { + emit(def); + } + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + +/* + * Compile into an XDR header file + */ +static +h_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + definition *def; + char *outfilename; + long tell; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + tell = ftell(fout); + while (def = get_definition()) { + print_datadef(def); + } + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + +/* + * Compile into an RPC service + */ +static +s_output(argc, argv, infile, define, extend, outfile, nomain) + int argc; + char *argv[]; + char *infile; + char *define; + int extend; + char *outfile; + int nomain; +{ + char *include; + definition *def; + int foundprogram; + char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <stdio.h>\n"); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + foundprogram = 0; + while (def = get_definition()) { + foundprogram |= (def->def_kind == DEF_PROGRAM); + } + if (extend && !foundprogram) { + (void) unlink(outfilename); + return; + } + if (nomain) { + write_programs((char *)NULL); + } else { + write_most(); + do_registers(argc, argv); + write_rest(); + write_programs("static"); + } +} + +static +l_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + char *include; + definition *def; + int foundprogram; + char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + foundprogram = 0; + while (def = get_definition()) { + foundprogram |= (def->def_kind == DEF_PROGRAM); + } + if (extend && !foundprogram) { + (void) unlink(outfilename); + return; + } + write_stubs(); +} + +/* + * Perform registrations for service output + */ +static +do_registers(argc, argv) + int argc; + char *argv[]; + +{ + int i; + + for (i = 1; i < argc; i++) { + if (streq(argv[i], "-s")) { + write_register(argv[i + 1]); + i++; + } + } +} + +/* + * Parse command line arguments + */ +static +parseargs(argc, argv, cmd) + int argc; + char *argv[]; + struct commandline *cmd; + +{ + int i; + int j; + char c; + char flag[(1 << 8 * sizeof(char))]; + int nflags; + + cmdname = argv[0]; + cmd->infile = cmd->outfile = NULL; + if (argc < 2) { + return (0); + } + flag['c'] = 0; + flag['h'] = 0; + flag['s'] = 0; + flag['o'] = 0; + flag['l'] = 0; + flag['m'] = 0; + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + if (cmd->infile) { + return (0); + } + cmd->infile = argv[i]; + } else { + for (j = 1; argv[i][j] != 0; j++) { + c = argv[i][j]; + switch (c) { + case 'c': + case 'h': + case 'l': + case 'm': + if (flag[c]) { + return (0); + } + flag[c] = 1; + break; + case 'o': + case 's': + if (argv[i][j - 1] != '-' || + argv[i][j + 1] != 0) { + return (0); + } + flag[c] = 1; + if (++i == argc) { + return (0); + } + if (c == 's') { + if (!streq(argv[i], "udp") && + !streq(argv[i], "tcp")) { + return (0); + } + } else if (c == 'o') { + if (cmd->outfile) { + return (0); + } + cmd->outfile = argv[i]; + } + goto nextarg; + + default: + return (0); + } + } + nextarg: + ; + } + } + cmd->cflag = flag['c']; + cmd->hflag = flag['h']; + cmd->sflag = flag['s']; + cmd->lflag = flag['l']; + cmd->mflag = flag['m']; + nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag; + if (nflags == 0) { + if (cmd->outfile != NULL || cmd->infile == NULL) { + return (0); + } + } else if (nflags > 1) { + return (0); + } + return (1); +} diff --git a/sunrpc/rpc_parse.c b/sunrpc/rpc_parse.c new file mode 100644 index 0000000000..9e4663fb36 --- /dev/null +++ b/sunrpc/rpc_parse.c @@ -0,0 +1,419 @@ +/* @(#)rpc_parse.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI"; +#endif + +/* + * rpc_parse.c, Parser for the RPC protocol compiler + * Copyright (C) 1987 Sun Microsystems, Inc. + */ +#include <stdio.h> +#include "rpc_util.h" +#include "rpc_scan.h" +#include "rpc_parse.h" + +/* + * return the next definition you see + */ +definition * +get_definition() +{ + definition *defp; + token tok; + + defp = ALLOC(definition); + get_token(&tok); + switch (tok.kind) { + case TOK_STRUCT: + def_struct(defp); + break; + case TOK_UNION: + def_union(defp); + break; + case TOK_TYPEDEF: + def_typedef(defp); + break; + case TOK_ENUM: + def_enum(defp); + break; + case TOK_PROGRAM: + def_program(defp); + break; + case TOK_CONST: + def_const(defp); + break; + case TOK_EOF: + return (NULL); + break; + default: + error("definition keyword expected"); + } + scan(TOK_SEMICOLON, &tok); + isdefined(defp); + return (defp); +} + +static +isdefined(defp) + definition *defp; +{ + STOREVAL(&defined, defp); +} + + +static +def_struct(defp) + definition *defp; +{ + token tok; + declaration dec; + decl_list *decls; + decl_list **tailp; + + defp->def_kind = DEF_STRUCT; + + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + tailp = &defp->def.st.decls; + do { + get_declaration(&dec, DEF_STRUCT); + decls = ALLOC(decl_list); + decls->decl = dec; + *tailp = decls; + tailp = &decls->next; + scan(TOK_SEMICOLON, &tok); + peek(&tok); + } while (tok.kind != TOK_RBRACE); + get_token(&tok); + *tailp = NULL; +} + +static +def_program(defp) + definition *defp; +{ + token tok; + version_list *vlist; + version_list **vtailp; + proc_list *plist; + proc_list **ptailp; + + defp->def_kind = DEF_PROGRAM; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + vtailp = &defp->def.pr.versions; + scan(TOK_VERSION, &tok); + do { + scan(TOK_IDENT, &tok); + vlist = ALLOC(version_list); + vlist->vers_name = tok.str; + scan(TOK_LBRACE, &tok); + ptailp = &vlist->procs; + do { + plist = ALLOC(proc_list); + get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM); + if (streq(plist->res_type, "opaque")) { + error("illegal result type"); + } + scan(TOK_IDENT, &tok); + plist->proc_name = tok.str; + scan(TOK_LPAREN, &tok); + get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM); + if (streq(plist->arg_type, "opaque")) { + error("illegal argument type"); + } + scan(TOK_RPAREN, &tok); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + scan(TOK_SEMICOLON, &tok); + plist->proc_num = tok.str; + *ptailp = plist; + ptailp = &plist->next; + peek(&tok); + } while (tok.kind != TOK_RBRACE); + *vtailp = vlist; + vtailp = &vlist->next; + scan(TOK_RBRACE, &tok); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + vlist->vers_num = tok.str; + scan(TOK_SEMICOLON, &tok); + scan2(TOK_VERSION, TOK_RBRACE, &tok); + } while (tok.kind == TOK_VERSION); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + defp->def.pr.prog_num = tok.str; + *vtailp = NULL; +} + +static +def_enum(defp) + definition *defp; +{ + token tok; + enumval_list *elist; + enumval_list **tailp; + + defp->def_kind = DEF_ENUM; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + tailp = &defp->def.en.vals; + do { + scan(TOK_IDENT, &tok); + elist = ALLOC(enumval_list); + elist->name = tok.str; + elist->assignment = NULL; + scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); + if (tok.kind == TOK_EQUAL) { + scan_num(&tok); + elist->assignment = tok.str; + scan2(TOK_COMMA, TOK_RBRACE, &tok); + } + *tailp = elist; + tailp = &elist->next; + } while (tok.kind != TOK_RBRACE); + *tailp = NULL; +} + +static +def_const(defp) + definition *defp; +{ + token tok; + + defp->def_kind = DEF_CONST; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_EQUAL, &tok); + scan2(TOK_IDENT, TOK_STRCONST, &tok); + defp->def.co = tok.str; +} + +static +def_union(defp) + definition *defp; +{ + token tok; + declaration dec; + case_list *cases; + case_list **tailp; + + defp->def_kind = DEF_UNION; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_SWITCH, &tok); + scan(TOK_LPAREN, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.enum_decl = dec; + tailp = &defp->def.un.cases; + scan(TOK_RPAREN, &tok); + scan(TOK_LBRACE, &tok); + scan(TOK_CASE, &tok); + while (tok.kind == TOK_CASE) { + scan(TOK_IDENT, &tok); + cases = ALLOC(case_list); + cases->case_name = tok.str; + scan(TOK_COLON, &tok); + get_declaration(&dec, DEF_UNION); + cases->case_decl = dec; + *tailp = cases; + tailp = &cases->next; + scan(TOK_SEMICOLON, &tok); + scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); + } + *tailp = NULL; + if (tok.kind == TOK_DEFAULT) { + scan(TOK_COLON, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.default_decl = ALLOC(declaration); + *defp->def.un.default_decl = dec; + scan(TOK_SEMICOLON, &tok); + scan(TOK_RBRACE, &tok); + } else { + defp->def.un.default_decl = NULL; + } +} + + +static +def_typedef(defp) + definition *defp; +{ + declaration dec; + + defp->def_kind = DEF_TYPEDEF; + get_declaration(&dec, DEF_TYPEDEF); + defp->def_name = dec.name; + defp->def.ty.old_prefix = dec.prefix; + defp->def.ty.old_type = dec.type; + defp->def.ty.rel = dec.rel; + defp->def.ty.array_max = dec.array_max; +} + + +static +get_declaration(dec, dkind) + declaration *dec; + defkind dkind; +{ + token tok; + + get_type(&dec->prefix, &dec->type, dkind); + dec->rel = REL_ALIAS; + if (streq(dec->type, "void")) { + return; + } + scan2(TOK_STAR, TOK_IDENT, &tok); + if (tok.kind == TOK_STAR) { + dec->rel = REL_POINTER; + scan(TOK_IDENT, &tok); + } + dec->name = tok.str; + if (peekscan(TOK_LBRACKET, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- use typedef"); + } + dec->rel = REL_VECTOR; + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RBRACKET, &tok); + } else if (peekscan(TOK_LANGLE, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- use typedef"); + } + dec->rel = REL_ARRAY; + if (peekscan(TOK_RANGLE, &tok)) { + dec->array_max = "~0"; /* unspecified size, use max */ + } else { + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RANGLE, &tok); + } + } + if (streq(dec->type, "opaque")) { + if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { + error("array declaration expected"); + } + } else if (streq(dec->type, "string")) { + if (dec->rel != REL_ARRAY) { + error("variable-length array declaration expected"); + } + } +} + + +static +get_type(prefixp, typep, dkind) + char **prefixp; + char **typep; + defkind dkind; +{ + token tok; + + *prefixp = NULL; + get_token(&tok); + switch (tok.kind) { + case TOK_IDENT: + *typep = tok.str; + break; + case TOK_STRUCT: + case TOK_ENUM: + case TOK_UNION: + *prefixp = tok.str; + scan(TOK_IDENT, &tok); + *typep = tok.str; + break; + case TOK_UNSIGNED: + unsigned_dec(typep); + break; + case TOK_SHORT: + *typep = "short"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_LONG: + *typep = "long"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_VOID: + if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { + error("voids allowed only inside union and program definitions"); + } + *typep = tok.str; + break; + case TOK_STRING: + case TOK_OPAQUE: + case TOK_CHAR: + case TOK_INT: + case TOK_FLOAT: + case TOK_DOUBLE: + case TOK_BOOL: + *typep = tok.str; + break; + default: + error("expected type specifier"); + } +} + + +static +unsigned_dec(typep) + char **typep; +{ + token tok; + + peek(&tok); + switch (tok.kind) { + case TOK_CHAR: + get_token(&tok); + *typep = "u_char"; + break; + case TOK_SHORT: + get_token(&tok); + *typep = "u_short"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_LONG: + get_token(&tok); + *typep = "u_long"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_INT: + get_token(&tok); + *typep = "u_int"; + break; + default: + *typep = "u_int"; + break; + } +} diff --git a/sunrpc/rpc_parse.h b/sunrpc/rpc_parse.h new file mode 100644 index 0000000000..b53cc56ff8 --- /dev/null +++ b/sunrpc/rpc_parse.h @@ -0,0 +1,157 @@ +/* + * 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 + */ +/* @(#)rpc_parse.h 1.3 87/03/09 (C) 1987 SMI */ + +/* + * rpc_parse.h, Definitions for the RPCL parser + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +enum defkind { + DEF_CONST, + DEF_STRUCT, + DEF_UNION, + DEF_ENUM, + DEF_TYPEDEF, + DEF_PROGRAM +}; +typedef enum defkind defkind; + +typedef char *const_def; + +enum relation { + REL_VECTOR, /* fixed length array */ + REL_ARRAY, /* variable length array */ + REL_POINTER, /* pointer */ + REL_ALIAS, /* simple */ +}; +typedef enum relation relation; + +struct typedef_def { + char *old_prefix; + char *old_type; + relation rel; + char *array_max; +}; +typedef struct typedef_def typedef_def; + + +struct enumval_list { + char *name; + char *assignment; + struct enumval_list *next; +}; +typedef struct enumval_list enumval_list; + +struct enum_def { + enumval_list *vals; +}; +typedef struct enum_def enum_def; + + +struct declaration { + char *prefix; + char *type; + char *name; + relation rel; + char *array_max; +}; +typedef struct declaration declaration; + + +struct decl_list { + declaration decl; + struct decl_list *next; +}; +typedef struct decl_list decl_list; + +struct struct_def { + decl_list *decls; +}; +typedef struct struct_def struct_def; + + +struct case_list { + char *case_name; + declaration case_decl; + struct case_list *next; +}; +typedef struct case_list case_list; + +struct union_def { + declaration enum_decl; + case_list *cases; + declaration *default_decl; +}; +typedef struct union_def union_def; + + + +struct proc_list { + char *proc_name; + char *proc_num; + char *arg_type; + char *arg_prefix; + char *res_type; + char *res_prefix; + struct proc_list *next; +}; +typedef struct proc_list proc_list; + + +struct version_list { + char *vers_name; + char *vers_num; + proc_list *procs; + struct version_list *next; +}; +typedef struct version_list version_list; + +struct program_def { + char *prog_num; + version_list *versions; +}; +typedef struct program_def program_def; + +struct definition { + char *def_name; + defkind def_kind; + union { + const_def co; + struct_def st; + union_def un; + enum_def en; + typedef_def ty; + program_def pr; + } def; +}; +typedef struct definition definition; + +/* @(#)rpc_parse.h 2.1 88/08/01 4.0 RPCSRC */ +definition *get_definition(); diff --git a/sunrpc/rpc_prot.c b/sunrpc/rpc_prot.c new file mode 100644 index 0000000000..4b1319ad56 --- /dev/null +++ b/sunrpc/rpc_prot.c @@ -0,0 +1,289 @@ +/* @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * rpc_prot.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements the rpc message definition, + * its serializer and some common rpc utility routines. + * The routines are meant for various implementations of rpc - + * they are NOT for the rpc client or rpc service implementations! + * Because authentication stuff is easy and is part of rpc, the opaque + * routines are also in this program. + */ + +#include <sys/param.h> + +#include <rpc/rpc.h> + +/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ + +struct opaque_auth _null_auth; + +/* + * XDR an opaque authentication struct + * (see auth.h) + */ +bool_t +xdr_opaque_auth(xdrs, ap) + register XDR *xdrs; + register struct opaque_auth *ap; +{ + + if (xdr_enum(xdrs, &(ap->oa_flavor))) + return (xdr_bytes(xdrs, &ap->oa_base, + &ap->oa_length, MAX_AUTH_BYTES)); + return (FALSE); +} + +/* + * XDR a DES block + */ +bool_t +xdr_des_block(xdrs, blkp) + register XDR *xdrs; + register des_block *blkp; +{ + return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block))); +} + +/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ + +/* + * XDR the MSG_ACCEPTED part of a reply message union + */ +bool_t +xdr_accepted_reply(xdrs, ar) + register XDR *xdrs; + register struct accepted_reply *ar; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) + return (FALSE); + if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) + return (FALSE); + switch (ar->ar_stat) { + + case SUCCESS: + return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); + + case PROG_MISMATCH: + if (! xdr_u_long(xdrs, &(ar->ar_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(ar->ar_vers.high))); + } + return (TRUE); /* TRUE => open ended set of problems */ +} + +/* + * XDR the MSG_DENIED part of a reply message union + */ +bool_t +xdr_rejected_reply(xdrs, rr) + register XDR *xdrs; + register struct rejected_reply *rr; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) + return (FALSE); + switch (rr->rj_stat) { + + case RPC_MISMATCH: + if (! xdr_u_long(xdrs, &(rr->rj_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(rr->rj_vers.high))); + + case AUTH_ERROR: + return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); + } + return (FALSE); +} + +static struct xdr_discrim reply_dscrm[3] = { + { (int)MSG_ACCEPTED, xdr_accepted_reply }, + { (int)MSG_DENIED, xdr_rejected_reply }, + { __dontcare__, NULL_xdrproc_t } }; + +/* + * XDR a reply message + */ +bool_t +xdr_replymsg(xdrs, rmsg) + register XDR *xdrs; + register struct rpc_msg *rmsg; +{ + if ( + xdr_u_long(xdrs, &(rmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && + (rmsg->rm_direction == REPLY) ) + return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), + (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t)); + return (FALSE); +} + + +/* + * Serializes the "static part" of a call message header. + * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. + * The rm_xid is not really static, but the user can easily munge on the fly. + */ +bool_t +xdr_callhdr(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + + cmsg->rm_direction = CALL; + cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; + if ( + (xdrs->x_op == XDR_ENCODE) && + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) ) + return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers))); + return (FALSE); +} + +/* ************************** Client utility routine ************* */ + +static void +accepted(acpt_stat, error) + register enum accept_stat acpt_stat; + register struct rpc_err *error; +{ + + switch (acpt_stat) { + + case PROG_UNAVAIL: + error->re_status = RPC_PROGUNAVAIL; + return; + + case PROG_MISMATCH: + error->re_status = RPC_PROGVERSMISMATCH; + return; + + case PROC_UNAVAIL: + error->re_status = RPC_PROCUNAVAIL; + return; + + case GARBAGE_ARGS: + error->re_status = RPC_CANTDECODEARGS; + return; + + case SYSTEM_ERR: + error->re_status = RPC_SYSTEMERROR; + return; + + case SUCCESS: + error->re_status = RPC_SUCCESS; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_ACCEPTED; + error->re_lb.s2 = (long)acpt_stat; +} + +static void +rejected(rjct_stat, error) + register enum reject_stat rjct_stat; + register struct rpc_err *error; +{ + + switch (rjct_stat) { + + case RPC_VERSMISMATCH: + error->re_status = RPC_VERSMISMATCH; + return; + + case AUTH_ERROR: + error->re_status = RPC_AUTHERROR; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_DENIED; + error->re_lb.s2 = (long)rjct_stat; +} + +/* + * given a reply message, fills in the error + */ +void +_seterr_reply(msg, error) + register struct rpc_msg *msg; + register struct rpc_err *error; +{ + + /* optimized for normal, SUCCESSful case */ + switch (msg->rm_reply.rp_stat) { + + case MSG_ACCEPTED: + if (msg->acpted_rply.ar_stat == SUCCESS) { + error->re_status = RPC_SUCCESS; + return; + }; + accepted(msg->acpted_rply.ar_stat, error); + break; + + case MSG_DENIED: + rejected(msg->rjcted_rply.rj_stat, error); + break; + + default: + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)(msg->rm_reply.rp_stat); + break; + } + switch (error->re_status) { + + case RPC_VERSMISMATCH: + error->re_vers.low = msg->rjcted_rply.rj_vers.low; + error->re_vers.high = msg->rjcted_rply.rj_vers.high; + break; + + case RPC_AUTHERROR: + error->re_why = msg->rjcted_rply.rj_why; + break; + + case RPC_PROGVERSMISMATCH: + error->re_vers.low = msg->acpted_rply.ar_vers.low; + error->re_vers.high = msg->acpted_rply.ar_vers.high; + break; + } +} diff --git a/sunrpc/rpc_scan.c b/sunrpc/rpc_scan.c new file mode 100644 index 0000000000..e46a1b5f2b --- /dev/null +++ b/sunrpc/rpc_scan.c @@ -0,0 +1,473 @@ +/* @(#)rpc_scan.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_scan.c 1.6 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_scan.c, Scanner for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <ctype.h> +#include <strings.h> +#include "rpc_scan.h" +#include "rpc_util.h" + +#define startcomment(where) (where[0] == '/' && where[1] == '*') +#define endcomment(where) (where[-1] == '*' && where[0] == '/') + +static int pushed = 0; /* is a token pushed */ +static token lasttok; /* last token, if pushed */ + +/* + * scan expecting 1 given token + */ +void +scan(expect, tokp) + tok_kind expect; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect) { + expected1(expect); + } +} + +/* + * scan expecting 2 given tokens + */ +void +scan2(expect1, expect2, tokp) + tok_kind expect1; + tok_kind expect2; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect1 && tokp->kind != expect2) { + expected2(expect1, expect2); + } +} + +/* + * scan expecting 3 given token + */ +void +scan3(expect1, expect2, expect3, tokp) + tok_kind expect1; + tok_kind expect2; + tok_kind expect3; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect1 && tokp->kind != expect2 + && tokp->kind != expect3) { + expected3(expect1, expect2, expect3); + } +} + + +/* + * scan expecting a constant, possibly symbolic + */ +void +scan_num(tokp) + token *tokp; +{ + get_token(tokp); + switch (tokp->kind) { + case TOK_IDENT: + break; + default: + error("constant or identifier expected"); + } +} + + +/* + * Peek at the next token + */ +void +peek(tokp) + token *tokp; +{ + get_token(tokp); + unget_token(tokp); +} + + +/* + * Peek at the next token and scan it if it matches what you expect + */ +int +peekscan(expect, tokp) + tok_kind expect; + token *tokp; +{ + peek(tokp); + if (tokp->kind == expect) { + get_token(tokp); + return (1); + } + return (0); +} + + + +/* + * Get the next token, printing out any directive that are encountered. + */ +void +get_token(tokp) + token *tokp; +{ + int commenting; + + if (pushed) { + pushed = 0; + *tokp = lasttok; + return; + } + commenting = 0; + for (;;) { + if (*where == 0) { + for (;;) { + if (!fgets(curline, MAXLINESIZE, fin)) { + tokp->kind = TOK_EOF; + *where = 0; + return; + } + linenum++; + if (commenting) { + break; + } else if (cppline(curline)) { + docppline(curline, &linenum, + &infilename); + } else if (directive(curline)) { + printdirective(curline); + } else { + break; + } + } + where = curline; + } else if (isspace(*where)) { + while (isspace(*where)) { + where++; /* eat */ + } + } else if (commenting) { + where++; + if (endcomment(where)) { + where++; + commenting--; + } + } else if (startcomment(where)) { + where += 2; + commenting++; + } else { + break; + } + } + + /* + * 'where' is not whitespace, comment or directive Must be a token! + */ + switch (*where) { + case ':': + tokp->kind = TOK_COLON; + where++; + break; + case ';': + tokp->kind = TOK_SEMICOLON; + where++; + break; + case ',': + tokp->kind = TOK_COMMA; + where++; + break; + case '=': + tokp->kind = TOK_EQUAL; + where++; + break; + case '*': + tokp->kind = TOK_STAR; + where++; + break; + case '[': + tokp->kind = TOK_LBRACKET; + where++; + break; + case ']': + tokp->kind = TOK_RBRACKET; + where++; + break; + case '{': + tokp->kind = TOK_LBRACE; + where++; + break; + case '}': + tokp->kind = TOK_RBRACE; + where++; + break; + case '(': + tokp->kind = TOK_LPAREN; + where++; + break; + case ')': + tokp->kind = TOK_RPAREN; + where++; + break; + case '<': + tokp->kind = TOK_LANGLE; + where++; + break; + case '>': + tokp->kind = TOK_RANGLE; + where++; + break; + + case '"': + tokp->kind = TOK_STRCONST; + findstrconst(&where, &tokp->str); + break; + + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tokp->kind = TOK_IDENT; + findconst(&where, &tokp->str); + break; + + + default: + if (!(isalpha(*where) || *where == '_')) { + char buf[100]; + char *p; + + s_print(buf, "illegal character in file: "); + p = buf + strlen(buf); + if (isprint(*where)) { + s_print(p, "%c", *where); + } else { + s_print(p, "%d", *where); + } + error(buf); + } + findkind(&where, tokp); + break; + } +} + + + +static +unget_token(tokp) + token *tokp; +{ + lasttok = *tokp; + pushed = 1; +} + + +static +findstrconst(str, val) + char **str; + char **val; +{ + char *p; + int size; + + p = *str; + do { + *p++; + } while (*p && *p != '"'); + if (*p == 0) { + error("unterminated string constant"); + } + p++; + size = p - *str; + *val = alloc(size + 1); + (void) strncpy(*val, *str, size); + (*val)[size] = 0; + *str = p; +} + +static +findconst(str, val) + char **str; + char **val; +{ + char *p; + int size; + + p = *str; + if (*p == '0' && *(p + 1) == 'x') { + p++; + do { + p++; + } while (isxdigit(*p)); + } else { + do { + p++; + } while (isdigit(*p)); + } + size = p - *str; + *val = alloc(size + 1); + (void) strncpy(*val, *str, size); + (*val)[size] = 0; + *str = p; +} + + + +static token symbols[] = { + {TOK_CONST, "const"}, + {TOK_UNION, "union"}, + {TOK_SWITCH, "switch"}, + {TOK_CASE, "case"}, + {TOK_DEFAULT, "default"}, + {TOK_STRUCT, "struct"}, + {TOK_TYPEDEF, "typedef"}, + {TOK_ENUM, "enum"}, + {TOK_OPAQUE, "opaque"}, + {TOK_BOOL, "bool"}, + {TOK_VOID, "void"}, + {TOK_CHAR, "char"}, + {TOK_INT, "int"}, + {TOK_UNSIGNED, "unsigned"}, + {TOK_SHORT, "short"}, + {TOK_LONG, "long"}, + {TOK_FLOAT, "float"}, + {TOK_DOUBLE, "double"}, + {TOK_STRING, "string"}, + {TOK_PROGRAM, "program"}, + {TOK_VERSION, "version"}, + {TOK_EOF, "??????"}, +}; + + +static +findkind(mark, tokp) + char **mark; + token *tokp; +{ + + int len; + token *s; + char *str; + + str = *mark; + for (s = symbols; s->kind != TOK_EOF; s++) { + len = strlen(s->str); + if (strncmp(str, s->str, len) == 0) { + if (!isalnum(str[len]) && str[len] != '_') { + tokp->kind = s->kind; + tokp->str = s->str; + *mark = str + len; + return; + } + } + } + tokp->kind = TOK_IDENT; + for (len = 0; isalnum(str[len]) || str[len] == '_'; len++); + tokp->str = alloc(len + 1); + (void) strncpy(tokp->str, str, len); + tokp->str[len] = 0; + *mark = str + len; +} + +static +cppline(line) + char *line; +{ + return (line == curline && *line == '#'); +} + +static +directive(line) + char *line; +{ + return (line == curline && *line == '%'); +} + +static +printdirective(line) + char *line; +{ + f_print(fout, "%s", line + 1); +} + +static +docppline(line, lineno, fname) + char *line; + int *lineno; + char **fname; +{ + char *file; + int num; + char *p; + + line++; + while (isspace(*line)) { + line++; + } + num = atoi(line); + while (isdigit(*line)) { + line++; + } + while (isspace(*line)) { + line++; + } + if (*line != '"') { + error("preprocessor error"); + } + line++; + p = file = alloc(strlen(line) + 1); + while (*line && *line != '"') { + *p++ = *line++; + } + if (*line == 0) { + error("preprocessor error"); + } + *p = 0; + if (*file == 0) { + *fname = NULL; + } else { + *fname = file; + } + *lineno = num - 1; +} diff --git a/sunrpc/rpc_scan.h b/sunrpc/rpc_scan.h new file mode 100644 index 0000000000..ad243d59c1 --- /dev/null +++ b/sunrpc/rpc_scan.h @@ -0,0 +1,101 @@ +/* @(#)rpc_scan.h 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +/* @(#)rpc_scan.h 1.3 87/03/09 (C) 1987 SMI */ + +/* + * rpc_scan.h, Definitions for the RPCL scanner + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +/* + * kinds of tokens + */ +enum tok_kind { + TOK_IDENT, + TOK_STRCONST, + TOK_LPAREN, + TOK_RPAREN, + TOK_LBRACE, + TOK_RBRACE, + TOK_LBRACKET, + TOK_RBRACKET, + TOK_LANGLE, + TOK_RANGLE, + TOK_STAR, + TOK_COMMA, + TOK_EQUAL, + TOK_COLON, + TOK_SEMICOLON, + TOK_CONST, + TOK_STRUCT, + TOK_UNION, + TOK_SWITCH, + TOK_CASE, + TOK_DEFAULT, + TOK_ENUM, + TOK_TYPEDEF, + TOK_INT, + TOK_SHORT, + TOK_LONG, + TOK_UNSIGNED, + TOK_FLOAT, + TOK_DOUBLE, + TOK_OPAQUE, + TOK_CHAR, + TOK_STRING, + TOK_BOOL, + TOK_VOID, + TOK_PROGRAM, + TOK_VERSION, + TOK_EOF +}; +typedef enum tok_kind tok_kind; + +/* + * a token + */ +struct token { + tok_kind kind; + char *str; +}; +typedef struct token token; + + +/* + * routine interface + */ +void scanprint(); +void scan(); +void scan2(); +void scan3(); +void scan_num(); +void peek(); +int peekscan(); +void get_token(); diff --git a/sunrpc/rpc_svcout.c b/sunrpc/rpc_svcout.c new file mode 100644 index 0000000000..7289b0da6e --- /dev/null +++ b/sunrpc/rpc_svcout.c @@ -0,0 +1,275 @@ +/* @(#)rpc_svcout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_svcout.c 1.6 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsytsems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_parse.h" +#include "rpc_util.h" + +static char RQSTP[] = "rqstp"; +static char TRANSP[] = "transp"; +static char ARG[] = "argument"; +static char RESULT[] = "result"; +static char ROUTINE[] = "local"; + + +/* + * write most of the service, that is, everything but the registrations. + */ +void +write_most() +{ + list *l; + definition *def; + version_list *vp; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind == DEF_PROGRAM) { + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "\nstatic void "); + pvname(def->def_name, vp->vers_num); + f_print(fout, "();"); + } + } + } + f_print(fout, "\n\n"); + f_print(fout, "main()\n"); + f_print(fout, "{\n"); + f_print(fout, "\tSVCXPRT *%s;\n", TRANSP); + f_print(fout, "\n"); + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + continue; + } + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "\t(void)pmap_unset(%s, %s);\n", def->def_name, vp->vers_name); + } + } +} + + +/* + * write a registration for the given transport + */ +void +write_register(transp) + char *transp; +{ + list *l; + definition *def; + version_list *vp; + + f_print(fout, "\n"); + f_print(fout, "\t%s = svc%s_create(RPC_ANYSOCK", TRANSP, transp); + if (streq(transp, "tcp")) { + f_print(fout, ", 0, 0"); + } + f_print(fout, ");\n"); + f_print(fout, "\tif (%s == NULL) {\n", TRANSP); + f_print(fout, "\t\t(void)fprintf(stderr, \"cannot create %s service.\\n\");\n", transp); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + continue; + } + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, + "\tif (!svc_register(%s, %s, %s, ", + TRANSP, def->def_name, vp->vers_name); + pvname(def->def_name, vp->vers_num); + f_print(fout, ", IPPROTO_%s)) {\n", + streq(transp, "udp") ? "UDP" : "TCP"); + f_print(fout, + "\t\t(void)fprintf(stderr, \"unable to register (%s, %s, %s).\\n\");\n", + def->def_name, vp->vers_name, transp); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + } + } +} + + +/* + * write the rest of the service + */ +void +write_rest() +{ + f_print(fout, "\tsvc_run();\n"); + f_print(fout, "\t(void)fprintf(stderr, \"svc_run returned\\n\");\n"); + f_print(fout, "\texit(1);\n"); + f_print(fout, "}\n"); +} + +void +write_programs(storage) + char *storage; +{ + list *l; + definition *def; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind == DEF_PROGRAM) { + write_program(def, storage); + } + } +} + + +static +write_program(def, storage) + definition *def; + char *storage; +{ + version_list *vp; + proc_list *proc; + int filled; + + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "\n"); + if (storage != NULL) { + f_print(fout, "%s ", storage); + } + f_print(fout, "void\n"); + pvname(def->def_name, vp->vers_num); + f_print(fout, "(%s, %s)\n", RQSTP, TRANSP); + f_print(fout, " struct svc_req *%s;\n", RQSTP); + f_print(fout, " SVCXPRT *%s;\n", TRANSP); + f_print(fout, "{\n"); + + filled = 0; + f_print(fout, "\tunion {\n"); + for (proc = vp->procs; proc != NULL; proc = proc->next) { + if (streq(proc->arg_type, "void")) { + continue; + } + filled = 1; + f_print(fout, "\t\t"); + ptype(proc->arg_prefix, proc->arg_type, 0); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_arg;\n"); + } + if (!filled) { + f_print(fout, "\t\tint fill;\n"); + } + f_print(fout, "\t} %s;\n", ARG); + f_print(fout, "\tchar *%s;\n", RESULT); + f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT); + f_print(fout, "\tchar *(*%s)();\n", ROUTINE); + f_print(fout, "\n"); + f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP); + + if (!nullproc(vp->procs)) { + f_print(fout, "\tcase NULLPROC:\n"); + f_print(fout, "\t\t(void)svc_sendreply(%s, xdr_void, (char *)NULL);\n", TRANSP); + f_print(fout, "\t\treturn;\n\n"); + } + for (proc = vp->procs; proc != NULL; proc = proc->next) { + f_print(fout, "\tcase %s:\n", proc->proc_name); + f_print(fout, "\t\txdr_%s = xdr_%s;\n", ARG, + stringfix(proc->arg_type)); + f_print(fout, "\t\txdr_%s = xdr_%s;\n", RESULT, + stringfix(proc->res_type)); + f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, ";\n"); + f_print(fout, "\t\tbreak;\n\n"); + } + f_print(fout, "\tdefault:\n"); + printerr("noproc", TRANSP); + f_print(fout, "\t\treturn;\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "\tbzero((char *)&%s, sizeof(%s));\n", ARG, ARG); + printif("getargs", TRANSP, "&", ARG); + printerr("decode", TRANSP); + f_print(fout, "\t\treturn;\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "\t%s = (*%s)(&%s, %s);\n", RESULT, ROUTINE, ARG, + RQSTP); + f_print(fout, + "\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n", + RESULT, TRANSP, RESULT, RESULT); + printerr("systemerr", TRANSP); + f_print(fout, "\t}\n"); + + printif("freeargs", TRANSP, "&", ARG); + f_print(fout, "\t\t(void)fprintf(stderr, \"unable to free arguments\\n\");\n"); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "}\n\n"); + } +} + +static +printerr(err, transp) + char *err; + char *transp; +{ + f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp); +} + +static +printif(proc, transp, prefix, arg) + char *proc; + char *transp; + char *prefix; + char *arg; +{ + f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n", + proc, transp, arg, prefix, arg); +} + + +nullproc(proc) + proc_list *proc; +{ + for (; proc != NULL; proc = proc->next) { + if (streq(proc->proc_num, "0")) { + return (1); + } + } + return (0); +} diff --git a/sunrpc/rpc_util.c b/sunrpc/rpc_util.c new file mode 100644 index 0000000000..8136535b2f --- /dev/null +++ b/sunrpc/rpc_util.c @@ -0,0 +1,436 @@ +/* @(#)rpc_util.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_util.c 1.5 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_util.c, Utility routines for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +char curline[MAXLINESIZE]; /* current read line */ +char *where = curline; /* current point in line */ +int linenum = 0; /* current line number */ + +char *infilename; /* input filename */ + +#define NFILES 4 +char *outfiles[NFILES]; /* output file names */ +int nfiles; + +FILE *fout; /* file pointer of current output */ +FILE *fin; /* file pointer of current input */ + +list *defined; /* list of defined things */ + +/* + * Reinitialize the world + */ +reinitialize() +{ + bzero(curline, MAXLINESIZE); + where = curline; + linenum = 0; + defined = NULL; +} + +/* + * string equality + */ +streq(a, b) + char *a; + char *b; +{ + return (strcmp(a, b) == 0); +} + +/* + * find a value in a list + */ +char * +findval(lst, val, cmp) + list *lst; + char *val; + int (*cmp) (); + +{ + for (; lst != NULL; lst = lst->next) { + if ((*cmp) (lst->val, val)) { + return (lst->val); + } + } + return (NULL); +} + +/* + * store a value in a list + */ +void +storeval(lstp, val) + list **lstp; + char *val; +{ + list **l; + list *lst; + + for (l = lstp; *l != NULL; l = (list **) & (*l)->next); + lst = ALLOC(list); + lst->val = val; + lst->next = NULL; + *l = lst; +} + + +static +findit(def, type) + definition *def; + char *type; +{ + return (streq(def->def_name, type)); +} + + +static char * +fixit(type, orig) + char *type; + char *orig; +{ + definition *def; + + def = (definition *) FINDVAL(defined, type, findit); + if (def == NULL || def->def_kind != DEF_TYPEDEF) { + return (orig); + } + switch (def->def.ty.rel) { + case REL_VECTOR: + return (def->def.ty.old_type); + case REL_ALIAS: + return (fixit(def->def.ty.old_type, orig)); + default: + return (orig); + } +} + +char * +fixtype(type) + char *type; +{ + return (fixit(type, type)); +} + +char * +stringfix(type) + char *type; +{ + if (streq(type, "string")) { + return ("wrapstring"); + } else { + return (type); + } +} + +void +ptype(prefix, type, follow) + char *prefix; + char *type; + int follow; +{ + if (prefix != NULL) { + if (streq(prefix, "enum")) { + f_print(fout, "enum "); + } else { + f_print(fout, "struct "); + } + } + if (streq(type, "bool")) { + f_print(fout, "bool_t "); + } else if (streq(type, "string")) { + f_print(fout, "char *"); + } else { + f_print(fout, "%s ", follow ? fixtype(type) : type); + } +} + + +static +typedefed(def, type) + definition *def; + char *type; +{ + if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { + return (0); + } else { + return (streq(def->def_name, type)); + } +} + +isvectordef(type, rel) + char *type; + relation rel; +{ + definition *def; + + for (;;) { + switch (rel) { + case REL_VECTOR: + return (!streq(type, "string")); + case REL_ARRAY: + return (0); + case REL_POINTER: + return (0); + case REL_ALIAS: + def = (definition *) FINDVAL(defined, type, typedefed); + if (def == NULL) { + return (0); + } + type = def->def.ty.old_type; + rel = def->def.ty.rel; + } + } +} + + +static char * +locase(str) + char *str; +{ + char c; + static char buf[100]; + char *p = buf; + + while (c = *str++) { + *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; + } + *p = 0; + return (buf); +} + + +void +pvname(pname, vnum) + char *pname; + char *vnum; +{ + f_print(fout, "%s_%s", locase(pname), vnum); +} + + +/* + * print a useful (?) error message, and then die + */ +void +error(msg) + char *msg; +{ + printwhere(); + f_print(stderr, "%s, line %d: ", infilename, linenum); + f_print(stderr, "%s\n", msg); + crash(); +} + +/* + * Something went wrong, unlink any files that we may have created and then + * die. + */ +crash() +{ + int i; + + for (i = 0; i < nfiles; i++) { + (void) unlink(outfiles[i]); + } + exit(1); +} + + +void +record_open(file) + char *file; +{ + if (nfiles < NFILES) { + outfiles[nfiles++] = file; + } else { + f_print(stderr, "too many files!\n"); + crash(); + } +} + +static char expectbuf[100]; +static char *toktostr(); + +/* + * error, token encountered was not the expected one + */ +void +expected1(exp1) + tok_kind exp1; +{ + s_print(expectbuf, "expected '%s'", + toktostr(exp1)); + error(expectbuf); +} + +/* + * error, token encountered was not one of two expected ones + */ +void +expected2(exp1, exp2) + tok_kind exp1, exp2; +{ + s_print(expectbuf, "expected '%s' or '%s'", + toktostr(exp1), + toktostr(exp2)); + error(expectbuf); +} + +/* + * error, token encountered was not one of 3 expected ones + */ +void +expected3(exp1, exp2, exp3) + tok_kind exp1, exp2, exp3; +{ + s_print(expectbuf, "expected '%s', '%s' or '%s'", + toktostr(exp1), + toktostr(exp2), + toktostr(exp3)); + error(expectbuf); +} + +void +tabify(f, tab) + FILE *f; + int tab; +{ + while (tab--) { + (void) fputc('\t', f); + } +} + + + +static token tokstrings[] = { + {TOK_IDENT, "identifier"}, + {TOK_CONST, "const"}, + {TOK_RPAREN, ")"}, + {TOK_LPAREN, "("}, + {TOK_RBRACE, "}"}, + {TOK_LBRACE, "{"}, + {TOK_LBRACKET, "["}, + {TOK_RBRACKET, "]"}, + {TOK_STAR, "*"}, + {TOK_COMMA, ","}, + {TOK_EQUAL, "="}, + {TOK_COLON, ":"}, + {TOK_SEMICOLON, ";"}, + {TOK_UNION, "union"}, + {TOK_STRUCT, "struct"}, + {TOK_SWITCH, "switch"}, + {TOK_CASE, "case"}, + {TOK_DEFAULT, "default"}, + {TOK_ENUM, "enum"}, + {TOK_TYPEDEF, "typedef"}, + {TOK_INT, "int"}, + {TOK_SHORT, "short"}, + {TOK_LONG, "long"}, + {TOK_UNSIGNED, "unsigned"}, + {TOK_DOUBLE, "double"}, + {TOK_FLOAT, "float"}, + {TOK_CHAR, "char"}, + {TOK_STRING, "string"}, + {TOK_OPAQUE, "opaque"}, + {TOK_BOOL, "bool"}, + {TOK_VOID, "void"}, + {TOK_PROGRAM, "program"}, + {TOK_VERSION, "version"}, + {TOK_EOF, "??????"} +}; + +static char * +toktostr(kind) + tok_kind kind; +{ + token *sp; + + for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); + return (sp->str); +} + + + +static +printbuf() +{ + char c; + int i; + int cnt; + +# define TABSIZE 4 + + for (i = 0; c = curline[i]; i++) { + if (c == '\t') { + cnt = 8 - (i % TABSIZE); + c = ' '; + } else { + cnt = 1; + } + while (cnt--) { + (void) fputc(c, stderr); + } + } +} + + +static +printwhere() +{ + int i; + char c; + int cnt; + + printbuf(); + for (i = 0; i < where - curline; i++) { + c = curline[i]; + if (c == '\t') { + cnt = 8 - (i % TABSIZE); + } else { + cnt = 1; + } + while (cnt--) { + (void) fputc('^', stderr); + } + } + (void) fputc('\n', stderr); +} diff --git a/sunrpc/rpc_util.h b/sunrpc/rpc_util.h new file mode 100644 index 0000000000..0dd188234a --- /dev/null +++ b/sunrpc/rpc_util.h @@ -0,0 +1,114 @@ +/* @(#)rpc_util.h 2.1 88/08/01 4.0 RPCSRC */ +/* + * 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 + */ +/* @(#)rpc_util.h 1.6 87/06/24 (C) 1987 SMI */ + +/* + * rpc_util.h, Useful definitions for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +extern char *malloc(); + +#define alloc(size) malloc((unsigned)(size)) +#define ALLOC(object) (object *) malloc(sizeof(object)) + +/* extern char *sprintf(); --roland@gnu */ + +#define s_print (void) sprintf +#define f_print (void) fprintf + +struct list { + char *val; + struct list *next; +}; +typedef struct list list; + +/* + * Global variables + */ +#define MAXLINESIZE 1024 +extern char curline[MAXLINESIZE]; +extern char *where; +extern int linenum; + +extern char *infilename; +extern FILE *fout; +extern FILE *fin; + +extern list *defined; + +/* + * rpc_util routines + */ +void storeval(); + +#define STOREVAL(list,item) \ + storeval(list,(char *)item) + +char *findval(); + +#define FINDVAL(list,item,finder) \ + findval(list, (char *) item, finder) + +char *fixtype(); +char *stringfix(); +void pvname(); +void ptype(); +int isvectordef(); +int streq(); +void error(); +void expected1(); +void expected2(); +void expected3(); +void tabify(); +void record_open(); + +/* + * rpc_cout routines + */ +void cprint(); +void emit(); + +/* + * rpc_hout routines + */ +void print_datadef(); + +/* + * rpc_svcout routines + */ +void write_most(); +void write_register(); +void write_rest(); +void write_programs(); + +/* + * rpc_clntout routines + */ +void write_stubs(); diff --git a/sunrpc/rpcinfo.c b/sunrpc/rpcinfo.c new file mode 100644 index 0000000000..961f9b0b2d --- /dev/null +++ b/sunrpc/rpcinfo.c @@ -0,0 +1,665 @@ +/* @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC */ +#ifndef lint +static char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI"; +#endif + +/* + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +/* + * rpcinfo: ping a particular rpc program + * or dump the portmapper + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include <rpc/rpc.h> +#include <stdio.h> +#include <sys/socket.h> +#include <netdb.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <signal.h> +#include <ctype.h> + +#define MAXHOSTLEN 256 + +#define MIN_VERS ((u_long) 0) +#define MAX_VERS ((u_long) 4294967295L) + +static void udpping(/*u_short portflag, int argc, char **argv*/); +static void tcpping(/*u_short portflag, int argc, char **argv*/); +static int pstatus(/*CLIENT *client, u_long prognum, u_long vers*/); +static void pmapdump(/*int argc, char **argv*/); +static bool_t reply_proc(/*void *res, struct sockaddr_in *who*/); +static void brdcst(/*int argc, char **argv*/); +static void deletereg(/* int argc, char **argv */) ; +static void usage(/*void*/); +static u_long getprognum(/*char *arg*/); +static u_long getvers(/*char *arg*/); +static void get_inet_address(/*struct sockaddr_in *addr, char *host*/); +extern u_long inet_addr(); /* in 4.2BSD, arpa/inet.h called that a in_addr */ +extern char *inet_ntoa(); + +/* + * Functions to be performed. + */ +#define NONE 0 /* no function */ +#define PMAPDUMP 1 /* dump portmapper registrations */ +#define TCPPING 2 /* ping TCP service */ +#define UDPPING 3 /* ping UDP service */ +#define BRDCST 4 /* ping broadcast UDP service */ +#define DELETES 5 /* delete registration for the service */ + +int +main(argc, argv) + int argc; + char **argv; +{ + register int c; + extern char *optarg; + extern int optind; + int errflg; + int function; + u_short portnum; + + function = NONE; + portnum = 0; + errflg = 0; + while ((c = getopt(argc, argv, "ptubdn:")) != EOF) { + switch (c) { + + case 'p': + if (function != NONE) + errflg = 1; + else + function = PMAPDUMP; + break; + + case 't': + if (function != NONE) + errflg = 1; + else + function = TCPPING; + break; + + case 'u': + if (function != NONE) + errflg = 1; + else + function = UDPPING; + break; + + case 'b': + if (function != NONE) + errflg = 1; + else + function = BRDCST; + break; + + case 'n': + portnum = (u_short) atoi(optarg); /* hope we don't get bogus # */ + break; + + case 'd': + if (function != NONE) + errflg = 1; + else + function = DELETES; + break; + + case '?': + errflg = 1; + } + } + + if (errflg || function == NONE) { + usage(); + return (1); + } + + switch (function) { + + case PMAPDUMP: + if (portnum != 0) { + usage(); + return (1); + } + pmapdump(argc - optind, argv + optind); + break; + + case UDPPING: + udpping(portnum, argc - optind, argv + optind); + break; + + case TCPPING: + tcpping(portnum, argc - optind, argv + optind); + break; + + case BRDCST: + if (portnum != 0) { + usage(); + return (1); + } + brdcst(argc - optind, argv + optind); + break; + + case DELETES: + deletereg(argc - optind, argv + optind); + break; + } + + return (0); +} + +static void +udpping(portnum, argc, argv) + u_short portnum; + int argc; + char **argv; +{ + struct timeval to; + struct sockaddr_in addr; + enum clnt_stat rpc_stat; + CLIENT *client; + u_long prognum, vers, minvers, maxvers; + int sock = RPC_ANYSOCK; + struct rpc_err rpcerr; + int failure; + + if (argc < 2 || argc > 3) { + usage(); + exit(1); + } + prognum = getprognum(argv[1]); + get_inet_address(&addr, argv[0]); + /* Open the socket here so it will survive calls to clnt_destroy */ + sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + perror("rpcinfo: socket"); + exit(1); + } + failure = 0; + if (argc == 2) { + /* + * A call to version 0 should fail with a program/version + * mismatch, and give us the range of versions supported. + */ + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, (u_long)0, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu is not available\n", + prognum); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * Oh dear, it DOES support version 0. + * Let's try version MAX_VERS. + */ + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, MAX_VERS, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, MAX_VERS); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * It also supports version MAX_VERS. + * Looks like we have a wise guy. + * OK, we give them information on all + * 4 billion versions they support... + */ + minvers = 0; + maxvers = MAX_VERS; + } else { + (void) pstatus(client, prognum, MAX_VERS); + exit(1); + } + } else { + (void) pstatus(client, prognum, (u_long)0); + exit(1); + } + clnt_destroy(client); + for (vers = minvers; vers <= maxvers; vers++) { + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, vers, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + clnt_destroy(client); + } + } + else { + vers = getvers(argv[2]); + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, vers, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + } + (void) close(sock); /* Close it up again */ + if (failure) + exit(1); +} + +static void +tcpping(portnum, argc, argv) + u_short portnum; + int argc; + char **argv; +{ + struct timeval to; + struct sockaddr_in addr; + enum clnt_stat rpc_stat; + CLIENT *client; + u_long prognum, vers, minvers, maxvers; + int sock = RPC_ANYSOCK; + struct rpc_err rpcerr; + int failure; + + if (argc < 2 || argc > 3) { + usage(); + exit(1); + } + prognum = getprognum(argv[1]); + get_inet_address(&addr, argv[0]); + failure = 0; + if (argc == 2) { + /* + * A call to version 0 should fail with a program/version + * mismatch, and give us the range of versions supported. + */ + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, MIN_VERS, + &sock, 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu is not available\n", + prognum); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * Oh dear, it DOES support version 0. + * Let's try version MAX_VERS. + */ + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, MAX_VERS, + &sock, 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, MAX_VERS); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * It also supports version MAX_VERS. + * Looks like we have a wise guy. + * OK, we give them information on all + * 4 billion versions they support... + */ + minvers = 0; + maxvers = MAX_VERS; + } else { + (void) pstatus(client, prognum, MAX_VERS); + exit(1); + } + } else { + (void) pstatus(client, prognum, MIN_VERS); + exit(1); + } + clnt_destroy(client); + (void) close(sock); + sock = RPC_ANYSOCK; /* Re-initialize it for later */ + for (vers = minvers; vers <= maxvers; vers++) { + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, vers, + &sock, 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_usec = 0; + to.tv_sec = 10; + rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + clnt_destroy(client); + (void) close(sock); + sock = RPC_ANYSOCK; + } + } + else { + vers = getvers(argv[2]); + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, vers, &sock, + 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_usec = 0; + to.tv_sec = 10; + rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + } + if (failure) + exit(1); +} + +/* + * This routine should take a pointer to an "rpc_err" structure, rather than + * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to + * a CLIENT structure rather than a pointer to an "rpc_err" structure. + * As such, we have to keep the CLIENT structure around in order to print + * a good error message. + */ +static int +pstatus(client, prognum, vers) + register CLIENT *client; + u_long prognum; + u_long vers; +{ + struct rpc_err rpcerr; + + clnt_geterr(client, &rpcerr); + if (rpcerr.re_status != RPC_SUCCESS) { + clnt_perror(client, "rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + return (-1); + } else { + printf("program %lu version %lu ready and waiting\n", + prognum, vers); + return (0); + } +} + +static void +pmapdump(argc, argv) + int argc; + char **argv; +{ + struct sockaddr_in server_addr; + register struct hostent *hp; + struct pmaplist *head = NULL; + int socket = RPC_ANYSOCK; + struct timeval minutetimeout; + register CLIENT *client; + struct rpcent *rpc; + + if (argc > 1) { + usage(); + exit(1); + } + if (argc == 1) + get_inet_address(&server_addr, argv[0]); + else { + bzero((char *)&server_addr, sizeof server_addr); + server_addr.sin_family = AF_INET; + if ((hp = gethostbyname("localhost")) != NULL) + bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, + hp->h_length); + else + server_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + } + minutetimeout.tv_sec = 60; + minutetimeout.tv_usec = 0; + server_addr.sin_port = htons(PMAPPORT); + if ((client = clnttcp_create(&server_addr, PMAPPROG, + PMAPVERS, &socket, 50, 500)) == NULL) { + clnt_pcreateerror("rpcinfo: can't contact portmapper"); + exit(1); + } + if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, + xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { + fprintf(stderr, "rpcinfo: can't contact portmapper: "); + clnt_perror(client, "rpcinfo"); + exit(1); + } + if (head == NULL) { + printf("No remote programs registered.\n"); + } else { + printf(" program vers proto port\n"); + for (; head != NULL; head = head->pml_next) { + printf("%10ld%5ld", + head->pml_map.pm_prog, + head->pml_map.pm_vers); + if (head->pml_map.pm_prot == IPPROTO_UDP) + printf("%6s", "udp"); + else if (head->pml_map.pm_prot == IPPROTO_TCP) + printf("%6s", "tcp"); + else + printf("%6ld", head->pml_map.pm_prot); + printf("%7ld", head->pml_map.pm_port); + rpc = getrpcbynumber(head->pml_map.pm_prog); + if (rpc) + printf(" %s\n", rpc->r_name); + else + printf("\n"); + } + } +} + +/* + * reply_proc collects replies from the broadcast. + * to get a unique list of responses the output of rpcinfo should + * be piped through sort(1) and then uniq(1). + */ + +/*ARGSUSED*/ +static bool_t +reply_proc(res, who) + void *res; /* Nothing comes back */ + struct sockaddr_in *who; /* Who sent us the reply */ +{ + register struct hostent *hp; + + hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr, + AF_INET); + printf("%s %s\n", inet_ntoa(who->sin_addr), + (hp == NULL) ? "(unknown)" : hp->h_name); + return(FALSE); +} + +static void +brdcst(argc, argv) + int argc; + char **argv; +{ + enum clnt_stat rpc_stat; + u_long prognum, vers; + + if (argc != 2) { + usage(); + exit(1); + } + prognum = getprognum(argv[0]); + vers = getvers(argv[1]); + rpc_stat = clnt_broadcast(prognum, vers, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, reply_proc); + if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) { + fprintf(stderr, "rpcinfo: broadcast failed: %s\n", + clnt_sperrno(rpc_stat)); + exit(1); + } + exit(0); +} + +static void +deletereg(argc, argv) + int argc; + char **argv; +{ u_long prog_num, version_num ; + + if (argc != 2) { + usage() ; + exit(1) ; + } + if (getuid()) { /* This command allowed only to root */ + fprintf(stderr, "Sorry. You are not root\n") ; + exit(1) ; + } + prog_num = getprognum(argv[0]); + version_num = getvers(argv[1]); + if ((pmap_unset(prog_num, version_num)) == 0) { + fprintf(stderr, "rpcinfo: Could not delete registration for prog %s version %s\n", + argv[0], argv[1]) ; + exit(1) ; + } +} + +static void +usage() +{ + fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"); + fprintf(stderr, " rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"); + fprintf(stderr, " rpcinfo -p [ host ]\n"); + fprintf(stderr, " rpcinfo -b prognum versnum\n"); + fprintf(stderr, " rpcinfo -d prognum versnum\n") ; +} + +static u_long +getprognum(arg) + char *arg; +{ + register struct rpcent *rpc; + register u_long prognum; + + if (isalpha(*arg)) { + rpc = getrpcbyname(arg); + if (rpc == NULL) { + fprintf(stderr, "rpcinfo: %s is unknown service\n", + arg); + exit(1); + } + prognum = rpc->r_number; + } else { + prognum = (u_long) atoi(arg); + } + + return (prognum); +} + +static u_long +getvers(arg) + char *arg; +{ + register u_long vers; + + vers = (int) atoi(arg); + return (vers); +} + +static void +get_inet_address(addr, host) + struct sockaddr_in *addr; + char *host; +{ + register struct hostent *hp; + + bzero((char *)addr, sizeof *addr); + addr->sin_addr.s_addr = (u_long) inet_addr(host); + if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) { + if ((hp = gethostbyname(host)) == NULL) { + fprintf(stderr, "rpcinfo: %s is unknown host\n", host); + exit(1); + } + bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length); + } + addr->sin_family = AF_INET; +} diff --git a/sunrpc/rpcsvc/bootparam.x b/sunrpc/rpcsvc/bootparam.x new file mode 100644 index 0000000000..65bc0dcbfb --- /dev/null +++ b/sunrpc/rpcsvc/bootparam.x @@ -0,0 +1,97 @@ +/* @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * RPC for bootparms service. + * There are two procedures: + * WHOAMI takes a net address and returns a client name and also a + * likely net address for routing + * GETFILE takes a client name and file identifier and returns the + * server name, server net address and pathname for the file. + * file identifiers typically include root, swap, pub and dump + */ + +#ifdef RPC_HDR +%#include <rpc/types.h> +%#include <sys/time.h> +%#include <sys/errno.h> +%#include <nfs/nfs.h> +#endif + +const MAX_MACHINE_NAME = 255; +const MAX_PATH_LEN = 1024; +const MAX_FILEID = 32; +const IP_ADDR_TYPE = 1; + +typedef string bp_machine_name_t<MAX_MACHINE_NAME>; +typedef string bp_path_t<MAX_PATH_LEN>; +typedef string bp_fileid_t<MAX_FILEID>; + +struct ip_addr_t { + char net; + char host; + char lh; + char impno; +}; + +union bp_address switch (int address_type) { + case IP_ADDR_TYPE: + ip_addr_t ip_addr; +}; + +struct bp_whoami_arg { + bp_address client_address; +}; + +struct bp_whoami_res { + bp_machine_name_t client_name; + bp_machine_name_t domain_name; + bp_address router_address; +}; + +struct bp_getfile_arg { + bp_machine_name_t client_name; + bp_fileid_t file_id; +}; + +struct bp_getfile_res { + bp_machine_name_t server_name; + bp_address server_address; + bp_path_t server_path; +}; + +program BOOTPARAMPROG { + version BOOTPARAMVERS { + bp_whoami_res BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1; + bp_getfile_res BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2; + } = 1; +} = 100026; diff --git a/sunrpc/rpcsvc/klm_prot.x b/sunrpc/rpcsvc/klm_prot.x new file mode 100644 index 0000000000..5f3e12e7d3 --- /dev/null +++ b/sunrpc/rpcsvc/klm_prot.x @@ -0,0 +1,134 @@ +/* @(#)klm_prot.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)klm_prot.x 1.7 87/07/08 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * Kernel/lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between the UNIX kernel (the "client") and the + * local lock manager. The local lock manager is a deamon running + * above the kernel. + */ + +const LM_MAXSTRLEN = 1024; + +/* + * lock manager status returns + */ +enum klm_stats { + klm_granted = 0, /* lock is granted */ + klm_denied = 1, /* lock is denied */ + klm_denied_nolocks = 2, /* no lock entry available */ + klm_working = 3 /* lock is being processed */ +}; + +/* + * lock manager lock identifier + */ +struct klm_lock { + string server_name<LM_MAXSTRLEN>; + netobj fh; /* a counted file handle */ + int pid; /* holder of the lock */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * lock holder identifier + */ +struct klm_holder { + bool exclusive; /* FALSE if shared lock */ + int svid; /* holder of the lock (pid) */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * reply to KLM_LOCK / KLM_UNLOCK / KLM_CANCEL + */ +struct klm_stat { + klm_stats stat; +}; + +/* + * reply to a KLM_TEST call + */ +union klm_testrply switch (klm_stats stat) { + case klm_denied: + struct klm_holder holder; + default: /* All other cases return no arguments */ + void; +}; + + +/* + * arguments to KLM_LOCK + */ +struct klm_lockargs { + bool block; + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_TEST + */ +struct klm_testargs { + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_UNLOCK + */ +struct klm_unlockargs { + struct klm_lock alock; +}; + +program KLM_PROG { + version KLM_VERS { + + klm_testrply KLM_TEST (struct klm_testargs) = 1; + + klm_stat KLM_LOCK (struct klm_lockargs) = 2; + + klm_stat KLM_CANCEL (struct klm_lockargs) = 3; + /* klm_granted=> the cancel request fails due to lock is already granted */ + /* klm_denied=> the cancel request successfully aborts +lock request */ + + klm_stat KLM_UNLOCK (struct klm_unlockargs) = 4; + } = 1; +} = 100020; + diff --git a/sunrpc/rpcsvc/mount.x b/sunrpc/rpcsvc/mount.x new file mode 100644 index 0000000000..7e0d7f3ad6 --- /dev/null +++ b/sunrpc/rpcsvc/mount.x @@ -0,0 +1,161 @@ +/* @(#)mount.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * Protocol description for the mount program + */ + + +const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +const FHSIZE = 32; /* size in bytes of a file handle */ + +/* + * The fhandle is the file handle that the server passes to the client. + * All file operations are done using the file handles to refer to a file + * or a directory. The file handle can contain whatever information the + * server needs to distinguish an individual file. + */ +typedef opaque fhandle[FHSIZE]; + +/* + * 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. The status corresponds with UNIX error numbers. + */ +union fhstatus switch (unsigned fhs_status) { +case 0: + fhandle fhs_fhandle; +default: + void; +}; + +/* + * The type dirpath is the pathname of a directory + */ +typedef string dirpath<MNTPATHLEN>; + +/* + * The type name is used for arbitrary names (hostnames, groupnames) + */ +typedef string name<MNTNAMLEN>; + +/* + * A list of who has what mounted + */ +typedef struct mountbody *mountlist; +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; + +/* + * A list of netgroups + */ +typedef struct groupnode *groups; +struct groupnode { + name gr_name; + groups gr_next; +}; + +/* + * A list of what is exported and to whom + */ +typedef struct exportnode *exports; +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; + +program MOUNTPROG { + /* + * Version one of the mount protocol communicates with version two + * of the NFS protocol. The only connecting point is the fhandle + * structure, which is the same for both protocols. + */ + version MOUNTVERS { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If fhs_status is 0, then fhs_fhandle contains the + * file handle for the directory. 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 + * the directory. + * Unix authentication required. + */ + fhstatus + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + + /* + * Identical to MOUNTPROC_EXPORT above + */ + exports + MOUNTPROC_EXPORTALL(void) = 6; + } = 1; +} = 100005; diff --git a/sunrpc/rpcsvc/nfs_prot.x b/sunrpc/rpcsvc/nfs_prot.x new file mode 100644 index 0000000000..7633e5add4 --- /dev/null +++ b/sunrpc/rpcsvc/nfs_prot.x @@ -0,0 +1,355 @@ +/* @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC */ + +/* + * 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 + */ + +/* + * nfs_prot.x 1.2 87/10/12 + * Copyright 1987 Sun Microsystems, Inc. + */ +const NFS_PORT = 2049; +const NFS_MAXDATA = 8192; +const NFS_MAXPATHLEN = 1024; +const NFS_MAXNAMLEN = 255; +const NFS_FHSIZE = 32; +const NFS_COOKIESIZE = 4; +const NFS_FIFO_DEV = -1; /* size kludge for named pipes */ + +/* + * File types + */ +const NFSMODE_FMT = 0170000; /* type of file */ +const NFSMODE_DIR = 0040000; /* directory */ +const NFSMODE_CHR = 0020000; /* character special */ +const NFSMODE_BLK = 0060000; /* block special */ +const NFSMODE_REG = 0100000; /* regular */ +const NFSMODE_LNK = 0120000; /* symbolic link */ +const NFSMODE_SOCK = 0140000; /* socket */ +const NFSMODE_FIFO = 0010000; /* fifo */ + +/* + * Error status + */ +enum nfsstat { + NFS_OK= 0, /* no error */ + NFSERR_PERM=1, /* Not owner */ + NFSERR_NOENT=2, /* No such file or directory */ + NFSERR_IO=5, /* I/O error */ + NFSERR_NXIO=6, /* No such device or address */ + NFSERR_ACCES=13, /* Permission denied */ + NFSERR_EXIST=17, /* File exists */ + NFSERR_NODEV=19, /* No such device */ + NFSERR_NOTDIR=20, /* Not a directory*/ + NFSERR_ISDIR=21, /* Is a directory */ + NFSERR_FBIG=27, /* File too large */ + NFSERR_NOSPC=28, /* No space left on device */ + NFSERR_ROFS=30, /* Read-only file system */ + NFSERR_NAMETOOLONG=63, /* File name too long */ + NFSERR_NOTEMPTY=66, /* Directory not empty */ + NFSERR_DQUOT=69, /* Disc quota exceeded */ + NFSERR_STALE=70, /* Stale NFS file handle */ + NFSERR_WFLUSH=99 /* write cache flushed */ +}; + +/* + * File types + */ +enum ftype { + NFNON = 0, /* non-file */ + NFREG = 1, /* regular file */ + NFDIR = 2, /* directory */ + NFBLK = 3, /* block special */ + NFCHR = 4, /* character special */ + NFLNK = 5, /* symbolic link */ + NFSOCK = 6, /* unix domain sockets */ + NFBAD = 7, /* unused */ + NFFIFO = 8 /* named pipe */ +}; + +/* + * File access handle + */ +struct nfs_fh { + opaque data[NFS_FHSIZE]; +}; + +/* + * Timeval + */ +struct nfstime { + unsigned seconds; + unsigned useconds; +}; + + +/* + * File attributes + */ +struct fattr { + ftype type; /* file type */ + unsigned mode; /* protection mode bits */ + unsigned nlink; /* # hard links */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + unsigned blocksize; /* prefered block size */ + unsigned rdev; /* special device # */ + unsigned blocks; /* Kb of disk used by file */ + unsigned fsid; /* device # */ + unsigned fileid; /* inode # */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ + nfstime ctime; /* time of last change */ +}; + +/* + * File attributes which can be set + */ +struct sattr { + unsigned mode; /* protection mode bits */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ +}; + + +typedef string filename<NFS_MAXNAMLEN>; +typedef string nfspath<NFS_MAXPATHLEN>; + +/* + * Reply status with file attributes + */ +union attrstat switch (nfsstat status) { +case NFS_OK: + fattr attributes; +default: + void; +}; + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; + +/* + * Arguments for directory operations + */ +struct diropargs { + nfs_fh dir; /* directory file handle */ + filename name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +struct diropokres { + nfs_fh file; + fattr attributes; +}; + +/* + * Results from directory operation + */ +union diropres switch (nfsstat status) { +case NFS_OK: + diropokres diropres; +default: + void; +}; + +union readlinkres switch (nfsstat status) { +case NFS_OK: + nfspath data; +default: + void; +}; + +/* + * Arguments to remote read + */ +struct readargs { + nfs_fh file; /* handle for file */ + unsigned offset; /* byte offset in file */ + unsigned count; /* immediate read count */ + unsigned totalcount; /* total read count (from this offset)*/ +}; + +/* + * Status OK portion of remote read reply + */ +struct readokres { + fattr attributes; /* attributes, need for pagin*/ + opaque data<NFS_MAXDATA>; +}; + +union readres switch (nfsstat status) { +case NFS_OK: + readokres reply; +default: + void; +}; + +/* + * Arguments to remote write + */ +struct writeargs { + nfs_fh file; /* handle for file */ + unsigned beginoffset; /* beginning byte offset in file */ + unsigned offset; /* current byte offset in file */ + unsigned totalcount; /* total write count (to this offset)*/ + opaque data<NFS_MAXDATA>; +}; + +struct createargs { + diropargs where; + sattr attributes; +}; + +struct renameargs { + diropargs from; + diropargs to; +}; + +struct linkargs { + nfs_fh from; + diropargs to; +}; + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; + + +typedef opaque nfscookie[NFS_COOKIESIZE]; + +/* + * Arguments to readdir + */ +struct readdirargs { + nfs_fh dir; /* directory handle */ + nfscookie cookie; + unsigned count; /* number of directory bytes to read */ +}; + +struct entry { + unsigned fileid; + filename name; + nfscookie cookie; + entry *nextentry; +}; + +struct dirlist { + entry *entries; + bool eof; +}; + +union readdirres switch (nfsstat status) { +case NFS_OK: + dirlist reply; +default: + void; +}; + +struct statfsokres { + unsigned tsize; /* preferred transfer size in bytes */ + unsigned bsize; /* fundamental file system block size */ + unsigned blocks; /* total blocks in file system */ + unsigned bfree; /* free blocks in fs */ + unsigned bavail; /* free blocks avail to non-superuser */ +}; + +union statfsres switch (nfsstat status) { +case NFS_OK: + statfsokres reply; +default: + void; +}; + +/* + * Remote file service routines + */ +program NFS_PROGRAM { + version NFS_VERSION { + void + NFSPROC_NULL(void) = 0; + + attrstat + NFSPROC_GETATTR(nfs_fh) = 1; + + attrstat + NFSPROC_SETATTR(sattrargs) = 2; + + void + NFSPROC_ROOT(void) = 3; + + diropres + NFSPROC_LOOKUP(diropargs) = 4; + + readlinkres + NFSPROC_READLINK(nfs_fh) = 5; + + readres + NFSPROC_READ(readargs) = 6; + + void + NFSPROC_WRITECACHE(void) = 7; + + attrstat + NFSPROC_WRITE(writeargs) = 8; + + diropres + NFSPROC_CREATE(createargs) = 9; + + nfsstat + NFSPROC_REMOVE(diropargs) = 10; + + nfsstat + NFSPROC_RENAME(renameargs) = 11; + + nfsstat + NFSPROC_LINK(linkargs) = 12; + + nfsstat + NFSPROC_SYMLINK(symlinkargs) = 13; + + diropres + NFSPROC_MKDIR(createargs) = 14; + + nfsstat + NFSPROC_RMDIR(diropargs) = 15; + + readdirres + NFSPROC_READDIR(readdirargs) = 16; + + statfsres + NFSPROC_STATFS(nfs_fh) = 17; + } = 2; +} = 100003; + diff --git a/sunrpc/rpcsvc/nlm_prot.x b/sunrpc/rpcsvc/nlm_prot.x new file mode 100644 index 0000000000..e60c9315c2 --- /dev/null +++ b/sunrpc/rpcsvc/nlm_prot.x @@ -0,0 +1,179 @@ +/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */ + +/* + * Network lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between local lock manager and remote lock manager + */ + +#ifdef RPC_HDR +%#define LM_MAXSTRLEN 1024 +%#define MAXNAMELEN LM_MAXSTRLEN+1 +#endif + +/* + * status of a call to the lock manager + */ +enum nlm_stats { + nlm_granted = 0, + nlm_denied = 1, + nlm_denied_nolocks = 2, + nlm_blocked = 3, + nlm_denied_grace_period = 4 +}; + +struct nlm_holder { + bool exclusive; + int svid; + netobj oh; + unsigned l_offset; + unsigned l_len; +}; + +union nlm_testrply switch (nlm_stats stat) { + case nlm_denied: + struct nlm_holder holder; + default: + void; +}; + +struct nlm_stat { + nlm_stats stat; +}; + +struct nlm_res { + netobj cookie; + nlm_stat stat; +}; + +struct nlm_testres { + netobj cookie; + nlm_testrply stat; +}; + +struct nlm_lock { + string caller_name<LM_MAXSTRLEN>; + netobj fh; /* identify a file */ + netobj oh; /* identify owner of a lock */ + int svid; /* generated from pid for svid */ + unsigned l_offset; + unsigned l_len; +}; + +struct nlm_lockargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; + bool reclaim; /* used for recovering locks */ + int state; /* specify local status monitor state */ +}; + +struct nlm_cancargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_testargs { + netobj cookie; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_unlockargs { + netobj cookie; + struct nlm_lock alock; +}; + + +#ifdef RPC_HDR +%/* +% * The following enums are actually bit encoded for efficient +% * boolean algebra.... DON'T change them..... +% */ +#endif +enum fsh_mode { + fsm_DN = 0, /* deny none */ + fsm_DR = 1, /* deny read */ + fsm_DW = 2, /* deny write */ + fsm_DRW = 3 /* deny read/write */ +}; + +enum fsh_access { + fsa_NONE = 0, /* for completeness */ + fsa_R = 1, /* read only */ + fsa_W = 2, /* write only */ + fsa_RW = 3 /* read/write */ +}; + +struct nlm_share { + string caller_name<LM_MAXSTRLEN>; + netobj fh; + netobj oh; + fsh_mode mode; + fsh_access access; +}; + +struct nlm_shareargs { + netobj cookie; + nlm_share share; + bool reclaim; +}; + +struct nlm_shareres { + netobj cookie; + nlm_stats stat; + int sequence; +}; + +struct nlm_notify { + string name<MAXNAMELEN>; + long state; +}; + +/* + * Over-the-wire protocol used between the network lock managers + */ + +program NLM_PROG { + version NLM_VERS { + + nlm_testres NLM_TEST(struct nlm_testargs) = 1; + + nlm_res NLM_LOCK(struct nlm_lockargs) = 2; + + nlm_res NLM_CANCEL(struct nlm_cancargs) = 3; + nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4; + + /* + * remote lock manager call-back to grant lock + */ + nlm_res NLM_GRANTED(struct nlm_testargs)= 5; + /* + * message passing style of requesting lock + */ + void NLM_TEST_MSG(struct nlm_testargs) = 6; + void NLM_LOCK_MSG(struct nlm_lockargs) = 7; + void NLM_CANCEL_MSG(struct nlm_cancargs) =8; + void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9; + void NLM_GRANTED_MSG(struct nlm_testargs) = 10; + void NLM_TEST_RES(nlm_testres) = 11; + void NLM_LOCK_RES(nlm_res) = 12; + void NLM_CANCEL_RES(nlm_res) = 13; + void NLM_UNLOCK_RES(nlm_res) = 14; + void NLM_GRANTED_RES(nlm_res) = 15; + } = 1; + + version NLM_VERSX { + nlm_shareres NLM_SHARE(nlm_shareargs) = 20; + nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21; + nlm_res NLM_NM_LOCK(nlm_lockargs) = 22; + void NLM_FREE_ALL(nlm_notify) = 23; + } = 3; + +} = 100021; + diff --git a/sunrpc/rpcsvc/rex.x b/sunrpc/rpcsvc/rex.x new file mode 100644 index 0000000000..6063fdd28a --- /dev/null +++ b/sunrpc/rpcsvc/rex.x @@ -0,0 +1,229 @@ +/* @(#)rex.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)rex.x 1.3 87/09/18 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * Remote execution (rex) protocol specification + */ + +const STRINGSIZE = 1024; +typedef string rexstring<1024>; + +/* + * values to pass to REXPROC_SIGNAL + */ +const SIGINT = 2; /* interrupt */ + +/* + * Values for rst_flags, below + */ +const REX_INTERACTIVE = 1; /* interactive mode */ + +struct rex_start { + rexstring rst_cmd<>; /* list of command and args */ + rexstring rst_host; /* working directory host name */ + rexstring rst_fsname; /* working directory file system name */ + rexstring rst_dirwithin;/* working directory within file system */ + rexstring rst_env<>; /* list of environment */ + unsigned int rst_port0; /* port for stdin */ + unsigned int rst_port1; /* port for stdout */ + unsigned int rst_port2; /* port for stderr */ + unsigned int rst_flags; /* options - see const above */ +}; + +struct rex_result { + int rlt_stat; /* integer status code */ + rexstring rlt_message; /* string message for human consumption */ +}; + + +struct sgttyb { + unsigned four; /* always equals 4 */ + opaque chars[4]; + /* chars[0] == input speed */ + /* chars[1] == output speed */ + /* chars[2] == kill character */ + /* chars[3] == erase character */ + unsigned flags; +}; +/* values for speeds above (baud rates) */ +const B0 = 0; +const B50 = 1; +const B75 = 2; +const B110 = 3; +const B134 = 4; +const B150 = 5; +const B200 = 6; +const B300 = 7; +const B600 = 8; +const B1200 = 9; +const B1800 = 10; +const B2400 = 11; +const B4800 = 12; +const B9600 = 13; +const B19200 = 14; +const B38400 = 15; + +/* values for flags above */ +const TANDEM = 0x00000001; /* send stopc on out q full */ +const CBREAK = 0x00000002; /* half-cooked mode */ +const LCASE = 0x00000004; /* simulate lower case */ +const ECHO = 0x00000008; /* echo input */ +const CRMOD = 0x00000010; /* map \r to \r\n on output */ +const RAW = 0x00000020; /* no i/o processing */ +const ODDP = 0x00000040; /* get/send odd parity */ +const EVENP = 0x00000080; /* get/send even parity */ +const ANYP = 0x000000c0; /* get any parity/send none */ +const NLDELAY = 0x00000300; /* \n delay */ +const NL0 = 0x00000000; +const NL1 = 0x00000100; /* tty 37 */ +const NL2 = 0x00000200; /* vt05 */ +const NL3 = 0x00000300; +const TBDELAY = 0x00000c00; /* horizontal tab delay */ +const TAB0 = 0x00000000; +const TAB1 = 0x00000400; /* tty 37 */ +const TAB2 = 0x00000800; +const XTABS = 0x00000c00; /* expand tabs on output */ +const CRDELAY = 0x00003000; /* \r delay */ +const CR0 = 0x00000000; +const CR1 = 0x00001000; /* tn 300 */ +const CR2 = 0x00002000; /* tty 37 */ +const CR3 = 0x00003000; /* concept 100 */ +const VTDELAY = 0x00004000; /* vertical tab delay */ +const FF0 = 0x00000000; +const FF1 = 0x00004000; /* tty 37 */ +const BSDELAY = 0x00008000; /* \b delay */ +const BS0 = 0x00000000; +const BS1 = 0x00008000; +const CRTBS = 0x00010000; /* do backspacing for crt */ +const PRTERA = 0x00020000; /* \ ... / erase */ +const CRTERA = 0x00040000; /* " \b " to wipe out char */ +const TILDE = 0x00080000; /* hazeltine tilde kludge */ +const MDMBUF = 0x00100000; /* start/stop output on carrier intr */ +const LITOUT = 0x00200000; /* literal output */ +const TOSTOP = 0x00400000; /* SIGTTOU on background output */ +const FLUSHO = 0x00800000; /* flush output to terminal */ +const NOHANG = 0x01000000; /* no SIGHUP on carrier drop */ +const L001000 = 0x02000000; +const CRTKIL = 0x04000000; /* kill line with " \b " */ +const PASS8 = 0x08000000; +const CTLECH = 0x10000000; /* echo control chars as ^X */ +const PENDIN = 0x20000000; /* tp->t_rawq needs reread */ +const DECCTQ = 0x40000000; /* only ^Q starts after ^S */ +const NOFLSH = 0x80000000; /* no output flush on signal */ + +struct tchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == interrupt char */ + /* chars[1] == quit char */ + /* chars[2] == start output char */ + /* chars[3] == stop output char */ + /* chars[4] == end-of-file char */ + /* chars[5] == input delimeter (like nl) */ +}; + +struct ltchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == stop process signal */ + /* chars[1] == delayed stop process signal */ + /* chars[2] == reprint line */ + /* chars[3] == flush output */ + /* chars[4] == word erase */ + /* chars[5] == literal next character */ + unsigned mode; +}; + +struct rex_ttysize { + int ts_lines; + int ts_cols; +}; + +struct rex_ttymode { + sgttyb basic; /* standard unix tty flags */ + tchars more; /* interrupt, kill characters, etc. */ + ltchars yetmore; /* special Berkeley characters */ + unsigned andmore; /* and Berkeley modes */ +}; + +/* values for andmore above */ +const LCRTBS = 0x0001; /* do backspacing for crt */ +const LPRTERA = 0x0002; /* \ ... / erase */ +const LCRTERA = 0x0004; /* " \b " to wipe out char */ +const LTILDE = 0x0008; /* hazeltine tilde kludge */ +const LMDMBUF = 0x0010; /* start/stop output on carrier intr */ +const LLITOUT = 0x0020; /* literal output */ +const LTOSTOP = 0x0040; /* SIGTTOU on background output */ +const LFLUSHO = 0x0080; /* flush output to terminal */ +const LNOHANG = 0x0100; /* no SIGHUP on carrier drop */ +const LL001000 = 0x0200; +const LCRTKIL = 0x0400; /* kill line with " \b " */ +const LPASS8 = 0x0800; +const LCTLECH = 0x1000; /* echo control chars as ^X */ +const LPENDIN = 0x2000; /* needs reread */ +const LDECCTQ = 0x4000; /* only ^Q starts after ^S */ +const LNOFLSH = 0x8000; /* no output flush on signal */ + +program REXPROG { + version REXVERS { + + /* + * Start remote execution + */ + rex_result + REXPROC_START(rex_start) = 1; + + /* + * Wait for remote execution to terminate + */ + rex_result + REXPROC_WAIT(void) = 2; + + /* + * Send tty modes + */ + void + REXPROC_MODES(rex_ttymode) = 3; + + /* + * Send window size change + */ + void + REXPROC_WINCH(rex_ttysize) = 4; + + /* + * Send other signal + */ + void + REXPROC_SIGNAL(int) = 5; + } = 1; +} = 100017; diff --git a/sunrpc/rpcsvc/rnusers.x b/sunrpc/rpcsvc/rnusers.x new file mode 100644 index 0000000000..257df1e6e9 --- /dev/null +++ b/sunrpc/rpcsvc/rnusers.x @@ -0,0 +1,86 @@ +/* @(#)rnusers.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)rnusers.x 1.2 87/09/20 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * Find out about remote users + */ + +const MAXUSERS = 100; +const MAXUTLEN = 256; + +struct utmp { + string ut_line<MAXUTLEN>; + string ut_name<MAXUTLEN>; + string ut_host<MAXUTLEN>; + int ut_time; +}; + + +struct utmpidle { + utmp ui_utmp; + unsigned int ui_idle; +}; + +typedef utmp utmparr<MAXUSERS>; + +typedef utmpidle utmpidlearr<MAXUSERS>; + +program RUSERSPROG { + /* + * Includes idle information + */ + version RUSERSVERS_IDLE { + int + RUSERSPROC_NUM(void) = 1; + + utmpidlearr + RUSERSPROC_NAMES(void) = 2; + + utmpidlearr + RUSERSPROC_ALLNAMES(void) = 3; + } = 1; + + /* + * Old version does not include idle information + */ + version RUSERSVERS_ORIG { + int + RUSERSPROC_NUM(void) = 1; + + utmparr + RUSERSPROC_NAMES(void) = 2; + + utmparr + RUSERSPROC_ALLNAMES(void) = 3; + } = 2; +} = 100002; + diff --git a/sunrpc/rpcsvc/rquota.x b/sunrpc/rpcsvc/rquota.x new file mode 100644 index 0000000000..62888f612a --- /dev/null +++ b/sunrpc/rpcsvc/rquota.x @@ -0,0 +1,61 @@ +/* @(#)rquota.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)rquota.x 1.2 87/09/20 Copyr 1987 Sun Micro */ + +/* + * Remote quota protocol + * Requires unix authentication + */ + +const RQ_PATHLEN = 1024; + +struct getquota_args { + string gqa_pathp<RQ_PATHLEN>; /* path to filesystem of interest */ + int gqa_uid; /* inquire about quota for uid */ +}; + +/* + * remote quota structure + */ +struct rquota { + int rq_bsize; /* block size for block counts */ + bool rq_active; /* indicates whether quota is active */ + unsigned int rq_bhardlimit; /* absolute limit on disk blks alloc */ + unsigned int rq_bsoftlimit; /* preferred limit on disk blks */ + unsigned int rq_curblocks; /* current block count */ + unsigned int rq_fhardlimit; /* absolute limit on allocated files */ + unsigned int rq_fsoftlimit; /* preferred file limit */ + unsigned int rq_curfiles; /* current # allocated files */ + unsigned int rq_btimeleft; /* time left for excessive disk use */ + unsigned int rq_ftimeleft; /* time left for excessive files */ +}; + +enum gqr_status { + Q_OK = 1, /* quota returned */ + Q_NOQUOTA = 2, /* noquota for uid */ + Q_EPERM = 3 /* no permission to access quota */ +}; + +union getquota_rslt switch (gqr_status status) { +case Q_OK: + rquota gqr_rquota; /* valid if status == Q_OK */ +case Q_NOQUOTA: + void; +case Q_EPERM: + void; +}; + +program RQUOTAPROG { + version RQUOTAVERS { + /* + * Get all quotas + */ + getquota_rslt + RQUOTAPROC_GETQUOTA(getquota_args) = 1; + + /* + * Get active quotas only + */ + getquota_rslt + RQUOTAPROC_GETACTIVEQUOTA(getquota_args) = 2; + } = 1; +} = 100011; diff --git a/sunrpc/rpcsvc/rstat.x b/sunrpc/rpcsvc/rstat.x new file mode 100644 index 0000000000..6367c43943 --- /dev/null +++ b/sunrpc/rpcsvc/rstat.x @@ -0,0 +1,145 @@ +/* @(#)rstat.x 2.2 88/08/01 4.0 RPCSRC */ +/* @(#)rstat.x 1.2 87/09/18 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * Gather statistics on remote machines + */ + +#ifdef RPC_HDR + +%#ifndef FSCALE +%/* +% * Scale factor for scaled integers used to count load averages. +% */ +%#define FSHIFT 8 /* bits to right of fixed binary point */ +%#define FSCALE (1<<FSHIFT) +% +%#endif /* ndef FSCALE */ + +#endif /* def RPC_HDR */ + +const CPUSTATES = 4; +const DK_NDRIVE = 4; + +/* + * GMT since 0:00, January 1, 1970 + */ +struct rstat_timeval { + unsigned int tv_sec; /* seconds */ + unsigned int tv_usec; /* and microseconds */ +}; + +struct statstime { /* RSTATVERS_TIME */ + int cp_time[CPUSTATES]; + int dk_xfer[DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + int avenrun[3]; /* scaled by FSCALE */ + rstat_timeval boottime; + rstat_timeval curtime; + int if_opackets; +}; + +struct statsswtch { /* RSTATVERS_SWTCH */ + int cp_time[CPUSTATES]; + int dk_xfer[DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + unsigned int avenrun[3];/* scaled by FSCALE */ + rstat_timeval boottime; + int if_opackets; +}; + +struct stats { /* RSTATVERS_ORIG */ + int cp_time[CPUSTATES]; + int dk_xfer[DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + int if_opackets; +}; + + +program RSTATPROG { + /* + * Newest version includes current time and context switching info + */ + version RSTATVERS_TIME { + statstime + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 3; + /* + * Does not have current time + */ + version RSTATVERS_SWTCH { + statsswtch + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 2; + /* + * Old version has no info about current time or context switching + */ + version RSTATVERS_ORIG { + stats + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 1; +} = 100001; diff --git a/sunrpc/rpcsvc/sm_inter.x b/sunrpc/rpcsvc/sm_inter.x new file mode 100644 index 0000000000..2817ebfda3 --- /dev/null +++ b/sunrpc/rpcsvc/sm_inter.x @@ -0,0 +1,116 @@ +/* @(#)sm_inter.x 2.2 88/08/01 4.0 RPCSRC */ +/* @(#)sm_inter.x 1.7 87/06/24 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * Status monitor protocol specification + * Copyright (C) 1986 Sun Microsystems, Inc. + * + */ + + +program SM_PROG { + version SM_VERS { + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* if res_stat == stat_succ, state = state number of site sm_name */ + struct sm_stat_res SM_STAT(struct sm_name) = 1; + + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* stat consists of state number of local site */ + struct sm_stat_res SM_MON(struct mon) = 2; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON(struct mon_id) = 3; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON_ALL(struct my_id) = 4; + + void SM_SIMU_CRASH(void) = 5; + + } = 1; +} = 100024; + +const SM_MAXSTRLEN = 1024; + +struct sm_name { + string mon_name<SM_MAXSTRLEN>; +}; + +struct my_id { + string my_name<SM_MAXSTRLEN>; /* name of the site iniates the monitoring request*/ + int my_prog; /* rpc program # of the requesting process */ + int my_vers; /* rpc version # of the requesting process */ + int my_proc; /* rpc procedure # of the requesting process */ +}; + +struct mon_id { + string mon_name<SM_MAXSTRLEN>; /* name of the site to be monitored */ + struct my_id my_id; +}; + + +struct mon{ + struct mon_id mon_id; + opaque priv[16]; /* private information to store at monitor for requesting process */ +}; + + +/* + * state # of status monitor monitonically increases each time + * status of the site changes: + * an even number (>= 0) indicates the site is down and + * an odd number (> 0) indicates the site is up; + */ +struct sm_stat { + int state; /* state # of status monitor */ +}; + +enum res { + stat_succ = 0, /* status monitor agrees to monitor */ + stat_fail = 1 /* status monitor cannot monitor */ +}; + +struct sm_stat_res { + res res_stat; + int state; +}; + +/* + * structure of the status message sent back by the status monitor + * when monitor site status changes + */ +struct status { + string mon_name<SM_MAXSTRLEN>; + int state; + opaque priv[16]; /* stored private information */ +}; diff --git a/sunrpc/rpcsvc/spray.x b/sunrpc/rpcsvc/spray.x new file mode 100644 index 0000000000..b242f0ac75 --- /dev/null +++ b/sunrpc/rpcsvc/spray.x @@ -0,0 +1,84 @@ +/* @(#)spray.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)spray.x 1.2 87/09/18 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * Spray a server with packets + * Useful for testing flakiness of network interfaces + */ + +const SPRAYMAX = 8845; /* max amount can spray */ + +/* + * GMT since 0:00, 1 January 1970 + */ +struct spraytimeval { + unsigned int sec; + unsigned int usec; +}; + +/* + * spray statistics + */ +struct spraycumul { + unsigned int counter; + spraytimeval clock; +}; + +/* + * spray data + */ +typedef opaque sprayarr<SPRAYMAX>; + +program SPRAYPROG { + version SPRAYVERS { + /* + * Just throw away the data and increment the counter + * This call never returns, so the client should always + * time it out. + */ + void + SPRAYPROC_SPRAY(sprayarr) = 1; + + /* + * Get the value of the counter and elapsed time since + * last CLEAR. + */ + spraycumul + SPRAYPROC_GET(void) = 2; + + /* + * Clear the counter and reset the elapsed time + */ + void + SPRAYPROC_CLEAR(void) = 3; + } = 1; +} = 100012; diff --git a/sunrpc/rpcsvc/yp.x b/sunrpc/rpcsvc/yp.x new file mode 100644 index 0000000000..8fe70a2706 --- /dev/null +++ b/sunrpc/rpcsvc/yp.x @@ -0,0 +1,291 @@ +/* @(#)yp.x 2.1 88/08/01 4.0 RPCSRC */ + +/* + * 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 + */ + +/* + * Protocol description file for the Yellow Pages Service + */ + +const YPMAXRECORD = 1024; +const YPMAXDOMAIN = 64; +const YPMAXMAP = 64; +const YPMAXPEER = 64; + + +enum ypstat { + YP_TRUE = 1, + YP_NOMORE = 2, + YP_FALSE = 0, + YP_NOMAP = -1, + YP_NODOM = -2, + YP_NOKEY = -3, + YP_BADOP = -4, + YP_BADDB = -5, + YP_YPERR = -6, + YP_BADARGS = -7, + YP_VERS = -8 +}; + + +enum ypxfrstat { + YPXFR_SUCC = 1, + YPXFR_AGE = 2, + YPXFR_NOMAP = -1, + YPXFR_NODOM = -2, + YPXFR_RSRC = -3, + YPXFR_RPC = -4, + YPXFR_MADDR = -5, + YPXFR_YPERR = -6, + YPXFR_BADARGS = -7, + YPXFR_DBM = -8, + YPXFR_FILE = -9, + YPXFR_SKEW = -10, + YPXFR_CLEAR = -11, + YPXFR_FORCE = -12, + YPXFR_XFRERR = -13, + YPXFR_REFUSED = -14 +}; + + +typedef string domainname<YPMAXDOMAIN>; +typedef string mapname<YPMAXMAP>; +typedef string peername<YPMAXPEER>; +typedef opaque keydat<YPMAXRECORD>; +typedef opaque valdat<YPMAXRECORD>; + + +struct ypmap_parms { + domainname domain; + mapname map; + unsigned int ordernum; + peername peer; +}; + +struct ypreq_key { + domainname domain; + mapname map; + keydat key; +}; + +struct ypreq_nokey { + domainname domain; + mapname map; +}; + +struct ypreq_xfr { + ypmap_parms map_parms; + unsigned int transid; + unsigned int prog; + unsigned int port; +}; + + +struct ypresp_val { + ypstat stat; + valdat val; +}; + +struct ypresp_key_val { + ypstat stat; + keydat key; + valdat val; +}; + + +struct ypresp_master { + ypstat stat; + peername peer; +}; + +struct ypresp_order { + ypstat stat; + unsigned int ordernum; +}; + +union ypresp_all switch (bool more) { +case TRUE: + ypresp_key_val val; +case FALSE: + void; +}; + +struct ypresp_xfr { + unsigned int transid; + ypxfrstat xfrstat; +}; + +struct ypmaplist { + mapname map; + ypmaplist *next; +}; + +struct ypresp_maplist { + ypstat stat; + ypmaplist *maps; +}; + +enum yppush_status { + YPPUSH_SUCC = 1, /* Success */ + YPPUSH_AGE = 2, /* Master's version not newer */ + YPPUSH_NOMAP = -1, /* Can't find server for map */ + YPPUSH_NODOM = -2, /* Domain not supported */ + YPPUSH_RSRC = -3, /* Local resource alloc failure */ + YPPUSH_RPC = -4, /* RPC failure talking to server */ + YPPUSH_MADDR = -5, /* Can't get master address */ + YPPUSH_YPERR = -6, /* YP server/map db error */ + YPPUSH_BADARGS = -7, /* Request arguments bad */ + YPPUSH_DBM = -8, /* Local dbm operation failed */ + YPPUSH_FILE = -9, /* Local file I/O operation failed */ + YPPUSH_SKEW = -10, /* Map version skew during transfer */ + YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */ + YPPUSH_FORCE = -12, /* No local order number in map use -f flag. */ + YPPUSH_XFRERR = -13, /* ypxfr error */ + YPPUSH_REFUSED = -14 /* Transfer request refused by ypserv */ +}; + +struct yppushresp_xfr { + unsigned transid; + yppush_status status; +}; + +/* + * Response structure and overall result status codes. Success and failure + * represent two separate response message types. + */ + +enum ypbind_resptype { + YPBIND_SUCC_VAL = 1, + YPBIND_FAIL_VAL = 2 +}; + +struct ypbind_binding { + opaque ypbind_binding_addr[4]; /* In network order */ + opaque ypbind_binding_port[2]; /* In network order */ +}; + +union ypbind_resp switch (ypbind_resptype ypbind_status) { +case YPBIND_FAIL_VAL: + unsigned ypbind_error; +case YPBIND_SUCC_VAL: + ypbind_binding ypbind_bindinfo; +}; + +/* Detailed failure reason codes for response field ypbind_error*/ + +const YPBIND_ERR_ERR = 1; /* Internal error */ +const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */ +const YPBIND_ERR_RESC = 3; /* System resource allocation failure */ + + +/* + * Request data structure for ypbind "Set domain" procedure. + */ +struct ypbind_setdom { + domainname ypsetdom_domain; + ypbind_binding ypsetdom_binding; + unsigned ypsetdom_vers; +}; + + +/* + * YP access protocol + */ +program YPPROG { + version YPVERS { + void + YPPROC_NULL(void) = 0; + + bool + YPPROC_DOMAIN(domainname) = 1; + + bool + YPPROC_DOMAIN_NONACK(domainname) = 2; + + ypresp_val + YPPROC_MATCH(ypreq_key) = 3; + + ypresp_key_val + YPPROC_FIRST(ypreq_key) = 4; + + ypresp_key_val + YPPROC_NEXT(ypreq_key) = 5; + + ypresp_xfr + YPPROC_XFR(ypreq_xfr) = 6; + + void + YPPROC_CLEAR(void) = 7; + + ypresp_all + YPPROC_ALL(ypreq_nokey) = 8; + + ypresp_master + YPPROC_MASTER(ypreq_nokey) = 9; + + ypresp_order + YPPROC_ORDER(ypreq_nokey) = 10; + + ypresp_maplist + YPPROC_MAPLIST(domainname) = 11; + } = 2; +} = 100004; + + +/* + * YPPUSHPROC_XFRRESP is the callback routine for result of YPPROC_XFR + */ +program YPPUSH_XFRRESPPROG { + version YPPUSH_XFRRESPVERS { + void + YPPUSHPROC_NULL(void) = 0; + + yppushresp_xfr + YPPUSHPROC_XFRRESP(void) = 1; + } = 1; +} = 0x40000000; /* transient: could be anything up to 0x5fffffff */ + + +/* + * YP binding protocol + */ +program YPBINDPROG { + version YPBINDVERS { + void + YPBINDPROC_NULL(void) = 0; + + ypbind_resp + YPBINDPROC_DOMAIN(domainname) = 1; + + void + YPBINDPROC_SETDOM(ypbind_setdom) = 2; + } = 2; +} = 100007; + + diff --git a/sunrpc/rpcsvc/yppasswd.x b/sunrpc/rpcsvc/yppasswd.x new file mode 100644 index 0000000000..ad349adbfa --- /dev/null +++ b/sunrpc/rpcsvc/yppasswd.x @@ -0,0 +1,63 @@ +/* @(#)yppasswd.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)yppasswd.x 1.1 87/04/13 Copyr 1987 Sun Micro */ + +/* + * 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 + */ + +/* + * YP password update protocol + * Requires unix authentication + */ +program YPPASSWDPROG { + version YPPASSWDVERS { + /* + * Update my passwd entry + */ + int + YPPASSWDPROC_UPDATE(yppasswd) = 1; + } = 1; +} = 100009; + + +struct passwd { + string pw_name<>; /* username */ + string pw_passwd<>; /* encrypted password */ + int pw_uid; /* user id */ + int pw_gid; /* group id */ + string pw_gecos<>; /* in real life name */ + string pw_dir<>; /* home directory */ + string pw_shell<>; /* default shell */ +}; + +struct yppasswd { + string oldpass<>; /* unencrypted old password */ + passwd newpw; /* new passwd entry */ +}; + + diff --git a/sunrpc/svc.c b/sunrpc/svc.c new file mode 100644 index 0000000000..3327ee5bdd --- /dev/null +++ b/sunrpc/svc.c @@ -0,0 +1,479 @@ +/* @(#)svc.c 2.4 88/08/11 4.0 RPCSRC; from 1.44 88/02/08 SMI */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro"; +#endif + +/* + * svc.c, Server-side remote procedure call interface. + * + * There are two sets of procedures here. The xprt routines are + * for handling transport handles. The svc routines handle the + * list of service routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <sys/errno.h> +#include <rpc/rpc.h> +#include <rpc/pmap_clnt.h> + +extern int errno; + +#ifdef FD_SETSIZE +static SVCXPRT **xports; +#else +#define NOFILE 32 + +static SVCXPRT *xports[NOFILE]; +#endif /* def FD_SETSIZE */ + +#define NULL_SVC ((struct svc_callout *)0) +#define RQCRED_SIZE 400 /* this size is excessive */ + +/* + * 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; + u_long sc_prog; + u_long sc_vers; + void (*sc_dispatch)(); +} *svc_head; + +static struct svc_callout *svc_find(); + +/* *************** SVCXPRT related stuff **************** */ + +/* + * Activate a transport handle. + */ +void +xprt_register(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + +#ifdef FD_SETSIZE + if (xports == NULL) { + xports = (SVCXPRT **) + mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); + } + if (sock < _rpc_dtablesize()) { + xports[sock] = xprt; + FD_SET(sock, &svc_fdset); + } +#else + if (sock < NOFILE) { + xports[sock] = xprt; + svc_fds |= (1 << sock); + } +#endif /* def FD_SETSIZE */ + +} + +/* + * De-activate a transport handle. + */ +void +xprt_unregister(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + +#ifdef FD_SETSIZE + if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) { + xports[sock] = (SVCXPRT *)0; + FD_CLR(sock, &svc_fdset); + } +#else + if ((sock < NOFILE) && (xports[sock] == xprt)) { + xports[sock] = (SVCXPRT *)0; + svc_fds &= ~(1 << sock); + } +#endif /* def FD_SETSIZE */ +} + + +/* ********************** CALLOUT list related stuff ************* */ + +/* + * Add a service program to the callout list. + * The dispatch routine will be called when a rpc request for this + * program number comes in. + */ +bool_t +svc_register(xprt, prog, vers, dispatch, protocol) + SVCXPRT *xprt; + u_long prog; + u_long vers; + void (*dispatch)(); + int protocol; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { + if (s->sc_dispatch == dispatch) + goto pmap_it; /* he is registering another xptr */ + return (FALSE); + } + s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); + if (s == (struct svc_callout *)0) { + return (FALSE); + } + s->sc_prog = prog; + s->sc_vers = vers; + s->sc_dispatch = dispatch; + s->sc_next = svc_head; + svc_head = s; +pmap_it: + /* now register the information with the local binder service */ + if (protocol) { + return (pmap_set(prog, vers, protocol, xprt->xp_port)); + } + return (TRUE); +} + +/* + * Remove a service program from the callout list. + */ +void +svc_unregister(prog, vers) + u_long prog; + u_long vers; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) + return; + if (prev == NULL_SVC) { + svc_head = s->sc_next; + } else { + prev->sc_next = s->sc_next; + } + s->sc_next = NULL_SVC; + mem_free((char *) s, (u_int) sizeof(struct svc_callout)); + /* now unregister the information with the local binder service */ + (void)pmap_unset(prog, vers); +} + +/* + * Search the callout list for a program number, return the callout + * struct. + */ +static struct svc_callout * +svc_find(prog, vers, prev) + u_long prog; + u_long vers; + struct svc_callout **prev; +{ + register struct svc_callout *s, *p; + + p = NULL_SVC; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if ((s->sc_prog == prog) && (s->sc_vers == vers)) + goto done; + p = s; + } +done: + *prev = p; + return (s); +} + +/* ******************* REPLY GENERATION ROUTINES ************ */ + +/* + * Send a reply to an rpc request + */ +bool_t +svc_sendreply(xprt, xdr_results, xdr_location) + register SVCXPRT *xprt; + xdrproc_t xdr_results; + caddr_t xdr_location; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SUCCESS; + rply.acpted_rply.ar_results.where = xdr_location; + rply.acpted_rply.ar_results.proc = xdr_results; + return (SVC_REPLY(xprt, &rply)); +} + +/* + * No procedure error reply + */ +void +svcerr_noproc(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROC_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Can't decode args error reply + */ +void +svcerr_decode(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = GARBAGE_ARGS; + SVC_REPLY(xprt, &rply); +} + +/* + * Some system error + */ +void +svcerr_systemerr(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SYSTEM_ERR; + SVC_REPLY(xprt, &rply); +} + +/* + * Authentication error reply + */ +void +svcerr_auth(xprt, why) + SVCXPRT *xprt; + enum auth_stat why; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_DENIED; + rply.rjcted_rply.rj_stat = AUTH_ERROR; + rply.rjcted_rply.rj_why = why; + SVC_REPLY(xprt, &rply); +} + +/* + * Auth too weak error reply + */ +void +svcerr_weakauth(xprt) + SVCXPRT *xprt; +{ + + svcerr_auth(xprt, AUTH_TOOWEAK); +} + +/* + * Program unavailable error reply + */ +void +svcerr_noprog(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Program version mismatch error reply + */ +void +svcerr_progvers(xprt, low_vers, high_vers) + register SVCXPRT *xprt; + u_long low_vers; + u_long high_vers; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_MISMATCH; + rply.acpted_rply.ar_vers.low = low_vers; + rply.acpted_rply.ar_vers.high = high_vers; + SVC_REPLY(xprt, &rply); +} + +/* ******************* SERVER INPUT STUFF ******************* */ + +/* + * Get server side input from some transport. + * + * Statement of authentication parameters management: + * This function owns and manages all authentication parameters, specifically + * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and + * the "cooked" credentials (rqst->rq_clntcred). + * However, this function does not know the structure of the cooked + * credentials, so it make the following assumptions: + * a) the structure is contiguous (no pointers), and + * b) the cred structure size does not exceed RQCRED_SIZE bytes. + * In all events, all three parameters are freed upon exit from this routine. + * The storage is trivially management on the call stack in user land, but + * is mallocated in kernel land. + */ + +void +svc_getreq(rdfds) + int rdfds; +{ +#ifdef FD_SETSIZE + fd_set readfds; + + FD_ZERO(&readfds); + readfds.fds_bits[0] = rdfds; + svc_getreqset(&readfds); +#else + int readfds = rdfds & svc_fds; + + svc_getreqset(&readfds); +#endif /* def FD_SETSIZE */ +} + +void +svc_getreqset(readfds) +#ifdef FD_SETSIZE + fd_set *readfds; +{ +#else + int *readfds; +{ + int readfds_local = *readfds; +#endif /* def FD_SETSIZE */ + enum xprt_stat stat; + struct rpc_msg msg; + int prog_found; + u_long low_vers; + u_long high_vers; + struct svc_req r; + register SVCXPRT *xprt; + register u_long mask; + register int bit; + register u_long *maskp; + register int setsize; + register int sock; + 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]); + + +#ifdef FD_SETSIZE + setsize = _rpc_dtablesize(); + maskp = (u_long *)readfds->fds_bits; + for (sock = 0; sock < setsize; sock += NFDBITS) { + for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) { + /* sock has input waiting */ + xprt = xports[sock + bit - 1]; +#else + for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) { + if ((readfds_local & 1) != 0) { + /* sock has input waiting */ + xprt = xports[sock]; +#endif /* def FD_SETSIZE */ + /* now receive msgs from xprtprt (support batch calls) */ + do { + if (SVC_RECV(xprt, &msg)) { + + /* now find the exported program and call it */ + register struct svc_callout *s; + enum auth_stat why; + + r.rq_xprt = xprt; + r.rq_prog = msg.rm_call.cb_prog; + r.rq_vers = msg.rm_call.cb_vers; + r.rq_proc = msg.rm_call.cb_proc; + r.rq_cred = msg.rm_call.cb_cred; + /* first authenticate the message */ + if ((why= _authenticate(&r, &msg)) != AUTH_OK) { + svcerr_auth(xprt, why); + goto call_done; + } + /* now match message with a registered service*/ + prog_found = FALSE; + low_vers = 0 - 1; + high_vers = 0; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if (s->sc_prog == r.rq_prog) { + if (s->sc_vers == r.rq_vers) { + (*s->sc_dispatch)(&r, xprt); + goto call_done; + } /* found correct version */ + prog_found = TRUE; + if (s->sc_vers < low_vers) + low_vers = s->sc_vers; + if (s->sc_vers > high_vers) + high_vers = s->sc_vers; + } /* found correct program */ + } + /* + * if we got here, the program or version + * is not served ... + */ + if (prog_found) + svcerr_progvers(xprt, + low_vers, high_vers); + else + svcerr_noprog(xprt); + /* Fall through to ... */ + } + call_done: + if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ + SVC_DESTROY(xprt); + break; + } + } while (stat == XPRT_MOREREQS); + } + } +} diff --git a/sunrpc/svc_auth.c b/sunrpc/svc_auth.c new file mode 100644 index 0000000000..ab7ab69421 --- /dev/null +++ b/sunrpc/svc_auth.c @@ -0,0 +1,114 @@ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC; from 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * svc_auth_nodes.c, Server-side rpc authenticator interface, + * *WITHOUT* DES authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.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) + * register struct svc_req *rqst; + * register struct rpc_msg *msg; + * + */ + +enum auth_stat _svcauth_null(); /* no authentication */ +enum auth_stat _svcauth_unix(); /* unix style (uid, gids) */ +enum auth_stat _svcauth_short(); /* short hand unix style */ + +static struct { + enum auth_stat (*authenticator)(); +} svcauthsw[] = { + _svcauth_null, /* AUTH_NULL */ + _svcauth_unix, /* AUTH_UNIX */ + _svcauth_short, /* AUTH_SHORT */ +}; +#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */ + + +/* + * The call rpc message, msg has been obtained from the wire. The msg contains + * the raw form of credentials and verifiers. authenticate returns AUTH_OK + * if the msg is successfully authenticated. If AUTH_OK then the routine also + * does the following things: + * set rqst->rq_xprt->verf to the appropriate response verifier; + * sets rqst->rq_client_cred to the "cooked" form of the credentials. + * + * NB: rqst->rq_cxprt->verf must be pre-alloctaed; + * its length is set appropriately. + * + * The caller still owns and is responsible for msg->u.cmb.cred and + * msg->u.cmb.verf. The authentication system retains ownership of + * rqst->rq_client_cred, the cooked credentials. + * + * There is an assumption that any flavour less than AUTH_NULL is + * invalid. + */ +enum auth_stat +_authenticate(rqst, msg) + register struct svc_req *rqst; + struct rpc_msg *msg; +{ + register int cred_flavor; + + rqst->rq_cred = msg->rm_call.cb_cred; + rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; + rqst->rq_xprt->xp_verf.oa_length = 0; + cred_flavor = rqst->rq_cred.oa_flavor; + if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) { + return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg)); + } + + return (AUTH_REJECTEDCRED); +} + +enum auth_stat +_svcauth_null(/*rqst, msg*/) + /*struct svc_req *rqst; + struct rpc_msg *msg;*/ +{ + + return (AUTH_OK); +} diff --git a/sunrpc/svc_authux.c b/sunrpc/svc_authux.c new file mode 100644 index 0000000000..ea00b7895f --- /dev/null +++ b/sunrpc/svc_authux.c @@ -0,0 +1,134 @@ +/* @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC; from 1.28 88/02/08 SMI */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_auth_unix.c + * Handles UNIX flavor authentication parameters on the service side of rpc. + * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT. + * _svcauth_unix does full blown unix style uid,gid+gids auth, + * _svcauth_short uses a shorthand auth to index into a cache of longhand auths. + * Note: the shorthand has been gutted for efficiency. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> + +/* + * Unix longhand authenticator + */ +enum auth_stat +_svcauth_unix(rqst, msg) + register struct svc_req *rqst; + register struct rpc_msg *msg; +{ + register enum auth_stat stat; + XDR xdrs; + register struct authunix_parms *aup; + register long *buf; + struct area { + struct authunix_parms area_aup; + char area_machname[MAX_MACHINE_NAME+1]; + int area_gids[NGRPS]; + } *area; + u_int auth_len; + int str_len, gid_len; + register int i; + + area = (struct area *) rqst->rq_clntcred; + aup = &area->area_aup; + aup->aup_machname = area->area_machname; + aup->aup_gids = area->area_gids; + auth_len = (u_int)msg->rm_call.cb_cred.oa_length; + xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE); + buf = XDR_INLINE(&xdrs, auth_len); + if (buf != NULL) { + aup->aup_time = IXDR_GET_LONG(buf); + str_len = IXDR_GET_U_LONG(buf); + if (str_len > MAX_MACHINE_NAME) { + stat = AUTH_BADCRED; + goto done; + } + bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len); + aup->aup_machname[str_len] = 0; + str_len = RNDUP(str_len); + buf += str_len / sizeof (long); + aup->aup_uid = IXDR_GET_LONG(buf); + aup->aup_gid = IXDR_GET_LONG(buf); + gid_len = IXDR_GET_U_LONG(buf); + if (gid_len > NGRPS) { + stat = AUTH_BADCRED; + goto done; + } + aup->aup_len = gid_len; + for (i = 0; i < gid_len; i++) { + aup->aup_gids[i] = IXDR_GET_LONG(buf); + } + /* + * five is the smallest unix credentials structure - + * timestamp, hostname len (0), uid, gid, and gids len (0). + */ + if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) { + (void) printf("bad auth_len gid %d str %d auth %d\n", + gid_len, str_len, auth_len); + stat = AUTH_BADCRED; + goto done; + } + } else if (! xdr_authunix_parms(&xdrs, aup)) { + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, aup); + stat = AUTH_BADCRED; + goto done; + } + 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/sunrpc/svc_raw.c b/sunrpc/svc_raw.c new file mode 100644 index 0000000000..1170ecec83 --- /dev/null +++ b/sunrpc/svc_raw.c @@ -0,0 +1,166 @@ +/* @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_raw.c, This a toy for simple testing and timing. + * Interface to create an rpc client and server in the same UNIX process. + * This lets us similate rpc and get rpc (round trip) overhead, without + * any interference from the kernal. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> + + +/* + * This is the "network" that we will be moving data over + */ +static struct svcraw_private { + char _raw_buf[UDPMSGSIZE]; + SVCXPRT server; + XDR xdr_stream; + char verf_body[MAX_AUTH_BYTES]; +} *svcraw_private; + +static bool_t svcraw_recv(); +static enum xprt_stat svcraw_stat(); +static bool_t svcraw_getargs(); +static bool_t svcraw_reply(); +static bool_t svcraw_freeargs(); +static void svcraw_destroy(); + +static struct xp_ops server_ops = { + svcraw_recv, + svcraw_stat, + svcraw_getargs, + svcraw_reply, + svcraw_freeargs, + svcraw_destroy +}; + +SVCXPRT * +svcraw_create() +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) { + srp = (struct svcraw_private *)calloc(1, sizeof (*srp)); + if (srp == 0) + return (0); + } + srp->server.xp_sock = 0; + srp->server.xp_port = 0; + srp->server.xp_ops = &server_ops; + srp->server.xp_verf.oa_base = srp->verf_body; + xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE); + return (&srp->server); +} + +static enum xprt_stat +svcraw_stat() +{ + + return (XPRT_IDLE); +} + +static bool_t +svcraw_recv(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (0); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + return (TRUE); +} + +static bool_t +svcraw_reply(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_replymsg(xdrs, msg)) + return (FALSE); + (void)XDR_GETPOS(xdrs); /* called just for overhead */ + return (TRUE); +} + +static bool_t +svcraw_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) + return (FALSE); + return ((*xdr_args)(&srp->xdr_stream, args_ptr)); +} + +static bool_t +svcraw_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcraw_destroy() +{ +} diff --git a/sunrpc/svc_run.c b/sunrpc/svc_run.c new file mode 100644 index 0000000000..c1c3e04781 --- /dev/null +++ b/sunrpc/svc_run.c @@ -0,0 +1,72 @@ +/* @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro"; +#endif + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * This is the rpc server side idle loop + * Wait for input, call server program. + */ +#include <rpc/rpc.h> +#include <sys/errno.h> + +void +svc_run() +{ +#ifdef FD_SETSIZE + fd_set readfds; +#else + int readfds; +#endif /* def FD_SETSIZE */ + extern int errno; + + for (;;) { +#ifdef FD_SETSIZE + readfds = svc_fdset; +#else + readfds = svc_fds; +#endif /* def FD_SETSIZE */ + switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0, + (struct timeval *)0)) { + case -1: + if (errno == EINTR) { + continue; + } + perror("svc_run: - select failed"); + return; + case 0: + continue; + default: + svc_getreqset(&readfds); + } + } +} diff --git a/sunrpc/svc_simple.c b/sunrpc/svc_simple.c new file mode 100644 index 0000000000..d6bcbd3c04 --- /dev/null +++ b/sunrpc/svc_simple.c @@ -0,0 +1,143 @@ +/* @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> + +static struct proglst { + char *(*p_progname)(); + int p_prognum; + int p_procnum; + xdrproc_t p_inproc, p_outproc; + struct proglst *p_nxt; +} *proglst; +static void universal(); +static SVCXPRT *transp; +struct proglst *pl; + +registerrpc(prognum, versnum, procnum, progname, inproc, outproc) + char *(*progname)(); + xdrproc_t inproc, outproc; +{ + + if (procnum == NULLPROC) { + (void) fprintf(stderr, + "can't reassign procedure number %d\n", NULLPROC); + return (-1); + } + if (transp == 0) { + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { + (void) fprintf(stderr, "couldn't create an rpc server\n"); + return (-1); + } + } + (void) pmap_unset((u_long)prognum, (u_long)versnum); + if (!svc_register(transp, (u_long)prognum, (u_long)versnum, + universal, IPPROTO_UDP)) { + (void) fprintf(stderr, "couldn't register prog %d vers %d\n", + prognum, versnum); + return (-1); + } + pl = (struct proglst *)malloc(sizeof(struct proglst)); + if (pl == NULL) { + (void) fprintf(stderr, "registerrpc: out of memory\n"); + return (-1); + } + pl->p_progname = progname; + pl->p_prognum = prognum; + pl->p_procnum = procnum; + pl->p_inproc = inproc; + pl->p_outproc = outproc; + pl->p_nxt = proglst; + proglst = pl; + return (0); +} + +static void +universal(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + int prog, proc; + char *outdata; + char xdrbuf[UDPMSGSIZE]; + struct proglst *pl; + + /* + * enforce "procnum 0 is echo" convention + */ + if (rqstp->rq_proc == NULLPROC) { + if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) { + (void) fprintf(stderr, "xxx\n"); + exit(1); + } + return; + } + prog = rqstp->rq_prog; + proc = rqstp->rq_proc; + for (pl = proglst; pl != NULL; pl = pl->p_nxt) + if (pl->p_prognum == prog && pl->p_procnum == proc) { + /* decode arguments into a CLEAN buffer */ + bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */ + if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { + svcerr_decode(transp); + return; + } + outdata = (*(pl->p_progname))(xdrbuf); + if (outdata == NULL && pl->p_outproc != xdr_void) + /* there was an error */ + return; + if (!svc_sendreply(transp, pl->p_outproc, outdata)) { + (void) fprintf(stderr, + "trouble replying to prog %d\n", + pl->p_prognum); + exit(1); + } + /* free the decoded arguments */ + (void)svc_freeargs(transp, pl->p_inproc, xdrbuf); + return; + } + (void) fprintf(stderr, "never registered prog %d\n", prog); + exit(1); +} + diff --git a/sunrpc/svc_tcp.c b/sunrpc/svc_tcp.c new file mode 100644 index 0000000000..587e0f0d9b --- /dev/null +++ b/sunrpc/svc_tcp.c @@ -0,0 +1,419 @@ +/* @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_tcp.c, Server side for TCP/IP based RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Actually implements two flavors of transporter - + * a tcp rendezvouser (a listner and connection establisher) + * and a record/tcp stream. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <errno.h> +extern bool_t abort(); +extern errno; + +/* + * Ops vector for TCP/IP based rpc service handle + */ +static bool_t svctcp_recv(); +static enum xprt_stat svctcp_stat(); +static bool_t svctcp_getargs(); +static bool_t svctcp_reply(); +static bool_t svctcp_freeargs(); +static void svctcp_destroy(); + +static struct xp_ops svctcp_op = { + svctcp_recv, + svctcp_stat, + svctcp_getargs, + svctcp_reply, + svctcp_freeargs, + svctcp_destroy +}; + +/* + * Ops vector for TCP/IP rendezvous handler + */ +static bool_t rendezvous_request(); +static enum xprt_stat rendezvous_stat(); + +static struct xp_ops svctcp_rendezvous_op = { + rendezvous_request, + rendezvous_stat, + abort, + abort, + abort, + svctcp_destroy +}; + +static int readtcp(), writetcp(); +static SVCXPRT *makefd_xprt(); + +struct tcp_rendezvous { /* kept in xprt->xp_p1 */ + u_int sendsize; + u_int recvsize; +}; + +struct tcp_conn { /* kept in xprt->xp_p1 */ + enum xprt_stat strm_stat; + u_long x_id; + XDR xdrs; + char verf_body[MAX_AUTH_BYTES]; +}; + +/* + * Usage: + * xprt = svctcp_create(sock, send_buf_size, recv_buf_size); + * + * Creates, registers, and returns a (rpc) tcp based transporter. + * Once *xprt is initialized, it is registered as a transporter + * see (svc.h, xprt_register). This routine returns + * a NULL if a problem occurred. + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svctcp_create + * binds it to an arbitrary port. The routine then starts a tcp + * listener on the socket's associated port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * + * Since tcp streams do buffered io similar to stdio, the caller can specify + * how big the send and receive buffers are via the second and third parms; + * 0 => use the system default. + */ +SVCXPRT * +svctcp_create(sock, sendsize, recvsize) + register int sock; + u_int sendsize; + u_int recvsize; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("svctcp_.c - udp socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) || + (listen(sock, 2) != 0)) { + perror("svctcp_.c - cannot getsockname or listen"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r)); + if (r == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + r->sendsize = sendsize; + r->recvsize = recvsize; + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)r; + xprt->xp_verf = _null_auth; + xprt->xp_ops = &svctcp_rendezvous_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +/* + * Like svtcp_create(), except the routine takes any *open* UNIX file + * descriptor as its first input. + */ +SVCXPRT * +svcfd_create(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + + return (makefd_xprt(fd, sendsize, recvsize)); +} + +static SVCXPRT * +makefd_xprt(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + register SVCXPRT *xprt; + register struct tcp_conn *cd; + + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == (SVCXPRT *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + goto done; + } + cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn)); + if (cd == (struct tcp_conn *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + mem_free((char *) xprt, sizeof(SVCXPRT)); + xprt = (SVCXPRT *)NULL; + goto done; + } + cd->strm_stat = XPRT_IDLE; + xdrrec_create(&(cd->xdrs), sendsize, recvsize, + (caddr_t)xprt, readtcp, writetcp); + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)cd; + xprt->xp_verf.oa_base = cd->verf_body; + xprt->xp_addrlen = 0; + xprt->xp_ops = &svctcp_op; /* truely deals with calls */ + xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ + xprt->xp_sock = fd; + xprt_register(xprt); + done: + return (xprt); +} + +static bool_t +rendezvous_request(xprt) + register SVCXPRT *xprt; +{ + int sock; + struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len; + + r = (struct tcp_rendezvous *)xprt->xp_p1; + again: + len = sizeof(struct sockaddr_in); + if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, + &len)) < 0) { + if (errno == EINTR) + goto again; + return (FALSE); + } + /* + * make a new transporter (re-uses xprt) + */ + xprt = makefd_xprt(sock, r->sendsize, r->recvsize); + xprt->xp_raddr = addr; + xprt->xp_addrlen = len; + return (FALSE); /* there is never an rpc msg to be processed */ +} + +static enum xprt_stat +rendezvous_stat() +{ + + return (XPRT_IDLE); +} + +static void +svctcp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1; + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + if (xprt->xp_port != 0) { + /* a rendezvouser socket */ + xprt->xp_port = 0; + } else { + /* an actual connection socket */ + XDR_DESTROY(&(cd->xdrs)); + } + mem_free((caddr_t)cd, sizeof(struct tcp_conn)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + +/* + * All read operations timeout after 35 seconds. + * A timeout is fatal for the connection. + */ +static struct timeval wait_per_try = { 35, 0 }; + +/* + * reads data from the tcp conection. + * any error is fatal and the connection is closed. + * (And a read of zero bytes is a half closed stream => error.) + */ +static int +readtcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + register int len; +{ + register int sock = xprt->xp_sock; +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; + + FD_ZERO(&mask); + FD_SET(sock, &mask); +#else + register int mask = 1 << sock; + int readfds; +#endif /* def FD_SETSIZE */ + do { + readfds = mask; + if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, + &wait_per_try) <= 0) { + if (errno == EINTR) { + continue; + } + goto fatal_err; + } +#ifdef FD_SETSIZE + } while (!FD_ISSET(sock, &readfds)); +#else + } while (readfds != mask); +#endif /* def FD_SETSIZE */ + if ((len = read(sock, buf, len)) > 0) { + return (len); + } +fatal_err: + ((struct tcp_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 +writetcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(xprt->xp_sock, buf, cnt)) < 0) { + ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = + XPRT_DIED; + return (-1); + } + } + return (len); +} + +static enum xprt_stat +svctcp_stat(xprt) + SVCXPRT *xprt; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + + if (cd->strm_stat == XPRT_DIED) + return (XPRT_DIED); + if (! xdrrec_eof(&(cd->xdrs))) + return (XPRT_MOREREQS); + return (XPRT_IDLE); +} + +static bool_t +svctcp_recv(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + + xdrs->x_op = XDR_DECODE; + (void)xdrrec_skiprecord(xdrs); + if (xdr_callmsg(xdrs, msg)) { + cd->x_id = msg->rm_xid; + return (TRUE); + } + return (FALSE); +} + +static bool_t +svctcp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr)); +} + +static bool_t +svctcp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = + &(((struct tcp_conn *)(xprt->xp_p1))->xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static bool_t +svctcp_reply(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + register bool_t stat; + + xdrs->x_op = XDR_ENCODE; + msg->rm_xid = cd->x_id; + stat = xdr_replymsg(xdrs, msg); + (void)xdrrec_endofrecord(xdrs, TRUE); + return (stat); +} diff --git a/sunrpc/svc_udp.c b/sunrpc/svc_udp.c new file mode 100644 index 0000000000..69ef7a1ce3 --- /dev/null +++ b/sunrpc/svc_udp.c @@ -0,0 +1,475 @@ +/* @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_udp.c, + * Server side for UDP/IP based RPC. (Does some caching in the hopes of + * achieving execute-at-most-once semantics.) + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <errno.h> + + +#define rpc_buffer(xprt) ((xprt)->xp_p1) +#define MAX(a, b) ((a > b) ? a : b) + +static bool_t svcudp_recv(); +static bool_t svcudp_reply(); +static enum xprt_stat svcudp_stat(); +static bool_t svcudp_getargs(); +static bool_t svcudp_freeargs(); +static void svcudp_destroy(); + +static struct xp_ops svcudp_op = { + svcudp_recv, + svcudp_stat, + svcudp_getargs, + svcudp_reply, + svcudp_freeargs, + svcudp_destroy +}; + +extern int errno; + +/* + * kept in xprt->xp_p2 + */ +struct svcudp_data { + u_int su_iosz; /* byte size of send.recv buffer */ + u_long su_xid; /* transaction id */ + XDR su_xdrs; /* XDR handle */ + char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ + char * su_cache; /* cached data, NULL if no cache */ +}; +#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) + +/* + * Usage: + * xprt = svcudp_create(sock); + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svcudp_create + * binds it to an arbitrary port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * Once *xprt is initialized, it is registered as a transporter; + * see (svc.h, xprt_register). + * The routines returns NULL if a problem occurred. + */ +SVCXPRT * +svcudp_bufcreate(sock, sendsz, recvsz) + register int sock; + u_int sendsz, recvsz; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct svcudp_data *su; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("svcudp_create: socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) { + perror("svcudp_create - cannot getsockname"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su = (struct svcudp_data *)mem_alloc(sizeof(*su)); + if (su == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; + if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + xdrmem_create( + &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); + su->su_cache = NULL; + xprt->xp_p2 = (caddr_t)su; + xprt->xp_verf.oa_base = su->su_verfbody; + xprt->xp_ops = &svcudp_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +SVCXPRT * +svcudp_create(sock) + int sock; +{ + + return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum xprt_stat +svcudp_stat(xprt) + SVCXPRT *xprt; +{ + + return (XPRT_IDLE); +} + +static bool_t +svcudp_recv(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int rlen; + char *reply; + u_long replylen; + + again: + xprt->xp_addrlen = sizeof(struct sockaddr_in); + rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, + 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); + if (rlen == -1 && errno == EINTR) + goto again; + if (rlen < 4*sizeof(u_long)) + return (FALSE); + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + su->su_xid = msg->rm_xid; + if (su->su_cache != NULL) { + if (cache_get(xprt, msg, &reply, &replylen)) { + (void) sendto(xprt->xp_sock, reply, (int) replylen, 0, + (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); + return (TRUE); + } + } + return (TRUE); +} + +static bool_t +svcudp_reply(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int slen; + register bool_t stat = FALSE; + + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + msg->rm_xid = su->su_xid; + if (xdr_replymsg(xdrs, msg)) { + slen = (int)XDR_GETPOS(xdrs); + if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, + (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) + == slen) { + stat = TRUE; + if (su->su_cache && slen >= 0) { + cache_set(xprt, (u_long) slen); + } + } + } + return (stat); +} + +static bool_t +svcudp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); +} + +static bool_t +svcudp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = &(su_data(xprt)->su_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcudp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct svcudp_data *su = su_data(xprt); + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + XDR_DESTROY(&(su->su_xdrs)); + mem_free(rpc_buffer(xprt), su->su_iosz); + mem_free((caddr_t)su, sizeof(struct svcudp_data)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + + +/***********this could be a separate file*********************/ + +/* + * Fifo cache for udp server + * Copies pointers to reply buffers into fifo cache + * Buffers are sent again if retransmissions are detected. + */ + +#define SPARSENESS 4 /* 75% sparse */ + +#define CACHE_PERROR(msg) \ + (void) fprintf(stderr,"%s\n", msg) + +#define ALLOC(type, size) \ + (type *) mem_alloc((unsigned) (sizeof(type) * (size))) + +#define BZERO(addr, type, size) \ + bzero((char *) addr, sizeof(type) * (int) (size)) + +/* + * An entry in the cache + */ +typedef struct cache_node *cache_ptr; +struct cache_node { + /* + * Index into cache is xid, proc, vers, prog and address + */ + u_long cache_xid; + u_long cache_proc; + u_long cache_vers; + u_long cache_prog; + struct sockaddr_in cache_addr; + /* + * The cached reply and length + */ + char * cache_reply; + u_long cache_replylen; + /* + * Next node on the list, if there is a collision + */ + cache_ptr cache_next; +}; + + + +/* + * The entire cache + */ +struct udp_cache { + u_long uc_size; /* size of cache */ + cache_ptr *uc_entries; /* hash table of entries in cache */ + cache_ptr *uc_fifo; /* fifo list of entries in cache */ + u_long uc_nextvictim; /* points to next victim in fifo list */ + u_long uc_prog; /* saved program number */ + u_long uc_vers; /* saved version number */ + u_long uc_proc; /* saved procedure number */ + struct sockaddr_in uc_addr; /* saved caller's address */ +}; + + +/* + * the hashing function + */ +#define CACHE_LOC(transp, xid) \ + (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size)) + + +/* + * Enable use of the cache. + * Note: there is no disable. + */ +svcudp_enablecache(transp, size) + SVCXPRT *transp; + u_long size; +{ + struct svcudp_data *su = su_data(transp); + struct udp_cache *uc; + + if (su->su_cache != NULL) { + CACHE_PERROR("enablecache: cache already enabled"); + return(0); + } + uc = ALLOC(struct udp_cache, 1); + if (uc == NULL) { + CACHE_PERROR("enablecache: could not allocate cache"); + return(0); + } + uc->uc_size = size; + uc->uc_nextvictim = 0; + uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS); + if (uc->uc_entries == NULL) { + CACHE_PERROR("enablecache: could not allocate cache data"); + return(0); + } + BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS); + uc->uc_fifo = ALLOC(cache_ptr, size); + if (uc->uc_fifo == NULL) { + CACHE_PERROR("enablecache: could not allocate cache fifo"); + return(0); + } + BZERO(uc->uc_fifo, cache_ptr, size); + su->su_cache = (char *) uc; + return(1); +} + + +/* + * Set an entry in the cache + */ +static +cache_set(xprt, replylen) + SVCXPRT *xprt; + u_long replylen; +{ + register cache_ptr victim; + register cache_ptr *vicp; + register struct svcudp_data *su = su_data(xprt); + struct udp_cache *uc = (struct udp_cache *) su->su_cache; + u_int loc; + char *newbuf; + + /* + * Find space for the new entry, either by + * reusing an old entry, or by mallocing a new one + */ + victim = uc->uc_fifo[uc->uc_nextvictim]; + if (victim != NULL) { + loc = CACHE_LOC(xprt, victim->cache_xid); + for (vicp = &uc->uc_entries[loc]; + *vicp != NULL && *vicp != victim; + vicp = &(*vicp)->cache_next) + ; + if (*vicp == NULL) { + CACHE_PERROR("cache_set: victim not found"); + return; + } + *vicp = victim->cache_next; /* remote from cache */ + newbuf = victim->cache_reply; + } else { + victim = ALLOC(struct cache_node, 1); + if (victim == NULL) { + CACHE_PERROR("cache_set: victim alloc failed"); + return; + } + newbuf = mem_alloc(su->su_iosz); + if (newbuf == NULL) { + CACHE_PERROR("cache_set: could not allocate new rpc_buffer"); + return; + } + } + + /* + * Store it away + */ + victim->cache_replylen = replylen; + victim->cache_reply = rpc_buffer(xprt); + rpc_buffer(xprt) = newbuf; + xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE); + victim->cache_xid = su->su_xid; + victim->cache_proc = uc->uc_proc; + victim->cache_vers = uc->uc_vers; + victim->cache_prog = uc->uc_prog; + victim->cache_addr = uc->uc_addr; + loc = CACHE_LOC(xprt, victim->cache_xid); + victim->cache_next = uc->uc_entries[loc]; + uc->uc_entries[loc] = victim; + uc->uc_fifo[uc->uc_nextvictim++] = victim; + uc->uc_nextvictim %= uc->uc_size; +} + +/* + * Try to get an entry from the cache + * return 1 if found, 0 if not found + */ +static +cache_get(xprt, msg, replyp, replylenp) + SVCXPRT *xprt; + struct rpc_msg *msg; + char **replyp; + u_long *replylenp; +{ + u_int loc; + register cache_ptr ent; + register struct svcudp_data *su = su_data(xprt); + register struct udp_cache *uc = (struct udp_cache *) su->su_cache; + +# define EQADDR(a1, a2) (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0) + + loc = CACHE_LOC(xprt, su->su_xid); + for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) { + if (ent->cache_xid == su->su_xid && + ent->cache_proc == uc->uc_proc && + ent->cache_vers == uc->uc_vers && + ent->cache_prog == uc->uc_prog && + EQADDR(ent->cache_addr, uc->uc_addr)) { + *replyp = ent->cache_reply; + *replylenp = ent->cache_replylen; + return(1); + } + } + /* + * Failed to find entry + * Remember a few things so we can do a set later + */ + uc->uc_proc = msg->rm_call.cb_proc; + uc->uc_vers = msg->rm_call.cb_vers; + uc->uc_prog = msg->rm_call.cb_prog; + uc->uc_addr = xprt->xp_raddr; + return(0); +} + diff --git a/sunrpc/xdr.c b/sunrpc/xdr.c new file mode 100644 index 0000000000..b8248c20b5 --- /dev/null +++ b/sunrpc/xdr.c @@ -0,0 +1,577 @@ +/* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr.c 1.35 87/08/12"; +#endif + +/* + * xdr.c, Generic XDR routines implementation. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + * + * These are the "generic" xdr routines used to serialize and de-serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> +char *malloc(); + +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * constants specific to the xdr "protocol" + */ +#define XDR_FALSE ((long) 0) +#define XDR_TRUE ((long) 1) +#define LASTUNSIGNED ((u_int) 0-1) + +/* + * for unit alignment + */ +static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; + +/* + * Free a data structure using XDR + * Not a filter, but a convenient utility nonetheless + */ +void +xdr_free(proc, objp) + xdrproc_t proc; + char *objp; +{ + XDR x; + + x.x_op = XDR_FREE; + (*proc)(&x, objp); +} + +/* + * XDR nothing + */ +bool_t +xdr_void(/* xdrs, addr */) + /* XDR *xdrs; */ + /* caddr_t addr; */ +{ + + return (TRUE); +} + +/* + * XDR integers + */ +bool_t +xdr_int(xdrs, ip) + XDR *xdrs; + int *ip; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)ip)); + return (xdr_long(xdrs, (long *)ip)); +#else + if (sizeof (int) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ip)); + } else { + return (xdr_short(xdrs, (short *)ip)); + } +#endif +} + +/* + * XDR unsigned integers + */ +bool_t +xdr_u_int(xdrs, up) + XDR *xdrs; + u_int *up; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)up)); + return (xdr_u_long(xdrs, (u_long *)up)); +#else + if (sizeof (u_int) == sizeof (u_long)) { + return (xdr_u_long(xdrs, (u_long *)up)); + } else { + return (xdr_short(xdrs, (short *)up)); + } +#endif +} + +/* + * XDR long integers + * same as xdr_u_long - open coded to save a proc call! + */ +bool_t +xdr_long(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_FREE) + return (TRUE); + + return (FALSE); +} + +/* + * XDR unsigned long integers + * same as xdr_long - open coded to save a proc call! + */ +bool_t +xdr_u_long(xdrs, ulp) + register XDR *xdrs; + u_long *ulp; +{ + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_FREE) + return (TRUE); + return (FALSE); +} + +/* + * XDR short integers + */ +bool_t +xdr_short(xdrs, sp) + register XDR *xdrs; + short *sp; +{ + long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (long) *sp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *sp = (short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR unsigned short integers + */ +bool_t +xdr_u_short(xdrs, usp) + register XDR *xdrs; + u_short *usp; +{ + u_long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (u_long) *usp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *usp = (u_short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + + +/* + * XDR a char + */ +bool_t +xdr_char(xdrs, cp) + XDR *xdrs; + char *cp; +{ + int i; + + i = (*cp); + if (!xdr_int(xdrs, &i)) { + return (FALSE); + } + *cp = i; + return (TRUE); +} + +/* + * XDR an unsigned char + */ +bool_t +xdr_u_char(xdrs, cp) + XDR *xdrs; + char *cp; +{ + u_int u; + + u = (*cp); + if (!xdr_u_int(xdrs, &u)) { + return (FALSE); + } + *cp = u; + return (TRUE); +} + +/* + * XDR booleans + */ +bool_t +xdr_bool(xdrs, bp) + register XDR *xdrs; + bool_t *bp; +{ + long lb; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + lb = *bp ? XDR_TRUE : XDR_FALSE; + return (XDR_PUTLONG(xdrs, &lb)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &lb)) { + return (FALSE); + } + *bp = (lb == XDR_FALSE) ? FALSE : TRUE; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR enumerations + */ +bool_t +xdr_enum(xdrs, ep) + XDR *xdrs; + enum_t *ep; +{ +#ifndef lint + enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ + + /* + * enums are treated as ints + */ + if (sizeof (enum sizecheck) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ep)); + } else if (sizeof (enum sizecheck) == sizeof (short)) { + return (xdr_short(xdrs, (short *)ep)); + } else { + return (FALSE); + } +#else + (void) (xdr_short(xdrs, (short *)ep)); + return (xdr_long(xdrs, (long *)ep)); +#endif +} + +/* + * XDR opaque data + * Allows the specification of a fixed size sequence of opaque bytes. + * cp points to the opaque object and cnt gives the byte length. + */ +bool_t +xdr_opaque(xdrs, cp, cnt) + register XDR *xdrs; + caddr_t cp; + register u_int cnt; +{ + register u_int rndup; + static crud[BYTES_PER_XDR_UNIT]; + + /* + * if no data we are done + */ + if (cnt == 0) + return (TRUE); + + /* + * round byte count to full xdr units + */ + rndup = cnt % BYTES_PER_XDR_UNIT; + if (rndup > 0) + rndup = BYTES_PER_XDR_UNIT - rndup; + + if (xdrs->x_op == XDR_DECODE) { + if (!XDR_GETBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_GETBYTES(xdrs, crud, rndup)); + } + + if (xdrs->x_op == XDR_ENCODE) { + if (!XDR_PUTBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); + } + + if (xdrs->x_op == XDR_FREE) { + return (TRUE); + } + + return (FALSE); +} + +/* + * XDR counted bytes + * *cpp is a pointer to the bytes, *sizep is the count. + * If *cpp is NULL maxsize bytes are allocated + */ +bool_t +xdr_bytes(xdrs, cpp, sizep, maxsize) + register XDR *xdrs; + char **cpp; + register u_int *sizep; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + register u_int nodesize; + + /* + * first deal with the length since xdr bytes are counted + */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + nodesize = *sizep; + if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) { + *cpp = sp = (char *)mem_alloc(nodesize); + } + if (sp == NULL) { + (void) fprintf(stderr, "xdr_bytes: out of memory\n"); + return (FALSE); + } + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, nodesize)); + + case XDR_FREE: + if (sp != NULL) { + mem_free(sp, nodesize); + *cpp = NULL; + } + return (TRUE); + } + return (FALSE); +} + +/* + * Implemented here due to commonality of the object. + */ +bool_t +xdr_netobj(xdrs, np) + XDR *xdrs; + struct netobj *np; +{ + + return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); +} + +/* + * XDR a descriminated union + * Support routine for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * an entry with a null procedure pointer. The routine gets + * the discriminant value and then searches the array of xdrdiscrims + * looking for that value. It calls the procedure given in the xdrdiscrim + * to handle the discriminant. If there is no specific routine a default + * routine may be called. + * If there is no specific or default routine an error is returned. + */ +bool_t +xdr_union(xdrs, dscmp, unp, choices, dfault) + register XDR *xdrs; + enum_t *dscmp; /* enum to decide which arm to work on */ + char *unp; /* the union itself */ + struct xdr_discrim *choices; /* [value, xdr proc] for each arm */ + xdrproc_t dfault; /* default xdr routine */ +{ + register enum_t dscm; + + /* + * we deal with the discriminator; it's an enum + */ + if (! xdr_enum(xdrs, dscmp)) { + return (FALSE); + } + dscm = *dscmp; + + /* + * search choices for a value that matches the discriminator. + * if we find one, execute the xdr routine for that value. + */ + for (; choices->proc != NULL_xdrproc_t; choices++) { + if (choices->value == dscm) + return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); + } + + /* + * no match - execute the default xdr routine if there is one + */ + return ((dfault == NULL_xdrproc_t) ? FALSE : + (*dfault)(xdrs, unp, LASTUNSIGNED)); +} + + +/* + * Non-portable xdr primitives. + * Care should be taken when moving these routines to new architectures. + */ + + +/* + * XDR null terminated ASCII strings + * xdr_string deals with "C strings" - arrays of bytes that are + * terminated by a NULL character. The parameter cpp references a + * pointer to storage; If the pointer is null, then the necessary + * storage is allocated. The last parameter is the max allowed length + * of the string as specified by a protocol. + */ +bool_t +xdr_string(xdrs, cpp, maxsize) + register XDR *xdrs; + char **cpp; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + u_int size; + u_int nodesize; + + /* + * first deal with the length since xdr strings are counted-strings + */ + switch (xdrs->x_op) { + case XDR_FREE: + if (sp == NULL) { + return(TRUE); /* already free */ + } + /* fall through... */ + case XDR_ENCODE: + size = strlen(sp); + break; + } + if (! xdr_u_int(xdrs, &size)) { + return (FALSE); + } + if (size > maxsize) { + return (FALSE); + } + nodesize = size + 1; + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) + *cpp = sp = (char *)mem_alloc(nodesize); + if (sp == NULL) { + (void) fprintf(stderr, "xdr_string: out of memory\n"); + return (FALSE); + } + sp[size] = 0; + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, size)); + + case XDR_FREE: + mem_free(sp, nodesize); + *cpp = NULL; + return (TRUE); + } + return (FALSE); +} + +/* + * Wrapper for xdr_string that can be called directly from + * routines like clnt_call + */ +bool_t +xdr_wrapstring(xdrs, cpp) + XDR *xdrs; + char **cpp; +{ + if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { + return (TRUE); + } + return (FALSE); +} diff --git a/sunrpc/xdr_array.c b/sunrpc/xdr_array.c new file mode 100644 index 0000000000..7c2831ccd2 --- /dev/null +++ b/sunrpc/xdr_array.c @@ -0,0 +1,153 @@ +/* @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_array.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * arrays. See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED ((u_int)0-1) + + +/* + * XDR an array of arbitrary elements + * *addrp is a pointer to the array, *sizep is the number of elements. + * If addrp is NULL (*sizep * elsize) bytes are allocated. + * elsize is the size (in bytes) of each element, and elproc is the + * xdr procedure to call to handle each element of the array. + */ +bool_t +xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc) + register XDR *xdrs; + caddr_t *addrp; /* array pointer */ + u_int *sizep; /* number of elements */ + u_int maxsize; /* max numberof elements */ + u_int elsize; /* size in bytes of each element */ + xdrproc_t elproc; /* xdr routine to handle each element */ +{ + register u_int i; + register caddr_t target = *addrp; + register u_int c; /* the actual element count */ + register bool_t stat = TRUE; + register u_int nodesize; + + /* like strings, arrays are really counted arrays */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + c = *sizep; + if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + nodesize = c * elsize; + + /* + * if we are deserializing, we may need to allocate an array. + * We also save time by checking for a null array if we are freeing. + */ + if (target == NULL) + switch (xdrs->x_op) { + case XDR_DECODE: + if (c == 0) + return (TRUE); + *addrp = target = mem_alloc(nodesize); + if (target == NULL) { + (void) fprintf(stderr, + "xdr_array: out of memory\n"); + return (FALSE); + } + bzero(target, nodesize); + break; + + case XDR_FREE: + return (TRUE); + } + + /* + * now we xdr each element of array + */ + for (i = 0; (i < c) && stat; i++) { + stat = (*elproc)(xdrs, target, LASTUNSIGNED); + target += elsize; + } + + /* + * the array may need freeing + */ + if (xdrs->x_op == XDR_FREE) { + mem_free(*addrp, nodesize); + *addrp = NULL; + } + return (stat); +} + +/* + * xdr_vector(): + * + * XDR a fixed length array. Unlike variable-length arrays, + * the storage of fixed length arrays is static and unfreeable. + * > basep: base of the array + * > size: size of the array + * > elemsize: size of each element + * > xdr_elem: routine to XDR each element + */ +bool_t +xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem) + register XDR *xdrs; + register char *basep; + register u_int nelem; + register u_int elemsize; + register xdrproc_t xdr_elem; +{ + register u_int i; + register char *elptr; + + elptr = basep; + for (i = 0; i < nelem; i++) { + if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) { + return(FALSE); + } + elptr += elemsize; + } + return(TRUE); +} + diff --git a/sunrpc/xdr_float.c b/sunrpc/xdr_float.c new file mode 100644 index 0000000000..549f8bd97b --- /dev/null +++ b/sunrpc/xdr_float.c @@ -0,0 +1,267 @@ +/* @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_float.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "floating point" xdr routines used to (de)serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * NB: Not portable. + * This routine works on Suns (Sky / 68000's) and Vaxen. + */ + +#ifdef vax + +/* What IEEE single precision floating point looks like on a Vax */ +struct ieee_single { + unsigned int mantissa: 23; + unsigned int exp : 8; + unsigned int sign : 1; +}; + +/* Vax single precision floating point */ +struct vax_single { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; +}; + +#define VAX_SNG_BIAS 0x81 +#define IEEE_SNG_BIAS 0x7f + +static struct sgl_limits { + struct vax_single s; + struct ieee_single ieee; +} sgl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ + { 0x0, 0xff, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ + { 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; +#endif /* vax */ + +bool_t +xdr_float(xdrs, fp) + register XDR *xdrs; + register float *fp; +{ +#ifdef vax + struct ieee_single is; + struct vax_single vs, *vsp; + struct sgl_limits *lim; + int i; +#endif + switch (xdrs->x_op) { + + case XDR_ENCODE: +#ifndef vax + return (XDR_PUTLONG(xdrs, (long *)fp)); +#else + vs = *((struct vax_single *)fp); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((vs.mantissa2 == lim->s.mantissa2) && + (vs.exp == lim->s.exp) && + (vs.mantissa1 == lim->s.mantissa1)) { + is = lim->ieee; + goto shipit; + } + } + is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; + is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; + shipit: + is.sign = vs.sign; + return (XDR_PUTLONG(xdrs, (long *)&is)); +#endif + + case XDR_DECODE: +#ifndef vax + return (XDR_GETLONG(xdrs, (long *)fp)); +#else + vsp = (struct vax_single *)fp; + if (!XDR_GETLONG(xdrs, (long *)&is)) + return (FALSE); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((is.exp == lim->ieee.exp) && + (is.mantissa == lim->ieee.mantissa)) { + *vsp = lim->s; + goto doneit; + } + } + vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; + vsp->mantissa2 = is.mantissa; + vsp->mantissa1 = (is.mantissa >> 16); + doneit: + vsp->sign = is.sign; + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * This routine works on Suns (Sky / 68000's) and Vaxen. + */ + +#ifdef vax +/* What IEEE double precision floating point looks like on a Vax */ +struct ieee_double { + unsigned int mantissa1 : 20; + unsigned int exp : 11; + unsigned int sign : 1; + unsigned int mantissa2 : 32; +}; + +/* Vax double precision floating point */ +struct vax_double { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; + unsigned int mantissa3 : 16; + unsigned int mantissa4 : 16; +}; + +#define VAX_DBL_BIAS 0x81 +#define IEEE_DBL_BIAS 0x3ff +#define MASK(nbits) ((1 << nbits) - 1) + +static struct dbl_limits { + struct vax_double d; + struct ieee_double ieee; +} dbl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ + { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ + { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; + +#endif /* vax */ + + +bool_t +xdr_double(xdrs, dp) + register XDR *xdrs; + double *dp; +{ + register long *lp; +#ifdef vax + struct ieee_double id; + struct vax_double vd; + register struct dbl_limits *lim; + int i; +#endif + + switch (xdrs->x_op) { + + case XDR_ENCODE: +#ifndef vax + lp = (long *)dp; +#else + vd = *((struct vax_double *)dp); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((vd.mantissa4 == lim->d.mantissa4) && + (vd.mantissa3 == lim->d.mantissa3) && + (vd.mantissa2 == lim->d.mantissa2) && + (vd.mantissa1 == lim->d.mantissa1) && + (vd.exp == lim->d.exp)) { + id = lim->ieee; + goto shipit; + } + } + id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; + id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); + id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | + (vd.mantissa3 << 13) | + ((vd.mantissa4 >> 3) & MASK(13)); + shipit: + id.sign = vd.sign; + lp = (long *)&id; +#endif + return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); + + case XDR_DECODE: +#ifndef vax + lp = (long *)dp; + return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp)); +#else + lp = (long *)&id; + if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp)) + return (FALSE); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((id.mantissa2 == lim->ieee.mantissa2) && + (id.mantissa1 == lim->ieee.mantissa1) && + (id.exp == lim->ieee.exp)) { + vd = lim->d; + goto doneit; + } + } + vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; + vd.mantissa1 = (id.mantissa1 >> 13); + vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | + (id.mantissa2 >> 29); + vd.mantissa3 = (id.mantissa2 >> 13); + vd.mantissa4 = (id.mantissa2 << 3); + doneit: + vd.sign = id.sign; + *dp = *((double *)&vd); + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} diff --git a/sunrpc/xdr_mem.c b/sunrpc/xdr_mem.c new file mode 100644 index 0000000000..558d369227 --- /dev/null +++ b/sunrpc/xdr_mem.c @@ -0,0 +1,184 @@ +/* @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_mem.h, XDR implementation using memory buffers. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * If you have some data to be interpreted as external data representation + * or to be converted to external data representation in a memory buffer, + * then this is the package for you. + * + */ + + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +static bool_t xdrmem_getlong(); +static bool_t xdrmem_putlong(); +static bool_t xdrmem_getbytes(); +static bool_t xdrmem_putbytes(); +static u_int xdrmem_getpos(); +static bool_t xdrmem_setpos(); +static long * xdrmem_inline(); +static void xdrmem_destroy(); + +static struct xdr_ops xdrmem_ops = { + xdrmem_getlong, + xdrmem_putlong, + xdrmem_getbytes, + xdrmem_putbytes, + xdrmem_getpos, + xdrmem_setpos, + xdrmem_inline, + xdrmem_destroy +}; + +/* + * The procedure xdrmem_create initializes a stream descriptor for a + * memory buffer. + */ +void +xdrmem_create(xdrs, addr, size, op) + register XDR *xdrs; + caddr_t addr; + u_int size; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; + xdrs->x_handy = size; +} + +static void +xdrmem_destroy(/*xdrs*/) + /*XDR *xdrs;*/ +{ +} + +static bool_t +xdrmem_getlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private)))); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_putlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *(long *)xdrs->x_private = (long)htonl((u_long)(*lp)); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_getbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +} + +static bool_t +xdrmem_putbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +} + +static u_int +xdrmem_getpos(xdrs) + register XDR *xdrs; +{ + + return ((u_int)xdrs->x_private - (u_int)xdrs->x_base); +} + +static bool_t +xdrmem_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register caddr_t newaddr = xdrs->x_base + pos; + register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; + + if ((long)newaddr > (long)lastaddr) + return (FALSE); + xdrs->x_private = newaddr; + xdrs->x_handy = (int)lastaddr - (int)newaddr; + return (TRUE); +} + +static long * +xdrmem_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + long *buf = 0; + + if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (long *) xdrs->x_private; + xdrs->x_private += len; + } + return (buf); +} diff --git a/sunrpc/xdr_rec.c b/sunrpc/xdr_rec.c new file mode 100644 index 0000000000..4d0d4ecfb3 --- /dev/null +++ b/sunrpc/xdr_rec.c @@ -0,0 +1,580 @@ +/* @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" + * layer above tcp (for rpc's use). + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These routines interface XDRSTREAMS to a tcp/ip connection. + * There is a record marking layer between the xdr stream + * and the tcp transport level. A record is composed on one or more + * record fragments. A record fragment is a thirty-two bit header followed + * by n bytes of data, where n is contained in the header. The header + * is represented as a htonl(u_long). Thegh order bit encodes + * whether or not the fragment is the last fragment of the record + * (1 => fragment is last, 0 => more fragments to follow. + * The other 31 bits encode the byte length of the fragment. + */ + +#include <stdio.h> +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +extern long lseek(); + +static u_int fix_buf_size(); + +static bool_t xdrrec_getlong(); +static bool_t xdrrec_putlong(); +static bool_t xdrrec_getbytes(); +static bool_t xdrrec_putbytes(); +static u_int xdrrec_getpos(); +static bool_t xdrrec_setpos(); +static long * xdrrec_inline(); +static void xdrrec_destroy(); + +static struct xdr_ops xdrrec_ops = { + xdrrec_getlong, + xdrrec_putlong, + xdrrec_getbytes, + xdrrec_putbytes, + xdrrec_getpos, + xdrrec_setpos, + xdrrec_inline, + xdrrec_destroy +}; + +/* + * A record is composed of one or more record fragments. + * A record fragment is a two-byte header followed by zero to + * 2**32-1 bytes. The header is treated as a long unsigned and is + * encode/decoded to the network via htonl/ntohl. The low order 31 bits + * are a byte count of the fragment. The highest order bit is a boolean: + * 1 => this fragment is the last fragment of the record, + * 0 => this fragment is followed by more fragment(s). + * + * The fragment/record machinery is not general; it is constructed to + * meet the needs of xdr and rpc based on tcp. + */ + +#define LAST_FRAG ((u_long)(1 << 31)) + +typedef struct rec_strm { + caddr_t tcp_handle; + caddr_t the_buffer; + /* + * out-goung bits + */ + int (*writeit)(); + caddr_t out_base; /* output buffer (points to frag header) */ + caddr_t out_finger; /* next output position */ + caddr_t out_boundry; /* data cannot up to this address */ + u_long *frag_header; /* beginning of curren fragment */ + bool_t frag_sent; /* true if buffer sent in middle of record */ + /* + * in-coming bits + */ + int (*readit)(); + u_long in_size; /* fixed size of the input buffer */ + caddr_t in_base; + caddr_t in_finger; /* location of next byte to be had */ + caddr_t in_boundry; /* can read up to this location */ + long fbtbc; /* fragment bytes to be consumed */ + bool_t last_frag; + u_int sendsize; + u_int recvsize; +} RECSTREAM; + + +/* + * Create an xdr handle for xdrrec + * xdrrec_create fills in xdrs. Sendsize and recvsize are + * send and recv buffer sizes (0 => use default). + * tcp_handle is an opaque handle that is passed as the first parameter to + * the procedures readit and writeit. Readit and writeit are read and + * write respectively. They are like the system + * calls expect that they take an opaque handle rather than an fd. + */ +void +xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit) + register XDR *xdrs; + register u_int sendsize; + register u_int recvsize; + caddr_t tcp_handle; + int (*readit)(); /* like read, but pass it a tcp_handle, not sock */ + int (*writeit)(); /* like write, but pass it a tcp_handle, not sock */ +{ + register RECSTREAM *rstrm = + (RECSTREAM *)mem_alloc(sizeof(RECSTREAM)); + + if (rstrm == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + /* + * This is bad. Should rework xdrrec_create to + * return a handle, and in this case return NULL + */ + return; + } + /* + * adjust sizes and allocate buffer quad byte aligned + */ + rstrm->sendsize = sendsize = fix_buf_size(sendsize); + rstrm->recvsize = recvsize = fix_buf_size(recvsize); + rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); + if (rstrm->the_buffer == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + return; + } + for (rstrm->out_base = rstrm->the_buffer; + (u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; + rstrm->out_base++); + rstrm->in_base = rstrm->out_base + sendsize; + /* + * now the rest ... + */ + xdrs->x_ops = &xdrrec_ops; + xdrs->x_private = (caddr_t)rstrm; + rstrm->tcp_handle = tcp_handle; + rstrm->readit = readit; + rstrm->writeit = writeit; + rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger += sizeof(u_long); + rstrm->out_boundry += sendsize; + rstrm->frag_sent = FALSE; + rstrm->in_size = recvsize; + rstrm->in_boundry = rstrm->in_base; + rstrm->in_finger = (rstrm->in_boundry += recvsize); + rstrm->fbtbc = 0; + rstrm->last_frag = TRUE; +} + + +/* + * The reoutines defined below are the xdr ops which will go into the + * xdr handle filled in by xdrrec_create. + */ + +static bool_t +xdrrec_getlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *buflp = (long *)(rstrm->in_finger); + long mylong; + + /* first try the inline, fast case */ + if ((rstrm->fbtbc >= sizeof(long)) && + (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) { + *lp = (long)ntohl((u_long)(*buflp)); + rstrm->fbtbc -= sizeof(long); + rstrm->in_finger += sizeof(long); + } else { + if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long))) + return (FALSE); + *lp = (long)ntohl((u_long)mylong); + } + return (TRUE); +} + +static bool_t +xdrrec_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *dest_lp = ((long *)(rstrm->out_finger)); + + if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) { + /* + * this case should almost never happen so the code is + * inefficient + */ + rstrm->out_finger -= sizeof(long); + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + dest_lp = ((long *)(rstrm->out_finger)); + rstrm->out_finger += sizeof(long); + } + *dest_lp = (long)htonl((u_long)(*lp)); + return (TRUE); +} + +static bool_t /* must manage buffers, fragments, and records */ +xdrrec_getbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = rstrm->fbtbc; + if (current == 0) { + if (rstrm->last_frag) + return (FALSE); + if (! set_input_fragment(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + if (! get_input_bytes(rstrm, addr, current)) + return (FALSE); + addr += current; + rstrm->fbtbc -= current; + len -= current; + } + return (TRUE); +} + +static bool_t +xdrrec_putbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger; + current = (len < current) ? len : current; + bcopy(addr, rstrm->out_finger, current); + rstrm->out_finger += current; + addr += current; + len -= current; + if (rstrm->out_finger == rstrm->out_boundry) { + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + } + } + return (TRUE); +} + +static u_int +xdrrec_getpos(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + register long pos; + + pos = lseek((int)rstrm->tcp_handle, (long) 0, 1); + if (pos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + pos += rstrm->out_finger - rstrm->out_base; + break; + + case XDR_DECODE: + pos -= rstrm->in_boundry - rstrm->in_finger; + break; + + default: + pos = (u_int) -1; + break; + } + return ((u_int) pos); +} + +static bool_t +xdrrec_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + u_int currpos = xdrrec_getpos(xdrs); + int delta = currpos - pos; + caddr_t newpos; + + if ((int)currpos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + newpos = rstrm->out_finger - delta; + if ((newpos > (caddr_t)(rstrm->frag_header)) && + (newpos < rstrm->out_boundry)) { + rstrm->out_finger = newpos; + return (TRUE); + } + break; + + case XDR_DECODE: + newpos = rstrm->in_finger - delta; + if ((delta < (int)(rstrm->fbtbc)) && + (newpos <= rstrm->in_boundry) && + (newpos >= rstrm->in_base)) { + rstrm->in_finger = newpos; + rstrm->fbtbc -= delta; + return (TRUE); + } + break; + } + return (FALSE); +} + +static long * +xdrrec_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + long * buf = NULL; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + if ((rstrm->out_finger + len) <= rstrm->out_boundry) { + buf = (long *) rstrm->out_finger; + rstrm->out_finger += len; + } + break; + + case XDR_DECODE: + if ((len <= rstrm->fbtbc) && + ((rstrm->in_finger + len) <= rstrm->in_boundry)) { + buf = (long *) rstrm->in_finger; + rstrm->fbtbc -= len; + rstrm->in_finger += len; + } + break; + } + return (buf); +} + +static void +xdrrec_destroy(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + + mem_free(rstrm->the_buffer, + rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); + mem_free((caddr_t)rstrm, sizeof(RECSTREAM)); +} + + +/* + * Exported routines to manage xdr records + */ + +/* + * Before reading (deserializing from the stream, one should always call + * this procedure to guarantee proper record alignment. + */ +bool_t +xdrrec_skiprecord(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (FALSE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (FALSE); + } + rstrm->last_frag = FALSE; + return (TRUE); +} + +/* + * Look ahead fuction. + * Returns TRUE iff there is no more input in the buffer + * after consuming the rest of the current record. + */ +bool_t +xdrrec_eof(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (TRUE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (TRUE); + } + if (rstrm->in_finger == rstrm->in_boundry) + return (TRUE); + return (FALSE); +} + +/* + * The client must tell the package when an end-of-record has occurred. + * The second paraemters tells whether the record should be flushed to the + * (output) tcp stream. (This let's the package support batched or + * pipelined procedure calls.) TRUE => immmediate flush to tcp connection. + */ +bool_t +xdrrec_endofrecord(xdrs, sendnow) + XDR *xdrs; + bool_t sendnow; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register u_long len; /* fragment length */ + + if (sendnow || rstrm->frag_sent || + ((u_long)rstrm->out_finger + sizeof(u_long) >= + (u_long)rstrm->out_boundry)) { + rstrm->frag_sent = FALSE; + return (flush_out(rstrm, TRUE)); + } + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - + sizeof(u_long); + *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG); + rstrm->frag_header = (u_long *)rstrm->out_finger; + rstrm->out_finger += sizeof(u_long); + return (TRUE); +} + + +/* + * Internal useful routines + */ +static bool_t +flush_out(rstrm, eor) + register RECSTREAM *rstrm; + bool_t eor; +{ + register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0; + register u_long len = (u_long)(rstrm->out_finger) - + (u_long)(rstrm->frag_header) - sizeof(u_long); + + *(rstrm->frag_header) = htonl(len | eormask); + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base); + if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len) + != (int)len) + return (FALSE); + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long); + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +fill_input_buf(rstrm) + register RECSTREAM *rstrm; +{ + register caddr_t where; + u_int i; + register int len; + + where = rstrm->in_base; + i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT; + where += i; + len = rstrm->in_size - i; + if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) + return (FALSE); + rstrm->in_finger = where; + where += len; + rstrm->in_boundry = where; + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +get_input_bytes(rstrm, addr, len) + register RECSTREAM *rstrm; + register caddr_t addr; + register int len; +{ + register int current; + + while (len > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + bcopy(rstrm->in_finger, addr, current); + rstrm->in_finger += current; + addr += current; + len -= current; + } + return (TRUE); +} + +static bool_t /* next two bytes of the input stream are treated as a header */ +set_input_fragment(rstrm) + register RECSTREAM *rstrm; +{ + u_long header; + + if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header))) + return (FALSE); + header = (long)ntohl(header); + rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE; + rstrm->fbtbc = header & (~LAST_FRAG); + return (TRUE); +} + +static bool_t /* consumes input bytes; knows nothing about records! */ +skip_input_bytes(rstrm, cnt) + register RECSTREAM *rstrm; + long cnt; +{ + register int current; + + while (cnt > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (cnt < current) ? cnt : current; + rstrm->in_finger += current; + cnt -= current; + } + return (TRUE); +} + +static u_int +fix_buf_size(s) + register u_int s; +{ + + if (s < 100) + s = 4000; + return (RNDUP(s)); +} diff --git a/sunrpc/xdr_ref.c b/sunrpc/xdr_ref.c new file mode 100644 index 0000000000..32d91d9999 --- /dev/null +++ b/sunrpc/xdr_ref.c @@ -0,0 +1,132 @@ +/* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI"; +#endif + +/* + * xdr_reference.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1987, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * "pointers". See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED ((u_int)0-1) + +/* + * XDR an indirect pointer + * xdr_reference is for recursively translating a structure that is + * referenced by a pointer inside the structure that is currently being + * translated. pp references a pointer to storage. If *pp is null + * the necessary storage is allocated. + * size is the sizeof the referneced structure. + * proc is the routine to handle the referenced structure. + */ +bool_t +xdr_reference(xdrs, pp, size, proc) + register XDR *xdrs; + caddr_t *pp; /* the pointer to work on */ + u_int size; /* size of the object pointed to */ + xdrproc_t proc; /* xdr routine to handle the object */ +{ + register caddr_t loc = *pp; + register bool_t stat; + + if (loc == NULL) + switch (xdrs->x_op) { + case XDR_FREE: + return (TRUE); + + case XDR_DECODE: + *pp = loc = (caddr_t) mem_alloc(size); + if (loc == NULL) { + (void) fprintf(stderr, + "xdr_reference: out of memory\n"); + return (FALSE); + } + bzero(loc, (int)size); + break; + } + + stat = (*proc)(xdrs, loc, LASTUNSIGNED); + + if (xdrs->x_op == XDR_FREE) { + mem_free(loc, size); + *pp = NULL; + } + return (stat); +} + + +/* + * xdr_pointer(): + * + * XDR a pointer to a possibly recursive data structure. This + * differs with xdr_reference in that it can serialize/deserialiaze + * trees correctly. + * + * What's sent is actually a union: + * + * union object_pointer switch (boolean b) { + * case TRUE: object_data data; + * case FALSE: void nothing; + * } + * + * > objpp: Pointer to the pointer to the object. + * > obj_size: size of the object. + * > xdr_obj: routine to XDR an object. + * + */ +bool_t +xdr_pointer(xdrs,objpp,obj_size,xdr_obj) + register XDR *xdrs; + char **objpp; + u_int obj_size; + xdrproc_t xdr_obj; +{ + + bool_t more_data; + + more_data = (*objpp != NULL); + if (! xdr_bool(xdrs,&more_data)) { + return (FALSE); + } + if (! more_data) { + *objpp = NULL; + return (TRUE); + } + return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); +} diff --git a/sunrpc/xdr_stdio.c b/sunrpc/xdr_stdio.c new file mode 100644 index 0000000000..694774f6f6 --- /dev/null +++ b/sunrpc/xdr_stdio.c @@ -0,0 +1,189 @@ +/* @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * 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(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_stdio.c, XDR implementation on standard i/o file. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements a XDR on a stdio stream. + * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes + * from the stream. + */ + +#include <rpc/types.h> +#include <stdio.h> +#include <rpc/xdr.h> + +static bool_t xdrstdio_getlong(); +static bool_t xdrstdio_putlong(); +static bool_t xdrstdio_getbytes(); +static bool_t xdrstdio_putbytes(); +static u_int xdrstdio_getpos(); +static bool_t xdrstdio_setpos(); +static long * xdrstdio_inline(); +static void xdrstdio_destroy(); + +/* + * Ops vector for stdio type XDR + */ +static struct xdr_ops xdrstdio_ops = { + xdrstdio_getlong, /* deseraialize a long int */ + xdrstdio_putlong, /* seraialize a long int */ + xdrstdio_getbytes, /* deserialize counted bytes */ + xdrstdio_putbytes, /* serialize counted bytes */ + xdrstdio_getpos, /* get offset in the stream */ + xdrstdio_setpos, /* set offset in the stream */ + xdrstdio_inline, /* prime stream for inline macros */ + xdrstdio_destroy /* destroy stream */ +}; + +/* + * Initialize a stdio xdr stream. + * Sets the xdr stream handle xdrs for use on the stream file. + * Operation flag is set to op. + */ +void +xdrstdio_create(xdrs, file, op) + register XDR *xdrs; + FILE *file; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrstdio_ops; + xdrs->x_private = (caddr_t)file; + xdrs->x_handy = 0; + xdrs->x_base = 0; +} + +/* + * Destroy a stdio xdr stream. + * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. + */ +static void +xdrstdio_destroy(xdrs) + register XDR *xdrs; +{ + (void)fflush((FILE *)xdrs->x_private); + /* xx should we close the file ?? */ +}; + +static bool_t +xdrstdio_getlong(xdrs, lp) + XDR *xdrs; + register long *lp; +{ + + if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); +#ifndef mc68000 + *lp = ntohl(*lp); +#endif + return (TRUE); +} + +static bool_t +xdrstdio_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + +#ifndef mc68000 + long mycopy = htonl(*lp); + lp = &mycopy; +#endif + if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_getbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_putbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static u_int +xdrstdio_getpos(xdrs) + XDR *xdrs; +{ + + return ((u_int) ftell((FILE *)xdrs->x_private)); +} + +static bool_t +xdrstdio_setpos(xdrs, pos) + XDR *xdrs; + u_int pos; +{ + + return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ? + FALSE : TRUE); +} + +static long * +xdrstdio_inline(xdrs, len) + XDR *xdrs; + u_int len; +{ + + /* + * Must do some work to implement this: must insure + * enough data in the underlying stdio buffer, + * that the buffer is aligned so that we can indirect through a + * long *, and stuff this pointer in xdrs->x_buf. Doing + * a fread or fwrite to a scratch buffer would defeat + * most of the gains to be had here and require storage + * management on this buffer, so we don't do this. + */ + return (NULL); +} |