diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-06-17 21:12:16 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-06-17 21:12:16 +0000 |
commit | cdb3c81f36283df4b53f24a374d78c695e9d8b06 (patch) | |
tree | 9494bff7c98929e44c41dcdde32dc3fc6faf4330 /libc/inet | |
parent | 6ba832b158c91c6b35e1832220b3fc5ebf76333f (diff) |
Re-backport all the rpc stuff from glibc 2.2.5. This allows us to make this
junk (and I do mean that ;-) thread safe without undue pain. Adds 12k worth to
the code size I'm afraid, but since I never use NFS and therefore never include
this stuff, I guess thats acceptable. I still need to enable the multi-threaded
bits...
-Erik
Diffstat (limited to 'libc/inet')
45 files changed, 8139 insertions, 5018 deletions
diff --git a/libc/inet/rpc/Makefile b/libc/inet/rpc/Makefile index c27965ad9..3728c22a7 100644 --- a/libc/inet/rpc/Makefile +++ b/libc/inet/rpc/Makefile @@ -23,17 +23,19 @@ TOPDIR=../../../ include $(TOPDIR)Rules.mak - -CSRC = auth_none.c auth_unix.c authunix_prot.c \ - bindresvport.c clnt_generic.c clnt_perror.c \ - clnt_raw.c clnt_simple.c clnt_tcp.c clnt_udp.c \ - get_myaddress.c getrpcent.c getrpcport.c pmap_clnt.c \ - pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_prot2.c \ - pmap_rmt.c rpc_callmsg.c rpc_commondata.c \ - rpc_dtablesize.c rpc_prot.c svc.c svc_auth.c \ - svc_auth_unix.c svc_raw.c svc_run.c svc_simple.c \ - svc_tcp.c svc_udp.c xdr.c xdr_array.c xdr_float.c \ - xdr_mem.c xdr_rec.c xdr_reference.c xdr_stdio.c rcmd.c +#CFLAGS+=-Werror + +CSRC :=auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ + clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \ + clnt_udp.c rpc_dtablesize.c get_myaddress.c getrpcent.c getrpcport.c \ + pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c \ + pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c rpc_callmsg.c \ + svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_run.c svc_simple.c \ + svc_tcp.c svc_udp.c xdr.c xdr_array.c xdr_float.c xdr_mem.c \ + xdr_rec.c xdr_reference.c xdr_stdio.c \ + rtime.c clnt_unix.c svc_unix.c create_xid.c xdr_intXX_t.c rcmd.c \ + rpc_thread.c +#openchild.c xdr_sizeof.c COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(COBJS) diff --git a/libc/inet/rpc/auth_none.c b/libc/inet/rpc/auth_none.c index 08cc1940e..0983b9532 100644 --- a/libc/inet/rpc/auth_none.c +++ b/libc/inet/rpc/auth_none.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,120 +5,128 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> - +/* + * Copyright (C) 1984, Sun Microsystems, Inc. + */ /* * auth_none.c - * Creates a client authentication handle for passing "null" - * credentials and verifiers to remote systems. - * - * Copyright (C) 1984, Sun Microsystems, Inc. + * Creates a client authentication handle for passing "null" + * credentials and verifiers to remote systems. */ -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <rpc/auth.h> +#include <rpc/rpc.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 void authnone_verf (AUTH *); +static void authnone_destroy (AUTH *); +static bool_t authnone_marshal (AUTH *, XDR *); +static bool_t authnone_validate (AUTH *, struct opaque_auth *); +static bool_t authnone_refresh (AUTH *); static struct auth_ops ops = { - authnone_verf, - authnone_marshal, - authnone_validate, - authnone_refresh, - authnone_destroy + 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; +struct authnone_private_s { + AUTH no_client; + char marshalled_client[MAX_MARSHEL_SIZE]; + u_int mcnt; +}; +#ifdef _RPC_THREAD_SAFE_ +#define authnone_private ((struct authnone_private_s *)RPC_THREAD_VARIABLE(authnone_private_s)) +#else +static struct authnone_private_s *authnone_private; +#endif -AUTH *authnone_create() +AUTH * +authnone_create (void) { - register struct authnone_private *ap = authnone_private; - XDR xdr_stream; - register XDR *xdrs; + struct authnone_private_s *ap; + XDR xdr_stream; + 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); + ap = (struct authnone_private_s *) authnone_private; + if (ap == NULL) + { + ap = (struct authnone_private_s *) calloc (1, sizeof (*ap)); + if (ap == NULL) + return NULL; + 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; +/*ARGSUSED */ +static bool_t +authnone_marshal (AUTH *client, XDR *xdrs) { - register struct authnone_private *ap = authnone_private; + struct authnone_private_s *ap; - if (ap == 0) - return (0); - return ((*xdrs->x_ops->x_putbytes) (xdrs, - ap->marshalled_client, ap->mcnt)); + ap = (struct authnone_private_s *) authnone_private; + if (ap == NULL) + return FALSE; + return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt); } -static void authnone_verf() +static void +authnone_verf (AUTH *auth) { } -static bool_t authnone_validate() +static bool_t +authnone_validate (AUTH *auth, struct opaque_auth *oa) { - - return (TRUE); + return TRUE; } -static bool_t authnone_refresh() +static bool_t +authnone_refresh (AUTH *auth) { - - return (FALSE); + return FALSE; } -static void authnone_destroy() +static void +authnone_destroy (AUTH *auth) { } diff --git a/libc/inet/rpc/auth_unix.c b/libc/inet/rpc/auth_unix.c index 003763003..3e14ba2a5 100644 --- a/libc/inet/rpc/auth_unix.c +++ b/libc/inet/rpc/auth_unix.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,11 +5,11 @@ * 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. @@ -18,293 +17,309 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> - /* - * auth_unix.c, Implements UNIX style authentication parameters. - * * Copyright (C) 1984, Sun Microsystems, Inc. + */ +/* + * auth_unix.c, Implements UNIX style authentication parameters. * * 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. - * */ +#define __FORCE_GLIBC +#include <features.h> + +#include <limits.h> #include <stdio.h> -#include <unistd.h> -#include <sys/types.h> #include <string.h> +#include <unistd.h> +#include <sys/param.h> #include <rpc/types.h> #include <rpc/xdr.h> #include <rpc/auth.h> #include <rpc/auth_unix.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif + /* * 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 void authunix_nextverf (AUTH *); +static bool_t authunix_marshal (AUTH *, XDR *); +static bool_t authunix_validate (AUTH *, struct opaque_auth *); +static bool_t authunix_refresh (AUTH *); +static void authunix_destroy (AUTH *); static struct auth_ops auth_unix_ops = { - authunix_nextverf, - authunix_marshal, - authunix_validate, - authunix_refresh, - authunix_destroy + 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 */ + struct opaque_auth au_origcred; /* original credentials */ + struct opaque_auth au_shcred; /* short hand cred */ + u_long au_shfaults; /* short hand cache faults */ + char au_marshed[MAX_AUTH_BYTES]; + u_int au_mpos; /* xdr pos at end of marshed */ }; - #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) -static void marshal_new_auth(); +static bool_t marshal_new_auth (AUTH *) internal_function; /* * Create a unix style authenticator. * Returns an auth handle with the given stuff in it. */ -AUTH *authunix_create __P ((char *machname, uid_t uid, - gid_t gid, int len, - gid_t *aup_gids)) +AUTH * +authunix_create (char *machname, uid_t uid, gid_t gid, int len, + gid_t *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); - } + struct authunix_parms aup; + char mymem[MAX_AUTH_BYTES]; + struct timeval now; + XDR xdrs; + AUTH *auth; + struct audata *au; + + /* + * Allocate and set up auth handle + */ + auth = (AUTH *) mem_alloc (sizeof (*auth)); + au = (struct audata *) mem_alloc (sizeof (*au)); + if (auth == NULL || au == NULL) + { +no_memory: +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("authunix_create: out of memory\n")); + else #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); + (void) fputs (_("authunix_create: out of memory\n"), stderr); + mem_free (auth, sizeof (*auth)); + mem_free (au, sizeof (*au)); + return NULL; + } + 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; + au->au_origcred.oa_base = mem_alloc ((u_int) len); + if (au->au_origcred.oa_base == NULL) + goto no_memory; + memcpy(au->au_origcred.oa_base, mymem, (u_int) len); + + /* + * set auth handle to reflect new cred. + */ + auth->ah_cred = au->au_origcred; + marshal_new_auth (auth); + return auth; } /* * Returns an auth handle with parameters determined by doing lots of * syscalls. */ -AUTH *authunix_create_default() +AUTH * +authunix_create_default (void) { - 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)); + int len; + char machname[MAX_MACHINE_NAME + 1]; + uid_t uid; + gid_t gid; + int max_nr_groups = sysconf (_SC_NGROUPS_MAX); + gid_t gids[max_nr_groups]; + + if (gethostname (machname, MAX_MACHINE_NAME) == -1) + abort (); + machname[MAX_MACHINE_NAME] = 0; + uid = geteuid (); + gid = getegid (); + + if ((len = getgroups (max_nr_groups, gids)) < 0) + abort (); + /* This braindamaged Sun code forces us here to truncate the + list of groups to NGRPS members since the code in + authuxprot.c transforms a fixed array. Grrr. */ + return authunix_create (machname, uid, gid, MIN (NGRPS, len), gids); } /* * authunix operations */ -static void authunix_nextverf(auth) -AUTH *auth; +static void +authunix_nextverf (AUTH *auth) { - /* no action necessary */ + /* no action necessary */ } -static bool_t authunix_marshal(auth, xdrs) -AUTH *auth; -XDR *xdrs; +static bool_t +authunix_marshal (AUTH *auth, XDR *xdrs) { - register struct audata *au = AUTH_PRIVATE(auth); + struct audata *au = AUTH_PRIVATE (auth); - return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); + return XDR_PUTBYTES (xdrs, au->au_marshed, au->au_mpos); } -static bool_t authunix_validate(auth, verf) -register AUTH *auth; -struct opaque_auth verf; +static bool_t +authunix_validate (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); + 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; } - return (TRUE); + 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; +static bool_t +authunix_refresh (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); + struct audata *au = AUTH_PRIVATE (auth); + struct authunix_parms aup; + struct timeval now; + XDR xdrs; + 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 = (gid_t *) 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; +static void +authunix_destroy (AUTH *auth) { - register struct audata *au = AUTH_PRIVATE(auth); + struct audata *au = AUTH_PRIVATE (auth); - mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); + 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); + 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)); + 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); + 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)); + mem_free ((caddr_t) auth, sizeof (*auth)); } /* * Marshals (pre-serializes) an auth struct. * sets private data, au_marshed and au_mpos */ -static void marshal_new_auth(auth) -register AUTH *auth; +static bool_t +internal_function +marshal_new_auth (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); + XDR xdr_stream; + XDR *xdrs = &xdr_stream; + 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); + + return TRUE; } diff --git a/libc/inet/rpc/authunix_prot.c b/libc/inet/rpc/authunix_prot.c index e3ad64644..b033c568a 100644 --- a/libc/inet/rpc/authunix_prot.c +++ b/libc/inet/rpc/authunix_prot.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,38 +5,35 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> - +/* + * Copyright (C) 1984, Sun Microsystems, Inc. + */ /* * 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> @@ -45,19 +41,25 @@ /* * XDR for unix authentication parameters. + * Unfortunately, none of these can be declared const. */ -bool_t xdr_authunix_parms(xdrs, p) -register XDR *xdrs; -register struct authunix_parms *p; +bool_t +xdr_authunix_parms (XDR * xdrs, 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), (xdrproc_t) xdr_int)) { - return (TRUE); - } - return (FALSE); + if (xdr_u_long (xdrs, &(p->aup_time)) + && xdr_string (xdrs, &(p->aup_machname), MAX_MACHINE_NAME) + && (sizeof (uid_t) == sizeof (short int) + ? xdr_u_short (xdrs, (u_short *) & (p->aup_uid)) + : xdr_u_int (xdrs, (u_int *) & (p->aup_uid))) + && (sizeof (gid_t) == sizeof (short int) + ? xdr_u_short (xdrs, (u_short *) & (p->aup_gid)) + : xdr_u_int (xdrs, (u_int *) & (p->aup_gid))) + && xdr_array (xdrs, (caddr_t *) & (p->aup_gids), + & (p->aup_len), NGRPS, sizeof (gid_t), + (sizeof (gid_t) == sizeof (short int) + ? (xdrproc_t) xdr_u_short : (xdrproc_t) xdr_u_int))) + { + return TRUE; + } + return FALSE; } diff --git a/libc/inet/rpc/bindresvport.c b/libc/inet/rpc/bindresvport.c index 752360232..7dcebe7dc 100644 --- a/libc/inet/rpc/bindresvport.c +++ b/libc/inet/rpc/bindresvport.c @@ -5,77 +5,84 @@ * 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. */ #define __FORCE_GLIBC #include <features.h> + +#include <errno.h> #include <unistd.h> #include <string.h> #include <sys/types.h> -#include <sys/errno.h> #include <sys/socket.h> #include <netinet/in.h> /* * Bind a socket to a privileged IP port */ -int bindresvport(sd, sin) -int sd; -struct sockaddr_in *sin; +int +bindresvport (int sd, struct sockaddr_in *sin) { - int res; - static short port; - struct sockaddr_in myaddr; - extern int errno; - int i; + int res; + static short port; + struct sockaddr_in myaddr; + 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) { - __set_errno(EPFNOSUPPORT); - return (-1); - } - if (port == 0) { - port = (getpid() % NPORTS) + STARTPORT; - } - res = -1; - __set_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, (struct sockaddr *)sin, (socklen_t)sizeof(struct sockaddr_in)); + if (sin == (struct sockaddr_in *) 0) + { + sin = &myaddr; + bzero (sin, sizeof (*sin)); + sin->sin_family = AF_INET; + } + else if (sin->sin_family != AF_INET) + { + __set_errno (EPFNOSUPPORT); + return -1; + } + + if (port == 0) + { + port = (getpid () % NPORTS) + STARTPORT; + } + res = -1; + __set_errno (EADDRINUSE); + + for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; ++i) + { + sin->sin_port = htons (port++); + if (port > ENDPORT) + { + port = STARTPORT; } - return (res); + res = bind(sd, (struct sockaddr *)sin, sizeof(struct sockaddr_in)); + } + + return res; } diff --git a/libc/inet/rpc/clnt_generic.c b/libc/inet/rpc/clnt_generic.c index 5b4b5997f..79df33113 100644 --- a/libc/inet/rpc/clnt_generic.c +++ b/libc/inet/rpc/clnt_generic.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,11 +5,11 @@ * 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. @@ -18,20 +17,25 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> /* * Copyright (C) 1987, Sun Microsystems, Inc. */ + +#define __FORCE_GLIBC +#include <features.h> + +#include <alloca.h> +#include <errno.h> +#include <string.h> #include <rpc/rpc.h> #include <sys/socket.h> #include <sys/errno.h> @@ -39,72 +43,126 @@ /* * Generic client creation: takes (hostname, program-number, protocol) and - * returns client handle. Default options are set, which the user can + * returns client handle. Default options are set, which the user can * change using the rpc equivalent of ioctl()'s. */ -CLIENT *clnt_create __P ((const char *hostname, const u_long prog, - const u_long vers, const char *proto)) +CLIENT * +clnt_create (const char *hostname, u_long prog, u_long vers, + const char *proto) { - struct hostent *h; - struct protoent *p; - struct sockaddr_in sin; - int sock; - struct timeval tv; - CLIENT *client; + struct hostent hostbuf, *h; + size_t hstbuflen; + char *hsttmpbuf; + struct protoent *p; + struct sockaddr_in sin; + struct sockaddr_un sun; + int sock; + struct timeval tv; + CLIENT *client; + int herr; - 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); - } -#ifdef __linux__ - bzero((char *) &sin, sizeof(sin)); -#endif - sin.sin_family = h->h_addrtype; - sin.sin_port = 0; -#ifndef __linux__ - bzero(sin.sin_zero, sizeof(sin.sin_zero)); + if (strcmp (proto, "unix") == 0) + { + bzero ((char *)&sun, sizeof (sun)); + sun.sun_family = AF_UNIX; + strcpy (sun.sun_path, hostname); + sock = RPC_ANYSOCK; + client = clntunix_create (&sun, prog, vers, &sock, 0, 0); + if (client == NULL) + return NULL; +#if 0 + /* This is not wanted. This would disable the user from having + a timeout in the clnt_call() call. Only a call to cnlt_control() + by the user should set the timeout value. */ + tv.tv_sec = 25; + tv.tv_usec = 0; + clnt_control (client, CLSET_TIMEOUT, (char *)&tv); #endif - 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); + return client; + } + + hstbuflen = 1024; + hsttmpbuf = alloca (hstbuflen); + while (gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen, + &h, &herr) != 0 + || h == NULL) + if (herr != NETDB_INTERNAL || errno != ERANGE) + { + get_rpc_createerr().cf_stat = RPC_UNKNOWNHOST; + return NULL; + } + else + { + /* Enlarge the buffer. */ + hstbuflen *= 2; + hsttmpbuf = alloca (hstbuflen); + } + + if (h->h_addrtype != AF_INET) + { + /* + * Only support INET for now + */ + struct rpc_createerr *ce = &get_rpc_createerr (); + ce->cf_stat = RPC_SYSTEMERROR; + ce->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)); + memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length); + +#warning getprotobyname is not reentrant... Add getprotobyname_r + p = getprotobyname(proto); + if (p == NULL) { + struct rpc_createerr *ce = &get_rpc_createerr (); + ce->cf_stat = RPC_UNKNOWNPROTO; + ce->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; } - 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, (char*)&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, (char*)&tv); - break; - default: - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; - return (NULL); +#if 0 + /* This is not wanted. This would disable the user from having + a timeout in the clnt_call() call. Only a call to cnlt_control() + by the user should set the timeout value. */ + tv.tv_sec = 25; + clnt_control (client, CLSET_TIMEOUT, (char *)&tv); +#endif + break; + case IPPROTO_TCP: + client = clnttcp_create (&sin, prog, vers, &sock, 0, 0); + if (client == NULL) + { + return NULL; } - return (client); +#if 0 + /* This is not wanted. This would disable the user from having + a timeout in the clnt_call() call. Only a call to cnlt_control() + by the user should set the timeout value. */ + tv.tv_sec = 25; + tv.tv_usec = 0; + clnt_control (client, CLSET_TIMEOUT, (char *)&tv); +#endif + break; + default: + { + struct rpc_createerr *ce = &get_rpc_createerr (); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = EPFNOSUPPORT; + } + return (NULL); + } + return client; } diff --git a/libc/inet/rpc/clnt_perror.c b/libc/inet/rpc/clnt_perror.c index a4d173707..3d5e6b217 100644 --- a/libc/inet/rpc/clnt_perror.c +++ b/libc/inet/rpc/clnt_perror.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; +#endif /* * clnt_perror.c @@ -36,254 +37,396 @@ * Copyright (C) 1984, Sun Microsystems, Inc. * */ +#define __FORCE_GLIBC +#include <features.h> #include <stdio.h> #include <string.h> +#include <rpc/rpc.h> -#include <rpc/types.h> -#include <rpc/auth.h> -#include <rpc/clnt.h> - -static char *auth_errmsg(); +#ifdef USE_IN_LIBIO +# include <wchar.h> +# include <libio/iolibio.h> +# define fputs(s, f) _IO_fputs (s, f) +#endif -extern char *strcpy(); +static char *auth_errmsg (enum auth_stat stat) internal_function; +#ifdef _RPC_THREAD_SAFE_ +/* + * Making buf a preprocessor macro requires renaming the local + * buf variable in a few functions. Overriding a global variable + * with a local variable of the same name is a bad idea, anyway. + */ +#define buf ((char *)RPC_THREAD_VARIABLE(clnt_perr_buf_s)) +#else static char *buf; +#endif -static char *_buf() +static char * +_buf (void) { - - if (buf == 0) - buf = (char *) malloc(256); - return (buf); + if (buf == NULL) + buf = (char *) malloc (256); + return buf; } /* * Print reply error info */ -char *clnt_sperror __P ((CLIENT *rpch, const char *s)) +char * +clnt_sperror (CLIENT * rpch, const char *msg) { - 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", strerror (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; + char chrbuf[1024]; + struct rpc_err e; + char *err; + char *str = _buf (); + char *strstart = str; + int len; + + if (str == NULL) + return NULL; + CLNT_GETERR (rpch, &e); + + len = sprintf (str, "%s: ", msg); + str += len; + + (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: + strerror_r (e.re_errno, chrbuf, sizeof chrbuf); + len = sprintf (str, "; errno = %s", chrbuf); + str += len; + break; + + case RPC_VERSMISMATCH: + len= sprintf (str, _("; low version = %lu, high version = %lu"), + e.re_vers.low, e.re_vers.high); + str += len; + break; + + case RPC_AUTHERROR: + err = auth_errmsg (e.re_why); + (void) strcpy(str, _("; why = ")); + str += strlen(str); + + if (err != NULL) + { + (void) strcpy(str, err); + str += strlen(str); + } + else + { + len = sprintf (str, _("(unknown authentication error - %d)"), + (int) e.re_why); + str += len; } - (void) sprintf(str, "\n"); - return (strstart); + break; + + case RPC_PROGVERSMISMATCH: + len = sprintf (str, _("; low version = %lu, high version = %lu"), + e.re_vers.low, e.re_vers.high); + str += len; + break; + + default: /* unknown */ + len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2); + str += len; + break; + } + *str = '\n'; + *++str = '\0'; + return (strstart); } -void clnt_perror __P ((CLIENT *rpch, const char *s)) +void +clnt_perror (CLIENT * rpch, const char *msg) { - (void) fprintf(stderr, "%s", clnt_sperror(rpch, s)); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", clnt_sperror (rpch, msg)); + else +#endif + (void) fputs (clnt_sperror (rpch, msg), stderr); } -struct rpc_errtab { - enum clnt_stat status; - char *message; +struct rpc_errtab +{ + enum clnt_stat status; + unsigned int message_off; }; -#if 0 -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)"} +static const char rpc_errstr[] = +{ +#define RPC_SUCCESS_IDX 0 + _("RPC: Success") + "\0" +#define RPC_CANTENCODEARGS_IDX (RPC_SUCCESS_IDX + sizeof "RPC: Success") + _("RPC: Can't encode arguments") + "\0" +#define RPC_CANTDECODERES_IDX (RPC_CANTENCODEARGS_IDX \ + + sizeof "RPC: Can't encode arguments") + _("RPC: Can't decode result") + "\0" +#define RPC_CANTSEND_IDX (RPC_CANTDECODERES_IDX \ + + sizeof "RPC: Can't decode result") + _("RPC: Unable to send") + "\0" +#define RPC_CANTRECV_IDX (RPC_CANTSEND_IDX \ + + sizeof "RPC: Unable to send") + _("RPC: Unable to receive") + "\0" +#define RPC_TIMEDOUT_IDX (RPC_CANTRECV_IDX \ + + sizeof "RPC: Unable to receive") + _("RPC: Timed out") + "\0" +#define RPC_VERSMISMATCH_IDX (RPC_TIMEDOUT_IDX \ + + sizeof "RPC: Timed out") + _("RPC: Incompatible versions of RPC") + "\0" +#define RPC_AUTHERROR_IDX (RPC_VERSMISMATCH_IDX \ + + sizeof "RPC: Incompatible versions of RPC") + _("RPC: Authentication error") + "\0" +#define RPC_PROGUNAVAIL_IDX (RPC_AUTHERROR_IDX \ + + sizeof "RPC: Authentication error") + _("RPC: Program unavailable") + "\0" +#define RPC_PROGVERSMISMATCH_IDX (RPC_PROGUNAVAIL_IDX \ + + sizeof "RPC: Program unavailable") + _("RPC: Program/version mismatch") + "\0" +#define RPC_PROCUNAVAIL_IDX (RPC_PROGVERSMISMATCH_IDX \ + + sizeof "RPC: Program/version mismatch") + _("RPC: Procedure unavailable") + "\0" +#define RPC_CANTDECODEARGS_IDX (RPC_PROCUNAVAIL_IDX \ + + sizeof "RPC: Procedure unavailable") + _("RPC: Server can't decode arguments") + "\0" +#define RPC_SYSTEMERROR_IDX (RPC_CANTDECODEARGS_IDX \ + + sizeof "RPC: Server can't decode arguments") + _("RPC: Remote system error") + "\0" +#define RPC_UNKNOWNHOST_IDX (RPC_SYSTEMERROR_IDX \ + + sizeof "RPC: Remote system error") + _("RPC: Unknown host") + "\0" +#define RPC_UNKNOWNPROTO_IDX (RPC_UNKNOWNHOST_IDX \ + + sizeof "RPC: Unknown host") + _("RPC: Unknown protocol") + "\0" +#define RPC_PMAPFAILURE_IDX (RPC_UNKNOWNPROTO_IDX \ + + sizeof "RPC: Unknown protocol") + _("RPC: Port mapper failure") + "\0" +#define RPC_PROGNOTREGISTERED_IDX (RPC_PMAPFAILURE_IDX \ + + sizeof "RPC: Port mapper failure") + _("RPC: Program not registered") + "\0" +#define RPC_FAILED_IDX (RPC_PROGNOTREGISTERED_IDX \ + + sizeof "RPC: Program not registered") + _("RPC: Failed (unspecified error)") }; -#endif + +static const struct rpc_errtab rpc_errlist[] = +{ + { RPC_SUCCESS, RPC_SUCCESS_IDX }, + { RPC_CANTENCODEARGS, RPC_CANTENCODEARGS_IDX }, + { RPC_CANTDECODERES, RPC_CANTDECODERES_IDX }, + { RPC_CANTSEND, RPC_CANTSEND_IDX }, + { RPC_CANTRECV, RPC_CANTRECV_IDX }, + { RPC_TIMEDOUT, RPC_TIMEDOUT_IDX }, + { RPC_VERSMISMATCH, RPC_VERSMISMATCH_IDX }, + { RPC_AUTHERROR, RPC_AUTHERROR_IDX }, + { RPC_PROGUNAVAIL, RPC_PROGUNAVAIL_IDX }, + { RPC_PROGVERSMISMATCH, RPC_PROGVERSMISMATCH_IDX }, + { RPC_PROCUNAVAIL, RPC_PROCUNAVAIL_IDX }, + { RPC_CANTDECODEARGS, RPC_CANTDECODEARGS_IDX }, + { RPC_SYSTEMERROR, RPC_SYSTEMERROR_IDX }, + { RPC_UNKNOWNHOST, RPC_UNKNOWNHOST_IDX }, + { RPC_UNKNOWNPROTO, RPC_UNKNOWNPROTO_IDX }, + { RPC_PMAPFAILURE, RPC_PMAPFAILURE_IDX }, + { RPC_PROGNOTREGISTERED, RPC_PROGNOTREGISTERED_IDX }, + { RPC_FAILED, RPC_FAILED_IDX } +}; + /* * This interface for use by clntrpc */ -char *clnt_sperrno(stat) -enum clnt_stat stat; +char * +clnt_sperrno (enum clnt_stat stat) { -#if 0 - int i; + size_t i; - for (i = 0; i < sizeof(rpc_errlist) / sizeof(struct rpc_errtab); i++) { - if (rpc_errlist[i].status == stat) { - return (rpc_errlist[i].message); - } + for (i = 0; i < sizeof (rpc_errlist) / sizeof (struct rpc_errtab); i++) + { + if (rpc_errlist[i].status == stat) + { + return (char*)_(rpc_errstr + rpc_errlist[i].message_off); } -#endif - return ("RPC: (unknown error code)"); + } + return _("RPC: (unknown error code)"); } -void clnt_perrno(num) -enum clnt_stat num; +void +clnt_perrno (enum clnt_stat num) { - (void) fprintf(stderr, "%s", clnt_sperrno(num)); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", clnt_sperrno (num)); + else +#endif + (void) fputs (clnt_sperrno (num), stderr); } -char *clnt_spcreateerror __P ((__const char *s)) +char * +clnt_spcreateerror (const char *msg) { -#if 0 - 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) - (void) strcat(str, strerror (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); -#endif - return(0); + char chrbuf[1024]; + char *str = _buf (); + char *cp; + int len; + struct rpc_createerr *ce; + + if (str == NULL) + return NULL; + ce = &get_rpc_createerr (); + len = sprintf (str, "%s: ", msg); + cp = str + len; + (void) strcpy(cp, clnt_sperrno (ce->cf_stat)); + cp += strlen(cp); + + switch (ce->cf_stat) + { + case RPC_PMAPFAILURE: + (void) strcpy(cp, " - "); + cp += strlen(cp); + + (void) strcpy(cp, clnt_sperrno (ce->cf_error.re_status)); + cp += strlen(cp); + + break; + + case RPC_SYSTEMERROR: + (void) strcpy(cp, " - "); + cp += strlen(cp); + + strerror_r (ce->cf_error.re_errno, chrbuf, sizeof chrbuf); + (void) strcpy(cp, chrbuf); + cp += strlen(cp); + break; + default: + break; + } + *cp = '\n'; + *++cp = '\0'; + return str; } -extern void clnt_pcreateerror __P ((__const char *s)) +void +clnt_pcreateerror (const char *msg) { - (void) fprintf(stderr, "%s", clnt_spcreateerror(s)); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", clnt_spcreateerror (msg)); + else +#endif + (void) fputs (clnt_spcreateerror (msg), stderr); } -struct auth_errtab { - enum auth_stat status; - char *message; +struct auth_errtab +{ + enum auth_stat status; + unsigned int message_off; }; -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 const char auth_errstr[] = +{ +#define AUTH_OK_IDX 0 + _("Authentication OK") + "\0" +#define AUTH_BADCRED_IDX (AUTH_OK_IDX + sizeof "Authentication OK") + _("Invalid client credential") + "\0" +#define AUTH_REJECTEDCRED_IDX (AUTH_BADCRED_IDX \ + + sizeof "Invalid client credential") + _("Server rejected credential") + "\0" +#define AUTH_BADVERF_IDX (AUTH_REJECTEDCRED_IDX \ + + sizeof "Server rejected credential") + _("Invalid client verifier") + "\0" +#define AUTH_REJECTEDVERF_IDX (AUTH_BADVERF_IDX \ + + sizeof "Invalid client verifier") + _("Server rejected verifier") + "\0" +#define AUTH_TOOWEAK_IDX (AUTH_REJECTEDVERF_IDX \ + + sizeof "Server rejected verifier") + _("Client credential too weak") + "\0" +#define AUTH_INVALIDRESP_IDX (AUTH_TOOWEAK_IDX \ + + sizeof "Client credential too weak") + _("Invalid server verifier") + "\0" +#define AUTH_FAILED_IDX (AUTH_INVALIDRESP_IDX \ + + sizeof "Invalid server verifier") + _("Failed (unspecified error)") +}; + +static const struct auth_errtab auth_errlist[] = +{ + { AUTH_OK, AUTH_OK_IDX }, + { AUTH_BADCRED, AUTH_BADCRED_IDX }, + { AUTH_REJECTEDCRED, AUTH_REJECTEDCRED_IDX }, + { AUTH_BADVERF, AUTH_BADVERF_IDX }, + { AUTH_REJECTEDVERF, AUTH_REJECTEDVERF_IDX }, + { AUTH_TOOWEAK, AUTH_TOOWEAK_IDX }, + { AUTH_INVALIDRESP, AUTH_INVALIDRESP_IDX }, + { AUTH_FAILED, AUTH_FAILED_IDX } }; -static char *auth_errmsg(stat) -enum auth_stat stat; +static char * +internal_function +auth_errmsg (enum auth_stat stat) { - int i; + size_t i; - for (i = 0; i < sizeof(auth_errlist) / sizeof(struct auth_errtab); i++) { - if (auth_errlist[i].status == stat) { - return (auth_errlist[i].message); - } + for (i = 0; i < sizeof (auth_errlist) / sizeof (struct auth_errtab); i++) + { + if (auth_errlist[i].status == stat) + { + return (char*)_(auth_errstr + auth_errlist[i].message_off); } - return (NULL); + } + return NULL; +} + + +static void __attribute__ ((unused)) +free_mem (void) +{ + free (buf); } diff --git a/libc/inet/rpc/clnt_raw.c b/libc/inet/rpc/clnt_raw.c index b10db18b6..0d424523e 100644 --- a/libc/inet/rpc/clnt_raw.c +++ b/libc/inet/rpc/clnt_raw.c @@ -6,11 +6,11 @@ * 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. @@ -18,17 +18,18 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * clnt_raw.c @@ -37,193 +38,216 @@ * * 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. + * This lets us simulate rpc and get round trip overhead, without + * any interference from the kernel. */ #include <rpc/rpc.h> +#include <rpc/svc.h> +#include <rpc/xdr.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 +struct clntraw_private_s + { + CLIENT client_object; + XDR xdr_stream; + char _raw_buf[UDPMSGSIZE]; + char mashl_callmsg[MCALL_MSG_SIZE]; + u_int mcnt; + }; +#ifdef _RPC_THREAD_SAFE_ +#define clntraw_private ((struct clntraw_private_s *)RPC_THREAD_VARIABLE(clntraw_private_s)) +#else +static struct clntraw_private_s *clntraw_private; +#endif + +static enum clnt_stat clntraw_call (CLIENT *, u_long, xdrproc_t, caddr_t, + xdrproc_t, caddr_t, struct timeval); +static void clntraw_abort (void); +static void clntraw_geterr (CLIENT *, struct rpc_err *); +static bool_t clntraw_freeres (CLIENT *, xdrproc_t, caddr_t); +static bool_t clntraw_control (CLIENT *, int, char *); +static void clntraw_destroy (CLIENT *); + +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; +CLIENT * +clntraw_create (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); + struct clntraw_private_s *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_s *) calloc (1, sizeof (*clp)); + if (clp == 0) + return (0); + clntraw_private = clp; + } + /* + * pre-serialize the static part of the call msg and stash it away + */ + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + xdrmem_create (xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); + if (!xdr_callhdr (xdrs, &call_msg)) + { + perror (_ ("clnt_raw.c - Fatal header serialization error.")); + } + clp->mcnt = XDR_GETPOS (xdrs); + XDR_DESTROY (xdrs); + + /* + * Set xdrmem for client/server shared buffer + */ + xdrmem_create (xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); + + /* + * create client handle + */ + client->cl_ops = &client_ops; + client->cl_auth = authnone_create (); + return client; } static enum clnt_stat -clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) -CLIENT *h; -u_long proc; -xdrproc_t xargs; -caddr_t argsp; -xdrproc_t xresults; -caddr_t resultsp; -struct timeval timeout; +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); + struct clntraw_private_s *clp = clntraw_private; + XDR *xdrs = &clp->xdr_stream; + struct rpc_msg msg; + enum clnt_stat status; + struct rpc_err error; + + if (clp == NULL) + 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; } - (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)); - } + 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); + return status; } -static void clntraw_geterr() +static void +clntraw_geterr (CLIENT *cl, struct rpc_err *err) { } -static bool_t clntraw_freeres(cl, xdr_res, res_ptr) -CLIENT *cl; -xdrproc_t xdr_res; -caddr_t res_ptr; +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)); + struct clntraw_private_s *clp = clntraw_private; + XDR *xdrs = &clp->xdr_stream; + bool_t rval; + + if (clp == NULL) + { + rval = (bool_t) RPC_FAILED; + return rval; + } + xdrs->x_op = XDR_FREE; + return (*xdr_res) (xdrs, res_ptr); } -static void clntraw_abort() +static void +clntraw_abort (void) { } -static bool_t clntraw_control() +static bool_t +clntraw_control (CLIENT *cl, int i, char *c) { - return (FALSE); + return FALSE; } -static void clntraw_destroy() +static void +clntraw_destroy (CLIENT *cl) { } diff --git a/libc/inet/rpc/clnt_simple.c b/libc/inet/rpc/clnt_simple.c index 3ec4aedfe..fe65d4e23 100644 --- a/libc/inet/rpc/clnt_simple.c +++ b/libc/inet/rpc/clnt_simple.c @@ -6,110 +6,159 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. */ +#define __FORCE_GLIBC +#include <features.h> + +#include <alloca.h> +#include <errno.h> #include <stdio.h> #include <unistd.h> #include <rpc/rpc.h> #include <sys/socket.h> #include <netdb.h> -#include <strings.h> +#include <string.h> -static struct callrpc_private { - CLIENT *client; - int socket; - int oldprognum, oldversnum, valid; - char *oldhost; -} *callrpc_private; +struct callrpc_private_s + { + CLIENT *client; + int socket; + u_long oldprognum, oldversnum, valid; + char *oldhost; + }; +#ifdef _RPC_THREAD_SAFE_ +#define callrpc_private ((struct callrpc_private_s *)RPC_THREAD_VARIABLE(callrpc_private_s)) +#else +static struct callrpc_private_s *callrpc_private; +#endif -int callrpc (const char *host, const u_long prognum, - const u_long versnum, const u_long procnum, - const xdrproc_t inproc, const char *in, - const xdrproc_t outproc, char *out) +int +callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum, + xdrproc_t inproc, const char *in, xdrproc_t outproc, char *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; + struct callrpc_private_s *crp = callrpc_private; + struct sockaddr_in server_addr; + enum clnt_stat clnt_stat; + struct hostent hostbuf, *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 == 0) + { + crp = (struct callrpc_private_s *) 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 + { + size_t buflen; + char *buffer; + int herr; + + crp->valid = 0; + if (crp->socket != RPC_ANYSOCK) + { + (void) close (crp->socket); + crp->socket = RPC_ANYSOCK; } - if (crp->valid && crp->oldprognum == prognum - && crp->oldversnum == versnum && - strcmp(crp->oldhost, host) == 0) + if (crp->client) { - /* 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); + clnt_destroy (crp->client); + crp->client = NULL; + } + + buflen = 1024; + buffer = alloca (buflen); + while (gethostbyname_r (host, &hostbuf, buffer, buflen, + &hp, &herr) != 0 + || hp == NULL) + if (herr != NETDB_INTERNAL || errno != ERANGE) + return (int) RPC_UNKNOWNHOST; + else + { + /* Enlarge the buffer. */ + buflen *= 2; + buffer = alloca (buflen); + } + + timeout.tv_usec = 0; + timeout.tv_sec = 5; + memcpy ((char *) &server_addr.sin_addr, hp->h_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) get_rpc_createerr().cf_stat; + crp->valid = 1; + crp->oldprognum = prognum; + crp->oldversnum = versnum; + (void) strncpy (crp->oldhost, host, 255); + crp->oldhost[255] = '\0'; + } + tottimeout.tv_sec = 25; + tottimeout.tv_usec = 0; + clnt_stat = clnt_call (crp->client, procnum, inproc, (char *) in, + outproc, out, tottimeout); + /* + * if call failed, empty cache + */ + if (clnt_stat != RPC_SUCCESS) + crp->valid = 0; + return (int) clnt_stat; +} + +#ifdef _RPC_THREAD_SAFE_ +void +__rpc_thread_clnt_cleanup (void) +{ + struct callrpc_private_s *rcp = RPC_THREAD_VARIABLE(callrpc_private_s); + + if (rcp) { + if (rcp->client) + CLNT_DESTROY (rcp->client); + free (rcp); } - tottimeout.tv_sec = 25; - tottimeout.tv_usec = 0; - clnt_stat = clnt_call(crp->client, procnum, inproc, (char*)in, - outproc, out, tottimeout); - /* - * if call failed, empty cache - */ - if (clnt_stat != RPC_SUCCESS) - crp->valid = 0; - return ((int) clnt_stat); } +#endif /* _RPC_THREAD_SAFE_ */ diff --git a/libc/inet/rpc/clnt_tcp.c b/libc/inet/rpc/clnt_tcp.c index 790ec0706..5ff8434b7 100644 --- a/libc/inet/rpc/clnt_tcp.c +++ b/libc/inet/rpc/clnt_tcp.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. @@ -49,47 +50,57 @@ * Now go hang yourself. */ +#define __FORCE_GLIBC +#include <features.h> + +#include <netdb.h> +#include <errno.h> #include <stdio.h> +#include <unistd.h> #include <rpc/rpc.h> +#include <sys/poll.h> #include <sys/socket.h> -#include <netdb.h> -#include <errno.h> #include <rpc/pmap_clnt.h> -#include <unistd.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif -#define MCALL_MSG_SIZE 24 +extern u_long _create_xid (void); -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 -}; +#define MCALL_MSG_SIZE 24 -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; +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; + }; + +static int readtcp (char *, char *, int); +static int writetcp (char *, char *, int); + +static enum clnt_stat clnttcp_call (CLIENT *, u_long, xdrproc_t, caddr_t, + xdrproc_t, caddr_t, struct timeval); +static void clnttcp_abort (void); +static void clnttcp_geterr (CLIENT *, struct rpc_err *); +static bool_t clnttcp_freeres (CLIENT *, xdrproc_t, caddr_t); +static bool_t clnttcp_control (CLIENT *, int, char *); +static void clnttcp_destroy (CLIENT *); + +static struct clnt_ops tcp_ops = +{ + clnttcp_call, + clnttcp_abort, + clnttcp_geterr, + clnttcp_freeres, + clnttcp_destroy, + clnttcp_control }; /* @@ -106,282 +117,355 @@ struct ct_data { * 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 * +clnttcp_create (struct sockaddr_in *raddr, u_long prog, u_long vers, + int *sockp, u_int sendsz, u_int recvsz) { - CLIENT *h; - register struct ct_data *ct; - struct timeval now; - struct rpc_msg call_msg; - - ct = NULL; /* in case of fooy */ - 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; + CLIENT *h; + struct ct_data *ct; + struct rpc_msg call_msg; + + h = (CLIENT *) mem_alloc (sizeof (*h)); + ct = (struct ct_data *) mem_alloc (sizeof (*ct)); + if (h == NULL || ct == NULL) + { + struct rpc_createerr *ce = &get_rpc_createerr (); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("clnttcp_create: out of memory\n")); + else +#endif + (void) fputs (_("clnttcp_create: out of memory\n"), stderr); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = ENOMEM; + 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); } - 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; + 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)) + { + struct rpc_createerr *ce = &get_rpc_createerr (); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = errno; + if (*sockp >= 0) + (void) close (*sockp); + 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; + 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 + */ + call_msg.rm_xid = _create_xid (); + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + + /* + * pre-serialize the static part of the call msg and stash it away + */ + xdrmem_create (&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, + XDR_ENCODE); + if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg)) + { + if (ct->ct_closeit) + { + (void) close (*sockp); } - - /* - * 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); + 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; +clnttcp_call (h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) + 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; + struct ct_data *ct = (struct ct_data *) h->cl_private; + XDR *xdrs = &(ct->ct_xdrs); + struct rpc_msg reply_msg; + u_long x_id; + u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall); /* yuk */ + bool_t shipnow; + int refreshes = 2; + + if (!ct->ct_waitset) + { + ct->ct_wait = timeout; + } + + shipnow = + (xdr_results == (xdrproc_t) 0 && ct->ct_wait.tv_sec == 0 + && ct->ct_wait.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 (ct->ct_wait.tv_sec == 0 && ct->ct_wait.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 = (xdrproc_t)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; } - - 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 ((u_int32_t) reply_msg.rm_xid == (u_int32_t) 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; } - 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); + else if (!(*xdr_results) (xdrs, results_ptr)) + { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTDECODERES; } - - - /* - * Keep receiving until we get a valid transaction id - */ - xdrs->x_op = XDR_DECODE; - while (TRUE) { - reply_msg.acpted_rply.ar_verf = _null_auth; - reply_msg.acpted_rply.ar_results.where = NULL; - reply_msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; - if (!xdrrec_skiprecord(xdrs)) - 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; + /* 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)); } - - /* - * 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); + } /* 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; +static void +clnttcp_geterr (h, errp) + CLIENT *h; + struct rpc_err *errp; { - register struct ct_data *ct = (struct ct_data *) h->cl_private; + struct ct_data *ct = + (struct ct_data *) h->cl_private; - *errp = ct->ct_error; + *errp = ct->ct_error; } -static bool_t clnttcp_freeres(cl, xdr_res, res_ptr) -CLIENT *cl; -xdrproc_t xdr_res; -caddr_t res_ptr; +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); + struct ct_data *ct = (struct ct_data *) cl->cl_private; + XDR *xdrs = &(ct->ct_xdrs); - xdrs->x_op = XDR_FREE; - return ((*xdr_res) (xdrs, res_ptr)); + xdrs->x_op = XDR_FREE; + return (*xdr_res) (xdrs, res_ptr); } -static void clnttcp_abort() +static void +clnttcp_abort () { } -static bool_t clnttcp_control(cl, request, info) -CLIENT *cl; -int request; -char *info; +static bool_t +clnttcp_control (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); + struct ct_data *ct = (struct ct_data *) cl->cl_private; + + + switch (request) + { + case CLSET_FD_CLOSE: + ct->ct_closeit = TRUE; + break; + case CLSET_FD_NCLOSE: + ct->ct_closeit = FALSE; + break; + 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; + case CLGET_FD: + *(int *)info = ct->ct_sock; + break; + case CLGET_XID: + /* + * use the knowledge that xid is the + * first element in the call structure *. + * This will get the xid of the PREVIOUS call + */ + *(u_long *)info = ntohl (*(u_long *)ct->ct_mcall); + break; + case CLSET_XID: + /* This will set the xid of the NEXT call */ + *(u_long *)ct->ct_mcall = htonl (*(u_long *)info - 1); + /* decrement by 1 as clnttcp_call() increments once */ + case CLGET_VERS: + /* + * This RELIES on the information that, in the call body, + * the version number field is the fifth field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl (*(u_long *)(ct->ct_mcall + + 4 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_VERS: + *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT) + = htonl (*(u_long *)info); + break; + case CLGET_PROG: + /* + * This RELIES on the information that, in the call body, + * the program number field is the field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + + 3 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_PROG: + *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + /* The following are only possible with TI-RPC */ + case CLGET_RETRY_TIMEOUT: + case CLSET_RETRY_TIMEOUT: + case CLGET_SVC_ADDR: + case CLSET_SVC_ADDR: + case CLSET_PUSH_TIMOD: + case CLSET_POP_TIMOD: + default: + return FALSE; + } + return TRUE; } -static void clnttcp_destroy(h) -CLIENT *h; +static void +clnttcp_destroy (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)); + 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)); } /* @@ -389,75 +473,68 @@ CLIENT *h; * 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; +static int +readtcp (char *ctptr, char *buf, 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, NULL, 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)) { - + struct ct_data *ct = (struct ct_data *)ctptr; + struct pollfd fd; + int milliseconds = (ct->ct_wait.tv_sec * 1000) + + (ct->ct_wait.tv_usec / 1000); + + if (len == 0) + return 0; + + fd.fd = ct->ct_sock; + fd.events = POLLIN; + while (TRUE) + { + switch (poll(&fd, 1, milliseconds)) + { 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; + ct->ct_error.re_status = RPC_TIMEDOUT; + return -1; case -1: - ct->ct_error.re_errno = errno; - ct->ct_error.re_status = RPC_CANTRECV; - break; + if (errno == EINTR) + continue; + ct->ct_error.re_status = RPC_CANTRECV; + ct->ct_error.re_errno = errno; + return -1; } - return (len); + 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; +static int +writetcp (char *ctptr, char *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); - } + int i, cnt; + struct ct_data *ct = (struct ct_data*)ctptr; + + 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); + } + return len; } diff --git a/libc/inet/rpc/clnt_udp.c b/libc/inet/rpc/clnt_udp.c index e11f9b8c6..5a5fbbc18 100644 --- a/libc/inet/rpc/clnt_udp.c +++ b/libc/inet/rpc/clnt_udp.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. @@ -36,54 +37,73 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ +#define __FORCE_GLIBC +#include <features.h> + #include <stdio.h> +#include <unistd.h> #include <rpc/rpc.h> +#include <rpc/xdr.h> +#include <rpc/clnt.h> +#include <sys/poll.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netdb.h> #include <errno.h> #include <rpc/pmap_clnt.h> -#include <unistd.h> +#include <net/if.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif -extern int errno; +#ifdef IP_RECVERR +#include "errqueue.h" +#include <sys/uio.h> +#endif + +extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *); +extern u_long _create_xid (void); /* * 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 +static enum clnt_stat clntudp_call (CLIENT *, u_long, xdrproc_t, caddr_t, + xdrproc_t, caddr_t, struct timeval); +static void clntudp_abort (void); +static void clntudp_geterr (CLIENT *, struct rpc_err *); +static bool_t clntudp_freeres (CLIENT *, xdrproc_t, caddr_t); +static bool_t clntudp_control (CLIENT *, int, char *); +static void clntudp_destroy (CLIENT *); + +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]; -}; +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. @@ -95,344 +115,495 @@ struct cu_data { * 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 + * no response has been heard; retransmission 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 * +clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, u_long version, + struct timeval wait, int *sockp, u_int sendsz, + u_int recvsz) { - CLIENT *cl; - register struct cu_data *cu; - struct timeval now; - struct rpc_msg call_msg; - - cu = NULL; /* in case of fooy */ - 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; + CLIENT *cl; + struct cu_data *cu = NULL; + struct rpc_msg call_msg; + + cl = (CLIENT *) mem_alloc (sizeof (CLIENT)); + sendsz = ((sendsz + 3) / 4) * 4; + recvsz = ((recvsz + 3) / 4) * 4; + cu = (struct cu_data *) mem_alloc (sizeof (*cu) + sendsz + recvsz); + if (cl == NULL || cu == NULL) + { + struct rpc_createerr *ce = &get_rpc_createerr (); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("clntudp_create: out of memory\n")); + else +#endif + (void) fputs (_("clntudp_create: out of memory\n"), stderr); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = ENOMEM; + goto fooy; + } + cu->cu_outbuf = &cu->cu_inbuf[recvsz]; + + if (raddr->sin_port == 0) + { + u_short port; + if ((port = + pmap_getport (raddr, program, version, IPPROTO_UDP)) == 0) + { + 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; + 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 = _create_xid (); + 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) + { + struct rpc_createerr *ce = &get_rpc_createerr (); + ce->cf_stat = RPC_SYSTEMERROR; + ce->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); + /* 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); +#ifdef IP_RECVERR + { + int on = 1; + setsockopt(*sockp, SOL_IP, IP_RECVERR, &on, sizeof(on)); + } +#endif + 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; +CLIENT * +clntudp_create (raddr, program, version, wait, sockp) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + int *sockp; { - return (clntudp_bufcreate(raddr, program, version, wait, sockp, - UDPMSGSIZE, UDPMSGSIZE)); + 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 */ +static int +is_network_up (int sock) { - 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); + struct ifconf ifc; + char buf[UDPMSGSIZE]; + struct ifreq ifreq, *ifr; + int n; + + ifc.ifc_len = sizeof (buf); + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, (char *) &ifc) == 0) + { + ifr = ifc.ifc_req; + for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) + { + ifreq = *ifr; + if (ioctl (sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) + break; + + if ((ifreq.ifr_flags & IFF_UP) + && ifr->ifr_addr.sa_family == AF_INET) + return 1; } + } + return 0; +} - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { - return (cu->cu_error.re_status = RPC_TIMEDOUT); +static enum clnt_stat +clntudp_call (cl, proc, xargs, argsp, xresults, resultsp, utimeout) + 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 */ +{ + struct cu_data *cu = (struct cu_data *) cl->cl_private; + XDR *xdrs; + int outlen = 0; + int inlen; + socklen_t fromlen; + struct pollfd fd; + int milliseconds = (cu->cu_wait.tv_sec * 1000) + + (cu->cu_wait.tv_usec / 1000); + 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; + int anyup; /* any network interface up */ + + 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); + if (xargs == NULL) + goto get_reply; + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS (xdrs, cu->cu_xdrpos); + /* + * the transaction is the first thing in the out buffer + */ + (*(uint32_t *) (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); + } + get_reply: + /* + * sub-optimal code appears here because we have + * some clock time to spare while the packets are in flight. + * (We assume that this is actually only executed once.) + */ + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = resultsp; + reply_msg.acpted_rply.ar_results.proc = xresults; + fd.fd = cu->cu_sock; + fd.events = POLLIN; + anyup = 0; + for (;;) + { + switch (poll (&fd, 1, milliseconds)) + { + + case 0: + if (anyup == 0) + { + anyup = is_network_up (cu->cu_sock); + if (!anyup) + return (cu->cu_error.re_status = RPC_CANTRECV); + } + + 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); } - /* - * 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, NULL, - 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); +#ifdef IP_RECVERR + if (fd.revents & POLLERR) + { + struct msghdr msg; + struct cmsghdr *cmsg; + struct sock_extended_err *e; + struct sockaddr_in err_addr; + struct iovec iov; + char *cbuf = (char *) alloca (outlen + 256); + int ret; + + iov.iov_base = cbuf + 256; + iov.iov_len = outlen; + msg.msg_name = (void *) &err_addr; + msg.msg_namelen = sizeof (err_addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_flags = 0; + msg.msg_control = cbuf; + msg.msg_controllen = 256; + ret = recvmsg (cu->cu_sock, &msg, MSG_ERRQUEUE); + if (ret >= 0 + && memcmp (cbuf + 256, cu->cu_outbuf, ret) == 0 + && (msg.msg_flags & MSG_ERRQUEUE) + && ((msg.msg_namelen == 0 + && ret >= 12) + || (msg.msg_namelen == sizeof (err_addr) + && err_addr.sin_family == AF_INET + && memcmp (&err_addr.sin_addr, &cu->cu_raddr.sin_addr, + sizeof (err_addr.sin_addr)) == 0 + && err_addr.sin_port == cu->cu_raddr.sin_port))) + for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; + cmsg = CMSG_NXTHDR (&msg, cmsg)) + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) + { + e = (struct sock_extended_err *) CMSG_DATA(cmsg); + cu->cu_error.re_errno = e->ee_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; +#endif + do + { + fromlen = sizeof (struct sockaddr); + inlen = recvfrom (cu->cu_sock, cu->cu_inbuf, + (int) cu->cu_recvsz, 0, + (struct sockaddr *) &from, &fromlen); } - return (cu->cu_error.re_status); + 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 < 4) + continue; + + /* see if reply transaction id matches sent id. + Don't do this if we only wait for a replay */ + if (xargs != NULL + && (*((u_int32_t *) (cu->cu_inbuf)) + != *((u_int32_t *) (cu->cu_outbuf)))) + continue; + /* we now assume we have the proper reply */ + break; + } + + /* + * now decode and validate the response + */ + xdrmem_create (&reply_xdrs, cu->cu_inbuf, (u_int) inlen, XDR_DECODE); + ok = xdr_replymsg (&reply_xdrs, &reply_msg); + /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ + if (ok) + { + _seterr_reply (&reply_msg, &(cu->cu_error)); + if (cu->cu_error.re_status == RPC_SUCCESS) + { + if (!AUTH_VALIDATE (cl->cl_auth, + &reply_msg.acpted_rply.ar_verf)) + { + cu->cu_error.re_status = RPC_AUTHERROR; + cu->cu_error.re_why = AUTH_INVALIDRESP; + } + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) + { + xdrs->x_op = XDR_FREE; + (void) xdr_opaque_auth (xdrs, + &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else + { + /* maybe our credentials need to be refreshed ... */ + if (nrefreshes > 0 && AUTH_REFRESH (cl->cl_auth)) + { + nrefreshes--; + goto call_again; + } + } /* end of unsuccessful completion */ + } /* end of valid reply message */ + else + { + 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; +static void +clntudp_geterr (CLIENT *cl, struct rpc_err *errp) { - register struct cu_data *cu = (struct cu_data *) cl->cl_private; + struct cu_data *cu = (struct cu_data *) cl->cl_private; - *errp = cu->cu_error; + *errp = cu->cu_error; } -static bool_t clntudp_freeres(cl, xdr_res, res_ptr) -CLIENT *cl; -xdrproc_t xdr_res; -caddr_t res_ptr; +static bool_t +clntudp_freeres (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); + struct cu_data *cu = (struct cu_data *) cl->cl_private; + XDR *xdrs = &(cu->cu_outxdrs); - xdrs->x_op = XDR_FREE; - return ((*xdr_res) (xdrs, res_ptr)); + xdrs->x_op = XDR_FREE; + return (*xdr_res) (xdrs, res_ptr); } -static void clntudp_abort( /*h */ ) - /*CLIENT *h; */ +static void +clntudp_abort (void) { } -static bool_t clntudp_control(cl, request, info) -CLIENT *cl; -int request; -char *info; +static bool_t +clntudp_control (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); + struct cu_data *cu = (struct cu_data *) cl->cl_private; + + switch (request) + { + case CLSET_FD_CLOSE: + cu->cu_closeit = TRUE; + break; + case CLSET_FD_NCLOSE: + cu->cu_closeit = FALSE; + break; + 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; + case CLGET_FD: + *(int *)info = cu->cu_sock; + break; + case CLGET_XID: + /* + * use the knowledge that xid is the + * first element in the call structure *. + * This will get the xid of the PREVIOUS call + */ + *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf); + break; + case CLSET_XID: + /* This will set the xid of the NEXT call */ + *(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1); + /* decrement by 1 as clntudp_call() increments once */ + case CLGET_VERS: + /* + * This RELIES on the information that, in the call body, + * the version number field is the fifth field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + + 4 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_VERS: + *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + case CLGET_PROG: + /* + * This RELIES on the information that, in the call body, + * the program number field is the field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + + 3 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_PROG: + *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + /* The following are only possible with TI-RPC */ + case CLGET_SVC_ADDR: + case CLSET_SVC_ADDR: + case CLSET_PUSH_TIMOD: + case CLSET_POP_TIMOD: + default: + return FALSE; + } + return TRUE; } -static void clntudp_destroy(cl) -CLIENT *cl; +static void +clntudp_destroy (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)); + 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/libc/inet/rpc/clnt_unix.c b/libc/inet/rpc/clnt_unix.c new file mode 100644 index 000000000..81d8c4686 --- /dev/null +++ b/libc/inet/rpc/clnt_unix.c @@ -0,0 +1,606 @@ +/* + * 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_unix.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. + */ + +#define __FORCE_GLIBC +#include <features.h> + +#include <netdb.h> +#include <errno.h> +#include <stdio.h> +#include <unistd.h> +#include <rpc/rpc.h> +#include <sys/uio.h> +#include <sys/poll.h> +#include <sys/socket.h> +#include <rpc/pmap_clnt.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif + +extern u_long _create_xid (void); + +#define MCALL_MSG_SIZE 24 + +struct ct_data + { + int ct_sock; + bool_t ct_closeit; + struct timeval ct_wait; + bool_t ct_waitset; /* wait set by clnt_control? */ + struct sockaddr_un ct_addr; + struct rpc_err ct_error; + char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ + u_int ct_mpos; /* pos after marshal */ + XDR ct_xdrs; + }; + +static int readunix (char *, char *, int); +static int writeunix (char *, char *, int); + +static enum clnt_stat clntunix_call (CLIENT *, u_long, xdrproc_t, caddr_t, + xdrproc_t, caddr_t, struct timeval); +static void clntunix_abort (void); +static void clntunix_geterr (CLIENT *, struct rpc_err *); +static bool_t clntunix_freeres (CLIENT *, xdrproc_t, caddr_t); +static bool_t clntunix_control (CLIENT *, int, char *); +static void clntunix_destroy (CLIENT *); + +static struct clnt_ops unix_ops = +{ + clntunix_call, + clntunix_abort, + clntunix_geterr, + clntunix_freeres, + clntunix_destroy, + clntunix_control +}; + +/* + * 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 * +clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers, + int *sockp, u_int sendsz, u_int recvsz) +{ + CLIENT *h; + struct ct_data *ct = (struct ct_data *) mem_alloc (sizeof (*ct)); + struct rpc_msg call_msg; + int len; + + h = (CLIENT *) mem_alloc (sizeof (*h)); + if (h == NULL || ct == NULL) + { + struct rpc_createerr *ce = &get_rpc_createerr (); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("clntunix_create: out of memory\n")); + else +#endif + (void) fputs (_("clntunix_create: out of memory\n"), stderr); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = ENOMEM; + goto fooy; + } + + /* + * If no socket given, open one + */ + if (*sockp < 0) + { + *sockp = socket (AF_UNIX, SOCK_STREAM, 0); + len = strlen (raddr->sun_path) + sizeof (raddr->sun_family) + 1; + if (*sockp < 0 + || connect (*sockp, (struct sockaddr *) raddr, len) < 0) + { + struct rpc_createerr *ce = &get_rpc_createerr (); + ce->cf_stat = RPC_SYSTEMERROR; + ce->cf_error.re_errno = errno; + if (*sockp != -1) + 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 + */ + call_msg.rm_xid = _create_xid (); + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + + /* + * pre-serialize the static part of the call msg and stash it away + */ + xdrmem_create (&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, XDR_ENCODE); + if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg)) + { + if (ct->ct_closeit) + close (*sockp); + goto fooy; + } + ct->ct_mpos = XDR_GETPOS (&(ct->ct_xdrs)); + XDR_DESTROY (&(ct->ct_xdrs)); + + /* + * Create a client handle which uses xdrrec for serialization + * and authnone for authentication. + */ + xdrrec_create (&(ct->ct_xdrs), sendsz, recvsz, + (caddr_t) ct, readunix, writeunix); + h->cl_ops = &unix_ops; + h->cl_private = (caddr_t) ct; + h->cl_auth = authnone_create (); + return h; + +fooy: + /* + * Something goofed, free stuff and barf + */ + mem_free ((caddr_t) ct, sizeof (struct ct_data)); + mem_free ((caddr_t) h, sizeof (CLIENT)); + return (CLIENT *) NULL; +} + +static enum clnt_stat +clntunix_call (h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) + CLIENT *h; + u_long proc; + xdrproc_t xdr_args; + caddr_t args_ptr; + xdrproc_t xdr_results; + caddr_t results_ptr; + struct timeval timeout; +{ + struct ct_data *ct = (struct ct_data *) h->cl_private; + XDR *xdrs = &(ct->ct_xdrs); + struct rpc_msg reply_msg; + u_long x_id; + u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall); /* yuk */ + bool_t shipnow; + int refreshes = 2; + + if (!ct->ct_waitset) + { + ct->ct_wait = timeout; + } + + shipnow = + (xdr_results == (xdrproc_t) 0 && ct->ct_wait.tv_sec == 0 + && ct->ct_wait.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 (ct->ct_wait.tv_sec == 0 && ct->ct_wait.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 = (xdrproc_t)xdr_void; + if (!xdrrec_skiprecord (xdrs)) + return ct->ct_error.re_status; + /* now decode and validate the response header */ + if (!xdr_replymsg (xdrs, &reply_msg)) + { + if (ct->ct_error.re_status == RPC_SUCCESS) + continue; + return ct->ct_error.re_status; + } + if (reply_msg.rm_xid == x_id) + break; + } + + /* + * process header + */ + _seterr_reply (&reply_msg, &(ct->ct_error)); + if (ct->ct_error.re_status == RPC_SUCCESS) + { + if (!AUTH_VALIDATE (h->cl_auth, &reply_msg.acpted_rply.ar_verf)) + { + ct->ct_error.re_status = RPC_AUTHERROR; + ct->ct_error.re_why = AUTH_INVALIDRESP; + } + else if (!(*xdr_results) (xdrs, results_ptr)) + { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTDECODERES; + } + /* free verifier ... */ + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) + { + xdrs->x_op = XDR_FREE; + (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else + { + /* maybe our credentials need to be refreshed ... */ + if (refreshes-- && AUTH_REFRESH (h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + return ct->ct_error.re_status; +} + +static void +clntunix_geterr (CLIENT *h, struct rpc_err *errp) +{ + struct ct_data *ct = (struct ct_data *) h->cl_private; + + *errp = ct->ct_error; +} + +static bool_t +clntunix_freeres (cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + struct ct_data *ct = (struct ct_data *) cl->cl_private; + XDR *xdrs = &(ct->ct_xdrs); + + xdrs->x_op = XDR_FREE; + return (*xdr_res) (xdrs, res_ptr); +} + +static void +clntunix_abort () +{ +} + +static bool_t +clntunix_control (CLIENT *cl, int request, char *info) +{ + struct ct_data *ct = (struct ct_data *) cl->cl_private; + + + switch (request) + { + case CLSET_FD_CLOSE: + ct->ct_closeit = TRUE; + break; + case CLSET_FD_NCLOSE: + ct->ct_closeit = FALSE; + break; + case CLSET_TIMEOUT: + ct->ct_wait = *(struct timeval *) info; + break; + case CLGET_TIMEOUT: + *(struct timeval *) info = ct->ct_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_un *) info = ct->ct_addr; + break; + case CLGET_FD: + *(int *)info = ct->ct_sock; + break; + case CLGET_XID: + /* + * use the knowledge that xid is the + * first element in the call structure *. + * This will get the xid of the PREVIOUS call + */ + *(u_long *) info = ntohl (*(u_long *)ct->ct_mcall); + break; + case CLSET_XID: + /* This will set the xid of the NEXT call */ + *(u_long *) ct->ct_mcall = htonl (*(u_long *)info - 1); + /* decrement by 1 as clntunix_call() increments once */ + case CLGET_VERS: + /* + * This RELIES on the information that, in the call body, + * the version number field is the fifth field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall + + 4 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_VERS: + *(u_long *) (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT) + = htonl (*(u_long *) info); + break; + case CLGET_PROG: + /* + * This RELIES on the information that, in the call body, + * the program number field is the field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall + + 3 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_PROG: + *(u_long *) (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *) info); + break; + /* The following are only possible with TI-RPC */ + case CLGET_RETRY_TIMEOUT: + case CLSET_RETRY_TIMEOUT: + case CLGET_SVC_ADDR: + case CLSET_SVC_ADDR: + case CLSET_PUSH_TIMOD: + case CLSET_POP_TIMOD: + default: + return FALSE; + } + return TRUE; +} + + +static void +clntunix_destroy (CLIENT *h) +{ + 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)); +} + +static int +__msgread (int sock, void *data, size_t cnt) +{ + struct iovec iov; + struct msghdr msg; +#ifdef SCM_CREDENTIALS + static char cm[CMSG_SPACE(sizeof (struct ucred))]; +#endif + int len; + + iov.iov_base = data; + iov.iov_len = cnt; + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; +#ifdef SCM_CREDENTIALS + msg.msg_control = (caddr_t) &cm; + msg.msg_controllen = CMSG_SPACE(sizeof (struct ucred)); +#endif + msg.msg_flags = 0; + +#ifdef SO_PASSCRED + { + int on = 1; + if (setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on))) + return -1; + } +#endif + + restart: + len = recvmsg (sock, &msg, 0); + if (len >= 0) + { + if (msg.msg_flags & MSG_CTRUNC || len == 0) + return 0; + else + return len; + } + if (errno == EINTR) + goto restart; + return -1; +} + +static int +__msgwrite (int sock, void *data, size_t cnt) +{ +#ifndef SCM_CREDENTIALS + /* We cannot implement this reliably. */ + __set_errno (ENOSYS); + return -1; +#else + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsg = alloca (CMSG_SPACE(sizeof (struct ucred))); + struct ucred cred; + int len; + + /* XXX I'm not sure, if gete?id() is always correct, or if we should use + get?id(). But since keyserv needs geteuid(), we have no other chance. + It would be much better, if the kernel could pass both to the server. */ + cred.pid = getpid (); + cred.uid = geteuid (); + cred.gid = getegid (); + + memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred); + + iov.iov_base = data; + iov.iov_len = cnt; + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = cmsg; + msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len); + msg.msg_flags = 0; + + restart: + len = sendmsg (sock, &msg, 0); + if (len >= 0) + return len; + if (errno == EINTR) + goto restart; + return -1; + +#endif +} + + +/* + * Interface between xdr serializer and unix connection. + * Behaves like the system calls, read & write, but keeps some error state + * around for the rpc level. + */ +static int +readunix (char *ctptr, char *buf, int len) +{ + struct ct_data *ct = (struct ct_data *) ctptr; + struct pollfd fd; + int milliseconds = ((ct->ct_wait.tv_sec * 1000) + + (ct->ct_wait.tv_usec / 1000)); + + if (len == 0) + return 0; + + fd.fd = ct->ct_sock; + fd.events = POLLIN; + while (TRUE) + { + switch (poll (&fd, 1, milliseconds)) + { + case 0: + ct->ct_error.re_status = RPC_TIMEDOUT; + return -1; + + case -1: + if (errno == EINTR) + continue; + ct->ct_error.re_status = RPC_CANTRECV; + ct->ct_error.re_errno = errno; + return -1; + } + break; + } + switch (len = __msgread (ct->ct_sock, buf, len)) + { + + case 0: + /* premature eof */ + ct->ct_error.re_errno = ECONNRESET; + ct->ct_error.re_status = RPC_CANTRECV; + len = -1; /* it's really an error */ + break; + + case -1: + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTRECV; + break; + } + return len; +} + +static int +writeunix (char *ctptr, char *buf, int len) +{ + int i, cnt; + struct ct_data *ct = (struct ct_data *) ctptr; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) + { + if ((i = __msgwrite (ct->ct_sock, buf, cnt)) == -1) + { + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTSEND; + return -1; + } + } + return len; +} diff --git a/libc/inet/rpc/create_xid.c b/libc/inet/rpc/create_xid.c new file mode 100644 index 000000000..c184e816d --- /dev/null +++ b/libc/inet/rpc/create_xid.c @@ -0,0 +1,64 @@ +/* Copyright (c) 1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define __FORCE_GLIBC +#include <features.h> + +#include <unistd.h> +#include <stdlib.h> +#include <sys/time.h> +#include <rpc/rpc.h> + +/* The RPC code is not threadsafe, but new code should be threadsafe. */ + +#ifdef _RPC_THREAD_SAFE_ //__UCLIBC_HAS_THREADS__ +#include <pthread.h> +static pthread_mutex_t createxid_lock = PTHREAD_MUTEX_INITIALIZER; +# define LOCK pthread_mutex_lock(&createxid_lock) +# define UNLOCK pthread_mutex_unlock(&createxid_lock); +#else +# define LOCK +# define UNLOCK +#endif + +static int is_initialized; +static struct drand48_data __rpc_lrand48_data; + +unsigned long +_create_xid (void) +{ + unsigned long res; + + LOCK; + + if (!is_initialized) + { + struct timeval now; + + gettimeofday (&now, (struct timezone *) 0); + srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data); + is_initialized = 1; + } + + lrand48_r (&__rpc_lrand48_data, &res); + + UNLOCK; + + return res; +} diff --git a/libc/inet/rpc/errqueue.h b/libc/inet/rpc/errqueue.h new file mode 100644 index 000000000..9ed6dc62b --- /dev/null +++ b/libc/inet/rpc/errqueue.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2000 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Linux version. */ + +#ifndef _BITS_ERRQUEUE_H +#define _BITS_ERRQUEUE_H 1 + +#include <sys/types.h> +#include <sys/socket.h> + +struct sock_extended_err + { + u_int32_t ee_errno; + u_int8_t ee_origin; + u_int8_t ee_type; + u_int8_t ee_code; + u_int8_t ee_pad; + u_int32_t ee_info; + u_int32_t ee_data; + }; + +#define SO_EE_ORIGIN_NONE 0 +#define SO_EE_ORIGIN_LOCAL 1 +#define SO_EE_ORIGIN_ICMP 2 +#define SO_EE_ORIGIN_ICMP6 3 + +#define SO_EE_OFFENDER(see) \ + ((struct sockaddr *)(((struct sock_extended_err)(see))+1)) + +#endif /* bits/errqueue.h */ diff --git a/libc/inet/rpc/get_myaddress.c b/libc/inet/rpc/get_myaddress.c index 1b80207f5..86277d239 100644 --- a/libc/inet/rpc/get_myaddress.c +++ b/libc/inet/rpc/get_myaddress.c @@ -1,4 +1,4 @@ -/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */ +/* @(#)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 @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * get_myaddress.c @@ -38,72 +39,70 @@ */ #include <rpc/types.h> +#include <rpc/clnt.h> #include <rpc/pmap_prot.h> #include <sys/socket.h> #include <stdio.h> -//#include <net/if.h> +#include <unistd.h> +#include <net/if.h> #include <sys/ioctl.h> -#include <arpa/inet.h> +/* Order of following two #includes reversed by roland@gnu */ #include <netinet/in.h> -#include <rpc/clnt.h> -#include <unistd.h> - -#ifdef __linux__ -/* DO use gethostbyname because it's portable */ -#include <netdb.h> -void get_myaddress(addr) -struct sockaddr_in *addr; -{ - char localhost[256 + 1]; - struct hostent *hp; +#include <arpa/inet.h> - gethostname(localhost, 256); - if ((hp = gethostbyname(localhost)) == NULL) { - perror("get_myaddress: gethostbyname"); - exit(1); - } - addr->sin_family = AF_INET; - bcopy((char *) hp->h_addr, (char *) &addr->sin_addr, hp->h_length); - addr->sin_port = htons(PMAPPORT); -} -#else -/* +/* * don't use gethostbyname, which would invoke yellow pages + * + * Avoid loopback interfaces. We return information from a loopback + * interface only if there are no other possible interfaces. */ -void get_myaddress(addr) -struct sockaddr_in *addr; +void +get_myaddress (struct sockaddr_in *addr) { - int s; - char buf[BUFSIZ]; - struct ifconf ifc; - struct ifreq ifreq, *ifr; - int len; + int s; + char buf[BUFSIZ]; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + int len, loopback = 0; - 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); + 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); + } + + again: + 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); } - 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++; + if ((ifreq.ifr_flags & IFF_UP) && (ifr->ifr_addr.sa_family == AF_INET) + && (!(ifreq.ifr_flags & IFF_LOOPBACK) || + (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK)))) + { + *addr = *((struct sockaddr_in *) &ifr->ifr_addr); + addr->sin_port = htons (PMAPPORT); + close (s); + return; } - (void) close(s); + ifr++; + } + if (loopback == 0) + { + loopback = 1; + goto again; + } + close (s); } -#endif diff --git a/libc/inet/rpc/getrpcport.c b/libc/inet/rpc/getrpcport.c index 295c23702..d3c4bb484 100644 --- a/libc/inet/rpc/getrpcport.c +++ b/libc/inet/rpc/getrpcport.c @@ -1,6 +1,7 @@ /* @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC */ -#define __FORCE_GLIBC -#include <features.h> +#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 @@ -8,23 +9,23 @@ * 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 @@ -34,22 +35,43 @@ * Copyright (c) 1985 by Sun Microsystems, Inc. */ +#define __FORCE_GLIBC +#include <features.h> + +#include <alloca.h> +#include <errno.h> #include <stdio.h> -#include <rpc/rpc.h> #include <netdb.h> -#include <sys/socket.h> +#include <string.h> +#include <rpc/rpc.h> +#include <rpc/clnt.h> #include <rpc/pmap_clnt.h> +#include <sys/socket.h> -extern int getrpcport (const char * host, u_long prognum, - u_long versnum, u_int proto) +int +getrpcport (const char *host, u_long prognum, u_long versnum, u_int proto) { - struct sockaddr_in addr; - struct hostent *hp; + struct sockaddr_in addr; + struct hostent hostbuf, *hp; + size_t buflen; + char *buffer; + int herr; + + buflen = 1024; + buffer = alloca (buflen); + while (gethostbyname_r (host, &hostbuf, buffer, buflen, &hp, &herr) != 0 + || hp == NULL) + if (herr != NETDB_INTERNAL || errno != ERANGE) + return 0; + else + { + /* Enlarge the buffer. */ + buflen *= 2; + buffer = alloca (buflen); + } - 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)); + memcpy ((char *) &addr.sin_addr, hp->h_addr, hp->h_length); + addr.sin_family = AF_INET; + addr.sin_port = 0; + return pmap_getport (&addr, prognum, versnum, proto); } diff --git a/libc/inet/rpc/pmap_clnt.c b/libc/inet/rpc/pmap_clnt.c index ccd912363..2382c153b 100644 --- a/libc/inet/rpc/pmap_clnt.c +++ b/libc/inet/rpc/pmap_clnt.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,111 +5,169 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> - +/* + * Copyright (C) 1984, Sun Microsystems, Inc. + */ /* * pmap_clnt.c * Client interface to pmap rpc service. - * - * Copyright (C) 1984, Sun Microsystems, Inc. */ +#define __FORCE_GLIBC +#include <features.h> + +#include <stdio.h> +#include <unistd.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <rpc/rpc.h> #include <rpc/pmap_prot.h> #include <rpc/pmap_clnt.h> -#include <unistd.h> -static struct timeval timeout = { 5, 0 }; -static struct timeval tottimeout = { 60, 0 }; +/* + * Same as get_myaddress, but we try to use the loopback + * interface. portmap caches interfaces, and on DHCP clients, + * it could be that only loopback is started at this time. + */ +static bool_t +__get_myaddress (struct sockaddr_in *addr) +{ + int s; + char buf[BUFSIZ]; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + int len, loopback = 1; + + 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); + } + + again: + 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) + && ((ifreq.ifr_flags & IFF_LOOPBACK) || (loopback == 0))) + { + *addr = *((struct sockaddr_in *) &ifr->ifr_addr); + addr->sin_port = htons (PMAPPORT); + close (s); + return TRUE; + } + ifr++; + } + if (loopback == 1) + { + loopback = 0; + goto again; + } + close (s); + return FALSE; +} -void clnt_perror(); +static const struct timeval timeout = {5, 0}; +static const struct timeval tottimeout = {60, 0}; /* * 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; +bool_t +pmap_set (u_long program, u_long version, int protocol, u_short port) { - struct sockaddr_in myaddress; - int socket = -1; - register CLIENT *client; - struct pmap parms; - bool_t rslt; + struct sockaddr_in myaddress; + int socket = -1; + 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, (xdrproc_t) xdr_pmap, (caddr_t) &parms, - (xdrproc_t) xdr_bool, (caddr_t) &rslt, - tottimeout) != RPC_SUCCESS) { - clnt_perror(client, "Cannot register service"); - return (FALSE); - } - CLNT_DESTROY(client); - (void) close(socket); - return (rslt); + if (!__get_myaddress (&myaddress)) + return FALSE; + 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, (xdrproc_t)xdr_pmap, (caddr_t)&parms, + (xdrproc_t)xdr_bool, (caddr_t)&rslt, + tottimeout) != RPC_SUCCESS) + { + clnt_perror (client, _("Cannot register service")); + return FALSE; + } + CLNT_DESTROY (client); + /* (void)close(socket); CLNT_DESTROY closes it */ + 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; +bool_t +pmap_unset (u_long program, u_long version) { - struct sockaddr_in myaddress; - int socket = -1; - register CLIENT *client; - struct pmap parms; - bool_t rslt; + struct sockaddr_in myaddress; + int socket = -1; + 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, (xdrproc_t) xdr_pmap, (caddr_t) &parms, - (xdrproc_t) xdr_bool, (caddr_t) &rslt, tottimeout); - CLNT_DESTROY(client); - (void) close(socket); - return (rslt); + if (!__get_myaddress (&myaddress)) + return FALSE; + 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, (xdrproc_t)xdr_pmap, (caddr_t)&parms, + (xdrproc_t)xdr_bool, (caddr_t)&rslt, tottimeout); + CLNT_DESTROY (client); + /* (void)close(socket); CLNT_DESTROY already closed it */ + return rslt; } diff --git a/libc/inet/rpc/pmap_getmaps.c b/libc/inet/rpc/pmap_getmaps.c index 7ebe472a5..2812b3aea 100644 --- a/libc/inet/rpc/pmap_getmaps.c +++ b/libc/inet/rpc/pmap_getmaps.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * pmap_getmap.c @@ -45,39 +46,35 @@ #include <netdb.h> #include <stdio.h> #include <errno.h> -//#include <net/if.h> -#include <sys/ioctl.h> -#include <unistd.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 * +pmap_getmaps (struct sockaddr_in *address) { - struct pmaplist *head = (struct pmaplist *) NULL; - int socket = -1; - struct timeval minutetimeout; - register CLIENT *client; + struct pmaplist *head = (struct pmaplist *) NULL; + int socket = -1; + struct timeval minutetimeout; + 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, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_pmaplist, (caddr_t) &head, - minutetimeout) != RPC_SUCCESS) { - clnt_perror(client, "pmap_getmaps rpc problem"); - } - CLNT_DESTROY(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, (xdrproc_t)xdr_void, NULL, + (xdrproc_t)xdr_pmaplist, (caddr_t)&head, + minutetimeout) != RPC_SUCCESS) + { + clnt_perror (client, _("pmap_getmaps rpc problem")); } - (void) close(socket); - address->sin_port = 0; - return (head); + CLNT_DESTROY (client); + } + /* (void)close(socket); CLNT_DESTROY already closed it */ + address->sin_port = 0; + return head; } diff --git a/libc/inet/rpc/pmap_getport.c b/libc/inet/rpc/pmap_getport.c index f1e771cde..b86472ccd 100644 --- a/libc/inet/rpc/pmap_getport.c +++ b/libc/inet/rpc/pmap_getport.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * pmap_getport.c @@ -41,49 +42,53 @@ #include <rpc/pmap_prot.h> #include <rpc/pmap_clnt.h> #include <sys/socket.h> -#include <unistd.h> -//#include <net/if.h> -static struct timeval timeout = { 5, 0 }; -static struct timeval tottimeout = { 60, 0 }; +static const struct timeval timeout = +{5, 0}; +static const struct timeval tottimeout = +{60, 0}; /* * Find the mapped port for program,version. * Calls the pmap service remotely to do the lookup. * Returns 0 if no map exists. */ -u_short pmap_getport(address, program, version, protocol) -struct sockaddr_in *address; -u_long program; -u_long version; -u_int protocol; +u_short +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; + u_short port = 0; + int socket = -1; + 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, - (xdrproc_t) xdr_pmap, (caddr_t) &parms, - (xdrproc_t) xdr_u_short, (caddr_t) &port, - tottimeout) != RPC_SUCCESS) { - rpc_createerr.cf_stat = RPC_PMAPFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - } else if (port == 0) { - rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - } - CLNT_DESTROY(client); + address->sin_port = htons (PMAPPORT); + client = clntudp_bufcreate (address, PMAPPROG, + PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client != (CLIENT *) NULL) + { + struct rpc_createerr *ce = &get_rpc_createerr (); + 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, (xdrproc_t)xdr_pmap, + (caddr_t)&parms, (xdrproc_t)xdr_u_short, + (caddr_t)&port, tottimeout) != RPC_SUCCESS) + { + ce->cf_stat = RPC_PMAPFAILURE; + clnt_geterr (client, &ce->cf_error); + } + else if (port == 0) + { + ce->cf_stat = RPC_PROGNOTREGISTERED; } - (void) close(socket); - address->sin_port = 0; - return (port); + CLNT_DESTROY (client); + } + /* (void)close(socket); CLNT_DESTROY already closed it */ + address->sin_port = 0; + return port; } diff --git a/libc/inet/rpc/pmap_prot.c b/libc/inet/rpc/pmap_prot.c index 637da4886..982971885 100644 --- a/libc/inet/rpc/pmap_prot.c +++ b/libc/inet/rpc/pmap_prot.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * pmap_prot.c @@ -42,14 +43,15 @@ #include <rpc/pmap_prot.h> -bool_t xdr_pmap(xdrs, regs) -XDR *xdrs; -struct pmap *regs; +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); + 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/libc/inet/rpc/pmap_prot2.c b/libc/inet/rpc/pmap_prot2.c index 3512b7dbe..6cb7c5e1b 100644 --- a/libc/inet/rpc/pmap_prot2.c +++ b/libc/inet/rpc/pmap_prot2.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * pmap_prot2.c @@ -42,34 +43,34 @@ #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; + * struct pmap pml_map; + * struct pmaplist *pml_map; * }; * - * Compare that declaration with a corresponding xdr declaration that + * 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 {}; + * 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. + * 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 @@ -80,37 +81,38 @@ * 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; +bool_t +xdr_pmaplist (xdrs, rp) + XDR *xdrs; + struct pmaplist **rp; { - /* - * more_elements is pre-computed in case the direction is - * XDR_ENCODE or XDR_FREE. more_elements is overwritten by - * xdr_bool when the direction is XDR_DECODE. - */ - bool_t more_elements; - register int freeing = (xdrs->x_op == XDR_FREE); - register struct pmaplist **next; -#warning expect "next" might be unitialized - - 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), (xdrproc_t) xdr_pmap)) - return (FALSE); + /* + * more_elements is pre-computed in case the direction is + * XDR_ENCODE or XDR_FREE. more_elements is overwritten by + * xdr_bool when the direction is XDR_DECODE. + */ + bool_t more_elements; + int freeing = (xdrs->x_op == XDR_FREE); + struct pmaplist **next = NULL; - rp = (freeing) ? next : &((*rp)->pml_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), + (xdrproc_t) xdr_pmap)) + return FALSE; + rp = freeing ? next : &((*rp)->pml_next); + } } diff --git a/libc/inet/rpc/pmap_rmt.c b/libc/inet/rpc/pmap_rmt.c index 13b557d71..0fee124d6 100644 --- a/libc/inet/rpc/pmap_rmt.c +++ b/libc/inet/rpc/pmap_rmt.c @@ -6,27 +6,30 @@ * 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 @@ -38,25 +41,27 @@ #define __FORCE_GLIBC #include <features.h> + #include <unistd.h> #include <string.h> -#include <sys/time.h> -#include <sys/types.h> #include <rpc/rpc.h> #include <rpc/pmap_prot.h> #include <rpc/pmap_clnt.h> #include <rpc/pmap_rmt.h> +#include <sys/poll.h> #include <sys/socket.h> #include <stdio.h> #include <errno.h> -//#include <net/if.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 }; +extern u_long _create_xid (void); +static const struct timeval timeout = {3, 0}; /* * pmapper remote-call-service interface. @@ -64,44 +69,46 @@ static struct timeval timeout = { 3, 0 }; * 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; +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; + int socket = -1; + 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, - (xdrproc_t) xdr_rmtcall_args, (caddr_t) &a, - (xdrproc_t) xdr_rmtcallres, (caddr_t) &r, tout); - CLNT_DESTROY(client); - } else { - stat = RPC_FAILED; - } - (void) close(socket); - addr->sin_port = 0; - return (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, (xdrproc_t)xdr_rmtcall_args, + (caddr_t)&a, (xdrproc_t)xdr_rmtcallres, + (caddr_t)&r, tout); + CLNT_DESTROY (client); + } + else + { + stat = RPC_FAILED; + } + /* (void)__close(socket); CLNT_DESTROY already closed it */ + addr->sin_port = 0; + return stat; } @@ -109,304 +116,298 @@ u_long *port_ptr; * XDR remote call arguments * written for XDR_ENCODE direction only */ -bool_t xdr_rmtcall_args(XDR *xdrs, struct rmtcallargs *cap) +bool_t +xdr_rmtcall_args (XDR *xdrs, struct rmtcallargs *cap) { - u_int lenposition, argposition, position; + 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); + 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; +bool_t +xdr_rmtcallres (xdrs, crp) + XDR *xdrs; + struct rmtcallres *crp; { - caddr_t port_ptr; + caddr_t port_ptr; - port_ptr = (caddr_t) crp->port_ptr; - if (xdr_reference(xdrs, &port_ptr, sizeof(u_long), - (xdrproc_t) xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { - crp->port_ptr = (u_long *) port_ptr; - return ((*(crp->xdr_results)) (xdrs, crp->results_ptr)); - } - return (FALSE); + port_ptr = (caddr_t) crp->port_ptr; + if (xdr_reference (xdrs, &port_ptr, sizeof (u_long), (xdrproc_t) xdr_u_long) + && xdr_u_long (xdrs, &crp->resultslen)) + { + crp->port_ptr = (u_long *) port_ptr; + return (*(crp->xdr_results)) (xdrs, crp->results_ptr); + } + return FALSE; } -void get_myaddress( struct sockaddr_in *addr); /* * The following is kludged-up support for simple rpc broadcasts. - * Someday a large, complicated system will replace these trivial + * 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... */ +static int +internal_function +getbroadcastnets (struct in_addr *addrs, int sock, char *buf) + /* int sock: any valid socket will do */ + /* char *buf: why allocate more when we can use existing... */ { -#ifdef __linux__ - struct sockaddr_in addr; - - get_myaddress(&addr); -#if 1 - printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); -#else - addrs[0] = inet_makeaddr(inet_netof(addr.sin_addr), INADDR_ANY); -#endif - return 1; -#else - struct ifconf ifc; - struct ifreq ifreq, *ifr; - struct sockaddr_in *sin; - int n, i; + 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); + 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; } - 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) { -#if 1 - printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); -#else - addrs[i++] = inet_makeaddr(inet_netof - (sin->sin_addr.s_addr), - INADDR_ANY); -#endif - } else { - addrs[i++] = ((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr; - } -#else /* 4.2 BSD */ -#if 1 - printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); -#else - addrs[i++] = inet_makeaddr(inet_netof - (sin->sin_addr.s_addr), INADDR_ANY); -#endif + 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); -#endif + } + return i; } -//typedef bool_t(*resultproc_t) (); -//void _rpc_dtablesize(void ); - 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 */ +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]; + enum clnt_stat stat = RPC_FAILED; + AUTH *unix_auth = authunix_create_default (); + XDR xdr_stream; + XDR *xdrs = &xdr_stream; + struct timeval t; + int outlen, inlen, nets; + socklen_t fromlen; + int sock; + int on = 1; + struct pollfd fd; + int milliseconds; + int i; + bool_t done = FALSE; + 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; + 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; - } + /* + * 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; + 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 */ + fd.fd = sock; + fd.events = POLLIN; + 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); */ + msg.rm_xid = xid = _create_xid (); + 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; + } } -#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; + if (eachresult == NULL) + { + stat = RPC_SUCCESS; + 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 = (xdrproc_t) xdr_rmtcallres; - readfds = mask; - switch (select(_rpc_dtablesize(), &readfds, NULL, NULL, &t)) { - - case 0: /* timed out */ - stat = RPC_TIMEDOUT; - continue; + recv_again: + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = (caddr_t) & r; + msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_rmtcallres; + milliseconds = t.tv_sec * 1000 + t.tv_usec / 1000; + switch (poll(&fd, 1, milliseconds)) + { - case -1: /* some kind of error */ - if (errno == EINTR) - goto recv_again; - perror("Broadcast select problem"); - stat = RPC_CANTRECV; - goto done_broad; + case 0: /* timed out */ + stat = RPC_TIMEDOUT; + continue; - } /* end of select results switch */ - try_again: - fromlen = sizeof(struct sockaddr); + case -1: /* some kind of error */ + if (errno == EINTR) + goto recv_again; + perror (_("Broadcast poll problem")); + stat = RPC_CANTRECV; + goto done_broad; - 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 { + } /* end of poll 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 ((size_t) 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 (((u_int32_t) msg.rm_xid == (u_int32_t) 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 */ + /* some kind of deserialization problem ... */ + if ((u_int32_t) msg.rm_xid == (u_int32_t) xid) + fprintf (stderr, "Broadcast deserialization problem"); + /* otherwise, just random garbage */ #endif - } - xdrs->x_op = XDR_FREE; - msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; - (void) xdr_replymsg(xdrs, &msg); - (void) (*xresults) (xdrs, resultsp); - xdr_destroy(xdrs); - if (done) { - stat = RPC_SUCCESS; - goto done_broad; - } else { - goto recv_again; - } } - done_broad: - (void) close(sock); - AUTH_DESTROY(unix_auth); - return (stat); + xdrs->x_op = XDR_FREE; + msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; + (void) xdr_replymsg (xdrs, &msg); + (void) (*xresults) (xdrs, resultsp); + xdr_destroy (xdrs); + if (done) + { + stat = RPC_SUCCESS; + goto done_broad; + } + else + { + goto recv_again; + } + } +done_broad: + (void) close (sock); + AUTH_DESTROY (unix_auth); + return stat; } diff --git a/libc/inet/rpc/rpc_callmsg.c b/libc/inet/rpc/rpc_callmsg.c index c6afbdcee..d509523e2 100644 --- a/libc/inet/rpc/rpc_callmsg.c +++ b/libc/inet/rpc/rpc_callmsg.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * rpc_callmsg.c @@ -37,149 +38,169 @@ * */ -#include <sys/param.h> +#define __FORCE_GLIBC +#include <features.h> +#include <string.h> +#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; +bool_t +xdr_callmsg (XDR *xdrs, struct rpc_msg *cmsg) { - register void *buf; - register struct opaque_auth *oa; + int32_t *buf; + struct opaque_auth *oa; - if (xdrs->x_op == XDR_ENCODE) { - if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { - return (FALSE); + 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_INT32 (buf, oa->oa_length); + if (oa->oa_length) + { + memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length); + buf = (int32_t *) ((char *) buf + RNDUP (oa->oa_length)); + } + oa = &cmsg->rm_call.cb_verf; + IXDR_PUT_ENUM (buf, oa->oa_flavor); + IXDR_PUT_INT32 (buf, oa->oa_length); + if (oa->oa_length) + { + memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length); + /* no real need.... + buf = (long *) ((char *) buf + RNDUP(oa->oa_length)); + */ + } + 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_INT32 (buf); + if (oa->oa_length) + { + if (oa->oa_length > MAX_AUTH_BYTES) + return FALSE; + if (oa->oa_base == NULL) + { + oa->oa_base = (caddr_t) + mem_alloc (oa->oa_length); } - if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { - return (FALSE); + buf = XDR_INLINE (xdrs, RNDUP (oa->oa_length)); + if (buf == NULL) + { + if (xdr_opaque (xdrs, oa->oa_base, + oa->oa_length) == FALSE) + return FALSE; } - 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); + else + { + memcpy (oa->oa_base, (caddr_t) buf, oa->oa_length); + /* no real need.... + buf = (long *) ((char *) buf + + RNDUP(oa->oa_length)); + */ } - } - 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); + } + 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_INT32 (buf); + } + if (oa->oa_length) + { + if (oa->oa_length > MAX_AUTH_BYTES) + return FALSE; + if (oa->oa_base == NULL) + { + oa->oa_base = (caddr_t) + mem_alloc (oa->oa_length); + } + buf = XDR_INLINE (xdrs, RNDUP (oa->oa_length)); + if (buf == NULL) + { + if (xdr_opaque (xdrs, oa->oa_base, + oa->oa_length) == FALSE) + return FALSE; + } + else + { + memcpy (oa->oa_base, (caddr_t) buf, oa->oa_length); + /* no real need... + buf = (long *) ((char *) buf + + RNDUP(oa->oa_length)); + */ } + } + 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); + } + 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/libc/inet/rpc/rpc_commondata.c b/libc/inet/rpc/rpc_commondata.c index b936017ae..6b22b3f66 100644 --- a/libc/inet/rpc/rpc_commondata.c +++ b/libc/inet/rpc/rpc_commondata.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,39 +5,42 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> #include <rpc/rpc.h> + +#ifdef _RPC_THREAD_SAFE_ +#undef svc_fdset +#undef rpc_createerr +#undef svc_pollfd +#undef svc_max_pollfd +#endif /* _RPC_THREAD_SAFE_ */ + /* * This file should only contain common data (global data) that is exported - * by public interfaces + * 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; +struct pollfd *svc_pollfd; +int svc_max_pollfd; diff --git a/libc/inet/rpc/rpc_dtablesize.c b/libc/inet/rpc/rpc_dtablesize.c index fdf6c1b1f..6a46aaf30 100644 --- a/libc/inet/rpc/rpc_dtablesize.c +++ b/libc/inet/rpc/rpc_dtablesize.c @@ -6,42 +6,49 @@ * 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 + #define __FORCE_GLIBC +#define __USE_BSD #include <features.h> -#include <rpc/clnt.h> #include <unistd.h> +#include <rpc/clnt.h> + /* * Cache the result of getdtablesize(), so we don't have to do an * expensive system call every time. */ -int _rpc_dtablesize(void) +int +_rpc_dtablesize (void) { - static int size; + static int size; + + if (size == 0) + size = getdtablesize (); - if (size == 0) { - size = getdtablesize(); - } - return (size); + return size; } diff --git a/libc/inet/rpc/rpc_prot.c b/libc/inet/rpc/rpc_prot.c index 1904bb0e6..bace2a7c4 100644 --- a/libc/inet/rpc/rpc_prot.c +++ b/libc/inet/rpc/rpc_prot.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * rpc_prot.c @@ -43,6 +44,9 @@ * routines are also in this program. */ +#define __FORCE_GLIBC +#include <features.h> + #include <sys/param.h> #include <rpc/rpc.h> @@ -53,25 +57,23 @@ * XDR an opaque authentication struct * (see auth.h) */ -bool_t xdr_opaque_auth(xdrs, ap) -register XDR *xdrs; -register struct opaque_auth *ap; +bool_t +xdr_opaque_auth (XDR *xdrs, 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); + 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; +bool_t +xdr_des_block (XDR *xdrs, des_block *blkp) { - return (xdr_opaque(xdrs, (caddr_t) blkp, sizeof(des_block))); + return xdr_opaque (xdrs, (caddr_t) blkp, sizeof (des_block)); } /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ @@ -79,75 +81,71 @@ register des_block *blkp; /* * 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; +bool_t +xdr_accepted_reply (XDR *xdrs, 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))); - default: /* silence the warnings */ - } - return (TRUE); /* TRUE => open ended set of problems */ + /* 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))); + default: + return TRUE; + } + 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; +bool_t +xdr_rejected_reply (XDR *xdrs, 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))); - default: /* silence the warnings */ - } - return (FALSE); + /* 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, (xdrproc_t) xdr_accepted_reply}, - {(int) MSG_DENIED, (xdrproc_t) xdr_rejected_reply}, - {__dontcare__, NULL_xdrproc_t} -}; +static const struct xdr_discrim reply_dscrm[3] = +{ + {(int) MSG_ACCEPTED, (xdrproc_t) xdr_accepted_reply}, + {(int) MSG_DENIED, (xdrproc_t) xdr_rejected_reply}, + {__dontcare__, NULL_xdrproc_t}}; /* * XDR a reply message */ -bool_t xdr_replymsg(xdrs, rmsg) -register XDR *xdrs; -register struct rpc_msg *rmsg; +bool_t +xdr_replymsg (xdrs, rmsg) + XDR *xdrs; + 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); + 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; } @@ -156,131 +154,129 @@ register struct rpc_msg *rmsg; * 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; +bool_t +xdr_callhdr (xdrs, cmsg) + XDR *xdrs; + 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); + 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; +static void +accepted (enum accept_stat acpt_stat, + 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; - - default: /* silence the warnings */ - } - /* 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; + 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; +static void +rejected (enum reject_stat rjct_stat, + struct rpc_err *error) { - - switch (rjct_stat) { - - case RPC_VERSMISMATCH: - error->re_status = RPC_VERSMISMATCH; - return; - - case AUTH_ERROR: - error->re_status = RPC_AUTHERROR; - return; - - default: /* silence the warnings */ - } - /* 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; + switch (rjct_stat) + { + case RPC_VERSMISMATCH: + error->re_status = RPC_VERSMISMATCH; + return; + case AUTH_ERROR: + error->re_status = RPC_AUTHERROR; + return; + default: + /* 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; + return; + } } /* * given a reply message, fills in the error */ -void _seterr_reply(msg, error) -register struct rpc_msg *msg; -register struct rpc_err *error; +void +_seterr_reply (struct rpc_msg *msg, + struct rpc_err *error) { - - /* optimized for normal, SUCCESSful case */ - switch (msg->rm_reply.rp_stat) { - - case MSG_ACCEPTED: - if (msg->acpted_rply.ar_stat == SUCCESS) { - error->re_status = RPC_SUCCESS; - return; - }; - accepted(msg->acpted_rply.ar_stat, error); - break; - - case MSG_DENIED: - rejected(msg->rjcted_rply.rj_stat, error); - break; - - default: - error->re_status = RPC_FAILED; - error->re_lb.s1 = (long) (msg->rm_reply.rp_stat); - break; - } - switch (error->re_status) { - - case RPC_VERSMISMATCH: - error->re_vers.low = msg->rjcted_rply.rj_vers.low; - error->re_vers.high = msg->rjcted_rply.rj_vers.high; - break; - - case RPC_AUTHERROR: - error->re_why = msg->rjcted_rply.rj_why; - break; - - case RPC_PROGVERSMISMATCH: - error->re_vers.low = msg->acpted_rply.ar_vers.low; - error->re_vers.high = msg->acpted_rply.ar_vers.high; - break; - - default: /* silence the warnings */ - } + /* optimized for normal, SUCCESSful case */ + switch (msg->rm_reply.rp_stat) + { + case MSG_ACCEPTED: + if (msg->acpted_rply.ar_stat == SUCCESS) + { + error->re_status = RPC_SUCCESS; + return; + }; + accepted (msg->acpted_rply.ar_stat, error); + break; + + case MSG_DENIED: + rejected (msg->rjcted_rply.rj_stat, error); + break; + + default: + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long) (msg->rm_reply.rp_stat); + break; + } + switch (error->re_status) + { + + case RPC_VERSMISMATCH: + error->re_vers.low = msg->rjcted_rply.rj_vers.low; + error->re_vers.high = msg->rjcted_rply.rj_vers.high; + break; + + case RPC_AUTHERROR: + error->re_why = msg->rjcted_rply.rj_why; + break; + + case RPC_PROGVERSMISMATCH: + error->re_vers.low = msg->acpted_rply.ar_vers.low; + error->re_vers.high = msg->acpted_rply.ar_vers.high; + break; + default: + break; + } } diff --git a/libc/inet/rpc/rpc_thread.c b/libc/inet/rpc/rpc_thread.c new file mode 100644 index 000000000..267149b62 --- /dev/null +++ b/libc/inet/rpc/rpc_thread.c @@ -0,0 +1,152 @@ +#define __FORCE_GLIBC +#include <features.h> + +#include <stdio.h> +#include <rpc/rpc.h> +#include <assert.h> + +#ifdef _RPC_THREAD_SAFE_ + +#include <bits/libc-lock.h> +#include <bits/libc-tsd.h> + + +/* Variable used in non-threaded applications or for the first thread. */ +static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem; +static struct rpc_thread_variables *__libc_tsd_RPC_VARS_data = + &__libc_tsd_RPC_VARS_mem; + +/* + * Task-variable destructor + */ +void +__rpc_thread_destroy (void) +{ + struct rpc_thread_variables *tvp = __rpc_thread_variables(); + + if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) { + __rpc_thread_svc_cleanup (); + __rpc_thread_clnt_cleanup (); + __rpc_thread_key_cleanup (); + free (tvp->authnone_private_s); + free (tvp->clnt_perr_buf_s); + free (tvp->clntraw_private_s); + free (tvp->svcraw_private_s); + free (tvp->authdes_cache_s); + free (tvp->authdes_lru_s); + free (tvp); + } +} + + +/* + * Initialize RPC multi-threaded operation + */ +static void +rpc_thread_multi (void) +{ + __libc_tsd_set (RPC_VARS, &__libc_tsd_RPC_VARS_mem); +} + + +struct rpc_thread_variables * +__rpc_thread_variables (void) +{ + __libc_once_define (static, once); + struct rpc_thread_variables *tvp; + + tvp = __libc_tsd_get (RPC_VARS); + if (tvp == NULL) { + __libc_once (once, rpc_thread_multi); + tvp = __libc_tsd_get (RPC_VARS); + if (tvp == NULL) { + tvp = calloc (1, sizeof *tvp); + if (tvp != NULL) + __libc_tsd_set (RPC_VARS, tvp); + else + tvp = __libc_tsd_RPC_VARS_data; + } + } + return tvp; +} + + +/* Global variables If we're single-threaded, or if this is the first + thread using the variable, use the existing global variable. This + provides backwards compatability for existing applications which + dynamically link against this code. */ +#undef svc_fdset +#undef rpc_createerr +#undef svc_pollfd +#undef svc_max_pollfd + +fd_set * +__rpc_thread_svc_fdset (void) +{ + struct rpc_thread_variables *tvp; + + tvp = __rpc_thread_variables (); + if (tvp == &__libc_tsd_RPC_VARS_mem) + return &svc_fdset; + return &tvp->svc_fdset_s; +} + +struct rpc_createerr * +__rpc_thread_createerr (void) +{ + struct rpc_thread_variables *tvp; + + tvp = __rpc_thread_variables (); + if (tvp == &__libc_tsd_RPC_VARS_mem) + return &rpc_createerr; + return &tvp->rpc_createerr_s; +} + +struct pollfd ** +__rpc_thread_svc_pollfd (void) +{ + struct rpc_thread_variables *tvp; + + tvp = __rpc_thread_variables (); + if (tvp == &__libc_tsd_RPC_VARS_mem) + return &svc_pollfd; + return &tvp->svc_pollfd_s; +} + +int * +__rpc_thread_svc_max_pollfd (void) +{ + struct rpc_thread_variables *tvp; + + tvp = __rpc_thread_variables (); + if (tvp == &__libc_tsd_RPC_VARS_mem) + return &svc_max_pollfd; + return &tvp->svc_max_pollfd_s; +} +#else + +fd_set * __rpc_thread_svc_fdset (void) +{ + extern fd_set svc_fdset; + return &(svc_fdset); +} + +struct rpc_createerr * __rpc_thread_createerr (void) +{ + extern struct rpc_createerr rpc_createerr; + return &(rpc_createerr); +} + +struct pollfd ** __rpc_thread_svc_pollfd (void) +{ + extern struct pollfd *svc_pollfd; + return &(svc_pollfd); +} + +int * __rpc_thread_svc_max_pollfd (void) +{ + extern int svc_max_pollfd; + return &(svc_max_pollfd); +} + +#endif /* _RPC_THREAD_SAFE_ */ diff --git a/libc/inet/rpc/rtime.c b/libc/inet/rpc/rtime.c new file mode 100644 index 000000000..683078142 --- /dev/null +++ b/libc/inet/rpc/rtime.c @@ -0,0 +1,149 @@ +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; +#endif +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1988 by Sun Microsystems, Inc. + */ +/* + * rtime - get time from remote machine + * + * gets time, obtaining value from host + * on the udp/time socket. Since timeserver returns + * with time of day in seconds since Jan 1, 1900, must + * subtract seconds before Jan 1, 1970 to get + * what unix uses. + */ +#define __FORCE_GLIBC +#include <features.h> + +#include <stdio.h> +#include <unistd.h> +#include <rpc/rpc.h> +#include <rpc/clnt.h> +#include <sys/types.h> +#include <sys/poll.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <rpc/auth_des.h> +#include <errno.h> +#include <netinet/in.h> + +#define NYEARS (u_long)(1970 - 1900) +#define TOFFSET (u_long)(60*60*24*(365*NYEARS + (NYEARS/4))) + +static void do_close (int); + +static void +do_close (int s) +{ + int save; + + save = errno; + close (s); + __set_errno (save); +} + +int +rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep, + struct rpc_timeval *timeout) +{ + int s; + struct pollfd fd; + int milliseconds; + int res; + unsigned long thetime; + struct sockaddr_in from; + int fromlen; + int type; + + if (timeout == NULL) + type = SOCK_STREAM; + else + type = SOCK_DGRAM; + + s = socket (AF_INET, type, 0); + if (s < 0) + return (-1); + + addrp->sin_family = AF_INET; + addrp->sin_port = htons (IPPORT_TIMESERVER); + if (type == SOCK_DGRAM) + { + res = sendto (s, (char *) &thetime, sizeof (thetime), 0, + (struct sockaddr *) addrp, sizeof (*addrp)); + if (res < 0) + { + do_close (s); + return -1; + } + milliseconds = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000); + fd.fd = s; + fd.events = POLLIN; + do + res = poll (&fd, 1, milliseconds); + while (res < 0 && errno == EINTR); + if (res <= 0) + { + if (res == 0) + __set_errno (ETIMEDOUT); + do_close (s); + return (-1); + } + fromlen = sizeof (from); + res = recvfrom (s, (char *) &thetime, sizeof (thetime), 0, + (struct sockaddr *) &from, &fromlen); + do_close (s); + if (res < 0) + return -1; + } + else + { + if (connect (s, (struct sockaddr *) addrp, sizeof (*addrp)) < 0) + { + do_close (s); + return -1; + } + res = read (s, (char *) &thetime, sizeof (thetime)); + do_close (s); + if (res < 0) + return (-1); + } + if (res != sizeof (thetime)) + { + __set_errno (EIO); + return -1; + } + thetime = ntohl (thetime); + timep->tv_sec = thetime - TOFFSET; + timep->tv_usec = 0; + return 0; +} diff --git a/libc/inet/rpc/svc.c b/libc/inet/rpc/svc.c index 89f10a696..92084bcc1 100644 --- a/libc/inet/rpc/svc.c +++ b/libc/inet/rpc/svc.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,30 +5,27 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> - /* * svc.c, Server-side remote procedure call interface. * @@ -40,299 +36,288 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ -#define __USE_XOPEN -#include <sys/errno.h> +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + +#include <errno.h> +#include <unistd.h> #include <rpc/rpc.h> +#include <rpc/svc.h> #include <rpc/pmap_clnt.h> -#ifdef __linux__ -#include <sys/types.h> -#include <sys/select.h> -#endif +#include <sys/poll.h> -extern int errno; - -#ifdef FD_SETSIZE -static SVCXPRT **xports; +#ifdef _RPC_THREAD_SAFE_ +#define xports ((SVCXPRT **)RPC_THREAD_VARIABLE(svc_xports_s)) #else -#define NOFILE 32 - -static SVCXPRT *xports[NOFILE]; -#endif /* def FD_SETSIZE */ +static SVCXPRT **xports; +#endif #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(); +#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 + appropriate procedure. */ +struct svc_callout { + struct svc_callout *sc_next; + rpcprog_t sc_prog; + rpcvers_t sc_vers; + void (*sc_dispatch) (struct svc_req *, SVCXPRT *); +}; +#ifdef _RPC_THREAD_SAFE_ +#define svc_head ((struct svc_callout *)RPC_THREAD_VARIABLE(svc_head_s)) +#else +static struct svc_callout *svc_head; +#endif /* *************** SVCXPRT related stuff **************** */ -/* - * Activate a transport handle. - */ -void xprt_register(xprt) -SVCXPRT *xprt; +/* Activate a transport handle. */ +void +xprt_register (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 */ - + register int sock = xprt->xp_sock; + register int i; + + if (xports == NULL) + { + xports = (SVCXPRT **) malloc (_rpc_dtablesize () * sizeof (SVCXPRT *)); + if (xports == NULL) /* Don´t add handle */ + return; + } + + if (sock < _rpc_dtablesize ()) + { + xports[sock] = xprt; + if (sock < FD_SETSIZE) + FD_SET (sock, &svc_fdset); + + /* Check if we have an empty slot */ + for (i = 0; i < svc_max_pollfd; ++i) + if (svc_pollfd[i].fd == -1) + { + svc_pollfd[i].fd = sock; + svc_pollfd[i].events = (POLLIN | POLLPRI | + POLLRDNORM | POLLRDBAND); + return; + } + + ++svc_max_pollfd; + svc_pollfd = realloc (svc_pollfd, + sizeof (struct pollfd) * svc_max_pollfd); + if (svc_pollfd == NULL) /* Out of memory */ + return; + + svc_pollfd[svc_max_pollfd - 1].fd = sock; + svc_pollfd[svc_max_pollfd - 1].events = (POLLIN | POLLPRI | + POLLRDNORM | POLLRDBAND); + } } -/* - * De-activate a transport handle. - */ -void xprt_unregister(xprt) -SVCXPRT *xprt; +/* De-activate a transport handle. */ +void +xprt_unregister (SVCXPRT *xprt) { - register int sock = xprt->xp_sock; + register int sock = xprt->xp_sock; + register int i; -#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 */ + if ((sock < _rpc_dtablesize ()) && (xports[sock] == xprt)) + { + xports[sock] = (SVCXPRT *) 0; + + if (sock < FD_SETSIZE) + FD_CLR (sock, &svc_fdset); + + for (i = 0; i < svc_max_pollfd; ++i) + if (svc_pollfd[i].fd == sock) + svc_pollfd[i].fd = -1; + } } /* ********************** 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 (SVCXPRT *xprt, u_long prog, - u_long vers, __dispatch_fn_t dispatch, u_long protocol) +/* Search the callout list for a program number, return the callout + struct. */ +static struct svc_callout * +svc_find (rpcprog_t prog, rpcvers_t vers, struct svc_callout **prev) { - 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); + 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; } -/* - * Remove a service program from the callout list. - */ -void svc_unregister(prog, vers) -u_long prog; -u_long vers; +/* 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 (SVCXPRT * xprt, rpcprog_t prog, rpcvers_t vers, + void (*dispatch) (struct svc_req *, SVCXPRT *), + rpcproc_t protocol) { - 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); + 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; } -/* - * 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; +/* Remove a service program from the callout list. */ +void +svc_unregister (rpcprog_t prog, rpcvers_t vers) { - register struct svc_callout *s, *p; + struct svc_callout *prev; + register struct svc_callout *s; - 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); + 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 */ + pmap_unset (prog, vers); } /* ******************* 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; +/* Send a reply to an rpc request */ +bool_t +svc_sendreply (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)); + 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; +/* No procedure error reply */ +void +svcerr_noproc (register SVCXPRT *xprt) { - struct rpc_msg rply; + 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); + 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; +/* Can't decode args error reply */ +void +svcerr_decode (register SVCXPRT *xprt) { - struct rpc_msg rply; + 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); + 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; +/* Some system error */ +void +svcerr_systemerr (register SVCXPRT *xprt) { - struct rpc_msg rply; + 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); + 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; +/* Authentication error reply */ +void +svcerr_auth (SVCXPRT *xprt, enum auth_stat why) { - struct rpc_msg rply; + 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); + 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; +/* Auth too weak error reply */ +void +svcerr_weakauth (SVCXPRT *xprt) { - - svcerr_auth(xprt, AUTH_TOOWEAK); + svcerr_auth (xprt, AUTH_TOOWEAK); } -/* - * Program unavailable error reply - */ -void svcerr_noprog(xprt) -register SVCXPRT *xprt; +/* Program unavailable error reply */ +void +svcerr_noprog (register SVCXPRT *xprt) { - struct rpc_msg rply; + 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); + 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; +/* Program version mismatch error reply */ +void +svcerr_progvers (register SVCXPRT *xprt, rpcvers_t low_vers, + rpcvers_t 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); + 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 ******************* */ @@ -345,132 +330,163 @@ u_long high_vers; * 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: + * 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. + * 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; +void +svc_getreq (int rdfds) { -#ifdef FD_SETSIZE - fd_set readfds; + fd_set readfds; - FD_ZERO(&readfds); -/*#ifdef __linux__*/ -#if 0 - readfds = rdfds; -#else - readfds.fds_bits[0] = rdfds; -#endif - svc_getreqset(&readfds); -#else - int readfds = rdfds & svc_fds; + FD_ZERO (&readfds); + readfds.fds_bits[0] = rdfds; + svc_getreqset (&readfds); +} - svc_getreqset(&readfds); -#endif /* def FD_SETSIZE */ +void +svc_getreqset (fd_set *readfds) +{ + register u_int32_t mask; + register u_int32_t *maskp; + register int setsize; + register int sock; + register int bit; + + setsize = _rpc_dtablesize (); + maskp = (u_int32_t *) readfds->fds_bits; + for (sock = 0; sock < setsize; sock += 32) + for (mask = *maskp++; (bit = ffs (mask)); mask ^= (1 << (bit - 1))) + svc_getreq_common (sock + bit - 1); } -void svc_getreqset(readfds) -#ifdef FD_SETSIZE -fd_set *readfds; +void +svc_getreq_poll (struct pollfd *pfdp, int pollretval) { -#else -int *readfds; + register int i; + register int fds_found; + + for (i = fds_found = 0; i < svc_max_pollfd && fds_found < pollretval; ++i) + { + register struct pollfd *p = &pfdp[i]; + + if (p->fd != -1 && p->revents) + { + /* fd has input waiting */ + ++fds_found; + + if (p->revents & POLLNVAL) + xprt_unregister (xports[p->fd]); + else + svc_getreq_common (p->fd); + } + } +} + + +void +svc_getreq_common (const int fd) { - 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(); -#ifdef __linux__ -/*#define NFDBITS 32*/ - maskp = (u_long *) readfds; -#else - maskp = (u_long *) readfds->fds_bits; -#endif - 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); + enum xprt_stat stat; + struct rpc_msg msg; + register SVCXPRT *xprt; + 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]); + + xprt = xports[fd]; + /* Do we control fd? */ + if (xprt == NULL) + return; + + /* now receive msgs from xprtprt (support batch calls) */ + do + { + if (SVC_RECV (xprt, &msg)) + { + /* now find the exported program and call it */ + struct svc_callout *s; + struct svc_req r; + enum auth_stat why; + rpcvers_t low_vers; + rpcvers_t high_vers; + int prog_found; + + r.rq_clntcred = &(cred_area[2 * MAX_AUTH_BYTES]); + 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 */ + /* Check for null flavor and bypass these calls if possible */ + + if (msg.rm_call.cb_cred.oa_flavor == AUTH_NULL) + { + r.rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; + r.rq_xprt->xp_verf.oa_length = 0; + } + else 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); } + +#ifdef _RPC_THREAD_SAFE_ + +void +__rpc_thread_svc_cleanup (void) +{ + struct svc_callout *svcp; + + while ((svcp = svc_head) != NULL) + svc_unregister (svcp->sc_prog, svcp->sc_vers); +} + +#endif /* _RPC_THREAD_SAFE_ */ diff --git a/libc/inet/rpc/svc_auth.c b/libc/inet/rpc/svc_auth.c index bb7061339..1ec8626c0 100644 --- a/libc/inet/rpc/svc_auth.c +++ b/libc/inet/rpc/svc_auth.c @@ -1,5 +1,4 @@ -#define __FORCE_GLIBC -#include <features.h> +/* @(#)svc_auth.c 2.4 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 @@ -7,11 +6,11 @@ * 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. @@ -28,44 +27,60 @@ * 2550 Garcia Avenue * Mountain View, California 94043 */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif /* - * svc_auth_nodes.c, Server-side rpc authenticator interface, - * *WITHOUT* DES authentication. + * svc_auth.c, Server-side rpc authenticator interface. * * Copyright (C) 1984, Sun Microsystems, Inc. */ #include <rpc/rpc.h> +#include <rpc/svc.h> +#include <rpc/svc_auth.h> /* - * svcauthsw is the bdevsw of server side authentication. - * + * 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; + * 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 enum auth_stat _svcauth_null (struct svc_req *, struct rpc_msg *); + /* no authentication */ +extern enum auth_stat _svcauth_unix (struct svc_req *, struct rpc_msg *); + /* unix style (uid, gids) */ +extern enum auth_stat _svcauth_short (struct svc_req *, struct rpc_msg *); + /* short hand unix style */ +#ifdef CONFIG_AUTH_DES +extern enum auth_stat _svcauth_des (struct svc_req *, struct rpc_msg *); + /* des style */ +#endif -static struct { - enum auth_stat (*authenticator) (); -} svcauthsw[] = { - {_svcauth_null}, /* AUTH_NULL */ - {_svcauth_unix}, /* AUTH_UNIX */ - {_svcauth_short}, /* AUTH_SHORT */ +static const struct + { + enum auth_stat (*authenticator) (struct svc_req *, struct rpc_msg *); + } +svcauthsw[] = +{ + { _svcauth_null }, /* AUTH_NULL */ + { _svcauth_unix }, /* AUTH_UNIX */ + { _svcauth_short }, /* AUTH_SHORT */ +#ifdef CONFIG_AUTH_DES + { _svcauth_des } /* AUTH_DES */ +#endif }; - -#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */ +#define AUTH_MAX 3 /* HIGHEST AUTH NUMBER */ /* @@ -76,7 +91,7 @@ static struct { * 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; + * NB: rqst->rq_cxprt->verf must be pre-allocated; * its length is set appropriately. * * The caller still owns and is responsible for msg->u.cmb.cred and @@ -86,27 +101,23 @@ static struct { * 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; +enum auth_stat +_authenticate (register struct svc_req *rqst, struct rpc_msg *msg) { - register int cred_flavor; + 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)); - } + 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); + return AUTH_REJECTEDCRED; } -enum auth_stat _svcauth_null( /*rqst, msg */ ) - /*struct svc_req *rqst; - struct rpc_msg *msg; */ +static enum auth_stat +_svcauth_null (struct svc_req *rqst, struct rpc_msg *msg) { - - return (AUTH_OK); + return AUTH_OK; } diff --git a/libc/inet/rpc/svc_auth_unix.c b/libc/inet/rpc/svc_auth_unix.c index 3d1de4ee4..84c563cdf 100644 --- a/libc/inet/rpc/svc_auth_unix.c +++ b/libc/inet/rpc/svc_auth_unix.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,29 +5,27 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> /* * svc_auth_unix.c @@ -41,82 +38,108 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + #include <stdio.h> +#include <string.h> #include <rpc/rpc.h> +#include <rpc/svc.h> /* * Unix longhand authenticator */ -enum auth_stat _svcauth_unix(rqst, msg) -register struct svc_req *rqst; -register struct rpc_msg *msg; +enum auth_stat +_svcauth_unix (struct svc_req *rqst, 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; + enum auth_stat stat; + XDR xdrs; + struct authunix_parms *aup; + int32_t *buf; + struct area + { + struct authunix_parms area_aup; + char area_machname[MAX_MACHINE_NAME + 1]; + gid_t area_gids[NGRPS]; + } + *area; + u_int auth_len; + u_int str_len, gid_len; + u_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 = (long *)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; + 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_INT32 (buf); + if (str_len > MAX_MACHINE_NAME) + { + stat = AUTH_BADCRED; + goto done; + } + memcpy (aup->aup_machname, (caddr_t) buf, (u_int) str_len); + aup->aup_machname[str_len] = 0; + str_len = RNDUP (str_len); + buf = (int32_t *) ((char *) buf + str_len); + aup->aup_uid = IXDR_GET_LONG (buf); + aup->aup_gid = IXDR_GET_LONG (buf); + gid_len = IXDR_GET_U_INT32 (buf); + if (gid_len > NGRPS) + { + 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); + aup->aup_len = gid_len; + for (i = 0; i < gid_len; i++) + { + aup->aup_gids[i] = IXDR_GET_LONG (buf); + } + /* + * five is the smallest unix credentials structure - + * timestamp, hostname len (0), uid, gid, and gids len (0). + */ + if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) + { + (void) printf ("bad auth_len gid %d str %d auth %d\n", + gid_len, str_len, auth_len); + stat = AUTH_BADCRED; + goto done; + } + } + else if (!xdr_authunix_parms (&xdrs, aup)) + { + xdrs.x_op = XDR_FREE; + (void) xdr_authunix_parms (&xdrs, aup); + stat = AUTH_BADCRED; + goto done; + } + + /* get the verifier */ + if ((u_int)msg->rm_call.cb_verf.oa_length) + { + rqst->rq_xprt->xp_verf.oa_flavor = + msg->rm_call.cb_verf.oa_flavor; + rqst->rq_xprt->xp_verf.oa_base = + msg->rm_call.cb_verf.oa_base; + rqst->rq_xprt->xp_verf.oa_length = + msg->rm_call.cb_verf.oa_length; + } + else + { + rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL; + rqst->rq_xprt->xp_verf.oa_length = 0; + } + stat = AUTH_OK; +done: + XDR_DESTROY (&xdrs); + return stat; } @@ -124,9 +147,9 @@ register struct rpc_msg *msg; * 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; +/*ARGSUSED */ +enum auth_stat +_svcauth_short (struct svc_req *rqst, struct rpc_msg *msg) { - return (AUTH_REJECTEDCRED); + return AUTH_REJECTEDCRED; } diff --git a/libc/inet/rpc/svc_raw.c b/libc/inet/rpc/svc_raw.c index 17d620eba..e4752a6cd 100644 --- a/libc/inet/rpc/svc_raw.c +++ b/libc/inet/rpc/svc_raw.c @@ -6,153 +6,160 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. + * This lets us simulate rpc and get rpc (round trip) overhead, without + * any interference from the kernel. * * Copyright (C) 1984, Sun Microsystems, Inc. */ #include <rpc/rpc.h> - +#include <rpc/svc.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 +struct svcraw_private_s + { + char _raw_buf[UDPMSGSIZE]; + SVCXPRT server; + XDR xdr_stream; + char verf_body[MAX_AUTH_BYTES]; + }; +#ifdef _RPC_THREAD_SAFE_ +#define svcraw_private ((struct svcraw_private_s *)RPC_THREAD_VARIABLE(svcraw_private_s)) +#else +static struct svcraw_private_s *svcraw_private; +#endif + +static bool_t svcraw_recv (SVCXPRT *, struct rpc_msg *); +static enum xprt_stat svcraw_stat (SVCXPRT *); +static bool_t svcraw_getargs (SVCXPRT *, xdrproc_t, caddr_t); +static bool_t svcraw_reply (SVCXPRT *, struct rpc_msg *); +static bool_t svcraw_freeargs (SVCXPRT *, xdrproc_t, caddr_t); +static void svcraw_destroy (SVCXPRT *); + +static struct xp_ops server_ops = +{ + svcraw_recv, + svcraw_stat, + svcraw_getargs, + svcraw_reply, + svcraw_freeargs, + svcraw_destroy }; -SVCXPRT *svcraw_create() +SVCXPRT * +svcraw_create (void) { - 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); + struct svcraw_private_s *srp = svcraw_private; + + if (srp == 0) + { + srp = (struct svcraw_private_s *) calloc (1, sizeof (*srp)); + if (srp == 0) + return NULL; + } + 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() +static enum xprt_stat +svcraw_stat (SVCXPRT *xprt) { - - return (XPRT_IDLE); + return XPRT_IDLE; } -static bool_t svcraw_recv(xprt, msg) -SVCXPRT *xprt; -struct rpc_msg *msg; +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); + struct svcraw_private_s *srp = svcraw_private; + XDR *xdrs; + + if (srp == 0) + return FALSE; + 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; +static bool_t +svcraw_reply (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); + struct svcraw_private_s *srp = svcraw_private; + 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; +static bool_t +svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) { - register struct svcraw_private *srp = svcraw_private; + struct svcraw_private_s *srp = svcraw_private; - if (srp == 0) - return (FALSE); - return ((*xdr_args) (&srp->xdr_stream, args_ptr)); + 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; +static bool_t +svcraw_freeargs (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)); + struct svcraw_private_s *srp = svcraw_private; + 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() +static void +svcraw_destroy (SVCXPRT *xprt) { } diff --git a/libc/inet/rpc/svc_run.c b/libc/inet/rpc/svc_run.c index cae787b92..3ef9fbd24 100644 --- a/libc/inet/rpc/svc_run.c +++ b/libc/inet/rpc/svc_run.c @@ -1,7 +1,3 @@ -/* @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC */ -#define __FORCE_GLIBC -#include <features.h> - /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,62 +5,85 @@ * 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. */ + +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + +#include <errno.h> +#include <unistd.h> +#include <sys/poll.h> #include <rpc/rpc.h> -#include <sys/errno.h> -void svc_run() +/* This function can be used as a signal handler to terminate the + server loop. */ +void +svc_exit (void) { -#ifdef FD_SETSIZE - fd_set readfds; -#else - int readfds; -#endif /* def FD_SETSIZE */ - extern int errno; + free (svc_pollfd); + svc_pollfd = NULL; + svc_max_pollfd = 0; +} + +void +svc_run (void) +{ + int i; + + for (;;) + { + struct pollfd *my_pollfd; + + if (svc_max_pollfd == 0 && svc_pollfd == NULL) + return; + + my_pollfd = malloc (sizeof (struct pollfd) * svc_max_pollfd); + for (i = 0; i < svc_max_pollfd; ++i) + { + my_pollfd[i].fd = svc_pollfd[i].fd; + my_pollfd[i].events = svc_pollfd[i].events; + my_pollfd[i].revents = 0; + } - for (;;) { -#ifdef FD_SETSIZE - readfds = svc_fdset; -#else - readfds = svc_fds; -#endif /* def FD_SETSIZE */ - switch (select(_rpc_dtablesize(), &readfds, NULL, NULL, - (struct timeval *) 0)) { - case -1: - if (errno == EINTR) { - continue; - } - perror("svc_run: - select failed"); - return; - case 0: - continue; - default: - svc_getreqset(&readfds); - } + switch (i = poll (my_pollfd, svc_max_pollfd, -1)) + { + case -1: + free (my_pollfd); + if (errno == EINTR) + continue; + perror (_("svc_run: - poll failed")); + return; + case 0: + free (my_pollfd); + continue; + default: + svc_getreq_poll (my_pollfd, i); + free (my_pollfd); } + } } diff --git a/libc/inet/rpc/svc_simple.c b/libc/inet/rpc/svc_simple.c index 73527875b..0b77304d9 100644 --- a/libc/inet/rpc/svc_simple.c +++ b/libc/inet/rpc/svc_simple.c @@ -6,138 +6,189 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> #include <stdio.h> +#include <string.h> +#include <unistd.h> #include <rpc/rpc.h> +#include <rpc/pmap_clnt.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; +#ifdef USE_IN_LIBIO +# include <wchar.h> +# include <libio/iolibio.h> +# define fputs(s, f) _IO_fputs (s, f) +#endif + +struct proglst_ + { + char *(*p_progname) (char *); + int p_prognum; + int p_procnum; + xdrproc_t p_inproc, p_outproc; + struct proglst_ *p_nxt; + }; +#ifdef _RPC_THREAD_SAFE_ +#define proglst ((struct proglst_ *)RPC_THREAD_VARIABLE(svcsimple_proglst_s)) +#else +static struct proglst_ *proglst; +#endif -extern bool_t pmap_unset(u_long program, u_long version); -int registerrpc(prognum, versnum, procnum, progname, inproc, outproc) -char *(*progname) (); -xdrproc_t inproc, outproc; +static void universal (struct svc_req *rqstp, SVCXPRT *transp_s); +#ifdef _RPC_THREAD_SAFE_ +#define transp ((SVCXPRT *)RPC_THREAD_VARIABLE(svcsimple_transp_s)) +#else +static SVCXPRT *transp; +#endif + +int +registerrpc (u_long prognum, u_long versnum, u_long procnum, + char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc) { + struct proglst_ *pl; + char *buf; - if (procnum == NULLPROC) { - (void) fprintf(stderr, - "can't reassign procedure number %lu\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 (procnum == NULLPROC) + { - if (pl == NULL) { - (void) fprintf(stderr, "registerrpc: out of memory\n"); - return (-1); + (void) asprintf (&buf, _("can't reassign procedure number %ld\n"), + NULLPROC); + goto err_out; + } + if (transp == 0) + { + transp = svcudp_create (RPC_ANYSOCK); + if (transp == NULL) + { + buf = strdup (_("couldn't create an rpc server\n")); + goto err_out; } - 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); + } + (void) pmap_unset ((u_long) prognum, (u_long) versnum); + if (!svc_register (transp, (u_long) prognum, (u_long) versnum, + universal, IPPROTO_UDP)) + { + (void) asprintf (&buf, _("couldn't register prog %ld vers %ld\n"), + prognum, versnum); + goto err_out; + } + pl = (struct proglst_ *) malloc (sizeof (struct proglst_)); + if (pl == NULL) + { + buf = strdup (_("registerrpc: out of memory\n")); + goto err_out; + } + 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; + + err_out: +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", buf); + else +#endif + (void) fputs (buf, stderr); + free (buf); + return -1; } -static void universal(rqstp, transp) -struct svc_req *rqstp; -SVCXPRT *transp; +static void +universal (struct svc_req *rqstp, SVCXPRT *transp_l) { - int prog, proc; - char *outdata; - char xdrbuf[UDPMSGSIZE]; - struct proglst *pl; + int prog, proc; + char *outdata; + char xdrbuf[UDPMSGSIZE]; + struct proglst_ *pl; + char *buf = NULL; - /* - * enforce "procnum 0 is echo" convention - */ - if (rqstp->rq_proc == NULLPROC) { - if (svc_sendreply(transp, (xdrproc_t) xdr_void, (char *) NULL) == FALSE) { - (void) fprintf(stderr, "xxx\n"); - exit(1); - } - return; + /* + * enforce "procnum 0 is echo" convention + */ + if (rqstp->rq_proc == NULLPROC) + { + if (svc_sendreply (transp_l, (xdrproc_t)xdr_void, (char *) NULL) == FALSE) + { + write (STDERR_FILENO, "xxx\n", 4); + exit (1); } - 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 != (xdrproc_t) 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); + 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_l, pl->p_inproc, xdrbuf)) + { + svcerr_decode (transp_l); + return; + } + outdata = (*(pl->p_progname)) (xdrbuf); + if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void) + /* there was an error */ + return; + if (!svc_sendreply (transp_l, pl->p_outproc, outdata)) + { + (void) asprintf (&buf, + _("trouble replying to prog %d\n"), + pl->p_prognum); + exit (1); + } + /* free the decoded arguments */ + (void) svc_freeargs (transp_l, pl->p_inproc, xdrbuf); + return; + } + (void) asprintf (&buf, _("never registered prog %d\n"), prog); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else +#endif + fputs (buf, stderr); + free (buf); + exit (1); } diff --git a/libc/inet/rpc/svc_tcp.c b/libc/inet/rpc/svc_tcp.c index 9adc11526..a2982796b 100644 --- a/libc/inet/rpc/svc_tcp.c +++ b/libc/inet/rpc/svc_tcp.c @@ -6,100 +6,126 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. + * 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) + * a tcp rendezvouser (a listener and connection establisher) * and a record/tcp stream. */ -#include <stdlib.h> +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + #include <stdio.h> +#include <unistd.h> +#include <string.h> #include <rpc/rpc.h> #include <sys/socket.h> +#include <sys/poll.h> #include <errno.h> -#include <unistd.h> +#include <stdlib.h> + +#ifdef USE_IN_LIBIO +# include <wchar.h> +# include <libio/iolibio.h> +# define fputs(s, f) _IO_fputs (s, f) +#endif /* * 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 +static bool_t svctcp_recv (SVCXPRT *, struct rpc_msg *); +static enum xprt_stat svctcp_stat (SVCXPRT *); +static bool_t svctcp_getargs (SVCXPRT *, xdrproc_t, caddr_t); +static bool_t svctcp_reply (SVCXPRT *, struct rpc_msg *); +static bool_t svctcp_freeargs (SVCXPRT *, xdrproc_t, caddr_t); +static void svctcp_destroy (SVCXPRT *); + +static const 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(); - -#warning Expect 3 warnings for initialization from incompatible pointer type -static struct xp_ops svctcp_rendezvous_op = { - rendezvous_request, - rendezvous_stat, - abort, - abort, - abort, - svctcp_destroy +static bool_t rendezvous_request (SVCXPRT *, struct rpc_msg *); +static enum xprt_stat rendezvous_stat (SVCXPRT *); +static void svctcp_rendezvous_abort (void); + +/* This function makes sure abort() relocation goes through PLT + and thus can be lazy bound. */ +static void +svctcp_rendezvous_abort (void) +{ + abort (); }; -static int readtcp(), writetcp(); -static SVCXPRT *makefd_xprt(); - -struct tcp_rendezvous { /* kept in xprt->xp_p1 */ - u_int sendsize; - u_int recvsize; +static const struct xp_ops svctcp_rendezvous_op = +{ + rendezvous_request, + rendezvous_stat, + (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) svctcp_rendezvous_abort, + (bool_t (*) (SVCXPRT *, struct rpc_msg *)) svctcp_rendezvous_abort, + (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) svctcp_rendezvous_abort, + svctcp_destroy }; -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]; -}; +static int readtcp (char*, char *, int); +static int writetcp (char *, char *, int); +static SVCXPRT *makefd_xprt (int, u_int, u_int) internal_function; + +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); + * 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 @@ -117,290 +143,284 @@ struct tcp_conn { /* kept in xprt->xp_p1 */ * 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; +SVCXPRT * +svctcp_create (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("svc_tcp.c - tcp socket creation problem"); - return ((SVCXPRT *) NULL); - } - madesock = TRUE; + bool_t madesock = FALSE; + SVCXPRT *xprt; + struct tcp_rendezvous *r; + struct sockaddr_in addr; + socklen_t len = sizeof (struct sockaddr_in); + + if (sock == RPC_ANYSOCK) + { + if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + perror (_("svc_tcp.c - tcp socket creation problem")); + return (SVCXPRT *) NULL; } - 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); + 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 (_("svc_tcp.c - cannot getsockname or listen")); + if (madesock) + (void) close (sock); + return (SVCXPRT *) NULL; + } + r = (struct tcp_rendezvous *) mem_alloc (sizeof (*r)); + xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); + if (r == NULL || xprt == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", _("svctcp_create: out of memory\n")); + else +#endif + (void) fputs (_("svctcp_create: out of memory\n"), stderr); + mem_free (r, sizeof (*r)); + mem_free (xprt, sizeof (SVCXPRT)); + return NULL; + } + r->sendsize = sendsize; + r->recvsize = recvsize; + 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; +SVCXPRT * +svcfd_create (int fd, u_int sendsize, u_int recvsize) { - - return (makefd_xprt(fd, sendsize, recvsize)); + return makefd_xprt (fd, sendsize, recvsize); } -static SVCXPRT *makefd_xprt(fd, sendsize, recvsize) -int fd; -u_int sendsize; -u_int recvsize; +static SVCXPRT * +internal_function +makefd_xprt (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); + SVCXPRT *xprt; + struct tcp_conn *cd; + + xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); + cd = (struct tcp_conn *) mem_alloc (sizeof (struct tcp_conn)); + if (xprt == (SVCXPRT *) NULL || cd == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("svc_tcp: makefd_xprt: out of memory\n")); + else +#endif + (void) fputs (_("svc_tcp: makefd_xprt: out of memory\n"), stderr); + mem_free (xprt, sizeof (SVCXPRT)); + mem_free (cd, sizeof (struct tcp_conn)); + return NULL; + } + 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; /* truly deals with calls */ + xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ + xprt->xp_sock = fd; + xprt_register (xprt); + return xprt; } -static bool_t rendezvous_request(xprt) -register SVCXPRT *xprt; +static bool_t +rendezvous_request (SVCXPRT *xprt, struct rpc_msg *errmsg) { - 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 */ + int sock; + struct tcp_rendezvous *r; + struct sockaddr_in addr; + socklen_t 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); + memcpy (&xprt->xp_raddr, &addr, sizeof (addr)); + xprt->xp_addrlen = len; + return FALSE; /* there is never an rpc msg to be processed */ } -static enum xprt_stat rendezvous_stat() +static enum xprt_stat +rendezvous_stat (SVCXPRT *xprt) { - - return (XPRT_IDLE); + return XPRT_IDLE; } -static void svctcp_destroy(xprt) -register SVCXPRT *xprt; +static void +svctcp_destroy (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)); + 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. + * reads data from the tcp connection. * 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; +static int +readtcp (char *xprtptr, char *buf, 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, NULL, 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); + SVCXPRT *xprt = (SVCXPRT *)xprtptr; + int sock = xprt->xp_sock; + int milliseconds = 35 * 1000; + struct pollfd pollfd; + + do + { + pollfd.fd = sock; + pollfd.events = POLLIN; + switch (poll (&pollfd, 1, milliseconds)) + { + case -1: + if (errno == EINTR) + continue; + /*FALLTHROUGH*/ + case 0: + goto fatal_err; + default: + if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP) + || (pollfd.revents & POLLNVAL)) + goto fatal_err; + break; } - fatal_err: - ((struct tcp_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED; - return (-1); + } + while ((pollfd.revents & POLLIN) == 0); + + 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; +static int +writetcp (char *xprtptr, char * 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); - } + SVCXPRT *xprt = (SVCXPRT *)xprtptr; + 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); + } + return len; } -static enum xprt_stat svctcp_stat(xprt) -SVCXPRT *xprt; +static enum xprt_stat +svctcp_stat (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); + 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; +static bool_t +svctcp_recv (SVCXPRT *xprt, 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); + struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1); + XDR *xdrs = &(cd->xdrs); + + xdrs->x_op = XDR_DECODE; + (void) xdrrec_skiprecord (xdrs); + if (xdr_callmsg (xdrs, msg)) + { + cd->x_id = msg->rm_xid; + return TRUE; + } + cd->strm_stat = XPRT_DIED; /* XXXX */ + return FALSE; } -static bool_t svctcp_getargs(xprt, xdr_args, args_ptr) -SVCXPRT *xprt; -xdrproc_t xdr_args; -caddr_t args_ptr; +static bool_t +svctcp_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) { - - return ((*xdr_args) - (&(((struct tcp_conn *) (xprt->xp_p1))->xdrs), 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; +static bool_t +svctcp_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) { - register XDR *xdrs = &(((struct tcp_conn *) (xprt->xp_p1))->xdrs); + XDR *xdrs = &(((struct tcp_conn *) (xprt->xp_p1))->xdrs); - xdrs->x_op = XDR_FREE; - return ((*xdr_args) (xdrs, args_ptr)); + 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; +static bool_t +svctcp_reply (SVCXPRT *xprt, 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); + struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1); + XDR *xdrs = &(cd->xdrs); + 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/libc/inet/rpc/svc_udp.c b/libc/inet/rpc/svc_udp.c index 0004acedc..98f935961 100644 --- a/libc/inet/rpc/svc_udp.c +++ b/libc/inet/rpc/svc_udp.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro"; +#endif /* * svc_udp.c, @@ -38,54 +39,69 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + #include <stdio.h> +#include <unistd.h> +#include <string.h> #include <rpc/rpc.h> #include <sys/socket.h> #include <errno.h> -#include <unistd.h> +#ifdef IP_PKTINFO +#include <sys/uio.h> +#endif + +#ifdef USE_IN_LIBIO +# include <wchar.h> +# include <libio/iolibio.h> +# define fputs(s, f) _IO_fputs (s, f) +#endif #define rpc_buffer(xprt) ((xprt)->xp_p1) #ifndef MAX #define MAX(a, b) ((a > b) ? a : b) #endif -static bool_t svcudp_recv(); -static bool_t svcudp_reply(); -static enum xprt_stat svcudp_stat(); -static bool_t svcudp_getargs(); -static bool_t svcudp_freeargs(); -static void svcudp_destroy(); - -static void cache_set(SVCXPRT *xprt, u_long replylen); -static int cache_get(SVCXPRT *xprt, struct rpc_msg *msg, - char **replyp, u_long *replylenp); - -static struct xp_ops svcudp_op = { - svcudp_recv, - svcudp_stat, - svcudp_getargs, - svcudp_reply, - svcudp_freeargs, - svcudp_destroy +static bool_t svcudp_recv (SVCXPRT *, struct rpc_msg *); +static bool_t svcudp_reply (SVCXPRT *, struct rpc_msg *); +static enum xprt_stat svcudp_stat (SVCXPRT *); +static bool_t svcudp_getargs (SVCXPRT *, xdrproc_t, caddr_t); +static bool_t svcudp_freeargs (SVCXPRT *, xdrproc_t, caddr_t); +static void svcudp_destroy (SVCXPRT *); + +static const struct xp_ops svcudp_op = +{ + svcudp_recv, + svcudp_stat, + svcudp_getargs, + svcudp_reply, + svcudp_freeargs, + svcudp_destroy }; +static int cache_get (SVCXPRT *, struct rpc_msg *, char **replyp, + u_long *replylenp); +static void cache_set (SVCXPRT *xprt, u_long replylen); + /* * 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 */ -}; - +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); + * 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 @@ -96,170 +112,272 @@ struct svcudp_data { * 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; +SVCXPRT * +svcudp_bufcreate (sock, sendsz, recvsz) + 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); + bool_t madesock = FALSE; + SVCXPRT *xprt; + struct svcudp_data *su; + struct sockaddr_in addr; + socklen_t len = sizeof (struct sockaddr_in); + int pad; + void *buf; + + if (sock == RPC_ANYSOCK) + { + if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + { + perror (_("svcudp_create: socket creation problem")); + return (SVCXPRT *) 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); + 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)); + su = (struct svcudp_data *) mem_alloc (sizeof (*su)); + buf = mem_alloc (((MAX (sendsz, recvsz) + 3) / 4) * 4); + if (xprt == NULL || su == NULL || buf == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", _("svcudp_create: out of memory\n")); + else +#endif + (void) fputs (_("svcudp_create: out of memory\n"), stderr); + mem_free (xprt, sizeof (SVCXPRT)); + mem_free (su, sizeof (*su)); + mem_free (buf, ((MAX (sendsz, recvsz) + 3) / 4) * 4); + return NULL; + } + su->su_iosz = ((MAX (sendsz, recvsz) + 3) / 4) * 4; + rpc_buffer (xprt) = buf; + 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; + +#ifdef IP_PKTINFO + if ((sizeof (struct iovec) + sizeof (struct msghdr) + + sizeof(struct cmsghdr) + sizeof (struct in_pktinfo)) + > sizeof (xprt->xp_pad)) + { +# ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("svcudp_create: xp_pad is too small for IP_PKTINFO\n")); + else +# endif + (void) fputs (_("svcudp_create: xp_pad is too small for IP_PKTINFO\n"), + stderr); + return NULL; + } + pad = 1; + if (setsockopt (sock, SOL_IP, IP_PKTINFO, (void *) &pad, + sizeof (pad)) == 0) + /* Set the padding to all 1s. */ + pad = 0xff; + else +#endif + /* Clear the padding. */ + pad = 0; + memset (&xprt->xp_pad [0], pad, sizeof (xprt->xp_pad)); + + xprt_register (xprt); + return xprt; } -SVCXPRT *svcudp_create(sock) -int sock; +SVCXPRT * +svcudp_create (sock) + int sock; { - return (svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); + return svcudp_bufcreate (sock, UDPMSGSIZE, UDPMSGSIZE); } -static enum xprt_stat svcudp_stat(xprt) -SVCXPRT *xprt; +static enum xprt_stat +svcudp_stat (xprt) + SVCXPRT *xprt; { - return (XPRT_IDLE); + return XPRT_IDLE; } -static bool_t svcudp_recv(xprt, msg) -register SVCXPRT *xprt; -struct rpc_msg *msg; +static bool_t +svcudp_recv (xprt, msg) + 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); - } + struct svcudp_data *su = su_data (xprt); + XDR *xdrs = &(su->su_xdrs); + int rlen; + char *reply; + u_long replylen; + socklen_t len; + + /* It is very tricky when you have IP aliases. We want to make sure + that we are sending the packet from the IP address where the + incoming packet is addressed to. H.J. */ +#ifdef IP_PKTINFO + struct iovec *iovp; + struct msghdr *mesgp; +#endif + +again: + /* FIXME -- should xp_addrlen be a size_t? */ + len = (socklen_t) sizeof(struct sockaddr_in); +#ifdef IP_PKTINFO + iovp = (struct iovec *) &xprt->xp_pad [0]; + mesgp = (struct msghdr *) &xprt->xp_pad [sizeof (struct iovec)]; + if (mesgp->msg_iovlen) + { + iovp->iov_base = rpc_buffer (xprt); + iovp->iov_len = su->su_iosz; + mesgp->msg_iov = iovp; + mesgp->msg_iovlen = 1; + mesgp->msg_name = &(xprt->xp_raddr); + mesgp->msg_namelen = len; + mesgp->msg_control = &xprt->xp_pad [sizeof (struct iovec) + + sizeof (struct msghdr)]; + mesgp->msg_controllen = sizeof(xprt->xp_pad) + - sizeof (struct iovec) - sizeof (struct msghdr); + rlen = recvmsg (xprt->xp_sock, mesgp, 0); + if (rlen >= 0) + len = mesgp->msg_namelen; + } + else +#endif + rlen = recvfrom (xprt->xp_sock, rpc_buffer (xprt), + (int) su->su_iosz, 0, + (struct sockaddr *) &(xprt->xp_raddr), &len); + xprt->xp_addrlen = len; + if (rlen == -1 && errno == EINTR) + goto again; + if (rlen < 16) /* < 4 32-bit ints? */ + 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)) + { +#ifdef IP_PKTINFO + if (mesgp->msg_iovlen) + { + iovp->iov_base = reply; + iovp->iov_len = replylen; + (void) sendmsg (xprt->xp_sock, mesgp, 0); + } + else +#endif + (void) sendto (xprt->xp_sock, reply, (int) replylen, 0, + (struct sockaddr *) &xprt->xp_raddr, len); + return TRUE; } - return (TRUE); + } + return TRUE; } -static bool_t svcudp_reply(xprt, msg) -register SVCXPRT *xprt; -struct rpc_msg *msg; +static bool_t +svcudp_reply (xprt, msg) + 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); - } - } + struct svcudp_data *su = su_data (xprt); + XDR *xdrs = &(su->su_xdrs); + int slen, sent; + bool_t stat = FALSE; +#ifdef IP_PKTINFO + struct iovec *iovp; + struct msghdr *mesgp; +#endif + + 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); +#ifdef IP_PKTINFO + mesgp = (struct msghdr *) &xprt->xp_pad [sizeof (struct iovec)]; + if (mesgp->msg_iovlen) + { + iovp = (struct iovec *) &xprt->xp_pad [0]; + iovp->iov_base = rpc_buffer (xprt); + iovp->iov_len = slen; + sent = sendmsg (xprt->xp_sock, mesgp, 0); } - return (stat); + else +#endif + sent = sendto (xprt->xp_sock, rpc_buffer (xprt), slen, 0, + (struct sockaddr *) &(xprt->xp_raddr), + xprt->xp_addrlen); + if (sent == 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; +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)); + 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; +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); + XDR *xdrs = &(su_data (xprt)->su_xdrs); - xdrs->x_op = XDR_FREE; - return ((*xdr_args) (xdrs, args_ptr)); + xdrs->x_op = XDR_FREE; + return (*xdr_args) (xdrs, args_ptr); } -static void svcudp_destroy(xprt) -register SVCXPRT *xprt; +static void +svcudp_destroy (xprt) + 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)); + 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)); } @@ -271,10 +389,18 @@ register SVCXPRT *xprt; * Buffers are sent again if retransmissions are detected. */ -#define SPARSENESS 4 /* 75% sparse */ +#define SPARSENESS 4 /* 75% sparse */ -#define CACHE_PERROR(msg) \ +#ifdef USE_IN_LIBIO +# define CACHE_PERROR(msg) \ + if (_IO_fwide (stderr, 0) > 0) \ + (void) __fwprintf(stderr, L"%s\n", msg); \ + else \ + (void) fprintf(stderr, "%s\n", msg) +#else +# define CACHE_PERROR(msg) \ (void) fprintf(stderr,"%s\n", msg) +#endif #define ALLOC(type, size) \ (type *) mem_alloc((unsigned) (sizeof(type) * (size))) @@ -286,41 +412,43 @@ register SVCXPRT *xprt; * 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; -}; +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 */ -}; +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 */ + }; /* @@ -331,144 +459,154 @@ struct udp_cache { /* - * Enable use of the cache. + * Enable use of the cache. * Note: there is no disable. */ -int svcudp_enablecache(transp, size) -SVCXPRT *transp; -u_long size; +int +svcudp_enablecache (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); + struct svcudp_data *su = su_data (transp); + struct udp_cache *uc; + + if (su->su_cache != NULL) + { + CACHE_PERROR (_("enablecache: cache already enabled")); + return 0; + } + uc = ALLOC (struct udp_cache, 1); + if (uc == NULL) + { + CACHE_PERROR (_("enablecache: could not allocate cache")); + return 0; + } + uc->uc_size = size; + uc->uc_nextvictim = 0; + uc->uc_entries = ALLOC (cache_ptr, size * SPARSENESS); + if (uc->uc_entries == NULL) + { + CACHE_PERROR (_("enablecache: could not allocate cache data")); + return 0; + } + BZERO (uc->uc_entries, cache_ptr, size * SPARSENESS); + uc->uc_fifo = ALLOC (cache_ptr, size); + if (uc->uc_fifo == NULL) + { + CACHE_PERROR (_("enablecache: could not allocate cache fifo")); + return 0; + } + BZERO (uc->uc_fifo, cache_ptr, size); + su->su_cache = (char *) uc; + return 1; } /* * Set an entry in the cache */ -static void cache_set(xprt, replylen) -SVCXPRT *xprt; -u_long replylen; +static void +cache_set (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; - } + cache_ptr victim; + cache_ptr *vicp; + 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; } - - /* - * 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; + *vicp = victim->cache_next; /* remote from cache */ + newbuf = victim->cache_reply; + } + else + { + victim = ALLOC (struct cache_node, 1); + if (victim == NULL) + { + CACHE_PERROR (_("cache_set: victim alloc failed")); + return; + } + newbuf = mem_alloc (su->su_iosz); + if (newbuf == NULL) + { + CACHE_PERROR (_("cache_set: could not allocate new rpc_buffer")); + return; + } + } + + /* + * Store it away + */ + victim->cache_replylen = replylen; + victim->cache_reply = rpc_buffer (xprt); + rpc_buffer (xprt) = newbuf; + xdrmem_create (&(su->su_xdrs), rpc_buffer (xprt), su->su_iosz, XDR_ENCODE); + victim->cache_xid = su->su_xid; + victim->cache_proc = uc->uc_proc; + victim->cache_vers = uc->uc_vers; + victim->cache_prog = uc->uc_prog; + victim->cache_addr = uc->uc_addr; + loc = CACHE_LOC (xprt, victim->cache_xid); + victim->cache_next = uc->uc_entries[loc]; + uc->uc_entries[loc] = victim; + uc->uc_fifo[uc->uc_nextvictim++] = victim; + uc->uc_nextvictim %= uc->uc_size; } /* * Try to get an entry from the cache * return 1 if found, 0 if not found */ -static int cache_get(xprt, msg, replyp, replylenp) -SVCXPRT *xprt; -struct rpc_msg *msg; -char **replyp; -u_long *replylenp; +static int +cache_get (xprt, msg, replyp, replylenp) + SVCXPRT *xprt; + struct rpc_msg *msg; + char **replyp; + u_long *replylenp; { - u_int loc; - register cache_ptr ent; - register struct svcudp_data *su = su_data(xprt); - register struct udp_cache *uc = (struct udp_cache *) su->su_cache; - -# define EQADDR(a1, a2) (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); - } + u_int loc; + cache_ptr ent; + struct svcudp_data *su = su_data (xprt); + struct udp_cache *uc = (struct udp_cache *) su->su_cache; + +#define EQADDR(a1, a2) (memcmp((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); + } + /* + * 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; + memcpy (&uc->uc_addr, &xprt->xp_raddr, sizeof (uc->uc_addr)); + return 0; } diff --git a/libc/inet/rpc/svc_unix.c b/libc/inet/rpc/svc_unix.c new file mode 100644 index 000000000..8e052d8a2 --- /dev/null +++ b/libc/inet/rpc/svc_unix.c @@ -0,0 +1,533 @@ +/* + * 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_unix.c, Server side for TCP/IP based RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Actually implements two flavors of transporter - + * a unix rendezvouser (a listener and connection establisher) + * and a record/unix stream. + */ + +#define __FORCE_GLIBC +#include <features.h> + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <rpc/rpc.h> +#include <rpc/svc.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <sys/poll.h> +#include <errno.h> +#include <stdlib.h> + +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif + +/* + * Ops vector for AF_UNIX based rpc service handle + */ +static bool_t svcunix_recv (SVCXPRT *, struct rpc_msg *); +static enum xprt_stat svcunix_stat (SVCXPRT *); +static bool_t svcunix_getargs (SVCXPRT *, xdrproc_t, caddr_t); +static bool_t svcunix_reply (SVCXPRT *, struct rpc_msg *); +static bool_t svcunix_freeargs (SVCXPRT *, xdrproc_t, caddr_t); +static void svcunix_destroy (SVCXPRT *); + +static const struct xp_ops svcunix_op = +{ + svcunix_recv, + svcunix_stat, + svcunix_getargs, + svcunix_reply, + svcunix_freeargs, + svcunix_destroy +}; + +/* + * Ops vector for AF_UNIX rendezvous handler + */ +static bool_t rendezvous_request (SVCXPRT *, struct rpc_msg *); +static enum xprt_stat rendezvous_stat (SVCXPRT *); +static void svcunix_rendezvous_abort (void); + +/* This function makes sure abort() relocation goes through PLT + and thus can be lazy bound. */ +static void +svcunix_rendezvous_abort (void) +{ + abort (); +}; + +static const struct xp_ops svcunix_rendezvous_op = +{ + rendezvous_request, + rendezvous_stat, + (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) svcunix_rendezvous_abort, + (bool_t (*) (SVCXPRT *, struct rpc_msg *)) svcunix_rendezvous_abort, + (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) svcunix_rendezvous_abort, + svcunix_destroy +}; + +static int readunix (char*, char *, int); +static int writeunix (char *, char *, int); +static SVCXPRT *makefd_xprt (int, u_int, u_int) internal_function; + +struct unix_rendezvous { /* kept in xprt->xp_p1 */ + u_int sendsize; + u_int recvsize; +}; + +struct unix_conn { /* kept in xprt->xp_p1 */ + enum xprt_stat strm_stat; + u_long x_id; + XDR xdrs; + char verf_body[MAX_AUTH_BYTES]; +}; + +/* + * Usage: + * xprt = svcunix_create(sock, send_buf_size, recv_buf_size); + * + * Creates, registers, and returns a (rpc) unix based transporter. + * Once *xprt is initialized, it is registered as a transporter + * see (svc.h, xprt_register). This routine returns + * a NULL if a problem occurred. + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svcunix_create + * binds it to an arbitrary port. The routine then starts a unix + * listener on the socket's associated port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * + * Since unix streams do buffered io similar to stdio, the caller can specify + * how big the send and receive buffers are via the second and third parms; + * 0 => use the system default. + */ +SVCXPRT * +svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path) +{ + bool_t madesock = FALSE; + SVCXPRT *xprt; + struct unix_rendezvous *r; + struct sockaddr_un addr; + socklen_t len = sizeof (struct sockaddr_in); + + if (sock == RPC_ANYSOCK) + { + if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) + { + perror (_("svc_unix.c - AF_UNIX socket creation problem")); + return (SVCXPRT *) NULL; + } + madesock = TRUE; + } + memset (&addr, '\0', sizeof (addr)); + addr.sun_family = AF_UNIX; + len = strlen (path) + 1; + memcpy (addr.sun_path, path, len); + len += sizeof (addr.sun_family); + + bind (sock, (struct sockaddr *) &addr, len); + + if (getsockname (sock, (struct sockaddr *) &addr, &len) != 0 + || listen (sock, 2) != 0) + { + perror (_("svc_unix.c - cannot getsockname or listen")); + if (madesock) + close (sock); + return (SVCXPRT *) NULL; + } + + r = (struct unix_rendezvous *) mem_alloc (sizeof (*r)); + xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); + if (r == NULL || xprt == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", _("svcunix_create: out of memory\n")); + else +#endif + fputs (_("svcunix_create: out of memory\n"), stderr); + mem_free (r, sizeof (*r)); + mem_free (xprt, sizeof (SVCXPRT)); + return NULL; + } + r->sendsize = sendsize; + r->recvsize = recvsize; + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t) r; + xprt->xp_verf = _null_auth; + xprt->xp_ops = &svcunix_rendezvous_op; + xprt->xp_port = -1; + xprt->xp_sock = sock; + xprt_register (xprt); + return xprt; +} + +/* + * Like svunix_create(), except the routine takes any *open* UNIX file + * descriptor as its first input. + */ +SVCXPRT * +svcunixfd_create (int fd, u_int sendsize, u_int recvsize) +{ + return makefd_xprt (fd, sendsize, recvsize); +} + +static SVCXPRT * +internal_function +makefd_xprt (int fd, u_int sendsize, u_int recvsize) +{ + SVCXPRT *xprt; + struct unix_conn *cd; + + xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); + cd = (struct unix_conn *) mem_alloc (sizeof (struct unix_conn)); + if (xprt == (SVCXPRT *) NULL || cd == (struct unix_conn *) NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("svc_unix: makefd_xprt: out of memory\n")); + else +#endif + (void) fputs (_("svc_unix: makefd_xprt: out of memory\n"), stderr); + mem_free (xprt, sizeof (SVCXPRT)); + mem_free (cd, sizeof (struct unix_conn)); + return NULL; + } + cd->strm_stat = XPRT_IDLE; + xdrrec_create (&(cd->xdrs), sendsize, recvsize, + (caddr_t) xprt, readunix, writeunix); + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t) cd; + xprt->xp_verf.oa_base = cd->verf_body; + xprt->xp_addrlen = 0; + xprt->xp_ops = &svcunix_op; /* truly deals with calls */ + xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ + xprt->xp_sock = fd; + xprt_register (xprt); + return xprt; +} + +static bool_t +rendezvous_request (SVCXPRT *xprt, struct rpc_msg *errmsg) +{ + int sock; + struct unix_rendezvous *r; + struct sockaddr_un addr; + struct sockaddr_in in_addr; + socklen_t len; + + r = (struct unix_rendezvous *) xprt->xp_p1; +again: + len = sizeof (struct sockaddr_un); + 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) + */ + memset (&in_addr, '\0', sizeof (in_addr)); + in_addr.sin_family = AF_UNIX; + xprt = makefd_xprt (sock, r->sendsize, r->recvsize); + memcpy (&xprt->xp_raddr, &in_addr, sizeof (in_addr)); + xprt->xp_addrlen = len; + return FALSE; /* there is never an rpc msg to be processed */ +} + +static enum xprt_stat +rendezvous_stat (SVCXPRT *xprt) +{ + return XPRT_IDLE; +} + +static void +svcunix_destroy (SVCXPRT *xprt) +{ + struct unix_conn *cd = (struct unix_conn *) xprt->xp_p1; + + xprt_unregister (xprt); + close (xprt->xp_sock); + if (xprt->xp_port != 0) + { + /* a rendezvouser socket */ + xprt->xp_port = 0; + } + else + { + /* an actual connection socket */ + XDR_DESTROY (&(cd->xdrs)); + } + mem_free ((caddr_t) cd, sizeof (struct unix_conn)); + mem_free ((caddr_t) xprt, sizeof (SVCXPRT)); +} + +#ifdef SCM_CREDENTIALS +struct cmessage { + struct cmsghdr cmsg; + struct ucred cmcred; + /* hack to make sure we have enough memory */ + char dummy[(CMSG_ALIGN (sizeof (struct ucred)) - sizeof (struct ucred) + sizeof (long))]; +}; + +/* XXX This is not thread safe, but since the main functions in svc.c + and the rpcgen generated *_svc functions for the daemon are also not + thread safe and uses static global variables, it doesn't matter. */ +static struct cmessage cm; +#endif + +static int +__msgread (int sock, void *data, size_t cnt) +{ + struct iovec iov; + struct msghdr msg; + int len; + + iov.iov_base = data; + iov.iov_len = cnt; + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; +#ifdef SCM_CREDENTIALS + msg.msg_control = (caddr_t) &cm; + msg.msg_controllen = sizeof (struct cmessage); +#endif + msg.msg_flags = 0; + +#ifdef SO_PASSCRED + { + int on = 1; + if (setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on))) + return -1; + } +#endif + + restart: + len = recvmsg (sock, &msg, 0); + if (len >= 0) + { + if (msg.msg_flags & MSG_CTRUNC || len == 0) + return 0; + else + return len; + } + if (errno == EINTR) + goto restart; + return -1; +} + +static int +__msgwrite (int sock, void *data, size_t cnt) +{ +#ifndef SCM_CREDENTIALS + /* We cannot implement this reliably. */ + __set_errno (ENOSYS); + return -1; +#else + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsg = &cm.cmsg; + struct ucred cred; + int len; + + /* XXX I'm not sure, if gete?id() is always correct, or if we should use + get?id(). But since keyserv needs geteuid(), we have no other chance. + It would be much better, if the kernel could pass both to the server. */ + cred.pid = getpid (); + cred.uid = geteuid (); + cred.gid = getegid (); + + memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred); + + iov.iov_base = data; + iov.iov_len = cnt; + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = cmsg; + msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len); + msg.msg_flags = 0; + + restart: + len = sendmsg (sock, &msg, 0); + if (len >= 0) + return len; + if (errno == EINTR) + goto restart; + return -1; + +#endif +} + +/* + * reads data from the unix connection. + * any error is fatal and the connection is closed. + * (And a read of zero bytes is a half closed stream => error.) + */ +static int +readunix (char *xprtptr, char *buf, int len) +{ + SVCXPRT *xprt = (SVCXPRT *) xprtptr; + int sock = xprt->xp_sock; + int milliseconds = 35 * 1000; + struct pollfd pollfd; + + do + { + pollfd.fd = sock; + pollfd.events = POLLIN; + switch (poll (&pollfd, 1, milliseconds)) + { + case -1: + if (errno == EINTR) + continue; + /*FALLTHROUGH*/ + case 0: + goto fatal_err; + default: + if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP) + || (pollfd.revents & POLLNVAL)) + goto fatal_err; + break; + } + } + while ((pollfd.revents & POLLIN) == 0); + + if ((len = __msgread (sock, buf, len)) > 0) + return len; + + fatal_err: + ((struct unix_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED; + return -1; +} + +/* + * writes data to the unix connection. + * Any error is fatal and the connection is closed. + */ +static int +writeunix (char *xprtptr, char * buf, int len) +{ + SVCXPRT *xprt = (SVCXPRT *) xprtptr; + int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) + { + if ((i = __msgwrite (xprt->xp_sock, buf, cnt)) < 0) + { + ((struct unix_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED; + return -1; + } + } + return len; +} + +static enum xprt_stat +svcunix_stat (SVCXPRT *xprt) +{ + struct unix_conn *cd = + (struct unix_conn *) (xprt->xp_p1); + + if (cd->strm_stat == XPRT_DIED) + return XPRT_DIED; + if (!xdrrec_eof (&(cd->xdrs))) + return XPRT_MOREREQS; + return XPRT_IDLE; +} + +static bool_t +svcunix_recv (SVCXPRT *xprt, struct rpc_msg *msg) +{ + struct unix_conn *cd = (struct unix_conn *) (xprt->xp_p1); + XDR *xdrs = &(cd->xdrs); + + xdrs->x_op = XDR_DECODE; + xdrrec_skiprecord (xdrs); + if (xdr_callmsg (xdrs, msg)) + { + cd->x_id = msg->rm_xid; + /* set up verifiers */ +#ifdef SCM_CREDENTIALS + msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX; + msg->rm_call.cb_verf.oa_base = (caddr_t) &cm; + msg->rm_call.cb_verf.oa_length = sizeof (cm); +#endif + return TRUE; + } + cd->strm_stat = XPRT_DIED; /* XXXX */ + return FALSE; +} + +static bool_t +svcunix_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) +{ + return (*xdr_args) (&(((struct unix_conn *) (xprt->xp_p1))->xdrs), + args_ptr); +} + +static bool_t +svcunix_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) +{ + XDR *xdrs = &(((struct unix_conn *) (xprt->xp_p1))->xdrs); + + xdrs->x_op = XDR_FREE; + return (*xdr_args) (xdrs, args_ptr); +} + +static bool_t +svcunix_reply (SVCXPRT *xprt, struct rpc_msg *msg) +{ + struct unix_conn *cd = (struct unix_conn *) (xprt->xp_p1); + XDR *xdrs = &(cd->xdrs); + 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/libc/inet/rpc/xdr.c b/libc/inet/rpc/xdr.c index cad61c5a8..a54b1172b 100644 --- a/libc/inet/rpc/xdr.c +++ b/libc/inet/rpc/xdr.c @@ -6,29 +6,30 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr.c 1.35 87/08/12"; +#endif /* * xdr.c, Generic XDR routines implementation. @@ -40,12 +41,21 @@ * xdr. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + #include <stdio.h> +#include <limits.h> #include <string.h> -#include <stdlib.h> + #include <rpc/types.h> #include <rpc/xdr.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif + /* * constants specific to the xdr "protocol" */ @@ -56,253 +66,400 @@ /* * for unit alignment */ -static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; +static const 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; +void +xdr_free (xdrproc_t proc, char *objp) { - XDR x; + XDR x; - x.x_op = XDR_FREE; - (*proc) (&x, objp); + x.x_op = XDR_FREE; + (*proc) (&x, objp); } /* * XDR nothing */ -bool_t xdr_void( /* xdrs, addr */ ) - /* XDR *xdrs; */ - /* caddr_t addr; */ +bool_t +xdr_void (void) { - - return (TRUE); + return TRUE; } /* * XDR integers */ -bool_t xdr_int(xdrs, ip) -XDR *xdrs; -int *ip; +bool_t +xdr_int (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)); +#if INT_MAX < LONG_MAX + long l; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + l = (long) *ip; + return XDR_PUTLONG (xdrs, &l); + + case XDR_DECODE: + if (!XDR_GETLONG (xdrs, &l)) + { + return FALSE; } + *ip = (int) l; + case XDR_FREE: + return TRUE; + } + return FALSE; +#elif INT_MAX == LONG_MAX + return xdr_long (xdrs, (long *) ip); +#elif INT_MAX == SHRT_MAX + return xdr_short (xdrs, (short *) ip); +#else +#error unexpected integer sizes in_xdr_int() #endif } /* * XDR unsigned integers */ -bool_t xdr_u_int(xdrs, up) -XDR *xdrs; -u_int *up; +bool_t +xdr_u_int (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)); +#if UINT_MAX < ULONG_MAX + u_long l; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + l = (u_long) * up; + return XDR_PUTLONG (xdrs, &l); + + case XDR_DECODE: + if (!XDR_GETLONG (xdrs, &l)) + { + return FALSE; } + *up = (u_int) l; + case XDR_FREE: + return TRUE; + } + return FALSE; +#elif UINT_MAX == ULONG_MAX + return xdr_u_long (xdrs, (u_long *) up); +#elif UINT_MAX == USHRT_MAX + return xdr_short (xdrs, (short *) up); +#else +#error unexpected integer sizes in_xdr_u_int() #endif } /* * XDR long integers - * same as xdr_u_long - open coded to save a proc call! + * The definition of xdr_long() is kept for backward + * compatibility. Instead xdr_int() should be used. */ -bool_t xdr_long(xdrs, lp) -register XDR *xdrs; -long *lp; +bool_t +xdr_long (XDR *xdrs, long *lp) { - if (xdrs->x_op == XDR_ENCODE) - return (XDR_PUTLONG(xdrs, lp)); + if (xdrs->x_op == XDR_ENCODE + && (sizeof (int32_t) == sizeof (long) + || (int32_t) *lp == *lp)) + return XDR_PUTLONG (xdrs, lp); - if (xdrs->x_op == XDR_DECODE) - return (XDR_GETLONG(xdrs, lp)); + if (xdrs->x_op == XDR_DECODE) + return XDR_GETLONG (xdrs, lp); - if (xdrs->x_op == XDR_FREE) - return (TRUE); + if (xdrs->x_op == XDR_FREE) + return TRUE; - return (FALSE); + return FALSE; } /* * XDR unsigned long integers - * same as xdr_long - open coded to save a proc call! + * The definition of xdr_u_long() is kept for backward + * compatibility. Instead xdr_u_int() should be used. */ -bool_t xdr_u_long(xdrs, ulp) -register XDR *xdrs; -u_long *ulp; +bool_t +xdr_u_long (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); + switch (xdrs->x_op) + { + case XDR_DECODE: + { + long int tmp; + + if (XDR_GETLONG (xdrs, &tmp) == FALSE) + return FALSE; + + *ulp = (uint32_t) tmp; + return TRUE; + } + + case XDR_ENCODE: + if (sizeof (uint32_t) != sizeof (u_long) + && (uint32_t) *ulp != *ulp) + return FALSE; + + return XDR_PUTLONG (xdrs, (long *) ulp); + + case XDR_FREE: + return TRUE; + } + return FALSE; } /* - * XDR short integers + * XDR hyper integers + * same as xdr_u_hyper - open coded to save a proc call! */ -bool_t xdr_short(xdrs, sp) -register XDR *xdrs; -short *sp; +bool_t +xdr_hyper (XDR *xdrs, quad_t *llp) { - long l; + long t1; + unsigned long int t2; + + if (xdrs->x_op == XDR_ENCODE) + { + t1 = (long) ((*llp) >> 32); + t2 = (long) (*llp); + return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2)); + } + + if (xdrs->x_op == XDR_DECODE) + { + if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2)) + return FALSE; + *llp = ((quad_t) t1) << 32; + *llp |= t2; + return TRUE; + } + + if (xdrs->x_op == XDR_FREE) + return TRUE; + + return FALSE; +} - switch (xdrs->x_op) { - case XDR_ENCODE: - l = (long) *sp; - return (XDR_PUTLONG(xdrs, &l)); +/* + * XDR hyper integers + * same as xdr_hyper - open coded to save a proc call! + */ +bool_t +xdr_u_hyper (XDR *xdrs, u_quad_t *ullp) +{ + unsigned long t1; + unsigned long t2; + + if (xdrs->x_op == XDR_ENCODE) + { + t1 = (unsigned long) ((*ullp) >> 32); + t2 = (unsigned long) (*ullp); + return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2)); + } + + if (xdrs->x_op == XDR_DECODE) + { + if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2)) + return FALSE; + *ullp = ((u_quad_t) t1) << 32; + *ullp |= t2; + return TRUE; + } + + if (xdrs->x_op == XDR_FREE) + return TRUE; + + return FALSE; +} - case XDR_DECODE: - if (!XDR_GETLONG(xdrs, &l)) { - return (FALSE); - } - *sp = (short) l; - return (TRUE); +bool_t +xdr_longlong_t (XDR *xdrs, quad_t *llp) +{ + return xdr_hyper (xdrs, llp); +} - case XDR_FREE: - return (TRUE); - } - return (FALSE); +bool_t +xdr_u_longlong_t (XDR *xdrs, u_quad_t *ullp) +{ + return xdr_u_hyper (xdrs, ullp); } /* - * XDR unsigned short integers + * XDR short integers */ -bool_t xdr_u_short(xdrs, usp) -register XDR *xdrs; -u_short *usp; +bool_t +xdr_short (XDR *xdrs, short *sp) { - u_long l; - - switch (xdrs->x_op) { - - case XDR_ENCODE: - l = (u_long) * usp; - return (XDR_PUTLONG(xdrs, &l)); + 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_DECODE: - if (!XDR_GETLONG(xdrs, &l)) { - return (FALSE); - } - *usp = (u_short) l; - return (TRUE); + case XDR_FREE: + return TRUE; + } + return FALSE; +} - case XDR_FREE: - return (TRUE); +/* + * XDR unsigned short integers + */ +bool_t +xdr_u_short (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; } - 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; +bool_t +xdr_char (XDR *xdrs, char *cp) { - int i; - - i = (*cp); - if (!xdr_int(xdrs, &i)) { - return (FALSE); - } - *cp = i; - return (TRUE); + int i; + + i = (*cp); + if (!xdr_int (xdrs, &i)) + { + return FALSE; + } + *cp = i; + return TRUE; } /* * XDR an unsigned char */ -bool_t xdr_u_char (XDR *xdrs, u_char *cp) +bool_t +xdr_u_char (XDR *xdrs, u_char *cp) { - u_int u; - - u = (*cp); - if (!xdr_u_int(xdrs, &u)) { - return (FALSE); - } - *cp = u; - return (TRUE); + 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; +bool_t +xdr_bool (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); + 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; } - 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; +bool_t +xdr_enum (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); + enum sizecheck + { + SIZEVAL + }; /* used to find the size of an enum */ + + /* + * enums are treated as ints + */ + if (sizeof (enum sizecheck) == 4) + { +#if INT_MAX < LONG_MAX + long l; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + l = *ep; + return XDR_PUTLONG (xdrs, &l); + + case XDR_DECODE: + if (!XDR_GETLONG (xdrs, &l)) + { + return FALSE; + } + *ep = l; + case XDR_FREE: + return TRUE; + } + return FALSE; #else - (void) (xdr_short(xdrs, (short *) ep)); - return (xdr_long(xdrs, (long *) ep)); + return xdr_long (xdrs, (long *) ep); #endif + } + else if (sizeof (enum sizecheck) == sizeof (short)) + { + return xdr_short (xdrs, (short *) ep); + } + else + { + return FALSE; + } } /* @@ -310,50 +467,49 @@ enum_t *ep; * 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; +bool_t +xdr_opaque (XDR *xdrs, caddr_t cp, u_int cnt) { - register u_int rndup; - static u_long 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, (caddr_t) 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)); + u_int rndup; + static char 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; + + switch (xdrs->x_op) + { + case XDR_DECODE: + if (!XDR_GETBYTES (xdrs, cp, cnt)) + { + return FALSE; } - - if (xdrs->x_op == XDR_FREE) { - return (TRUE); + if (rndup == 0) + return TRUE; + return XDR_GETBYTES (xdrs, (caddr_t)crud, rndup); + + case XDR_ENCODE: + if (!XDR_PUTBYTES (xdrs, cp, cnt)) + { + return FALSE; } - - return (FALSE); + if (rndup == 0) + return TRUE; + return XDR_PUTBYTES (xdrs, xdr_zero, rndup); + + case XDR_FREE: + return TRUE; + } + return FALSE; } /* @@ -361,70 +517,83 @@ register u_int cnt; * *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; +bool_t +xdr_bytes (xdrs, cpp, sizep, maxsize) + XDR *xdrs; + char **cpp; + 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); + char *sp = *cpp; /* sp is the actual string pointer */ + 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; } - nodesize = *sizep; - if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { - return (FALSE); + if (sp == NULL) + { + *cpp = sp = (char *) mem_alloc (nodesize); } + if (sp == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", _("xdr_bytes: out of memory\n")); + else +#endif + (void) fputs (_("xdr_bytes: out of memory\n"), stderr); + return FALSE; + } + /* fall into ... */ - /* - * 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_ENCODE: + return xdr_opaque (xdrs, sp, nodesize); - case XDR_FREE: - if (sp != NULL) { - mem_free(sp, nodesize); - *cpp = NULL; - } - return (TRUE); + case XDR_FREE: + if (sp != NULL) + { + mem_free (sp, nodesize); + *cpp = NULL; } - return (FALSE); + return TRUE; + } + return FALSE; } /* * Implemented here due to commonality of the object. */ -bool_t xdr_netobj(xdrs, np) -XDR *xdrs; -struct netobj *np; +bool_t +xdr_netobj (xdrs, np) + XDR *xdrs; + struct netobj *np; { - return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); + return xdr_bytes (xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ); } /* - * XDR a descriminated union + * XDR a discriminated 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 @@ -434,37 +603,40 @@ struct netobj *np; * 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 */ -const struct xdr_discrim *choices; /* [value, xdr proc] for each arm */ -xdrproc_t dfault; /* default xdr routine */ +bool_t +xdr_union (xdrs, dscmp, unp, choices, dfault) + XDR *xdrs; + enum_t *dscmp; /* enum to decide which arm to work on */ + char *unp; /* the union itself */ + const 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)); + 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)); } @@ -482,76 +654,94 @@ xdrproc_t dfault; /* default xdr routine */ * 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; +bool_t +xdr_string (xdrs, cpp, maxsize) + 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; - default: /* silence the warnings */ + 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 */ } - if (!xdr_u_int(xdrs, &size)) { - return (FALSE); + /* fall through... */ + case XDR_ENCODE: + if (sp == NULL) + return FALSE; + size = strlen (sp); + break; + case XDR_DECODE: + 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 (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); + if (sp == NULL) + *cpp = sp = (char *) mem_alloc (nodesize); + if (sp == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("xdr_string: out of memory\n")); + else +#endif + (void) fputs (_("xdr_string: out of memory\n"), stderr); + return FALSE; } - 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 +/* + * Wrapper for xdr_string that can be called directly from * routines like clnt_call */ -bool_t xdr_wrapstring(xdrs, cpp) -XDR *xdrs; -char **cpp; +bool_t +xdr_wrapstring (xdrs, cpp) + XDR *xdrs; + char **cpp; { - if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { - return (TRUE); - } - return (FALSE); + if (xdr_string (xdrs, cpp, LASTUNSIGNED)) + { + return TRUE; + } + return FALSE; } diff --git a/libc/inet/rpc/xdr_array.c b/libc/inet/rpc/xdr_array.c index 359fda6ae..11e2a9d2f 100644 --- a/libc/inet/rpc/xdr_array.c +++ b/libc/inet/rpc/xdr_array.c @@ -6,32 +6,33 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. + * xdr_array.c, Generic XDR routines implementation. * * Copyright (C) 1984, Sun Microsystems, Inc. * @@ -39,12 +40,19 @@ * arrays. See xdr.h for more info on the interface to xdr. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + #include <stdio.h> #include <string.h> - #include <rpc/types.h> #include <rpc/xdr.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif + #define LASTUNSIGNED ((u_int)0-1) @@ -55,68 +63,82 @@ * 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 */ +bool_t +xdr_array (xdrs, addrp, sizep, maxsize, elsize, elproc) + 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; + u_int i; + caddr_t target = *addrp; + u_int c; /* the actual element count */ + bool_t stat = TRUE; + 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; + /* 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 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) - 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; + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("xdr_array: out of memory\n")); + else +#endif + (void) fputs (_("xdr_array: out of memory\n"), stderr); + return FALSE; + } + bzero (target, nodesize); + break; - case XDR_FREE: - return (TRUE); - default: /* silence the warnings */ - } + case XDR_FREE: + return TRUE; + default: + break; + } - /* - * now we xdr each element of array - */ - for (i = 0; (i < c) && stat; i++) { - stat = (*elproc) (xdrs, target, LASTUNSIGNED); - target += elsize; - } + /* + * 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); + /* + * the array may need freeing + */ + if (xdrs->x_op == XDR_FREE) + { + mem_free (*addrp, nodesize); + *addrp = NULL; + } + return stat; } /* @@ -129,22 +151,25 @@ xdrproc_t elproc; /* xdr routine to handle each element */ * > 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; +bool_t +xdr_vector (xdrs, basep, nelem, elemsize, xdr_elem) + XDR *xdrs; + char *basep; + u_int nelem; + u_int elemsize; + xdrproc_t xdr_elem; { - register u_int i; - register char *elptr; + u_int i; + char *elptr; - elptr = basep; - for (i = 0; i < nelem; i++) { - if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED)) { - return (FALSE); - } - elptr += elemsize; + elptr = basep; + for (i = 0; i < nelem; i++) + { + if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED)) + { + return FALSE; } - return (TRUE); + elptr += elemsize; + } + return TRUE; } diff --git a/libc/inet/rpc/xdr_float.c b/libc/inet/rpc/xdr_float.c index 623682e0c..5b3802b56 100644 --- a/libc/inet/rpc/xdr_float.c +++ b/libc/inet/rpc/xdr_float.c @@ -6,32 +6,33 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. + * xdr_float.c, Generic XDR routines implementation. * * Copyright (C) 1984, Sun Microsystems, Inc. * @@ -40,7 +41,12 @@ * xdr. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + #include <stdio.h> +#include <endian.h> #include <rpc/types.h> #include <rpc/xdr.h> @@ -50,26 +56,23 @@ * This routine works on Suns (Sky / 68000's) and Vaxen. */ -#ifdef __linux__ -/* cheat big time */ -#define sparc -#endif +#define LSW (__FLOAT_WORD_ORDER == __BIG_ENDIAN) #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; +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; +struct vax_single { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; }; #define VAX_SNG_BIAS 0x81 @@ -79,22 +82,19 @@ 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 */ + {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ + { 0x0, 0xff, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ + { 0x0, 0x0, 0x0 }} /* Min IEEE */ }; -#endif /* vax */ +#endif /* vax */ -bool_t xdr_float(xdrs, fp) -register XDR *xdrs; -register float *fp; +bool_t +xdr_float(xdrs, fp) + XDR *xdrs; + float *fp; { -#if !defined(mc68000) && !defined(sparc) +#ifdef vax struct ieee_single is; struct vax_single vs, *vsp; struct sgl_limits *lim; @@ -103,14 +103,11 @@ register float *fp; switch (xdrs->x_op) { case XDR_ENCODE: -#if defined(mc68000) || defined(sparc) - return (XDR_PUTLONG(xdrs, (long *) fp)); -#else - vs = *((struct vax_single *) fp); +#ifdef vax + vs = *((struct vax_single *)fp); for (i = 0, lim = sgl_limits; - - i < sizeof(sgl_limits) / sizeof(struct sgl_limits); - i++, lim++) { + 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)) { @@ -120,22 +117,27 @@ register float *fp; } is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; - shipit: + shipit: is.sign = vs.sign; - return (XDR_PUTLONG(xdrs, (long *) &is)); + return (XDR_PUTLONG(xdrs, (long *)&is)); +#else + if (sizeof(float) == sizeof(long)) + return (XDR_PUTLONG(xdrs, (long *)fp)); + else if (sizeof(float) == sizeof(int)) { + long tmp = *(int *)fp; + return (XDR_PUTLONG(xdrs, &tmp)); + } + break; #endif case XDR_DECODE: -#if defined(mc68000) || defined(sparc) - return (XDR_GETLONG(xdrs, (long *) fp)); -#else - vsp = (struct vax_single *) fp; - if (!XDR_GETLONG(xdrs, (long *) &is)) +#ifdef vax + 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++) { + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { if ((is.exp == lim->ieee.exp) && (is.mantissa == lim->ieee.mantissa)) { *vsp = lim->s; @@ -145,9 +147,20 @@ register float *fp; vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; vsp->mantissa2 = is.mantissa; vsp->mantissa1 = (is.mantissa >> 16); - doneit: + doneit: vsp->sign = is.sign; return (TRUE); +#else + if (sizeof(float) == sizeof(long)) + return (XDR_GETLONG(xdrs, (long *)fp)); + else if (sizeof(float) == sizeof(int)) { + long tmp; + if (XDR_GETLONG(xdrs, &tmp)) { + *(int *)fp = tmp; + return (TRUE); + } + } + break; #endif case XDR_FREE: @@ -162,21 +175,21 @@ register float *fp; #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; +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; +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 @@ -184,31 +197,26 @@ struct vax_double { #define MASK(nbits) ((1 << nbits) - 1) static struct dbl_limits { - struct vax_double d; - struct ieee_double ieee; + 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 */ + {{ 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 */ +#endif /* vax */ -bool_t xdr_double(xdrs, dp) -register XDR *xdrs; -double *dp; +bool_t +xdr_double(xdrs, dp) + XDR *xdrs; + double *dp; { - register long *lp; - -#if !defined(mc68000) && !defined(sparc) - struct ieee_double id; - struct vax_double vd; +#ifdef vax + struct ieee_double id; + struct vax_double vd; register struct dbl_limits *lim; int i; #endif @@ -216,14 +224,11 @@ double *dp; switch (xdrs->x_op) { case XDR_ENCODE: -#if defined(mc68000) || defined(sparc) - lp = (long *) dp; -#else - vd = *((struct vax_double *) dp); +#ifdef vax + vd = *((struct vax_double *)dp); for (i = 0, lim = dbl_limits; - - i < sizeof(dbl_limits) / sizeof(struct dbl_limits); - i++, lim++) { + 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) && @@ -236,25 +241,34 @@ double *dp; 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: + (vd.mantissa3 << 13) | + ((vd.mantissa4 >> 3) & MASK(13)); + shipit: id.sign = vd.sign; - lp = (long *) &id; + dp = (double *)&id; #endif - return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); + if (2*sizeof(long) == sizeof(double)) { + long *lp = (long *)dp; + return (XDR_PUTLONG(xdrs, lp+!LSW) && + XDR_PUTLONG(xdrs, lp+LSW)); + } else if (2*sizeof(int) == sizeof(double)) { + int *ip = (int *)dp; + long tmp[2]; + tmp[0] = ip[!LSW]; + tmp[1] = ip[LSW]; + return (XDR_PUTLONG(xdrs, tmp) && + XDR_PUTLONG(xdrs, tmp+1)); + } + break; case XDR_DECODE: -#if defined(mc68000) || defined(sparc) - lp = (long *) dp; - return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp)); -#else - lp = (long *) &id; +#ifdef vax + 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++) { + 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)) { @@ -265,13 +279,29 @@ double *dp; 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); + (id.mantissa2 >> 29); vd.mantissa3 = (id.mantissa2 >> 13); vd.mantissa4 = (id.mantissa2 << 3); - doneit: + doneit: vd.sign = id.sign; - *dp = *((double *) &vd); + *dp = *((double *)&vd); return (TRUE); +#else + if (2*sizeof(long) == sizeof(double)) { + long *lp = (long *)dp; + return (XDR_GETLONG(xdrs, lp+!LSW) && + XDR_GETLONG(xdrs, lp+LSW)); + } else if (2*sizeof(int) == sizeof(double)) { + int *ip = (int *)dp; + long tmp[2]; + if (XDR_GETLONG(xdrs, tmp+!LSW) && + XDR_GETLONG(xdrs, tmp+LSW)) { + ip[0] = tmp[0]; + ip[1] = tmp[1]; + return (TRUE); + } + } + break; #endif case XDR_FREE: diff --git a/libc/inet/rpc/xdr_intXX_t.c b/libc/inet/rpc/xdr_intXX_t.c new file mode 100644 index 000000000..d36d1623b --- /dev/null +++ b/libc/inet/rpc/xdr_intXX_t.c @@ -0,0 +1,203 @@ +/* Copyright (c) 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* XDR 64bit integers */ +bool_t +xdr_int64_t (XDR *xdrs, int64_t *ip) +{ + int32_t t1; + /* This must be unsigned, otherwise we get problems with sign + extension in the DECODE case. */ + uint32_t t2; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + t1 = (int32_t) ((*ip) >> 32); + t2 = (int32_t) (*ip); + return (XDR_PUTINT32(xdrs, &t1) && XDR_PUTINT32(xdrs, &t2)); + case XDR_DECODE: + if (!XDR_GETINT32(xdrs, &t1) || !XDR_GETINT32(xdrs, &t2)) + return FALSE; + *ip = ((int64_t) t1) << 32; + *ip |= t2; + return TRUE; + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} + +/* XDR 64bit unsigned integers */ +bool_t +xdr_uint64_t (XDR *xdrs, uint64_t *uip) +{ + uint32_t t1; + uint32_t t2; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + t1 = (uint32_t) ((*uip) >> 32); + t2 = (uint32_t) (*uip); + return (XDR_PUTINT32 (xdrs, (int32_t *) &t1) && + XDR_PUTINT32(xdrs, (int32_t *) &t2)); + case XDR_DECODE: + if (!XDR_GETINT32(xdrs, (int32_t *) &t1) || + !XDR_GETINT32(xdrs, (int32_t *) &t2)) + return FALSE; + *uip = ((uint64_t) t1) << 32; + *uip |= t2; + return TRUE; + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} + +/* XDR 32bit integers */ +bool_t +xdr_int32_t (XDR *xdrs, int32_t *lp) +{ + switch (xdrs->x_op) + { + case XDR_ENCODE: + return XDR_PUTINT32 (xdrs, lp); + case XDR_DECODE: + return XDR_GETINT32 (xdrs, lp); + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} + +/* XDR 32bit unsigned integers */ +bool_t +xdr_uint32_t (XDR *xdrs, uint32_t *ulp) +{ + switch (xdrs->x_op) + { + case XDR_ENCODE: + return XDR_PUTINT32 (xdrs, (int32_t *) ulp); + case XDR_DECODE: + return XDR_GETINT32 (xdrs, (int32_t *) ulp); + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} + +/* XDR 16bit integers */ +bool_t +xdr_int16_t (XDR *xdrs, int16_t *ip) +{ + int32_t t; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + t = (int32_t) *ip; + return XDR_PUTINT32 (xdrs, &t); + case XDR_DECODE: + if (!XDR_GETINT32 (xdrs, &t)) + return FALSE; + *ip = (int16_t) t; + return TRUE; + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} + +/* XDR 16bit unsigned integers */ +bool_t +xdr_uint16_t (XDR *xdrs, uint16_t *uip) +{ + uint32_t ut; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + ut = (uint32_t) *uip; + return XDR_PUTINT32 (xdrs, (int32_t *) &ut); + case XDR_DECODE: + if (!XDR_GETINT32 (xdrs, (int32_t *) &ut)) + return FALSE; + *uip = (uint16_t) ut; + return TRUE; + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} + +/* XDR 8bit integers */ +bool_t +xdr_int8_t (XDR *xdrs, int8_t *ip) +{ + int32_t t; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + t = (int32_t) *ip; + return XDR_PUTINT32 (xdrs, &t); + case XDR_DECODE: + if (!XDR_GETINT32 (xdrs, &t)) + return FALSE; + *ip = (int8_t) t; + return TRUE; + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} + +/* XDR 8bit unsigned integers */ +bool_t +xdr_uint8_t (XDR *xdrs, uint8_t *uip) +{ + uint32_t ut; + + switch (xdrs->x_op) + { + case XDR_ENCODE: + ut = (uint32_t) *uip; + return XDR_PUTINT32 (xdrs, (int32_t *) &ut); + case XDR_DECODE: + if (!XDR_GETINT32 (xdrs, (int32_t *) &ut)) + return FALSE; + *uip = (uint8_t) ut; + return TRUE; + case XDR_FREE: + return TRUE; + default: + return FALSE; + } +} diff --git a/libc/inet/rpc/xdr_mem.c b/libc/inet/rpc/xdr_mem.c index aa5349656..e80de7b1a 100644 --- a/libc/inet/rpc/xdr_mem.c +++ b/libc/inet/rpc/xdr_mem.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,29 +5,27 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> /* * xdr_mem.h, XDR implementation using memory buffers. @@ -41,138 +38,195 @@ * */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + + #include <string.h> -#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 int32_t *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 +#include <rpc/rpc.h> + +static bool_t xdrmem_getlong (XDR *, long *); +static bool_t xdrmem_putlong (XDR *, const long *); +static bool_t xdrmem_getbytes (XDR *, caddr_t, u_int); +static bool_t xdrmem_putbytes (XDR *, const char *, u_int); +static u_int xdrmem_getpos (const XDR *); +static bool_t xdrmem_setpos (XDR *, u_int); +static int32_t *xdrmem_inline (XDR *, int); +static void xdrmem_destroy (XDR *); +static bool_t xdrmem_getint32 (XDR *, int32_t *); +static bool_t xdrmem_putint32 (XDR *, const int32_t *); + +static const struct xdr_ops xdrmem_ops = +{ + xdrmem_getlong, + xdrmem_putlong, + xdrmem_getbytes, + xdrmem_putbytes, + xdrmem_getpos, + xdrmem_setpos, + xdrmem_inline, + xdrmem_destroy, + xdrmem_getint32, + xdrmem_putint32 }; /* * The procedure xdrmem_create initializes a stream descriptor for a - * memory buffer. + * memory buffer. */ -void xdrmem_create(xdrs, addr, size, op) -register XDR *xdrs; -caddr_t addr; -u_int size; -enum xdr_op op; +void +xdrmem_create (XDR *xdrs, const 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; + xdrs->x_op = op; + /* We have to add the const since the `struct xdr_ops' in `struct XDR' + is not `const'. */ + xdrs->x_ops = (struct xdr_ops *) &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; + xdrs->x_handy = size; } -static void xdrmem_destroy( /*xdrs */ ) - /*XDR *xdrs; */ +/* + * Nothing needs to be done for the memory case. The argument is clearly + * const. + */ + +static void +xdrmem_destroy (XDR *xdrs) { } -static bool_t xdrmem_getlong(xdrs, lp) -register XDR *xdrs; -long *lp; +/* + * Gets the next word from the memory referenced by xdrs and places it + * in the long pointed to by lp. It then increments the private word to + * point at the next element. Neither object pointed to is const + */ +static bool_t +xdrmem_getlong (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); + if ((xdrs->x_handy -= 4) < 0) + return FALSE; + *lp = (int32_t) ntohl ((*((int32_t *) (xdrs->x_private)))); + xdrs->x_private += 4; + return TRUE; } -static bool_t xdrmem_putlong(xdrs, lp) -register XDR *xdrs; -long *lp; +/* + * Puts the long pointed to by lp in the memory referenced by xdrs. It + * then increments the private word to point at the next element. The + * long pointed at is const + */ +static bool_t +xdrmem_putlong (XDR *xdrs, const 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); + if ((xdrs->x_handy -= 4) < 0) + return FALSE; + *(int32_t *) xdrs->x_private = htonl (*lp); + xdrs->x_private += 4; + return TRUE; } -static bool_t xdrmem_getbytes(xdrs, addr, len) -register XDR *xdrs; -caddr_t addr; -register u_int len; +/* + * Gets an unaligned number of bytes from the xdrs structure and writes them + * to the address passed in addr. Be very careful when calling this routine + * as it could leave the xdrs pointing to an unaligned structure which is not + * a good idea. None of the things pointed to are const. + */ +static bool_t +xdrmem_getbytes (XDR *xdrs, caddr_t addr, u_int len) { - - if ((xdrs->x_handy -= len) < 0) - return (FALSE); - bcopy(xdrs->x_private, addr, len); - xdrs->x_private += len; - return (TRUE); + if ((xdrs->x_handy -= len) < 0) + return FALSE; + memcpy (addr, xdrs->x_private, 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; +/* + * The complementary function to the above. The same warnings apply about + * unaligned data. The source address is const. + */ +static bool_t +xdrmem_putbytes (XDR *xdrs, const char *addr, u_int len) { + if ((xdrs->x_handy -= len) < 0) + return FALSE; + memcpy (xdrs->x_private, addr, len); + xdrs->x_private += len; + return TRUE; +} - if ((xdrs->x_handy -= len) < 0) - return (FALSE); - bcopy(addr, xdrs->x_private, len); - xdrs->x_private += len; - return (TRUE); +/* + * Not sure what this one does. But it clearly doesn't modify the contents + * of xdrs. **FIXME** does this not assume u_int == u_long? + */ +static u_int +xdrmem_getpos (const XDR *xdrs) +{ + return (u_long) xdrs->x_private - (u_long) xdrs->x_base; } -static u_int xdrmem_getpos(xdrs) -register XDR *xdrs; +/* + * xdrs modified + */ +static bool_t +xdrmem_setpos (xdrs, pos) + XDR *xdrs; + u_int pos; { + caddr_t newaddr = xdrs->x_base + pos; + caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; + + if ((long) newaddr > (long) lastaddr) + return FALSE; + xdrs->x_private = newaddr; + xdrs->x_handy = (long) lastaddr - (long) newaddr; + return TRUE; +} - return ((u_int) xdrs->x_private - (u_int) xdrs->x_base); +/* + * xdrs modified + */ +static int32_t * +xdrmem_inline (XDR *xdrs, int len) +{ + int32_t *buf = 0; + + if (xdrs->x_handy >= len) + { + xdrs->x_handy -= len; + buf = (int32_t *) xdrs->x_private; + xdrs->x_private += len; + } + return buf; } -static bool_t xdrmem_setpos(xdrs, pos) -register XDR *xdrs; -u_int pos; +/* + * Gets the next word from the memory referenced by xdrs and places it + * in the int pointed to by ip. It then increments the private word to + * point at the next element. Neither object pointed to is const + */ +static bool_t +xdrmem_getint32 (XDR *xdrs, int32_t *ip) { - 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); + if ((xdrs->x_handy -= 4) < 0) + return FALSE; + *ip = ntohl ((*((int32_t *) (xdrs->x_private)))); + xdrs->x_private += 4; + return TRUE; } -static int32_t *xdrmem_inline(xdrs, len) -register XDR *xdrs; -int len; +/* + * Puts the long pointed to by lp in the memory referenced by xdrs. It + * then increments the private word to point at the next element. The + * long pointed at is const + */ +static bool_t +xdrmem_putint32 (XDR *xdrs, const int32_t *ip) { - int32_t *buf = 0; - - if (xdrs->x_handy >= len) { - xdrs->x_handy -= len; - buf = (int32_t *) xdrs->x_private; - xdrs->x_private += len; - } - return (buf); + if ((xdrs->x_handy -= 4) < 0) + return FALSE; + *(int32_t *) xdrs->x_private = htonl (*ip); + xdrs->x_private += 4; + return TRUE; } diff --git a/libc/inet/rpc/xdr_rec.c b/libc/inet/rpc/xdr_rec.c index 3e4a1b582..9c21f57f4 100644 --- a/libc/inet/rpc/xdr_rec.c +++ b/libc/inet/rpc/xdr_rec.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,29 +5,27 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> /* * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" @@ -41,40 +38,50 @@ * 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 + * is represented as a htonl(u_long). The high order bit encodes * whether or not the fragment is the last fragment of the record - * (1 => fragment is last, 0 => more fragments to follow. + * (1 => fragment is last, 0 => more fragments to follow. * The other 31 bits encode the byte length of the fragment. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + + #include <stdio.h> #include <string.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 int32_t *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 +#include <unistd.h> +#include <rpc/rpc.h> + +#ifdef USE_IN_LIBIO +# include <wchar.h> +# include <libio/iolibio.h> +# define fputs(s, f) _IO_fputs (s, f) +#endif + +static bool_t xdrrec_getlong (XDR *, long *); +static bool_t xdrrec_putlong (XDR *, const long *); +static bool_t xdrrec_getbytes (XDR *, caddr_t, u_int); +static bool_t xdrrec_putbytes (XDR *, const char *, u_int); +static u_int xdrrec_getpos (const XDR *); +static bool_t xdrrec_setpos (XDR *, u_int); +static int32_t *xdrrec_inline (XDR *, int); +static void xdrrec_destroy (XDR *); +static bool_t xdrrec_getint32 (XDR *, int32_t *); +static bool_t xdrrec_putint32 (XDR *, const int32_t *); + +static const struct xdr_ops xdrrec_ops = { + xdrrec_getlong, + xdrrec_putlong, + xdrrec_getbytes, + xdrrec_putbytes, + xdrrec_getpos, + xdrrec_setpos, + xdrrec_inline, + xdrrec_destroy, + xdrrec_getint32, + xdrrec_putint32 }; /* @@ -90,39 +97,41 @@ static struct xdr_ops xdrrec_ops = { * 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; - -static bool_t flush_out(register RECSTREAM *rstrm, bool_t eor); -static bool_t set_input_fragment(register RECSTREAM *rstrm); -static bool_t get_input_bytes(register RECSTREAM *rstrm, - register caddr_t addr, register int len); -static bool_t skip_input_bytes(register RECSTREAM *rstrm, long cnt); +#define LAST_FRAG (1UL << 31) + +typedef struct rec_strm + { + caddr_t tcp_handle; + caddr_t the_buffer; + /* + * out-going bits + */ + int (*writeit) (char *, char *, int); + 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_int32_t *frag_header; /* beginning of curren fragment */ + bool_t frag_sent; /* true if buffer sent in middle of record */ + /* + * in-coming bits + */ + int (*readit) (char *, char *, int); + 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; + +static u_int fix_buf_size (u_int) internal_function; +static bool_t skip_input_bytes (RECSTREAM *, long) internal_function; +static bool_t flush_out (RECSTREAM *, bool_t) internal_function; +static bool_t set_input_fragment (RECSTREAM *) internal_function; +static bool_t get_input_bytes (RECSTREAM *, caddr_t, int) internal_function; /* * Create an xdr handle for xdrrec @@ -133,265 +142,330 @@ static bool_t skip_input_bytes(register RECSTREAM *rstrm, long cnt); * 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 */ +void +xdrrec_create (XDR *xdrs, u_int sendsize, + u_int recvsize, caddr_t tcp_handle, + int (*readit) (char *, char *, int), + int (*writeit) (char *, char *, int)) { - 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; + RECSTREAM *rstrm = (RECSTREAM *) mem_alloc (sizeof (RECSTREAM)); + caddr_t tmp; + char *buf; + + sendsize = fix_buf_size (sendsize); + recvsize = fix_buf_size (recvsize); + buf = mem_alloc (sendsize + recvsize + BYTES_PER_XDR_UNIT); + + if (rstrm == NULL || buf == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", _("xdrrec_create: out of memory\n")); + else +#endif + (void) fputs (_("xdrrec_create: out of memory\n"), stderr); + mem_free (rstrm, sizeof (RECSTREAM)); + mem_free (buf, sendsize + recvsize + BYTES_PER_XDR_UNIT); + /* + * 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; + rstrm->recvsize = recvsize; + rstrm->the_buffer = buf; + tmp = rstrm->the_buffer; + if ((size_t)tmp % BYTES_PER_XDR_UNIT) + tmp += BYTES_PER_XDR_UNIT - (size_t)tmp % BYTES_PER_XDR_UNIT; + rstrm->out_base = tmp; + rstrm->in_base = tmp + sendsize; + /* + * now the rest ... + */ + /* We have to add the const since the `struct xdr_ops' in `struct XDR' + is not `const'. */ + xdrs->x_ops = (struct xdr_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_int32_t *) rstrm->out_base; + rstrm->out_finger += 4; + 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 + * The routines 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; +static bool_t +xdrrec_getlong (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); + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + int32_t *buflp = (int32_t *) rstrm->in_finger; + int32_t mylong; + + /* first try the inline, fast case */ + if (rstrm->fbtbc >= BYTES_PER_XDR_UNIT && + rstrm->in_boundry - (char *) buflp >= BYTES_PER_XDR_UNIT) + { + *lp = (int32_t) ntohl (*buflp); + rstrm->fbtbc -= BYTES_PER_XDR_UNIT; + rstrm->in_finger += BYTES_PER_XDR_UNIT; + } + else + { + if (!xdrrec_getbytes (xdrs, (caddr_t) & mylong, + BYTES_PER_XDR_UNIT)) + return FALSE; + *lp = (int32_t) ntohl (mylong); + } + return TRUE; } -static bool_t xdrrec_putlong(xdrs, lp) -XDR *xdrs; -long *lp; +static bool_t +xdrrec_putlong (XDR *xdrs, const 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); + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + int32_t *dest_lp = (int32_t *) rstrm->out_finger; + + if ((rstrm->out_finger += BYTES_PER_XDR_UNIT) > rstrm->out_boundry) + { + /* + * this case should almost never happen so the code is + * inefficient + */ + rstrm->out_finger -= BYTES_PER_XDR_UNIT; + rstrm->frag_sent = TRUE; + if (!flush_out (rstrm, FALSE)) + return FALSE; + dest_lp = (int32_t *) rstrm->out_finger; + rstrm->out_finger += BYTES_PER_XDR_UNIT; + } + *dest_lp = htonl (*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; +static bool_t /* must manage buffers, fragments, and records */ +xdrrec_getbytes (XDR *xdrs, caddr_t addr, 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; + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + u_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; } - return (TRUE); + 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; +static bool_t +xdrrec_putbytes (XDR *xdrs, const char *addr, 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); - } + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + u_int current; + + while (len > 0) + { + current = rstrm->out_boundry - rstrm->out_finger; + current = (len < current) ? len : current; + memcpy (rstrm->out_finger, addr, current); + rstrm->out_finger += current; + addr += current; + len -= current; + if (rstrm->out_finger == rstrm->out_boundry && len > 0) + { + rstrm->frag_sent = TRUE; + if (!flush_out (rstrm, FALSE)) + return FALSE; } - return (TRUE); + } + return TRUE; } -static u_int xdrrec_getpos(xdrs) -register XDR *xdrs; +static u_int +xdrrec_getpos (const 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); + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + long pos; + + pos = lseek ((int) (long) 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; +static bool_t +xdrrec_setpos (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; - default: /* silence the warnings */ - } - return (FALSE); + 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; + + default: + break; + } + return FALSE; } -static int32_t *xdrrec_inline(xdrs, len) -register XDR *xdrs; -int len; +static int32_t * +xdrrec_inline (XDR *xdrs, int len) { - register RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; - int32_t *buf = NULL; - - switch (xdrs->x_op) { - - case XDR_ENCODE: - if ((rstrm->out_finger + len) <= rstrm->out_boundry) { - buf = (int32_t *) rstrm->out_finger; - rstrm->out_finger += len; - } - break; - - case XDR_DECODE: - if ((len <= rstrm->fbtbc) && - ((rstrm->in_finger + len) <= rstrm->in_boundry)) { - buf = (int32_t *) rstrm->in_finger; - rstrm->fbtbc -= len; - rstrm->in_finger += len; - } - break; - default: /* silence the warnings */ + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + int32_t *buf = NULL; + + switch (xdrs->x_op) + { + + case XDR_ENCODE: + if ((rstrm->out_finger + len) <= rstrm->out_boundry) + { + buf = (int32_t *) rstrm->out_finger; + rstrm->out_finger += len; + } + break; + + case XDR_DECODE: + if ((len <= rstrm->fbtbc) && + ((rstrm->in_finger + len) <= rstrm->in_boundry)) + { + buf = (int32_t *) rstrm->in_finger; + rstrm->fbtbc -= len; + rstrm->in_finger += len; } - return (buf); + break; + + default: + break; + } + return buf; } -static void xdrrec_destroy(xdrs) -register XDR *xdrs; +static void +xdrrec_destroy (XDR *xdrs) { - register RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + 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)); +} - mem_free(rstrm->the_buffer, - rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); - mem_free((caddr_t) rstrm, sizeof(RECSTREAM)); +static bool_t +xdrrec_getint32 (XDR *xdrs, int32_t *ip) +{ + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + int32_t *bufip = (int32_t *) rstrm->in_finger; + int32_t mylong; + + /* first try the inline, fast case */ + if (rstrm->fbtbc >= BYTES_PER_XDR_UNIT && + rstrm->in_boundry - (char *) bufip >= BYTES_PER_XDR_UNIT) + { + *ip = ntohl (*bufip); + rstrm->fbtbc -= BYTES_PER_XDR_UNIT; + rstrm->in_finger += BYTES_PER_XDR_UNIT; + } + else + { + if (!xdrrec_getbytes (xdrs, (caddr_t) &mylong, + BYTES_PER_XDR_UNIT)) + return FALSE; + *ip = ntohl (mylong); + } + return TRUE; } +static bool_t +xdrrec_putint32 (XDR *xdrs, const int32_t *ip) +{ + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + int32_t *dest_ip = (int32_t *) rstrm->out_finger; + + if ((rstrm->out_finger += BYTES_PER_XDR_UNIT) > rstrm->out_boundry) + { + /* + * this case should almost never happen so the code is + * inefficient + */ + rstrm->out_finger -= BYTES_PER_XDR_UNIT; + rstrm->frag_sent = TRUE; + if (!flush_out (rstrm, FALSE)) + return FALSE; + dest_ip = (int32_t *) rstrm->out_finger; + rstrm->out_finger += BYTES_PER_XDR_UNIT; + } + *dest_ip = htonl (*ip); + return TRUE; +} /* * Exported routines to manage xdr records @@ -401,181 +475,190 @@ register XDR *xdrs; * Before reading (deserializing from the stream, one should always call * this procedure to guarantee proper record alignment. */ -bool_t xdrrec_skiprecord(xdrs) -XDR *xdrs; +bool_t +xdrrec_skiprecord (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); + 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 + * Lookahead function. + * 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; +bool_t +xdrrec_eof (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); + 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. + * The second parameter tells whether the record should be flushed to the + * (output) tcp stream. (This lets the package support batched or + * pipelined procedure calls.) TRUE => immediate flush to tcp connection. */ -bool_t xdrrec_endofrecord(xdrs, sendnow) -XDR *xdrs; -bool_t sendnow; +bool_t +xdrrec_endofrecord (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); + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + u_long len; /* fragment length */ + + if (sendnow || rstrm->frag_sent + || rstrm->out_finger + BYTES_PER_XDR_UNIT >= rstrm->out_boundry) + { + rstrm->frag_sent = FALSE; + return flush_out (rstrm, TRUE); + } + len = (rstrm->out_finger - (char *) rstrm->frag_header + - BYTES_PER_XDR_UNIT); + *rstrm->frag_header = htonl ((u_long) len | LAST_FRAG); + rstrm->frag_header = (u_int32_t *) rstrm->out_finger; + rstrm->out_finger += BYTES_PER_XDR_UNIT; + return TRUE; } /* * Internal useful routines */ -static bool_t flush_out(rstrm, eor) -register RECSTREAM *rstrm; -bool_t eor; +static bool_t +internal_function +flush_out (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); + u_long eormask = (eor == TRUE) ? LAST_FRAG : 0; + u_long len = (rstrm->out_finger - (char *) rstrm->frag_header + - BYTES_PER_XDR_UNIT); + + *rstrm->frag_header = htonl (len | eormask); + len = rstrm->out_finger - rstrm->out_base; + if ((*(rstrm->writeit)) (rstrm->tcp_handle, rstrm->out_base, (int) len) + != (int) len) + return FALSE; + rstrm->frag_header = (u_int32_t *) rstrm->out_base; + rstrm->out_finger = (caddr_t) rstrm->out_base + BYTES_PER_XDR_UNIT; + return TRUE; } -static bool_t -/* knows nothing about records! Only about input buffers */ -fill_input_buf(rstrm) -register RECSTREAM *rstrm; +static bool_t /* knows nothing about records! Only about input buffers */ +fill_input_buf (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); + caddr_t where; + size_t i; + int len; + + where = rstrm->in_base; + i = (size_t) 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; +static bool_t /* knows nothing about records! Only about input buffers */ +internal_function +get_input_bytes (RECSTREAM *rstrm, caddr_t addr, 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; + int current; + + while (len > 0) + { + current = rstrm->in_boundry - rstrm->in_finger; + if (current == 0) + { + if (!fill_input_buf (rstrm)) + return FALSE; + continue; } - return (TRUE); + current = (len < current) ? len : current; + memcpy (addr, rstrm->in_finger, 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; +static bool_t /* next two bytes of the input stream are treated as a header */ +internal_function +set_input_fragment (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); + uint32_t header; + + if (! get_input_bytes (rstrm, (caddr_t)&header, BYTES_PER_XDR_UNIT)) + return FALSE; + header = ntohl (header); + rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE; + /* + * Sanity check. Try not to accept wildly incorrect fragment + * sizes. Unfortunately, only a size of zero can be identified as + * 'wildely incorrect', and this only, if it is not the last + * fragment of a message. Ridiculously large fragment sizes may look + * wrong, but we don't have any way to be certain that they aren't + * what the client actually intended to send us. Many existing RPC + * implementations may sent a fragment of size zero as the last + * fragment of a message. + */ + if (header == 0) + return FALSE; + 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; +static bool_t /* consumes input bytes; knows nothing about records! */ +internal_function +skip_input_bytes (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; + int current; + + while (cnt > 0) + { + current = rstrm->in_boundry - rstrm->in_finger; + if (current == 0) + { + if (!fill_input_buf (rstrm)) + return FALSE; + continue; } - return (TRUE); + current = (cnt < current) ? cnt : current; + rstrm->in_finger += current; + cnt -= current; + } + return TRUE; } -static u_int fix_buf_size(s) -register u_int s; +static u_int +internal_function +fix_buf_size (u_int s) { - - if (s < 100) - s = 4000; - return (RNDUP(s)); + if (s < 100) + s = 4000; + return RNDUP (s); } diff --git a/libc/inet/rpc/xdr_reference.c b/libc/inet/rpc/xdr_reference.c index 94b8a4bb6..708531bf8 100644 --- a/libc/inet/rpc/xdr_reference.c +++ b/libc/inet/rpc/xdr_reference.c @@ -6,32 +6,33 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> +#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. + * xdr_reference.c, Generic XDR routines implementation. * * Copyright (C) 1987, Sun Microsystems, Inc. * @@ -39,11 +40,21 @@ * "pointers". See xdr.h for more info on the interface to xdr. */ +#define __FORCE_GLIBC +#define _GNU_SOURCE +#include <features.h> + #include <stdio.h> #include <string.h> #include <rpc/types.h> #include <rpc/xdr.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +# include <libio/iolibio.h> +# define fputs(s, f) _IO_fputs (s, f) +#endif + #define LASTUNSIGNED ((u_int)0-1) /* @@ -52,41 +63,52 @@ * 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. + * size is the size of 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 */ +bool_t +xdr_reference (xdrs, pp, size, proc) + 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; + caddr_t loc = *pp; + bool_t stat; - if (loc == NULL) - switch (xdrs->x_op) { - case XDR_FREE: - return (TRUE); + 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; - default: /* silence the warnings */ - } + case XDR_DECODE: + *pp = loc = (caddr_t) mem_alloc (size); + if (loc == NULL) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + (void) __fwprintf (stderr, L"%s", + _("xdr_reference: out of memory\n")); + else +#endif + (void) fputs (_("xdr_reference: out of memory\n"), stderr); + return FALSE; + } + bzero (loc, (int) size); + break; + default: + break; + } - stat = (*proc) (xdrs, loc, LASTUNSIGNED); + stat = (*proc) (xdrs, loc, LASTUNSIGNED); - if (xdrs->x_op == XDR_FREE) { - mem_free(loc, size); - *pp = NULL; - } - return (stat); + if (xdrs->x_op == XDR_FREE) + { + mem_free (loc, size); + *pp = NULL; + } + return stat; } @@ -94,7 +116,7 @@ xdrproc_t proc; /* xdr routine to handle the object */ * xdr_pointer(): * * XDR a pointer to a possibly recursive data structure. This - * differs with xdr_reference in that it can serialize/deserialiaze + * differs with xdr_reference in that it can serialize/deserialize * trees correctly. * * What's sent is actually a union: @@ -109,22 +131,25 @@ xdrproc_t proc; /* xdr routine to handle 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 +xdr_pointer (xdrs, objpp, obj_size, xdr_obj) + XDR *xdrs; + char **objpp; + u_int obj_size; + xdrproc_t xdr_obj; { - bool_t more_data; + 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)); + 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/libc/inet/rpc/xdr_stdio.c b/libc/inet/rpc/xdr_stdio.c index 5b420d61e..411cf17da 100644 --- a/libc/inet/rpc/xdr_stdio.c +++ b/libc/inet/rpc/xdr_stdio.c @@ -1,4 +1,3 @@ -/* @(#)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 @@ -6,29 +5,27 @@ * 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 */ -#define __FORCE_GLIBC -#include <features.h> /* * xdr_stdio.c, XDR implementation on standard i/o file. @@ -44,27 +41,40 @@ #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 int32_t *xdrstdio_inline(); -static void xdrstdio_destroy(); +#ifdef USE_IN_LIBIO +# include <libio/iolibio.h> +# define fflush(s) _IO_fflush (s) +# define fread(p, m, n, s) _IO_fread (p, m, n, s) +# define ftell(s) _IO_ftell (s) +# define fwrite(p, m, n, s) _IO_fwrite (p, m, n, s) +#endif + +static bool_t xdrstdio_getlong (XDR *, long *); +static bool_t xdrstdio_putlong (XDR *, const long *); +static bool_t xdrstdio_getbytes (XDR *, caddr_t, u_int); +static bool_t xdrstdio_putbytes (XDR *, const char *, u_int); +static u_int xdrstdio_getpos (const XDR *); +static bool_t xdrstdio_setpos (XDR *, u_int); +static int32_t *xdrstdio_inline (XDR *, int); +static void xdrstdio_destroy (XDR *); +static bool_t xdrstdio_getint32 (XDR *, int32_t *); +static bool_t xdrstdio_putint32 (XDR *, const int32_t *); /* * 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 */ +static const struct xdr_ops xdrstdio_ops = +{ + xdrstdio_getlong, /* deserialize a long int */ + xdrstdio_putlong, /* serialize 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 */ + xdrstdio_getint32, /* deserialize a int */ + xdrstdio_putint32 /* serialize a int */ }; /* @@ -72,113 +82,113 @@ static struct xdr_ops xdrstdio_ops = { * 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; +void +xdrstdio_create (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; + xdrs->x_op = op; + /* We have to add the const since the `struct xdr_ops' in `struct XDR' + is not `const'. */ + xdrs->x_ops = (struct xdr_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; +static void +xdrstdio_destroy (XDR *xdrs) { - (void) fflush((FILE *) xdrs->x_private); - /* xx should we close the file ?? */ + (void) fflush ((FILE *) xdrs->x_private); + /* xx should we close the file ?? */ }; -static bool_t xdrstdio_getlong(xdrs, lp) -XDR *xdrs; -register long *lp; +static bool_t +xdrstdio_getlong (XDR *xdrs, long *lp) { + int32_t mycopy; - if (fread((caddr_t) lp, sizeof(long), 1, (FILE *) xdrs->x_private) != - 1) return (FALSE); - -#ifndef mc68000 - *lp = ntohl(*lp); -#endif - return (TRUE); + if (fread ((caddr_t) & mycopy, 4, 1, (FILE *) xdrs->x_private) != 1) + return FALSE; + *lp = (int32_t) ntohl (mycopy); + return TRUE; } -static bool_t xdrstdio_putlong(xdrs, lp) -XDR *xdrs; -long *lp; +static bool_t +xdrstdio_putlong (XDR *xdrs, const 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); + long mycopy = htonl (*lp); + lp = &mycopy; + if (fwrite ((caddr_t) lp, 4, 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; +static bool_t +xdrstdio_getbytes (XDR *xdrs, const caddr_t addr, u_int len) { - - if ((len != 0) - && (fread(addr, (int) len, 1, (FILE *) xdrs->x_private) != 1)) - return (FALSE); - return (TRUE); + 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; +static bool_t +xdrstdio_putbytes (XDR *xdrs, const char *addr, u_int len) { + if ((len != 0) && (fwrite (addr, (int) len, 1, + (FILE *) xdrs->x_private) != 1)) + return FALSE; + return TRUE; +} - if ((len != 0) - && (fwrite(addr, (int) len, 1, (FILE *) xdrs->x_private) != 1)) - return (FALSE); - return (TRUE); +static u_int +xdrstdio_getpos (const XDR *xdrs) +{ + return (u_int) ftell ((FILE *) xdrs->x_private); } -static u_int xdrstdio_getpos(xdrs) -XDR *xdrs; +static bool_t +xdrstdio_setpos (XDR *xdrs, u_int pos) { + return fseek ((FILE *) xdrs->x_private, (long) pos, 0) < 0 ? FALSE : TRUE; +} - return ((u_int) ftell((FILE *) xdrs->x_private)); +static int32_t * +xdrstdio_inline (XDR *xdrs, 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; } -static bool_t xdrstdio_setpos(xdrs, pos) -XDR *xdrs; -u_int pos; +static bool_t +xdrstdio_getint32 (XDR *xdrs, int32_t *ip) { + int32_t mycopy; - return ((fseek((FILE *) xdrs->x_private, (long) pos, 0) < 0) ? - FALSE : TRUE); + if (fread ((caddr_t) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1) + return FALSE; + *ip = ntohl (mycopy); + return TRUE; } -static int32_t *xdrstdio_inline(xdrs, len) -XDR *xdrs; -u_int len; +static bool_t +xdrstdio_putint32 (XDR *xdrs, const int32_t *ip) { + int32_t mycopy = htonl (*ip); - /* - * 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); + ip = &mycopy; + if (fwrite ((caddr_t) ip, 4, 1, (FILE *) xdrs->x_private) != 1) + return FALSE; + return TRUE; } |