OSDN Git Service

Re-backport all the rpc stuff from glibc 2.2.5. This allows us to make this
authorEric Andersen <andersen@codepoet.org>
Mon, 17 Jun 2002 21:12:16 +0000 (21:12 -0000)
committerEric Andersen <andersen@codepoet.org>
Mon, 17 Jun 2002 21:12:16 +0000 (21:12 -0000)
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

45 files changed:
libc/inet/rpc/Makefile
libc/inet/rpc/auth_none.c
libc/inet/rpc/auth_unix.c
libc/inet/rpc/authunix_prot.c
libc/inet/rpc/bindresvport.c
libc/inet/rpc/clnt_generic.c
libc/inet/rpc/clnt_perror.c
libc/inet/rpc/clnt_raw.c
libc/inet/rpc/clnt_simple.c
libc/inet/rpc/clnt_tcp.c
libc/inet/rpc/clnt_udp.c
libc/inet/rpc/clnt_unix.c [new file with mode: 0644]
libc/inet/rpc/create_xid.c [new file with mode: 0644]
libc/inet/rpc/errqueue.h [new file with mode: 0644]
libc/inet/rpc/get_myaddress.c
libc/inet/rpc/getrpcport.c
libc/inet/rpc/pmap_clnt.c
libc/inet/rpc/pmap_getmaps.c
libc/inet/rpc/pmap_getport.c
libc/inet/rpc/pmap_prot.c
libc/inet/rpc/pmap_prot2.c
libc/inet/rpc/pmap_rmt.c
libc/inet/rpc/rpc_callmsg.c
libc/inet/rpc/rpc_commondata.c
libc/inet/rpc/rpc_dtablesize.c
libc/inet/rpc/rpc_prot.c
libc/inet/rpc/rpc_thread.c [new file with mode: 0644]
libc/inet/rpc/rtime.c [new file with mode: 0644]
libc/inet/rpc/svc.c
libc/inet/rpc/svc_auth.c
libc/inet/rpc/svc_auth_unix.c
libc/inet/rpc/svc_raw.c
libc/inet/rpc/svc_run.c
libc/inet/rpc/svc_simple.c
libc/inet/rpc/svc_tcp.c
libc/inet/rpc/svc_udp.c
libc/inet/rpc/svc_unix.c [new file with mode: 0644]
libc/inet/rpc/xdr.c
libc/inet/rpc/xdr_array.c
libc/inet/rpc/xdr_float.c
libc/inet/rpc/xdr_intXX_t.c [new file with mode: 0644]
libc/inet/rpc/xdr_mem.c
libc/inet/rpc/xdr_rec.c
libc/inet/rpc/xdr_reference.c
libc/inet/rpc/xdr_stdio.c

index c27965a..3728c22 100644 (file)
 
 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)
 
index 08cc194..0983b95 100644 (file)
@@ -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
  * 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)
 {
 }
index 0037630..3e14ba2 100644 (file)
@@ -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.
  * 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;
 }
index e3ad646..b033c56 100644 (file)
@@ -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>
 
 /*
  * 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;
 }
index 7523602..7dcebe7 100644 (file)
@@ -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;
 }
index 5b4b599..79df331 100644 (file)
@@ -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.
  * 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>
 
 /*
  * 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;
 }
index a4d1737..3d5e6b2 100644 (file)
@@ -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
  * 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);
 }
index b10db18..0d42452 100644 (file)
@@ -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.
  * 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
  *
  * 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)
 {
 }
index 3ec4aed..fe65d4e 100644 (file)
  * 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_ */
index 790ec07..5ff8434 100644 (file)
@@ -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.
  * 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;
 }
index e11f9b8..5a5fbbc 100644 (file)
@@ -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.
  * 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 (file)
index 0000000..81d8c46
--- /dev/null
@@ -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 (file)
index 0000000..c184e81
--- /dev/null
@@ -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 (file)
index 0000000..9ed6dc6
--- /dev/null
@@ -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 */
index 1b80207..86277d2 100644 (file)
@@ -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
  */
 
 #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
index 295c237..d3c4bb4 100644 (file)
@@ -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
  * 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);
 }
index ccd9123..2382c15 100644 (file)
@@ -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
  * 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;
 }
index 7ebe472..2812b3a 100644 (file)
@@ -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
 #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;
 }
index f1e771c..b86472c 100644 (file)
@@ -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
 #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;
 }
index 637da48..9829718 100644 (file)
@@ -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
 #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;
 }
index 3512b7d..6cb7c5e 100644 (file)
@@ -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
 #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
  * 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);
+    }
 }
index 13b557d..0fee124 100644 (file)
@@ -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
 
 #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;
 }
index c6afbdc..d509523 100644 (file)
@@ -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
  *
  */
 
-#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;
 }
index b936017..6b22b3f 100644 (file)
@@ -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;
index fdf6c1b..6a46aaf 100644 (file)
@@ -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;
 }
index 1904bb0..bace2a7 100644 (file)
@@ -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>
  * 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 (file)
index 0000000..267149b
--- /dev/null
@@ -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 (file)
index 0000000..6830781
--- /dev/null
@@ -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;
+}
index 89f10a6..92084bc 100644 (file)
@@ -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.
  *
  * 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_ */
index bb70613..1ec8626 100644 (file)
@@ -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.
  * 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;
 }
index 3d1de4e..84c563c 100644 (file)
@@ -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
  * 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;
 }
index 17d620e..e4752a6 100644 (file)
  * 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)
 {
 }
index cae787b..3ef9fbd 100644 (file)
@@ -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);
        }
+    }
 }
index 7352787..0b77304 100644 (file)
  * 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);
 }
index 9adc115..a298279 100644 (file)
  * 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;
 }
index 0004ace..98f9359 100644 (file)
@@ -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,
  * 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 (file)
index 0000000..8e052d8
--- /dev/null
@@ -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;
+}
index cad61c5..a54b117 100644 (file)
@@ -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.
  * 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"
  */
 /*
  * 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;
 }
index 359fda6..11e2a9d 100644 (file)
@@ -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.
  *
  * 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)
 
 
  * 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;
 }
index 623682e..5b3802b 100644 (file)
@@ -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.
  *
  * xdr.
  */
 
+#define __FORCE_GLIBC
+#define _GNU_SOURCE
+#include <features.h>
+
 #include <stdio.h>
+#include <endian.h>
 
 #include <rpc/types.h>
 #include <rpc/xdr.h>
  * 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 (file)
index 0000000..d36d162
--- /dev/null
@@ -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;
+    }
+}
index aa53496..e80de7b 100644 (file)
@@ -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.
  *
  */
 
+#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;
 }
index 3e4a1b5..9c21f57 100644 (file)
@@ -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"
  * 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);
 }
index 94b8a4b..708531b 100644 (file)
@@ -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.
  *
  * "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)
 
 /*
  * 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);
 }
index 5b420d6..411cf17 100644 (file)
@@ -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.
 #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;
 }