summaryrefslogtreecommitdiff
path: root/libc/inet
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-06-17 21:12:16 +0000
committerEric Andersen <andersen@codepoet.org>2002-06-17 21:12:16 +0000
commitcdb3c81f36283df4b53f24a374d78c695e9d8b06 (patch)
tree9494bff7c98929e44c41dcdde32dc3fc6faf4330 /libc/inet
parent6ba832b158c91c6b35e1832220b3fc5ebf76333f (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')
-rw-r--r--libc/inet/rpc/Makefile24
-rw-r--r--libc/inet/rpc/auth_none.c145
-rw-r--r--libc/inet/rpc/auth_unix.c427
-rw-r--r--libc/inet/rpc/authunix_prot.c52
-rw-r--r--libc/inet/rpc/bindresvport.c77
-rw-r--r--libc/inet/rpc/clnt_generic.c194
-rw-r--r--libc/inet/rpc/clnt_perror.c555
-rw-r--r--libc/inet/rpc/clnt_raw.c338
-rw-r--r--libc/inet/rpc/clnt_simple.c191
-rw-r--r--libc/inet/rpc/clnt_tcp.c775
-rw-r--r--libc/inet/rpc/clnt_udp.c851
-rw-r--r--libc/inet/rpc/clnt_unix.c606
-rw-r--r--libc/inet/rpc/create_xid.c64
-rw-r--r--libc/inet/rpc/errqueue.h46
-rw-r--r--libc/inet/rpc/get_myaddress.c127
-rw-r--r--libc/inet/rpc/getrpcport.c60
-rw-r--r--libc/inet/rpc/pmap_clnt.c189
-rw-r--r--libc/inet/rpc/pmap_getmaps.c65
-rw-r--r--libc/inet/rpc/pmap_getport.c89
-rw-r--r--libc/inet/rpc/pmap_prot.c32
-rw-r--r--libc/inet/rpc/pmap_prot2.c102
-rw-r--r--libc/inet/rpc/pmap_rmt.c615
-rw-r--r--libc/inet/rpc/rpc_callmsg.c299
-rw-r--r--libc/inet/rpc/rpc_commondata.c30
-rw-r--r--libc/inet/rpc/rpc_dtablesize.c31
-rw-r--r--libc/inet/rpc/rpc_prot.c364
-rw-r--r--libc/inet/rpc/rpc_thread.c152
-rw-r--r--libc/inet/rpc/rtime.c149
-rw-r--r--libc/inet/rpc/svc.c730
-rw-r--r--libc/inet/rpc/svc_auth.c99
-rw-r--r--libc/inet/rpc/svc_auth_unix.c181
-rw-r--r--libc/inet/rpc/svc_raw.c203
-rw-r--r--libc/inet/rpc/svc_run.c93
-rw-r--r--libc/inet/rpc/svc_simple.c241
-rw-r--r--libc/inet/rpc/svc_tcp.c582
-rw-r--r--libc/inet/rpc/svc_udp.c782
-rw-r--r--libc/inet/rpc/svc_unix.c533
-rw-r--r--libc/inet/rpc/xdr.c880
-rw-r--r--libc/inet/rpc/xdr_array.c183
-rw-r--r--libc/inet/rpc/xdr_float.c240
-rw-r--r--libc/inet/rpc/xdr_intXX_t.c203
-rw-r--r--libc/inet/rpc/xdr_mem.c272
-rw-r--r--libc/inet/rpc/xdr_rec.c947
-rw-r--r--libc/inet/rpc/xdr_reference.c129
-rw-r--r--libc/inet/rpc/xdr_stdio.c210
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, &regs->pm_prog) &&
- xdr_u_long(xdrs, &regs->pm_vers) &&
- xdr_u_long(xdrs, &regs->pm_prot))
- return (xdr_u_long(xdrs, &regs->pm_port));
- return (FALSE);
+ if (xdr_u_long (xdrs, &regs->pm_prog) &&
+ xdr_u_long (xdrs, &regs->pm_vers) &&
+ xdr_u_long (xdrs, &regs->pm_prot))
+ return xdr_u_long (xdrs, &regs->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;
}