Initial import
authorFelix Fietkau <nbd@openwrt.org>
Sun, 13 Feb 2011 01:11:25 +0000 (02:11 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 13 Feb 2011 01:11:25 +0000 (02:11 +0100)
70 files changed:
CMakeLists.txt [new file with mode: 0644]
auth_none.c [new file with mode: 0644]
auth_unix.c [new file with mode: 0644]
authunix_prot.c [new file with mode: 0644]
bindresvport.c [new file with mode: 0644]
clnt_generic.c [new file with mode: 0644]
clnt_perror.c [new file with mode: 0644]
clnt_raw.c [new file with mode: 0644]
clnt_simple.c [new file with mode: 0644]
clnt_tcp.c [new file with mode: 0644]
clnt_udp.c [new file with mode: 0644]
clnt_unix.c [new file with mode: 0644]
compat.h [new file with mode: 0644]
create_xid.c [new file with mode: 0644]
errqueue.h [new file with mode: 0644]
get_myaddress.c [new file with mode: 0644]
getrpcent.c [new file with mode: 0644]
getrpcport.c [new file with mode: 0644]
libintl.h [new file with mode: 0644]
pm_getmaps.c [new file with mode: 0644]
pm_getport.c [new file with mode: 0644]
pmap_clnt.c [new file with mode: 0644]
pmap_prot.c [new file with mode: 0644]
pmap_prot2.c [new file with mode: 0644]
pmap_rmt.c [new file with mode: 0644]
rcmd.c [new file with mode: 0644]
rexec.c [new file with mode: 0644]
rpc/auth.h [new file with mode: 0644]
rpc/auth_des.h [new file with mode: 0644]
rpc/auth_unix.h [new file with mode: 0644]
rpc/clnt.h [new file with mode: 0644]
rpc/des_crypt.h [new file with mode: 0644]
rpc/key_prot.h [new file with mode: 0644]
rpc/netdb.h [new file with mode: 0644]
rpc/pmap_clnt.h [new file with mode: 0644]
rpc/pmap_prot.h [new file with mode: 0644]
rpc/pmap_rmt.h [new file with mode: 0644]
rpc/rpc.h [new file with mode: 0644]
rpc/rpc_des.h [new file with mode: 0644]
rpc/rpc_msg.h [new file with mode: 0644]
rpc/svc.h [new file with mode: 0644]
rpc/svc_auth.h [new file with mode: 0644]
rpc/types.h [new file with mode: 0644]
rpc/xdr.h [new file with mode: 0644]
rpc_cmsg.c [new file with mode: 0644]
rpc_commondata.c [new file with mode: 0644]
rpc_dtablesize.c [new file with mode: 0644]
rpc_private.h [new file with mode: 0644]
rpc_prot.c [new file with mode: 0644]
rpc_thread.c [new file with mode: 0644]
rtime.c [new file with mode: 0644]
ruserpass.c [new file with mode: 0644]
sa_len.c [new file with mode: 0644]
svc.c [new file with mode: 0644]
svc_auth.c [new file with mode: 0644]
svc_authux.c [new file with mode: 0644]
svc_raw.c [new file with mode: 0644]
svc_run.c [new file with mode: 0644]
svc_simple.c [new file with mode: 0644]
svc_tcp.c [new file with mode: 0644]
svc_udp.c [new file with mode: 0644]
svc_unix.c [new file with mode: 0644]
xdr.c [new file with mode: 0644]
xdr_array.c [new file with mode: 0644]
xdr_float.c [new file with mode: 0644]
xdr_intXX_t.c [new file with mode: 0644]
xdr_mem.c [new file with mode: 0644]
xdr_rec.c [new file with mode: 0644]
xdr_reference.c [new file with mode: 0644]
xdr_stdio.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e82217e
--- /dev/null
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 2.6)
+
+PROJECT(rpc C)
+ADD_DEFINITIONS(-Os -Wall --std=gnu99 -g3 -I. -include compat.h)
+
+FILE(GLOB SOURCES *.c)
+
+ADD_LIBRARY(rpc SHARED ${SOURCES})
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+
+FILE(GLOB headers rpc/*.h)
+INSTALL(FILES ${headers}
+       DESTINATION include/rpc
+)
+INSTALL(TARGETS rpc
+       LIBRARY DESTINATION lib
+)
diff --git a/auth_none.c b/auth_none.c
new file mode 100644 (file)
index 0000000..c48bbfe
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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) 1984, Sun Microsystems, Inc.
+ */
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null"
+ * credentials and verifiers to remote systems.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include "rpc_private.h"
+
+
+#define MAX_MARSHAL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+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 const struct auth_ops ops = {
+  authnone_verf,
+  authnone_marshal,
+  authnone_validate,
+  authnone_refresh,
+  authnone_destroy
+};
+
+/* Internal data and routines */
+
+struct authnone_private_s {
+  AUTH no_client;
+  char marshalled_client[MAX_MARSHAL_SIZE];
+  u_int mcnt;
+};
+#ifdef __UCLIBC_HAS_THREADS__
+#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 (void)
+{
+  struct authnone_private_s *ap;
+  XDR xdr_stream;
+  XDR *xdrs;
+
+  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 = (struct auth_ops *)&ops;
+      xdrs = &xdr_stream;
+      xdrmem_create (xdrs, ap->marshalled_client, (u_int) MAX_MARSHAL_SIZE,
+                    XDR_ENCODE);
+      (void) xdr_opaque_auth (xdrs, &ap->no_client.ah_cred);
+      (void) xdr_opaque_auth (xdrs, &ap->no_client.ah_verf);
+      ap->mcnt = XDR_GETPOS (xdrs);
+      XDR_DESTROY (xdrs);
+    }
+  return (&ap->no_client);
+}
+libc_hidden_def(authnone_create)
+
+static bool_t
+authnone_marshal (AUTH *client attribute_unused, XDR *xdrs)
+{
+  struct authnone_private_s *ap;
+
+  ap = authnone_private;
+  if (ap == NULL)
+    return FALSE;
+  return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt);
+}
+
+static void
+authnone_verf (AUTH *auth attribute_unused)
+{
+}
+
+static bool_t
+authnone_validate (AUTH *auth attribute_unused, struct opaque_auth *oa attribute_unused)
+{
+  return TRUE;
+}
+
+static bool_t
+authnone_refresh (AUTH *auth attribute_unused)
+{
+  return FALSE;
+}
+
+static void
+authnone_destroy (AUTH *auth attribute_unused)
+{
+}
diff --git a/auth_unix.c b/auth_unix.c
new file mode 100644 (file)
index 0000000..1337214
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * 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) 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 <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 (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
+};
+
+/*
+ * This struct is pointed to by the ah_private field of an auth_handle.
+ */
+struct audata {
+  struct opaque_auth au_origcred;      /* original credentials */
+  struct opaque_auth au_shcred;        /* short hand cred */
+  u_long au_shfaults;          /* short hand cache faults */
+  char au_marshed[MAX_AUTH_BYTES];
+  u_int au_mpos;               /* xdr pos at end of marshed */
+};
+#define        AUTH_PRIVATE(auth)      ((struct audata *)auth->ah_private)
+
+static bool_t marshal_new_auth (AUTH *) internal_function;
+
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+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;
+  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
+       (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;
+}
+libc_hidden_def(authunix_create)
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default (void)
+{
+  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 = NULL;
+  AUTH *ret_auth;
+
+  if (max_nr_groups) {
+    gids = (gid_t*)malloc(sizeof(*gids) * max_nr_groups);
+    if (gids == NULL)
+      abort ();
+  }
+
+  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.  */
+  ret_auth = authunix_create (machname, uid, gid, MIN (NGRPS, len), gids);
+  free (gids);
+  return ret_auth;
+}
+libc_hidden_def(authunix_create_default)
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf (AUTH *auth attribute_unused)
+{
+  /* no action necessary */
+}
+
+static bool_t
+authunix_marshal (AUTH *auth, XDR *xdrs)
+{
+  struct audata *au = AUTH_PRIVATE (auth);
+
+  return XDR_PUTBYTES (xdrs, au->au_marshed, au->au_mpos);
+}
+
+static bool_t
+authunix_validate (AUTH *auth, struct opaque_auth *verf)
+{
+  struct audata *au;
+  XDR xdrs;
+
+  if (verf->oa_flavor == AUTH_SHORT)
+    {
+      au = AUTH_PRIVATE (auth);
+      xdrmem_create (&xdrs, verf->oa_base, verf->oa_length,
+                    XDR_DECODE);
+
+      if (au->au_shcred.oa_base != NULL)
+       {
+         mem_free (au->au_shcred.oa_base,
+                   au->au_shcred.oa_length);
+         au->au_shcred.oa_base = NULL;
+       }
+      if (xdr_opaque_auth (&xdrs, &au->au_shcred))
+       {
+         auth->ah_cred = au->au_shcred;
+       }
+      else
+       {
+         xdrs.x_op = XDR_FREE;
+         (void) xdr_opaque_auth (&xdrs, &au->au_shcred);
+         au->au_shcred.oa_base = NULL;
+         auth->ah_cred = au->au_origcred;
+       }
+      marshal_new_auth (auth);
+    }
+  return TRUE;
+}
+
+static bool_t
+authunix_refresh (AUTH *auth)
+{
+  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 *auth)
+{
+  struct audata *au = AUTH_PRIVATE (auth);
+
+  mem_free (au->au_origcred.oa_base, au->au_origcred.oa_length);
+
+  if (au->au_shcred.oa_base != NULL)
+    mem_free (au->au_shcred.oa_base, au->au_shcred.oa_length);
+
+  mem_free (auth->ah_private, sizeof (struct audata));
+
+  if (auth->ah_verf.oa_base != NULL)
+    mem_free (auth->ah_verf.oa_base, auth->ah_verf.oa_length);
+
+  mem_free ((caddr_t) auth, sizeof (*auth));
+}
+
+/*
+ * Marshals (pre-serializes) an auth struct.
+ * sets private data, au_marshed and au_mpos
+ */
+static bool_t
+internal_function
+marshal_new_auth (AUTH *auth)
+{
+  XDR xdr_stream;
+  XDR *xdrs = &xdr_stream;
+  struct audata *au = AUTH_PRIVATE (auth);
+
+  xdrmem_create (xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
+  if ((!xdr_opaque_auth (xdrs, &(auth->ah_cred))) ||
+      (!xdr_opaque_auth (xdrs, &(auth->ah_verf))))
+    perror (_("auth_none.c - Fatal marshalling problem"));
+  else
+    au->au_mpos = XDR_GETPOS (xdrs);
+
+  XDR_DESTROY (xdrs);
+
+  return TRUE;
+}
diff --git a/authunix_prot.c b/authunix_prot.c
new file mode 100644 (file)
index 0000000..2729900
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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) 1984, Sun Microsystems, Inc.
+ */
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+
+/*
+ * XDR for unix authentication parameters.
+ * Unfortunately, none of these can be declared const.
+ */
+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)
+      && (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;
+}
+libc_hidden_def(xdr_authunix_parms)
diff --git a/bindresvport.c b/bindresvport.c
new file mode 100644 (file)
index 0000000..fc077af
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport (int sd, struct sockaddr_in *sin)
+{
+  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;
+      memset (sin, 0, 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, sizeof(struct sockaddr_in));
+    }
+
+  return res;
+}
+libc_hidden_def(bindresvport)
diff --git a/clnt_generic.c b/clnt_generic.c
new file mode 100644 (file)
index 0000000..8aeae1e
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Copyright (C) 1987, 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 <netdb.h>
+
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *
+clnt_create (const char *hostname, u_long prog, u_long vers,
+            const char *proto)
+{
+  struct hostent hostbuf, *h;
+  size_t hstbuflen;
+  char *hsttmpbuf;
+  struct protoent protobuf, *p;
+  size_t prtbuflen;
+  char *prttmpbuf;
+  struct sockaddr_in sin;
+  struct sockaddr_un sun;
+  int sock;
+  struct timeval tv;
+  CLIENT *client;
+  int herr;
+
+  if (strcmp (proto, "unix") == 0)
+    {
+      memset ((char *)&sun, 0, 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
+      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;
+  memset (sin.sin_zero, 0, sizeof (sin.sin_zero));
+  memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length);
+
+  prtbuflen = 1024;
+  prttmpbuf = alloca (prtbuflen);
+  while (getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p) != 0
+        || p == NULL)
+       if (errno != ERANGE)
+      {
+       struct rpc_createerr *ce = &get_rpc_createerr ();
+       ce->cf_stat = RPC_UNKNOWNPROTO;
+       ce->cf_error.re_errno = EPFNOSUPPORT;
+       return NULL;
+      }
+    else
+      {
+       /* Enlarge the buffer.  */
+       prtbuflen *= 2;
+       prttmpbuf = alloca (prtbuflen);
+      }
+
+  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;
+       }
+#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;
+       }
+#if 0
+      /* This is not wanted.  This would disable the user from having
+        a timeout in the clnt_call() call.  Only a call to cnlt_control()
+        by the user should set the timeout value.  */
+      tv.tv_sec = 25;
+      tv.tv_usec = 0;
+      clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
+#endif
+      break;
+    default:
+      {
+       struct rpc_createerr *ce = &get_rpc_createerr ();
+       ce->cf_stat = RPC_SYSTEMERROR;
+       ce->cf_error.re_errno = EPFNOSUPPORT;
+      }
+      return (NULL);
+    }
+  return client;
+}
diff --git a/clnt_perror.c b/clnt_perror.c
new file mode 100644 (file)
index 0000000..8dbae72
--- /dev/null
@@ -0,0 +1,435 @@
+/* @(#)clnt_perror.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+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_private.h"
+
+#ifdef USE_IN_LIBIO
+# include <wchar.h>
+# include <libio/iolibio.h>
+# define fputs(s, f) _IO_fputs (s, f)
+#endif
+
+static char *auth_errmsg (enum auth_stat stat) internal_function;
+
+#ifdef __UCLIBC_HAS_THREADS__
+/*
+ * 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 (void)
+{
+  if (buf == NULL)
+    buf = (char *) malloc (256);
+  return buf;
+}
+
+struct rpc_errtab
+{
+  enum clnt_stat status;
+  unsigned int message_off;
+};
+
+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)")
+};
+
+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 (enum clnt_stat stat)
+{
+  size_t i;
+
+  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);
+       }
+    }
+  return _("RPC: (unknown error code)");
+}
+libc_hidden_def(clnt_sperrno)
+
+void
+clnt_perrno (enum clnt_stat 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);
+}
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror (CLIENT * rpch, const char *msg)
+{
+  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:
+      __glibc_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;
+       }
+      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);
+}
+libc_hidden_def(clnt_sperror)
+
+void
+clnt_perror (CLIENT * rpch, const char *msg)
+{
+#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);
+}
+libc_hidden_def(clnt_perror)
+
+char *
+clnt_spcreateerror (const char *msg)
+{
+  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);
+
+      __glibc_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;
+}
+libc_hidden_def(clnt_spcreateerror)
+
+void
+clnt_pcreateerror (const char *msg)
+{
+#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;
+  unsigned int message_off;
+};
+
+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 *
+internal_function
+auth_errmsg (enum auth_stat stat)
+{
+  size_t i;
+
+  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;
+}
+
+
+static void __attribute_used__
+free_mem (void)
+{
+  free (buf);
+}
diff --git a/clnt_raw.c b/clnt_raw.c
new file mode 100644 (file)
index 0000000..75dd982
--- /dev/null
@@ -0,0 +1,248 @@
+/* @(#)clnt_raw.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us simulate rpc and get round trip overhead, without
+ * any interference from the kernel.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include "rpc_private.h"
+#include <rpc/svc.h>
+#include <rpc/xdr.h>
+
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+struct clntraw_private_s
+  {
+    CLIENT client_object;
+    XDR xdr_stream;
+    char _raw_buf[UDPMSGSIZE];
+    char mashl_callmsg[MCALL_MSG_SIZE];
+    u_int mcnt;
+  };
+#ifdef __UCLIBC_HAS_THREADS__
+#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 const struct clnt_ops client_ops =
+{
+  clntraw_call,
+  clntraw_abort,
+  clntraw_geterr,
+  clntraw_freeres,
+  clntraw_destroy,
+  clntraw_control
+};
+
+/*
+ * Create a client handle for memory based rpc.
+ */
+CLIENT *
+clntraw_create (u_long prog, u_long vers)
+{
+  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 (CLIENT *h, u_long proc, xdrproc_t xargs, caddr_t argsp,
+                         xdrproc_t xresults, caddr_t resultsp,
+                         struct timeval timeout attribute_unused)
+{
+  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;
+       }
+      if (msg.acpted_rply.ar_verf.oa_base != NULL)
+       {
+         xdrs->x_op = XDR_FREE;
+         (void) xdr_opaque_auth (xdrs, &(msg.acpted_rply.ar_verf));
+       }
+    }
+
+  return status;
+}
+
+static void
+clntraw_geterr (CLIENT *cl attribute_unused, struct rpc_err *err attribute_unused)
+{
+}
+
+
+static bool_t
+clntraw_freeres (CLIENT *cl attribute_unused, xdrproc_t xdr_res, caddr_t 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 (void)
+{
+}
+
+static bool_t
+clntraw_control (CLIENT *cl attribute_unused, int i attribute_unused, char *c attribute_unused)
+{
+  return FALSE;
+}
+
+static void
+clntraw_destroy (CLIENT *cl attribute_unused)
+{
+}
diff --git a/clnt_simple.c b/clnt_simple.c
new file mode 100644 (file)
index 0000000..f66228a
--- /dev/null
@@ -0,0 +1,164 @@
+/* @(#)clnt_simple.c   2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+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_private.h"
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+
+
+struct callrpc_private_s
+  {
+    CLIENT *client;
+    int socket;
+    u_long oldprognum, oldversnum, valid;
+    char *oldhost;
+  };
+#ifdef __UCLIBC_HAS_THREADS__
+#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, u_long prognum, u_long versnum, u_long procnum,
+        xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
+{
+  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_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->client)
+       {
+         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 __UCLIBC_HAS_THREADS__
+void attribute_hidden __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);
+       }
+}
+#endif /* __UCLIBC_HAS_THREADS__ */
diff --git a/clnt_tcp.c b/clnt_tcp.c
new file mode 100644 (file)
index 0000000..d01fc80
--- /dev/null
@@ -0,0 +1,531 @@
+/* @(#)clnt_tcp.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer.  The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message.  Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#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 <rpc/pmap_clnt.h>
+#ifdef USE_IN_LIBIO
+# include <wchar.h>
+#endif
+
+extern u_long _create_xid (void) attribute_hidden;
+
+#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;
+  };
+
+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 const struct clnt_ops tcp_ops =
+{
+  clnttcp_call,
+  clnttcp_abort,
+  clnttcp_geterr,
+  clnttcp_freeres,
+  clnttcp_destroy,
+  clnttcp_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 *
+clnttcp_create (struct sockaddr_in *raddr, u_long prog, u_long vers,
+               int *sockp, u_int sendsz, u_int recvsz)
+{
+  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);
+       }
+      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;
+       }
+      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);
+       }
+      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);
+}
+libc_hidden_def(clnttcp_create)
+
+static enum clnt_stat
+clnttcp_call (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 ((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;
+       }
+      else if (!(*xdr_results) (xdrs, results_ptr))
+       {
+         if (ct->ct_error.re_status == RPC_SUCCESS)
+           ct->ct_error.re_status = RPC_CANTDECODERES;
+       }
+      /* free verifier ... */
+      if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
+       {
+         xdrs->x_op = XDR_FREE;
+         (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf));
+       }
+    }                          /* end successful completion */
+  else
+    {
+      /* maybe our credentials need to be refreshed ... */
+      if (refreshes-- && AUTH_REFRESH (h->cl_auth))
+       goto call_again;
+    }                          /* end of unsuccessful completion */
+  return ct->ct_error.re_status;
+}
+
+static void
+clnttcp_geterr (CLIENT *h, struct rpc_err *errp)
+{
+  struct ct_data *ct =
+  (struct ct_data *) h->cl_private;
+
+  *errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres (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
+clnttcp_abort (void)
+{
+}
+
+static bool_t
+clnttcp_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;
+      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 (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));
+}
+
+/*
+ * Interface between xdr serializer and tcp connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readtcp (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 = 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 (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 = write (ct->ct_sock, buf, cnt)) == -1)
+       {
+         ct->ct_error.re_errno = errno;
+         ct->ct_error.re_status = RPC_CANTSEND;
+         return -1;
+       }
+    }
+  return len;
+}
diff --git a/clnt_udp.c b/clnt_udp.c
new file mode 100644 (file)
index 0000000..fe8b7f8
--- /dev/null
@@ -0,0 +1,608 @@
+/* @(#)clnt_udp.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+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 <net/if.h>
+#ifdef USE_IN_LIBIO
+# include <wchar.h>
+#endif
+
+#ifdef IP_RECVERR
+#include "errqueue.h"
+#include <sys/uio.h>
+#endif
+
+/* CMSG_NXTHDR is using it */
+
+
+extern u_long _create_xid (void) attribute_hidden;
+
+/*
+ * UDP bases client side rpc operations
+ */
+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 const struct clnt_ops udp_ops =
+{
+  clntudp_call,
+  clntudp_abort,
+  clntudp_geterr,
+  clntudp_freeres,
+  clntudp_destroy,
+  clntudp_control
+};
+
+/*
+ * Private data kept per client handle
+ */
+struct cu_data
+  {
+    int cu_sock;
+    bool_t cu_closeit;
+    struct sockaddr_in cu_raddr;
+    int cu_rlen;
+    struct timeval cu_wait;
+    struct timeval cu_total;
+    struct rpc_err cu_error;
+    XDR cu_outxdrs;
+    u_int cu_xdrpos;
+    u_int cu_sendsz;
+    char *cu_outbuf;
+    u_int cu_recvsz;
+    char cu_inbuf[1];
+  };
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ *     Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard; 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 (struct sockaddr_in *raddr, u_long program, u_long version,
+                  struct timeval wait, int *sockp, u_int sendsz,
+                  u_int recvsz)
+{
+  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;
+       }
+      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;
+       }
+      /* 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;
+}
+libc_hidden_def(clntudp_bufcreate)
+
+CLIENT *
+clntudp_create (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);
+}
+libc_hidden_def(clntudp_create)
+
+static int
+is_network_up (int sock)
+{
+  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;
+}
+
+static enum clnt_stat
+clntudp_call (
+     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);
+       }
+#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);
+               }
+       }
+#endif
+      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 < 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 (CLIENT *cl, struct rpc_err *errp)
+{
+  struct cu_data *cu = (struct cu_data *) cl->cl_private;
+
+  *errp = cu->cu_error;
+}
+
+
+static bool_t
+clntudp_freeres (CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr)
+{
+  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);
+}
+
+static void
+clntudp_abort (void)
+{
+}
+
+static bool_t
+clntudp_control (CLIENT *cl, int request, char *info)
+{
+  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 (CLIENT *cl)
+{
+  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/clnt_unix.c b/clnt_unix.c
new file mode 100644 (file)
index 0000000..c7756f7
--- /dev/null
@@ -0,0 +1,600 @@
+/*
+ * 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) attribute_hidden;
+
+#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 const 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;
+}
+libc_hidden_def(clntunix_create)
+
+static enum clnt_stat
+clntunix_call (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 (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 (void)
+{
+}
+
+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 -why??*/ 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/compat.h b/compat.h
new file mode 100644 (file)
index 0000000..c1c74d5
--- /dev/null
+++ b/compat.h
@@ -0,0 +1,29 @@
+#ifndef __UCLIBC_COMPAT_H
+#define __UCLIBC_COMPAT_H
+
+#define _XOPEN_SOURCE
+#define _GNU_SOURCE
+
+#include <features.h>
+
+#undef __UCLIBC_HAS_THREADS__
+#include <bits/uClibc_mutex.h>
+#include <sys/poll.h>
+
+#if 0
+#undef __UCLIBC_MUTEX_LOCK
+#undef __UCLIBC_MUTEX_UNLOCK
+#define __UCLIBC_MUTEX_LOCK(M) pthread_mutex_lock(&(M))
+#define __UCLIBC_MUTEX_UNLOCK(M) pthread_mutex_unlock(&(M))
+#endif
+
+#define smallint int
+
+#define _(...) __VA_ARGS__
+#define internal_function
+#define attribute_hidden
+#define attribute_unused
+#define attribute_noreturn
+#define libc_hidden_def(...)
+
+#endif
diff --git a/create_xid.c b/create_xid.c
new file mode 100644 (file)
index 0000000..3b4e8c0
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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. */
+
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+
+static smallint is_initialized;
+static struct drand48_data __rpc_lrand48_data;
+
+u_long _create_xid (void) attribute_hidden;
+u_long _create_xid (void)
+{
+  long res;
+
+  __UCLIBC_MUTEX_LOCK(mylock);
+
+  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);
+
+  __UCLIBC_MUTEX_UNLOCK(mylock);
+
+  return res;
+}
diff --git a/errqueue.h b/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 */
diff --git a/get_myaddress.c b/get_myaddress.c
new file mode 100644 (file)
index 0000000..ab4ac33
--- /dev/null
@@ -0,0 +1,109 @@
+/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl.  This avoids using the yellowpages.
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/clnt.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+/* Order of following two #includes reversed by roland@gnu */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+/*
+ * don't use gethostbyname, which would invoke yellow pages
+ *
+ * Avoid loopback interfaces.  We return information from a loopback
+ * interface only if there are no other possible interfaces.
+ */
+void
+get_myaddress (struct sockaddr_in *addr)
+{
+  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);
+    }
+
+ 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 == 1 && (ifreq.ifr_flags & IFF_LOOPBACK))))
+       {
+         *addr = *((struct sockaddr_in *) &ifr->ifr_addr);
+         addr->sin_port = htons (PMAPPORT);
+         close (s);
+         return;
+       }
+      ifr++;
+    }
+  if (loopback == 0)
+    {
+      loopback = 1;
+      goto again;
+    }
+  close (s);
+}
diff --git a/getrpcent.c b/getrpcent.c
new file mode 100644 (file)
index 0000000..de20d64
--- /dev/null
@@ -0,0 +1,347 @@
+/* @(#)getrpcent.c     2.2 88/07/29 4.0 RPCSRC */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+
+
+/*
+ * Internet version.
+ */
+static struct rpcdata {
+       FILE *rpcf;
+       char *current;
+       int currentlen;
+       int stayopen;
+#define        MAXALIASES      35
+       char *rpc_aliases[MAXALIASES];
+       struct rpcent rpc;
+       char line[BUFSIZ + 1];
+       char *domain;
+} *rpcdata;
+
+static const char RPCDB[] = "/etc/rpc";
+
+static struct rpcdata *_rpcdata(void)
+{
+       register struct rpcdata *d = rpcdata;
+
+       if (d == NULL) {
+               d = (struct rpcdata *) calloc(1, sizeof(struct rpcdata));
+
+               rpcdata = d;
+       }
+       return d;
+}
+
+void endrpcent(void)
+{
+       register struct rpcdata *d = _rpcdata();
+
+       if (d == NULL)
+               return;
+       if (d->stayopen)
+               return;
+       free(d->current);
+       d->current = NULL;
+       if (d->rpcf) {
+               fclose(d->rpcf);
+               d->rpcf = NULL;
+       }
+}
+libc_hidden_def(endrpcent)
+
+void setrpcent(int f)
+{
+       register struct rpcdata *d = _rpcdata();
+
+       if (d == NULL)
+               return;
+       if (d->rpcf == NULL)
+               d->rpcf = fopen(RPCDB, "r");
+       else
+               rewind(d->rpcf);
+       free(d->current);
+       d->current = NULL;
+       d->stayopen |= f;
+}
+libc_hidden_def(setrpcent)
+
+static struct rpcent *interpret(struct rpcdata *);
+
+static struct rpcent *__get_next_rpcent(struct rpcdata *d)
+{
+       if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
+               return NULL;
+       return interpret(d);
+}
+
+struct rpcent *getrpcent(void)
+{
+       register struct rpcdata *d = _rpcdata();
+
+       if (d == NULL)
+               return NULL;
+       if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
+               return NULL;
+       return __get_next_rpcent(d);
+}
+libc_hidden_def(getrpcent)
+
+struct rpcent *getrpcbynumber(register int number)
+{
+       register struct rpcdata *d = _rpcdata();
+       register struct rpcent *rpc;
+
+       if (d == NULL)
+               return NULL;
+       setrpcent(0);
+       while ((rpc = getrpcent())) {
+               if (rpc->r_number == number)
+                       break;
+       }
+       endrpcent();
+       return rpc;
+}
+libc_hidden_def(getrpcbynumber)
+
+struct rpcent *getrpcbyname(const char *name)
+{
+       struct rpcent *rpc;
+       char **rp;
+
+       setrpcent(0);
+       while ((rpc = getrpcent())) {
+               if (strcmp(rpc->r_name, name) == 0)
+                       return rpc;
+               for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+                       if (strcmp(*rp, name) == 0)
+                               return rpc;
+               }
+       }
+       endrpcent();
+       return NULL;
+}
+libc_hidden_def(getrpcbyname)
+
+#ifdef __linux__
+static char *firstwhite(char *s)
+{
+       char *s1, *s2;
+
+       s1 = strchr(s, ' ');
+       s2 = strchr(s, '\t');
+       if (s1) {
+               if (s2)
+                       return (s1 < s2) ? s1 : s2;
+               else
+                       return s1;
+       } else
+               return s2;
+}
+#endif
+
+static struct rpcent *interpret(register struct rpcdata *d)
+{
+       char *p;
+       register char *cp, **q;
+
+       p = d->line;
+       d->line[strlen(p)-1] = '\n';
+       if (*p == '#')
+               return __get_next_rpcent(d);
+       cp = strchr(p, '#');
+       if (cp == NULL) {
+               cp = strchr(p, '\n');
+               if (cp == NULL)
+                       return __get_next_rpcent(d);
+       }
+       *cp = '\0';
+#ifdef __linux__
+       if ((cp = firstwhite(p)))
+               *cp++ = 0;
+       else
+               return __get_next_rpcent(d);
+#else
+       cp = strchr(p, ' ');
+       if (cp == NULL) {
+               cp = strchr(p, '\t');
+               if (cp == NULL)
+                       return __get_next_rpcent(d);
+       }
+       *cp++ = '\0';
+#endif
+       /* THIS STUFF IS INTERNET SPECIFIC */
+       d->rpc.r_name = d->line;
+       while (*cp == ' ' || *cp == '\t')
+               cp++;
+       d->rpc.r_number = atoi(cp);
+       q = d->rpc.r_aliases = d->rpc_aliases;
+#ifdef __linux__
+       if ((cp = firstwhite(cp)))
+               *cp++ = '\0';
+#else
+       cp = strchr(p, ' ');
+       if (cp != NULL)
+               *cp++ = '\0';
+       else {
+               cp = strchr(p, '\t');
+               if (cp != NULL)
+                       *cp++ = '\0';
+       }
+#endif
+       while (cp && *cp) {
+               if (*cp == ' ' || *cp == '\t') {
+                       cp++;
+                       continue;
+               }
+               if (q < &(d->rpc_aliases[MAXALIASES - 1]))
+                       *q++ = cp;
+#ifdef __linux__
+               if ((cp = firstwhite(cp)))
+                       *cp++ = '\0';
+#else
+               cp = strchr(p, ' ');
+               if (cp != NULL)
+                       *cp++ = '\0';
+               else {
+                       cp = strchr(p, '\t');
+                       if (cp != NULL)
+                               *cp++ = '\0';
+               }
+#endif
+       }
+       *q = NULL;
+       return &d->rpc;
+}
+
+#if defined(__UCLIBC_HAS_REENTRANT_RPC__)
+
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+
+
+static int __copy_rpcent(struct rpcent *r, struct rpcent *result_buf, char *buffer,
+               size_t buflen, struct rpcent **result)
+{
+       size_t i, s;
+
+       *result = NULL;
+
+       if (!r)
+               return ENOENT;
+
+       /* copy the struct from the shared mem */
+       memset(result_buf, 0x00, sizeof(*result_buf));
+       memset(buffer, 0x00, buflen);
+
+       result_buf->r_number = r->r_number;
+
+       /* copy the aliases ... need to not only copy the alias strings,
+        * but the array of pointers to the alias strings */
+       i = 0;
+       while (r->r_aliases[i++]) ;
+
+       s = i-- * sizeof(char*);
+       if (buflen < s)
+               goto err_out;
+       result_buf->r_aliases = (char**)buffer;
+       buffer += s;
+       buflen -= s;
+
+       while (i-- > 0) {
+               s = strlen(r->r_aliases[i]) + 1;
+               if (buflen < s)
+                       goto err_out;
+               result_buf->r_aliases[i] = buffer;
+               buffer += s;
+               buflen -= s;
+               memcpy(result_buf->r_aliases[i], r->r_aliases[i], s);
+       }
+
+       /* copy the name */
+       i = strlen(r->r_name);
+       if (buflen <= i)
+               goto err_out;
+       result_buf->r_name = buffer;
+       memcpy(result_buf->r_name, r->r_name, i);
+
+       /* that was a hoot eh ? */
+       *result = result_buf;
+
+       return 0;
+err_out:
+       return ERANGE;
+}
+
+int getrpcbynumber_r(int number, struct rpcent *result_buf, char *buffer,
+               size_t buflen, struct rpcent **result)
+{
+       int ret;
+       __UCLIBC_MUTEX_LOCK(mylock);
+       ret = __copy_rpcent(getrpcbynumber(number), result_buf, buffer, buflen, result);
+       __UCLIBC_MUTEX_UNLOCK(mylock);
+       return ret;
+}
+
+int getrpcbyname_r(const char *name, struct rpcent *result_buf, char *buffer,
+               size_t buflen, struct rpcent **result)
+{
+       int ret;
+       __UCLIBC_MUTEX_LOCK(mylock);
+       ret = __copy_rpcent(getrpcbyname(name), result_buf, buffer, buflen, result);
+       __UCLIBC_MUTEX_UNLOCK(mylock);
+       return ret;
+}
+
+int getrpcent_r(struct rpcent *result_buf, char *buffer,
+               size_t buflen, struct rpcent **result)
+{
+       int ret;
+       __UCLIBC_MUTEX_LOCK(mylock);
+       ret = __copy_rpcent(getrpcent(), result_buf, buffer, buflen, result);
+       __UCLIBC_MUTEX_UNLOCK(mylock);
+       return ret;
+}
+
+#endif /* __UCLIBC_HAS_REENTRANT_RPC__ */
diff --git a/getrpcport.c b/getrpcport.c
new file mode 100644 (file)
index 0000000..9c4f443
--- /dev/null
@@ -0,0 +1,78 @@
+/* @(#)getrpcport.c    2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static  char sccsid[] = "@(#)getrpcport.c 1.3 87/08/11 SMI";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+
+#include <alloca.h>
+#include <errno.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/clnt.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+
+
+int
+getrpcport (const char *host, u_long prognum, u_long versnum, u_int proto)
+{
+  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);
+      }
+
+  memcpy ((char *) &addr.sin_addr, hp->h_addr, hp->h_length);
+  addr.sin_family = AF_INET;
+  addr.sin_port = 0;
+  return pmap_getport (&addr, prognum, versnum, proto);
+}
diff --git a/libintl.h b/libintl.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pm_getmaps.c b/pm_getmaps.c
new file mode 100644 (file)
index 0000000..e7b97e6
--- /dev/null
@@ -0,0 +1,84 @@
+/* @(#)pmap_getmaps.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <netdb.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps (struct sockaddr_in *address)
+{
+  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);
+
+  /* Don't need a reserved port to get ports from the portmapper.  */
+  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);
+    }
+  /* (void)__close(_socket); CLNT_DESTROY already closed it */
+  address->sin_port = 0;
+  return head;
+}
diff --git a/pm_getport.c b/pm_getport.c
new file mode 100644 (file)
index 0000000..8a42761
--- /dev/null
@@ -0,0 +1,94 @@
+/* @(#)pmap_getport.c  2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+
+
+static const struct timeval timeout =
+{5, 0};
+static const struct timeval tottimeout =
+{60, 0};
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+pmap_getport (struct sockaddr_in *address, u_long program, u_long version,
+                         u_int protocol)
+{
+  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)
+    {
+      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;
+       }
+      CLNT_DESTROY (client);
+    }
+  /* (void)__close(_socket); CLNT_DESTROY already closed it */
+  address->sin_port = 0;
+  return port;
+}
+libc_hidden_def(pmap_getport)
diff --git a/pmap_clnt.c b/pmap_clnt.c
new file mode 100644 (file)
index 0000000..c35a2e9
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * 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) 1984, Sun Microsystems, Inc.
+ */
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ */
+
+#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>
+
+
+/*
+ * 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;
+}
+
+
+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 (u_long program, u_long version, int protocol, u_short port)
+{
+  struct sockaddr_in myaddress;
+  int _socket = -1;
+  CLIENT *client;
+  struct pmap parms;
+  bool_t 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"));
+      rslt = FALSE;
+    }
+  CLNT_DESTROY (client);
+  /* (void)close(_socket); CLNT_DESTROY closes it */
+  return rslt;
+}
+libc_hidden_def (pmap_set)
+
+/*
+ * Remove the mapping between program,version and port.
+ * Calls the pmap service remotely to do the un-mapping.
+ */
+bool_t
+pmap_unset (u_long program, u_long version)
+{
+  struct sockaddr_in myaddress;
+  int _socket = -1;
+  CLIENT *client;
+  struct pmap parms;
+  bool_t 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;
+}
+libc_hidden_def (pmap_unset)
diff --git a/pmap_prot.c b/pmap_prot.c
new file mode 100644 (file)
index 0000000..342dbad
--- /dev/null
@@ -0,0 +1,56 @@
+/* @(#)pmap_prot.c     2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+bool_t
+xdr_pmap (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;
+}
+libc_hidden_def(xdr_pmap)
diff --git a/pmap_prot2.c b/pmap_prot2.c
new file mode 100644 (file)
index 0000000..f383757
--- /dev/null
@@ -0,0 +1,117 @@
+/* @(#)pmap_prot2.c    2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+/*
+ * What is going on with linked lists? (!)
+ * First recall the link list declaration from pmap_prot.h:
+ *
+ * struct pmaplist {
+ *      struct pmap pml_map;
+ *      struct pmaplist *pml_map;
+ * };
+ *
+ * Compare that declaration with a corresponding xdr declaration that
+ * is (a) pointer-less, and (b) recursive:
+ *
+ * typedef union switch (bool_t) {
+ *
+ *      case TRUE: struct {
+ *              struct pmap;
+ *              pmaplist_t foo;
+ *      };
+ *
+ *      case FALSE: struct {};
+ * } pmaplist_t;
+ *
+ * Notice that the xdr declaration has no nxt pointer while
+ * the C declaration has no bool_t variable.  The bool_t can be
+ * interpreted as ``more data follows me''; if FALSE then nothing
+ * follows this bool_t; if TRUE then the bool_t is followed by
+ * an actual struct pmap, and then (recursively) by the
+ * xdr union, pamplist_t.
+ *
+ * This could be implemented via the xdr_union primitive, though this
+ * would cause a one recursive call per element in the list.  Rather than do
+ * that we can ``unwind'' the recursion
+ * into a while loop and do the union arms in-place.
+ *
+ * The head of the list is what the C programmer wishes to past around
+ * the net, yet is the data that the pointer points to which is interesting;
+ * this sounds like a job for xdr_reference!
+ */
+bool_t
+xdr_pmaplist (XDR *xdrs, struct pmaplist **rp)
+{
+  /*
+   * more_elements is pre-computed in case the direction is
+   * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
+   * xdr_bool when the direction is XDR_DECODE.
+   */
+  bool_t more_elements;
+  int freeing = (xdrs->x_op == XDR_FREE);
+  struct pmaplist **next = NULL;
+
+  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);
+    }
+}
+libc_hidden_def(xdr_pmaplist)
diff --git a/pmap_rmt.c b/pmap_rmt.c
new file mode 100644 (file)
index 0000000..f9dd6e7
--- /dev/null
@@ -0,0 +1,412 @@
+/* @(#)pmap_rmt.c      2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+
+#include <unistd.h>
+#include <string.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>
+#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 u_long _create_xid (void) attribute_hidden;
+
+static const struct timeval timeout = {3, 0};
+
+/*
+ * pmapper remote-call-service interface.
+ * This routine is used to call the pmapper remote call service
+ * which will look up a service program in the port maps, and then
+ * remotely call that routine with the given parameters.  This allows
+ * programs to do a lookup and call in one step.
+ */
+enum clnt_stat
+pmap_rmtcall (struct sockaddr_in *addr, u_long prog, u_long vers, u_long proc,
+                         xdrproc_t xdrargs, caddr_t argsp, xdrproc_t xdrres, caddr_t resp,
+                         struct timeval tout, u_long *port_ptr)
+{
+  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); CLNT_DESTROY already closed it */
+  addr->sin_port = 0;
+  return stat;
+}
+
+
+/*
+ * XDR remote call arguments
+ * written for XDR_ENCODE direction only
+ */
+bool_t
+xdr_rmtcall_args (XDR *xdrs, struct rmtcallargs *cap)
+{
+  u_int lenposition, argposition, position;
+
+  if (xdr_u_long (xdrs, &(cap->prog)) &&
+      xdr_u_long (xdrs, &(cap->vers)) &&
+      xdr_u_long (xdrs, &(cap->proc)))
+    {
+      u_long dummy_arglen = 0;
+      lenposition = XDR_GETPOS (xdrs);
+      if (!xdr_u_long (xdrs, &dummy_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;
+}
+libc_hidden_def(xdr_rmtcall_args)
+
+/*
+ * XDR remote call results
+ * written for XDR_DECODE direction only
+ */
+bool_t
+xdr_rmtcallres (XDR *xdrs, struct rmtcallres *crp)
+{
+  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;
+}
+libc_hidden_def(xdr_rmtcallres)
+
+
+/*
+ * The following is kludged-up support for simple rpc broadcasts.
+ * Someday a large, complicated system will replace these trivial
+ * routines which only support udp/ip .
+ */
+
+static int
+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... */
+{
+  struct ifconf ifc;
+  struct ifreq ifreq, *ifr;
+  struct sockaddr_in *sin;
+  int n, i;
+
+  ifc.ifc_len = UDPMSGSIZE;
+  ifc.ifc_buf = buf;
+  if (ioctl (sock, SIOCGIFCONF, (char *) &ifc) < 0)
+    {
+      perror (_("broadcast: ioctl (get interface configuration)"));
+      return (0);
+    }
+  ifr = ifc.ifc_req;
+  for (i = 0, n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++)
+    {
+      ifreq = *ifr;
+      if (ioctl (sock, SIOCGIFFLAGS, (char *) &ifreq) < 0)
+       {
+         perror (_("broadcast: ioctl (get interface flags)"));
+         continue;
+       }
+      if ((ifreq.ifr_flags & IFF_BROADCAST) &&
+         (ifreq.ifr_flags & IFF_UP) &&
+         ifr->ifr_addr.sa_family == AF_INET)
+       {
+         sin = (struct sockaddr_in *) &ifr->ifr_addr;
+#ifdef SIOCGIFBRDADDR          /* 4.3BSD */
+         if (ioctl (sock, SIOCGIFBRDADDR, (char *) &ifreq) < 0)
+           {
+             addrs[i++] = inet_makeaddr (inet_netof
+             /* Changed to pass struct instead of s_addr member
+                by roland@gnu.  */
+                                         (sin->sin_addr), INADDR_ANY);
+           }
+         else
+           {
+             addrs[i++] = ((struct sockaddr_in *)
+                           &ifreq.ifr_addr)->sin_addr;
+           }
+#else /* 4.2 BSD */
+         addrs[i++] = inet_makeaddr (inet_netof
+                                     (sin->sin_addr.s_addr), INADDR_ANY);
+#endif
+       }
+    }
+  return i;
+}
+
+
+enum clnt_stat
+clnt_broadcast (
+     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 = 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;
+    }
+#ifdef SO_BROADCAST
+  if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0)
+    {
+      perror (_("Cannot set socket option SO_BROADCAST"));
+      stat = RPC_CANTSEND;
+      goto done_broad;
+    }
+#endif /* def SO_BROADCAST */
+  fd.fd = sock;
+  fd.events = POLLIN;
+  nets = getbroadcastnets (addrs, sock, inbuf);
+  memset ((char *) &baddr, 0, 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;
+           }
+       }
+      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;
+      milliseconds = t.tv_sec * 1000 + t.tv_usec / 1000;
+      switch (poll(&fd, 1, milliseconds))
+       {
+
+       case 0:         /* timed out */
+         stat = RPC_TIMEDOUT;
+         continue;
+
+       case -1:                /* some kind of error */
+         if (errno == EINTR)
+           goto recv_again;
+         perror (_("Broadcast poll problem"));
+         stat = RPC_CANTRECV;
+         goto done_broad;
+
+       }                       /* 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 ((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;
+}
diff --git a/rcmd.c b/rcmd.c
new file mode 100644 (file)
index 0000000..fb1bd93
--- /dev/null
+++ b/rcmd.c
@@ -0,0 +1,689 @@
+/*
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1983, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+static char sccsid[] = "@(#)rcmd.c     8.3 (Berkeley) 3/26/94";
+#endif /* LIBC_SCCS and not lint */
+
+#define __UCLIBC_HIDE_DEPRECATED__
+#include <features.h>
+#include <sys/param.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <signal.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <ctype.h>
+#include <string.h>
+#include <libintl.h>
+#include <stdlib.h>
+#ifdef __UCLIBC_HAS_WCHAR__
+#include <wchar.h>
+#endif
+#include <sys/uio.h>
+#include <bits/uClibc_alloc.h>
+
+
+/* some forward declarations */
+static int __ivaliduser2(FILE *hostf, u_int32_t raddr,
+                        const char *luser, const char *ruser, const char *rhost);
+static int iruserok2 (u_int32_t raddr, int superuser, const char *ruser,
+                     const char *luser, const char *rhost);
+
+
+int rcmd(char **ahost, u_short rport, const char *locuser, const char *remuser,
+                const char *cmd, int *fd2p)
+{
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
+       int herr;
+       struct hostent hostbuf;
+       size_t hstbuflen;
+       char *tmphstbuf;
+#endif
+       struct hostent *hp;
+       struct sockaddr_in sin, from;
+       struct pollfd pfd[2];
+       int32_t oldmask;
+       pid_t pid;
+       int s, lport, timo;
+       char c;
+
+       pid = getpid();
+
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
+       hstbuflen = 1024;
+       tmphstbuf = stack_heap_alloc(hstbuflen);
+
+       while (gethostbyname_r (*ahost, &hostbuf, tmphstbuf,
+                   hstbuflen, &hp, &herr) != 0 || hp == NULL)
+       {
+           if (herr != NETDB_INTERNAL || errno != ERANGE)
+           {
+               __set_h_errno (herr);
+               stack_heap_free(tmphstbuf);
+               herror(*ahost);
+               return -1;
+           }
+           else
+           {
+               /* Enlarge the buffer.  */
+               hstbuflen *= 2;
+               stack_heap_free(tmphstbuf);
+               tmphstbuf = stack_heap_alloc(hstbuflen);
+           }
+       }
+       stack_heap_free(tmphstbuf);
+#else /* call the non-reentrant version */
+       if ((hp = gethostbyname(*ahost)) == NULL) {
+           return -1;
+       }
+#endif
+       pfd[0].events = POLLIN;
+       pfd[1].events = POLLIN;
+
+        *ahost = hp->h_name;
+        oldmask = sigblock(sigmask(SIGURG)); /* __sigblock */
+       for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
+               s = rresvport(&lport);
+               if (s < 0) {
+                       if (errno == EAGAIN)
+                           (void)fprintf(stderr,
+                                         "rcmd: socket: All ports in use\n");
+                       else
+                           (void)fprintf(stderr, "rcmd: socket: %m\n");
+                       sigsetmask(oldmask); /* sigsetmask */
+                       return -1;
+               }
+               fcntl(s, F_SETOWN, pid);
+               sin.sin_family = hp->h_addrtype;
+               memmove(&sin.sin_addr, hp->h_addr_list[0],
+                     MIN (sizeof (sin.sin_addr), hp->h_length));
+               sin.sin_port = rport;
+               if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) /* __connect */
+                       break;
+               (void)close(s);
+               if (errno == EADDRINUSE) {
+                       lport--;
+                       continue;
+               }
+               if (errno == ECONNREFUSED && timo <= 16) {
+                               (void)sleep(timo); /* __sleep */
+                       timo *= 2;
+                       continue;
+               }
+               if (hp->h_addr_list[1] != NULL) {
+                       int oerrno = errno;
+
+                       (void)fprintf(stderr, "connect to address %s: ",
+                           inet_ntoa(sin.sin_addr));
+                       __set_errno (oerrno);
+                       perror(0);
+                       hp->h_addr_list++;
+                       memmove(&sin.sin_addr, hp->h_addr_list[0],
+                             MIN (sizeof (sin.sin_addr), hp->h_length));
+                       (void)fprintf(stderr, "Trying %s...\n",
+                           inet_ntoa(sin.sin_addr));
+                       continue;
+               }
+               (void)fprintf(stderr, "%s: %m\n", hp->h_name);
+               sigsetmask(oldmask); /* __sigsetmask */
+               return -1;
+       }
+       lport--;
+       if (fd2p == 0) {
+               write(s, "", 1);
+               lport = 0;
+       } else {
+               char num[8];
+               int s2 = rresvport(&lport), s3;
+               socklen_t len = sizeof(from);
+
+               if (s2 < 0)
+                       goto bad;
+               listen(s2, 1);
+               (void)snprintf(num, sizeof(num), "%d", lport); /* __snprintf */
+               if (write(s, num, strlen(num)+1) != strlen(num)+1) {
+                       (void)fprintf(stderr,
+                                     "rcmd: write (setting up stderr): %m\n");
+                       (void)close(s2);
+                       goto bad;
+               }
+               pfd[0].fd = s;
+               pfd[1].fd = s2;
+               __set_errno (0);
+               if (poll (pfd, 2, -1) < 1 || (pfd[1].revents & POLLIN) == 0){
+                   if (errno != 0)
+                       (void)fprintf(stderr, "rcmd: poll (setting up stderr): %m\n");
+                   else
+                       (void)fprintf(stderr, "poll: protocol failure in circuit setup\n");
+                       (void)close(s2);
+                       goto bad;
+               }
+               s3 = accept(s2, (struct sockaddr *)&from, &len);
+               (void)close(s2);
+               if (s3 < 0) {
+                       (void)fprintf(stderr,
+                           "rcmd: accept: %m\n");
+                       lport = 0;
+                       goto bad;
+               }
+               *fd2p = s3;
+               from.sin_port = ntohs((u_short)from.sin_port);
+               if (from.sin_family != AF_INET ||
+                   from.sin_port >= IPPORT_RESERVED ||
+                   from.sin_port < IPPORT_RESERVED / 2) {
+                       (void)fprintf(stderr,
+                           "socket: protocol failure in circuit setup\n");
+                       goto bad2;
+               }
+       }
+       (void)write(s, locuser, strlen(locuser)+1);
+       (void)write(s, remuser, strlen(remuser)+1);
+       (void)write(s, cmd, strlen(cmd)+1);
+       if (read(s, &c, 1) != 1) {
+               (void)fprintf(stderr,
+                   "rcmd: %s: %m\n", *ahost);
+               goto bad2;
+       }
+       if (c != 0) {
+               while (read(s, &c, 1) == 1) {
+                       (void)write(STDERR_FILENO, &c, 1);
+                       if (c == '\n')
+                               break;
+               }
+               goto bad2;
+       }
+       sigsetmask(oldmask);
+       return s;
+bad2:
+       if (lport)
+               (void)close(*fd2p);
+bad:
+       (void)close(s);
+       sigsetmask(oldmask);
+       return -1;
+}
+
+int rresvport(int *alport)
+{
+    struct sockaddr_in sin;
+    int s;
+
+    sin.sin_family = AF_INET;
+    sin.sin_addr.s_addr = INADDR_ANY;
+    s = socket(AF_INET, SOCK_STREAM, 0);
+    if (s < 0)
+       return -1;
+    for (;;) {
+       sin.sin_port = htons((u_short)*alport);
+       if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+           return s;
+       if (errno != EADDRINUSE) {
+           (void)close(s);
+           return -1;
+       }
+       (*alport)--;
+       if (*alport == IPPORT_RESERVED/2) {
+           (void)close(s);
+           __set_errno (EAGAIN);               /* close */
+           return -1;
+       }
+    }
+
+    return -1;
+}
+libc_hidden_def(rresvport)
+
+/* This needs to be exported ... while it is not a documented interface
+ * for rcp related apps, it's a required one that is used to control the
+ * rhost behavior.  Legacy sucks.
+ */
+int  __check_rhosts_file = 1;
+
+int ruserok(const char *rhost, int superuser, const char *ruser,
+                       const char *luser)
+{
+        struct hostent *hp;
+       u_int32_t addr;
+       char **ap;
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
+       size_t buflen;
+       char *buffer;
+       int herr;
+       struct hostent hostbuf;
+#endif
+
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
+       buflen = 1024;
+       buffer = stack_heap_alloc(buflen);
+
+       while (gethostbyname_r (rhost, &hostbuf, buffer,
+                   buflen, &hp, &herr) != 0 || hp == NULL)
+       {
+           if (herr != NETDB_INTERNAL || errno != ERANGE) {
+               stack_heap_free(buffer);
+               return -1;
+           } else
+           {
+               /* Enlarge the buffer.  */
+               buflen *= 2;
+               stack_heap_free(buffer);
+               buffer = stack_heap_alloc(buflen);
+           }
+       }
+       stack_heap_free(buffer);
+#else
+       if ((hp = gethostbyname(rhost)) == NULL) {
+               return -1;
+       }
+#endif
+       for (ap = hp->h_addr_list; *ap; ++ap) {
+               memmove(&addr, *ap, sizeof(addr));
+               if (iruserok2(addr, superuser, ruser, luser, rhost) == 0)
+                       return 0;
+       }
+       return -1;
+}
+
+
+/* Extremely paranoid file open function. */
+static FILE *
+iruserfopen (const char *file, uid_t okuser)
+{
+  struct stat st;
+  char *cp = NULL;
+  FILE *res = NULL;
+
+  /* If not a regular file, if owned by someone other than user or
+     root, if writeable by anyone but the owner, or if hardlinked
+     anywhere, quit.  */
+  if (lstat (file, &st))
+    cp = "lstat failed";
+  else if (!S_ISREG (st.st_mode))
+    cp = "not regular file";
+  else
+    {
+      res = fopen (file, "r");
+      if (!res)
+       cp = "cannot open";
+      else if (fstat (fileno (res), &st) < 0)
+       cp = "fstat failed";
+      else if (st.st_uid && st.st_uid != okuser)
+       cp = "bad owner";
+      else if (st.st_mode & (S_IWGRP|S_IWOTH))
+       cp = "writeable by other than owner";
+      else if (st.st_nlink > 1)
+       cp = "hard linked somewhere";
+    }
+
+  /* If there were any problems, quit.  */
+  if (cp != NULL)
+    {
+      if (res)
+       fclose (res);
+      return NULL;
+    }
+
+  return res;
+}
+
+
+/*
+ * New .rhosts strategy: We are passed an ip address. We spin through
+ * hosts.equiv and .rhosts looking for a match. When the .rhosts only
+ * has ip addresses, we don't have to trust a nameserver.  When it
+ * contains hostnames, we spin through the list of addresses the nameserver
+ * gives us and look for a match.
+ *
+ * Returns 0 if ok, -1 if not ok.
+ */
+static int
+iruserok2 (u_int32_t raddr, int superuser, const char *ruser, const char *luser,
+                  const char *rhost)
+{
+       FILE *hostf = NULL;
+       int isbad = -1;
+
+       if (!superuser)
+               hostf = iruserfopen (_PATH_HEQUIV, 0);
+
+       if (hostf) {
+               isbad = __ivaliduser2 (hostf, raddr, luser, ruser, rhost);
+               fclose (hostf);
+
+               if (!isbad)
+                       return 0;
+       }
+
+       if (__check_rhosts_file || superuser) {
+               char *pbuf;
+               struct passwd *pwd;
+               size_t dirlen;
+               uid_t uid;
+
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
+               size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
+               struct passwd pwdbuf;
+               char *buffer = stack_heap_alloc(buflen);
+
+               if (getpwnam_r (luser, &pwdbuf, buffer,
+                           buflen, &pwd) != 0 || pwd == NULL)
+               {
+                       stack_heap_free(buffer);
+                       return -1;
+               }
+               stack_heap_free(buffer);
+#else
+               if ((pwd = getpwnam(luser)) == NULL)
+                       return -1;
+#endif
+
+               dirlen = strlen (pwd->pw_dir);
+               pbuf = malloc (dirlen + sizeof "/.rhosts");
+               strcpy (pbuf, pwd->pw_dir);
+               strcat (pbuf, "/.rhosts");
+
+               /* Change effective uid while reading .rhosts.  If root and
+                  reading an NFS mounted file system, can't read files that
+                  are protected read/write owner only.  */
+               uid = geteuid ();
+               seteuid (pwd->pw_uid);
+               hostf = iruserfopen (pbuf, pwd->pw_uid);
+               free(pbuf);
+
+               if (hostf != NULL) {
+                       isbad = __ivaliduser2 (hostf, raddr, luser, ruser, rhost);
+                       fclose (hostf);
+               }
+
+               seteuid (uid);
+               return isbad;
+       }
+       return -1;
+}
+
+/* This is the exported version.  */
+int iruserok (u_int32_t raddr, int superuser, const char * ruser, const char * luser);
+int iruserok (u_int32_t raddr, int superuser, const char * ruser, const char * luser)
+{
+       return iruserok2 (raddr, superuser, ruser, luser, "-");
+}
+
+
+/*
+ * XXX
+ * Don't make static, used by lpd(8).
+ *
+ * This function is not used anymore. It is only present because lpd(8)
+ * calls it (!?!). We simply call __invaliduser2() with an illegal rhost
+ * argument. This means that netgroups won't work in .rhost/hosts.equiv
+ * files. If you want lpd to work with netgroups, fix lpd to use ruserok()
+ * or PAM.
+ * Returns 0 if ok, -1 if not ok.
+ */
+int
+__ivaliduser(FILE *hostf, u_int32_t raddr, const char *luser, const char *ruser);
+int
+__ivaliduser(FILE *hostf, u_int32_t raddr, const char *luser, const char *ruser)
+{
+       return __ivaliduser2(hostf, raddr, luser, ruser, "-");
+}
+
+
+/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */
+static int
+__icheckhost (u_int32_t raddr, char *lhost, const char *rhost)
+{
+       struct hostent *hp;
+       u_int32_t laddr;
+       int negate=1;    /* Multiply return with this to get -1 instead of 1 */
+       char **pp;
+
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
+       int save_errno;
+       size_t buflen;
+       char *buffer;
+       struct hostent hostbuf;
+       int herr;
+#endif
+
+#ifdef HAVE_NETGROUP
+       /* Check nis netgroup.  */
+       if (strncmp ("+@", lhost, 2) == 0)
+               return innetgr (&lhost[2], rhost, NULL, NULL);
+
+       if (strncmp ("-@", lhost, 2) == 0)
+               return -innetgr (&lhost[2], rhost, NULL, NULL);
+#endif /* HAVE_NETGROUP */
+
+       /* -host */
+       if (strncmp ("-", lhost,1) == 0) {
+               negate = -1;
+               lhost++;
+       } else if (strcmp ("+",lhost) == 0) {
+               return 1;                    /* asking for trouble, but ok.. */
+       }
+
+       /* Try for raw ip address first. */
+       if (isdigit (*lhost) && (laddr = inet_addr (lhost)) != INADDR_NONE)
+               return negate * (! (raddr ^ laddr));
+
+       /* Better be a hostname. */
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
+       buflen = 1024;
+       buffer = malloc(buflen);
+       save_errno = errno;
+
+       while (gethostbyname_r (lhost, &hostbuf, buffer, buflen, &hp, &herr)
+              != 0) {
+           free(buffer);
+           return (0);
+       }
+       free(buffer);
+       __set_errno (save_errno);
+#else
+       hp = gethostbyname(lhost);
+#endif /* __UCLIBC_HAS_REENTRANT_RPC__ */
+
+       if (hp == NULL)
+               return 0;
+
+       /* Spin through ip addresses. */
+       for (pp = hp->h_addr_list; *pp; ++pp)
+               if (!memcmp (&raddr, *pp, sizeof (u_int32_t)))
+                       return negate;
+
+       /* No match. */
+       return (0);
+}
+
+/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */
+static int
+__icheckuser (const char *luser, const char *ruser)
+{
+
+    /*
+      luser is user entry from .rhosts/hosts.equiv file
+      ruser is user id on remote host
+      */
+
+#ifdef HAVE_NETGROUP
+    /* [-+]@netgroup */
+    if (strncmp ("+@", luser, 2) == 0)
+       return innetgr (&luser[2], NULL, ruser, NULL);
+
+    if (strncmp ("-@", luser,2) == 0)
+       return -innetgr (&luser[2], NULL, ruser, NULL);
+#endif /* HAVE_NETGROUP */
+
+    /* -user */
+    if (strncmp ("-", luser, 1) == 0)
+       return -(strcmp (&luser[1], ruser) == 0);
+
+    /* + */
+    if (strcmp ("+", luser) == 0)
+       return 1;
+
+    /* simple string match */
+    return strcmp (ruser, luser) == 0;
+}
+
+/*
+ * Returns 1 for blank lines (or only comment lines) and 0 otherwise
+ */
+static int
+__isempty(char *p)
+{
+    while (*p && isspace (*p)) {
+       ++p;
+    }
+
+    return (*p == '\0' || *p == '#') ? 1 : 0 ;
+}
+
+/*
+ * Returns 0 if positive match, -1 if _not_ ok.
+ */
+static int
+__ivaliduser2(FILE *hostf, u_int32_t raddr,    const char *luser,
+                         const char *ruser, const char *rhost)
+{
+    register const char *user;
+    register char *p;
+    int hcheck, ucheck;
+    char *buf = NULL;
+    size_t bufsize = 0;
+    int retval = -1;
+
+    while (getline (&buf, &bufsize, hostf) > 0) {
+       buf[bufsize - 1] = '\0'; /* Make sure it's terminated.  */
+        p = buf;
+
+       /* Skip empty or comment lines */
+       if (__isempty (p)) {
+           continue;
+       }
+
+       /* Skip lines that are too long. */
+       if (strchr (p, '\n') == NULL) {
+           int ch = getc_unlocked (hostf);
+
+           while (ch != '\n' && ch != EOF)
+             ch = getc_unlocked (hostf);
+           continue;
+       }
+
+       for (;*p && !isspace(*p); ++p) {
+           *p = tolower (*p);
+       }
+
+       /* Next we want to find the permitted name for the remote user.  */
+       if (*p == ' ' || *p == '\t') {
+           /* <nul> terminate hostname and skip spaces */
+           for (*p++='\0'; *p && isspace (*p); ++p);
+
+           user = p;                   /* this is the user's name */
+           while (*p && !isspace (*p))
+               ++p;                    /* find end of user's name */
+       } else
+           user = p;
+
+       *p = '\0';              /* <nul> terminate username (+host?) */
+
+       /* buf -> host(?) ; user -> username(?) */
+
+       /* First check host part */
+       hcheck = __icheckhost (raddr, buf, rhost);
+
+       if (hcheck < 0)
+           break;
+
+       if (hcheck) {
+           /* Then check user part */
+           if (! (*user))
+               user = luser;
+
+           ucheck = __icheckuser (user, ruser);
+
+           /* Positive 'host user' match? */
+           if (ucheck > 0) {
+               retval = 0;
+               break;
+           }
+
+           /* Negative 'host -user' match? */
+           if (ucheck < 0)
+               break;
+
+           /* Neither, go on looking for match */
+       }
+    }
+
+    free (buf);
+
+    return retval;
+}
diff --git a/rexec.c b/rexec.c
new file mode 100644 (file)
index 0000000..4148fdd
--- /dev/null
+++ b/rexec.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <alloca.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define SA_LEN(_x)      __libc_sa_len((_x)->sa_family)
+extern int __libc_sa_len(sa_family_t __af) __THROW attribute_hidden;
+
+/* int rexecoptions; - google does not know it */
+static char ahostbuf[NI_MAXHOST];
+
+int
+rexec_af(char **ahost, int rport, const char *name, const char *pass, const char *cmd, int *fd2p, sa_family_t af)
+{
+       struct sockaddr_storage sa2, from;
+       struct addrinfo hints, *res0;
+       const char *orig_name = name;
+       const char *orig_pass = pass;
+       u_short port = 0;
+       int s, timo = 1, s3;
+       char c;
+       int gai;
+       char servbuff[NI_MAXSERV];
+
+       if (sizeof(servbuff) < sizeof(int)*3 + 2) {
+               snprintf(servbuff, sizeof(servbuff), "%d", ntohs(rport));
+               servbuff[sizeof(servbuff) - 1] = '\0';
+       } else {
+               sprintf(servbuff, "%d", ntohs(rport));
+       }
+
+       memset(&hints, '\0', sizeof(hints));
+       hints.ai_family = af;
+       hints.ai_socktype = SOCK_STREAM;
+       hints.ai_flags = AI_CANONNAME;
+       gai = getaddrinfo(*ahost, servbuff, &hints, &res0);
+       if (gai) {
+               /* XXX: set errno? */
+               return -1;
+       }
+
+       if (res0->ai_canonname) {
+               strncpy(ahostbuf, res0->ai_canonname, sizeof(ahostbuf));
+               ahostbuf[sizeof(ahostbuf)-1] = '\0';
+               *ahost = ahostbuf;
+       }
+       else {
+               *ahost = NULL;
+               __set_errno(ENOENT);
+               return -1;
+       }
+       ruserpass(res0->ai_canonname, &name, &pass);
+retry:
+       s = socket(res0->ai_family, res0->ai_socktype, 0);
+       if (s < 0) {
+               perror("rexec: socket");
+               return -1;
+       }
+       if (connect(s, res0->ai_addr, res0->ai_addrlen) < 0) {
+               if (errno == ECONNREFUSED && timo <= 16) {
+                       (void) close(s);
+                       sleep(timo);
+                       timo *= 2;
+                       goto retry;
+               }
+               perror(res0->ai_canonname);
+               return -1;
+       }
+       if (fd2p == 0) {
+               (void) write(s, "", 1);
+               port = 0;
+       } else {
+               char num[32];
+               int s2;
+               socklen_t sa2len;
+
+               s2 = socket(res0->ai_family, res0->ai_socktype, 0);
+               if (s2 < 0) {
+                       (void) close(s);
+                       return -1;
+               }
+               listen(s2, 1);
+               sa2len = sizeof(sa2);
+               if (getsockname(s2, (struct sockaddr *)&sa2, &sa2len) < 0) {
+                       perror("getsockname");
+                       (void) close(s2);
+                       goto bad;
+               } else if (sa2len != SA_LEN((struct sockaddr *)&sa2)) {
+                       __set_errno(EINVAL);
+                       (void) close(s2);
+                       goto bad;
+               }
+               port = 0;
+               if (!getnameinfo((struct sockaddr *)&sa2, sa2len,
+                                NULL, 0, servbuff, sizeof(servbuff),
+                                NI_NUMERICSERV))
+                       port = atoi(servbuff);
+               (void) sprintf(num, "%u", port);
+               (void) write(s, num, strlen(num)+1);
+               {
+                       socklen_t len = sizeof(from);
+                       s3 = TEMP_FAILURE_RETRY(accept(s2,
+                                       (struct sockaddr *)&from, &len));
+                       close(s2);
+                       if (s3 < 0) {
+                               perror("accept");
+                               port = 0;
+                               goto bad;
+                       }
+               }
+               *fd2p = s3;
+       }
+       (void) write(s, name, strlen(name) + 1);
+       /* should public key encypt the password here */
+       (void) write(s, pass, strlen(pass) + 1);
+       (void) write(s, cmd, strlen(cmd) + 1);
+
+       /* We don't need the memory allocated for the name and the password
+          in ruserpass anymore.  */
+       if (name != orig_name)
+               free((char *) name);
+       if (pass != orig_pass)
+               free((char *) pass);
+
+       if (read(s, &c, 1) != 1) {
+               perror(*ahost);
+               goto bad;
+       }
+       if (c != 0) {
+               while (read(s, &c, 1) == 1) {
+                       (void) write(2, &c, 1);
+                       if (c == '\n')
+                               break;
+               }
+               goto bad;
+       }
+       freeaddrinfo(res0);
+       return s;
+bad:
+       if (port)
+               (void) close(*fd2p);
+       (void) close(s);
+       freeaddrinfo(res0);
+       return -1;
+}
+libc_hidden_def(rexec_af)
+
+int
+rexec(char **ahost, int rport, const char *name, const char *pass,
+         const char *cmd, int *fd2p)
+{
+       return rexec_af(ahost, rport, name, pass, cmd, fd2p, AF_INET);
+}
diff --git a/rpc/auth.h b/rpc/auth.h
new file mode 100644 (file)
index 0000000..a156c56
--- /dev/null
@@ -0,0 +1,232 @@
+/* @(#)auth.h  2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client.  The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+#ifndef _RPC_AUTH_H
+
+#define _RPC_AUTH_H    1
+#ifdef _LIBC
+/* Some adjustments to make the libc source from glibc
+ * compile more easily with uClibc... */
+#ifndef __FORCE_GLIBC
+#define __FORCE_GLIBC
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#define _(X)   X
+#endif
+#include <features.h>
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+#define MAX_AUTH_BYTES 400
+#define MAXNETNAMELEN  255     /* maximum length of network user's name */
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+       AUTH_OK=0,
+       /*
+        * failed at remote end
+        */
+       AUTH_BADCRED=1,                 /* bogus credentials (seal broken) */
+       AUTH_REJECTEDCRED=2,            /* client should begin new session */
+       AUTH_BADVERF=3,                 /* bogus verifier (seal broken) */
+       AUTH_REJECTEDVERF=4,            /* verifier expired or was replayed */
+       AUTH_TOOWEAK=5,                 /* rejected due to security reasons */
+       /*
+        * failed locally
+       */
+       AUTH_INVALIDRESP=6,             /* bogus response verifier */
+       AUTH_FAILED=7                   /* some unknown reason */
+};
+
+union des_block {
+       struct {
+               u_int32_t high;
+               u_int32_t low;
+       } key;
+       char c[8];
+};
+typedef union des_block des_block;
+extern bool_t xdr_des_block (XDR *__xdrs, des_block *__blkp) __THROW;
+
+/*
+ * Authentication info.  Opaque to client.
+ */
+struct opaque_auth {
+       enum_t  oa_flavor;              /* flavor of auth */
+       caddr_t oa_base;                /* address of more auth stuff */
+       u_int   oa_length;              /* not to exceed MAX_AUTH_BYTES */
+};
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct AUTH AUTH;
+struct AUTH {
+  struct opaque_auth ah_cred;
+  struct opaque_auth ah_verf;
+  union des_block ah_key;
+  struct auth_ops {
+    void (*ah_nextverf) (AUTH *);
+    int  (*ah_marshal) (AUTH *, XDR *);                /* nextverf & serialize */
+    int  (*ah_validate) (AUTH *, struct opaque_auth *);
+                                               /* validate verifier */
+    int  (*ah_refresh) (AUTH *);               /* refresh credentials */
+    void (*ah_destroy) (AUTH *);               /* destroy this structure */
+  } *ah_ops;
+  caddr_t ah_private;
+};
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH        *auth;
+ * XDR *xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth)            \
+               ((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth)            \
+               ((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs)      \
+               ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs)      \
+               ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp)     \
+               ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp)     \
+               ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth)             \
+               ((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth)             \
+               ((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth)             \
+               ((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth)             \
+               ((*((auth)->ah_ops->ah_destroy))(auth))
+
+
+extern struct opaque_auth _null_auth;
+
+
+/*
+ * These are the various implementations of client side authenticators.
+ */
+
+/*
+ * Unix style authentication
+ * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
+ *     char *machname;
+ *     int uid;
+ *     int gid;
+ *     int len;
+ *     int *aup_gids;
+ */
+extern AUTH *authunix_create (char *__machname, __uid_t __uid, __gid_t __gid,
+                             int __len, __gid_t *__aup_gids);
+libc_hidden_proto(authunix_create)
+extern AUTH *authunix_create_default (void);
+libc_hidden_proto(authunix_create_default)
+extern AUTH *authnone_create (void) __THROW;
+libc_hidden_proto(authnone_create)
+#if 0
+extern AUTH *authdes_create (const char *__servername, u_int __window,
+                            struct sockaddr *__syncaddr, des_block *__ckey)
+     __THROW;
+extern AUTH *authdes_pk_create (const char *, netobj *, u_int,
+                               struct sockaddr *, des_block *) __THROW;
+#endif
+
+
+#define AUTH_NONE      0               /* no authentication */
+#define        AUTH_NULL       0               /* backward compatibility */
+#define        AUTH_SYS        1               /* unix style (uid, gids) */
+#define        AUTH_UNIX       AUTH_SYS
+#define        AUTH_SHORT      2               /* short hand unix style */
+#define AUTH_DES       3               /* des style (encrypted timestamps) */
+#define AUTH_DH                AUTH_DES        /* Diffie-Hellman (this is DES) */
+#define AUTH_KERB       4               /* kerberos style */
+
+#if 0
+/*
+ *  Netname manipulating functions
+ *
+ */
+extern int getnetname (char *) __THROW;
+extern int host2netname (char *, __const char *, __const char *) __THROW;
+extern int user2netname (char *, __const uid_t, __const char *) __THROW;
+extern int netname2user (__const char *, uid_t *, gid_t *, int *, gid_t *)
+     __THROW;
+extern int netname2host (__const char *, char *, __const int) __THROW;
+
+/*
+ *
+ * These routines interface to the keyserv daemon
+ *
+ */
+extern int key_decryptsession (char *, des_block *);
+extern int key_decryptsession_pk (char *, netobj *, des_block *);
+extern int key_encryptsession (char *, des_block *);
+extern int key_encryptsession_pk (char *, netobj *, des_block *);
+extern int key_gendes (des_block *);
+extern int key_setsecret (char *);
+extern int key_secretkey_is_set (void);
+extern int key_get_conv (char *, des_block *);
+#endif
+
+/*
+ * XDR an opaque authentication struct.
+ */
+extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *) __THROW;
+libc_hidden_proto(xdr_opaque_auth)
+
+__END_DECLS
+
+#endif /* rpc/auth.h */
diff --git a/rpc/auth_des.h b/rpc/auth_des.h
new file mode 100644 (file)
index 0000000..d51b7ce
--- /dev/null
@@ -0,0 +1,117 @@
+/* Copyright (C) 1996, 1997, 1998, 1999 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.  */
+
+#ifndef _RPC_AUTH_DES_H
+#define _RPC_AUTH_DES_H        1
+
+#include <sys/cdefs.h>
+#include <rpc/auth.h>
+
+__BEGIN_DECLS
+
+#if 0
+/* There are two kinds of "names": fullnames and nicknames */
+enum authdes_namekind
+  {
+    ADN_FULLNAME,
+    ADN_NICKNAME
+  };
+
+/* A fullname contains the network name of the client,
+   a conversation key and the window */
+struct authdes_fullname
+  {
+    char *name;                /* network name of client, up to MAXNETNAMELEN */
+    des_block key;     /* conversation key */
+    uint32_t window;   /* associated window */
+  };
+
+/* A credential */
+struct authdes_cred
+  {
+    enum authdes_namekind adc_namekind;
+    struct authdes_fullname adc_fullname;
+    uint32_t adc_nickname;
+  };
+#endif
+
+/* A timeval replacement for !32bit platforms */
+struct rpc_timeval
+  {
+    uint32_t tv_sec;            /* Seconds.  */
+    uint32_t tv_usec;           /* Microseconds.  */
+  };
+
+#if 0
+/* A des authentication verifier */
+struct authdes_verf
+  {
+    union
+      {
+       struct rpc_timeval adv_ctime;   /* clear time */
+       des_block adv_xtime;            /* crypt time */
+      }
+    adv_time_u;
+    uint32_t adv_int_u;
+  };
+
+/* des authentication verifier: client variety
+
+   adv_timestamp is the current time.
+   adv_winverf is the credential window + 1.
+   Both are encrypted using the conversation key. */
+#define adv_timestamp  adv_time_u.adv_ctime
+#define adv_xtimestamp adv_time_u.adv_xtime
+#define adv_winverf    adv_int_u
+
+/* des authentication verifier: server variety
+
+   adv_timeverf is the client's timestamp + client's window
+   adv_nickname is the server's nickname for the client.
+   adv_timeverf is encrypted using the conversation key. */
+#define adv_timeverf   adv_time_u.adv_ctime
+#define adv_xtimeverf  adv_time_u.adv_xtime
+#define adv_nickname   adv_int_u
+
+/* Map a des credential into a unix cred. */
+extern int authdes_getucred (__const struct authdes_cred * __adc,
+                            uid_t * __uid, gid_t * __gid,
+                            short *__grouplen, gid_t * __groups) __THROW;
+
+/* Get the public key for NAME and place it in KEY.  NAME can only be
+   up to MAXNETNAMELEN bytes long and the destination buffer KEY should
+   have HEXKEYBYTES + 1 bytes long to fit all characters from the key.  */
+extern int getpublickey (__const char *__name, char *__key) __THROW;
+
+/* Get the secret key for NAME and place it in KEY.  PASSWD is used to
+   decrypt the encrypted key stored in the database.  NAME can only be
+   up to MAXNETNAMELEN bytes long and the destination buffer KEY
+   should have HEXKEYBYTES + 1 bytes long to fit all characters from
+   the key.  */
+extern int getsecretkey (__const char *__name, char *__key,
+                        __const char *__passwd) __THROW;
+#endif
+
+extern int rtime (struct sockaddr_in *__addrp, struct rpc_timeval *__timep,
+                 struct rpc_timeval *__timeout) __THROW;
+libc_hidden_proto(rtime)
+
+__END_DECLS
+
+
+#endif /* rpc/auth_des.h */
diff --git a/rpc/auth_unix.h b/rpc/auth_unix.h
new file mode 100644 (file)
index 0000000..713fcb4
--- /dev/null
@@ -0,0 +1,91 @@
+/* @(#)auth_unix.h     2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)auth_unix.h 1.5 86/07/16 SMI      */
+
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * The system is very weak.  The client uses no encryption for  it
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ */
+
+#ifndef _RPC_AUTH_UNIX_H
+#define _RPC_AUTH_UNIX_H       1
+
+#include <features.h>
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+/* The machine name is part of a credential; it may not exceed 255 bytes */
+#define MAX_MACHINE_NAME 255
+
+/* gids compose part of a credential; there may not be more than 16 of them */
+#define NGRPS 16
+
+/*
+ * Unix style credentials.
+ */
+struct authunix_parms
+  {
+    u_long aup_time;
+    char *aup_machname;
+    __uid_t aup_uid;
+    __gid_t aup_gid;
+    u_int aup_len;
+    __gid_t *aup_gids;
+  };
+
+extern bool_t xdr_authunix_parms (XDR *__xdrs, struct authunix_parms *__p)
+     __THROW;
+libc_hidden_proto(xdr_authunix_parms)
+
+/*
+ * If a response verifier has flavor AUTH_SHORT,
+ * then the body of the response verifier encapsulates the following structure;
+ * again it is serialized in the obvious fashion.
+ */
+struct short_hand_verf
+  {
+    struct opaque_auth new_cred;
+  };
+
+__END_DECLS
+
+#endif /* rpc/auth_unix.h */
diff --git a/rpc/clnt.h b/rpc/clnt.h
new file mode 100644 (file)
index 0000000..608c7e7
--- /dev/null
@@ -0,0 +1,433 @@
+/* @(#)clnt.h  2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_CLNT_H
+#define _RPC_CLNT_H    1
+
+#include <features.h>
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <sys/un.h>
+
+__BEGIN_DECLS
+
+/*
+ * Rpc calls return an enum clnt_stat.  This should be looked at more,
+ * since each implementation is required to live with this (implementation
+ * independent) list of errors.
+ */
+enum clnt_stat {
+       RPC_SUCCESS=0,                  /* call succeeded */
+       /*
+        * local errors
+        */
+       RPC_CANTENCODEARGS=1,           /* can't encode arguments */
+       RPC_CANTDECODERES=2,            /* can't decode results */
+       RPC_CANTSEND=3,                 /* failure in sending call */
+       RPC_CANTRECV=4,                 /* failure in receiving result */
+       RPC_TIMEDOUT=5,                 /* call timed out */
+       /*
+        * remote errors
+        */
+       RPC_VERSMISMATCH=6,             /* rpc versions not compatible */
+       RPC_AUTHERROR=7,                /* authentication error */
+       RPC_PROGUNAVAIL=8,              /* program not available */
+       RPC_PROGVERSMISMATCH=9,         /* program version mismatched */
+       RPC_PROCUNAVAIL=10,             /* procedure unavailable */
+       RPC_CANTDECODEARGS=11,          /* decode arguments error */
+       RPC_SYSTEMERROR=12,             /* generic "other problem" */
+       RPC_NOBROADCAST = 21,           /* Broadcasting not supported */
+       /*
+        * callrpc & clnt_create errors
+        */
+       RPC_UNKNOWNHOST=13,             /* unknown host name */
+       RPC_UNKNOWNPROTO=17,            /* unknown protocol */
+       RPC_UNKNOWNADDR = 19,           /* Remote address unknown */
+
+       /*
+        * rpcbind errors
+        */
+       RPC_RPCBFAILURE=14,             /* portmapper failed in its call */
+#define RPC_PMAPFAILURE RPC_RPCBFAILURE
+       RPC_PROGNOTREGISTERED=15,       /* remote program is not registered */
+       RPC_N2AXLATEFAILURE = 22,       /* Name to addr translation failed */
+       /*
+        * unspecified error
+        */
+       RPC_FAILED=16,
+       RPC_INTR=18,
+       RPC_TLIERROR=20,
+       RPC_UDERROR=23,
+        /*
+         * asynchronous errors
+         */
+        RPC_INPROGRESS = 24,
+        RPC_STALERACHANDLE = 25
+};
+
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+  enum clnt_stat re_status;
+  union {
+    int RE_errno;              /* related system error */
+    enum auth_stat RE_why;     /* why the auth error occurred */
+    struct {
+      u_long low;              /* lowest verion supported */
+      u_long high;             /* highest verion supported */
+    } RE_vers;
+    struct {                   /* maybe meaningful if RPC_FAILED */
+      long s1;
+      long s2;
+    } RE_lb;                   /* life boot & debugging only */
+  } ru;
+#define        re_errno        ru.RE_errno
+#define        re_why          ru.RE_why
+#define        re_vers         ru.RE_vers
+#define        re_lb           ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations, see e.g. rpc_udp.c.
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct CLIENT CLIENT;
+struct CLIENT {
+  AUTH *cl_auth;                /* authenticator */
+  /* not sure whether non-const-ness is a part of the spec... if it is,
+   * enclose "const" in #ifdef _LIBC / #endif
+   * to make it effective only for libc compile */
+  const
+  struct clnt_ops {
+    enum clnt_stat (*cl_call) (CLIENT *, u_long, xdrproc_t, caddr_t, xdrproc_t,
+                              caddr_t, struct timeval);
+                               /* call remote procedure */
+    void (*cl_abort) (void);   /* abort a call */
+    void (*cl_geterr) (CLIENT *, struct rpc_err *);
+                               /* get specific error code */
+    bool_t (*cl_freeres) (CLIENT *, xdrproc_t, caddr_t);
+                               /* frees results */
+    void (*cl_destroy) (CLIENT *); /* destroy this structure */
+    bool_t (*cl_control) (CLIENT *, int, char *);
+                               /* the ioctl() of rpc */
+  } *cl_ops;
+  caddr_t cl_private;          /* private stuff */
+};
+
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ *     CLIENT *rh;
+ *     u_long proc;
+ *     xdrproc_t xargs;
+ *     caddr_t argsp;
+ *     xdrproc_t xres;
+ *     caddr_t resp;
+ *     struct timeval timeout;
+ */
+#define        CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)     \
+       ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+#define        clnt_call(rh, proc, xargs, argsp, xres, resp, secs)     \
+       ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_ABORT(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
+#define        clnt_abort(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_GETERR(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define        clnt_geterr(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ *     CLIENT *rh;
+ *     xdrproc_t xres;
+ *     caddr_t resp;
+ */
+#define        CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+#define        clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ *      CLIENT *cl;
+ *      u_int request;
+ *      char *info;
+ */
+#define        CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define        clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to all transports
+ *
+ * Note: options marked XXX are no-ops in this implementation of RPC.
+ * The are present in TI-RPC but can't be implemented here since they
+ * depend on the presence of STREAMS/TLI, which we don't have.
+ */
+#define CLSET_TIMEOUT        1    /* set timeout (timeval) */
+#define CLGET_TIMEOUT        2    /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR    3    /* get server's address (sockaddr) */
+#define CLGET_FD             6    /* get connections file descriptor */
+#define CLGET_SVC_ADDR       7    /* get server's address (netbuf)      XXX */
+#define CLSET_FD_CLOSE       8    /* close fd while clnt_destroy */
+#define CLSET_FD_NCLOSE      9    /* Do not close fd while clnt_destroy*/
+#define CLGET_XID            10   /* Get xid */
+#define CLSET_XID            11   /* Set xid */
+#define CLGET_VERS           12   /* Get version number */
+#define CLSET_VERS           13   /* Set version number */
+#define CLGET_PROG           14   /* Get program number */
+#define CLSET_PROG           15   /* Set program number */
+#define CLSET_SVC_ADDR       16   /* get server's address (netbuf)      XXX */
+#define CLSET_PUSH_TIMOD     17   /* push timod if not already present  XXX */
+#define CLSET_POP_TIMOD      18   /* pop timod                          XXX */
+/*
+ * Connectionless only control operations
+ */
+#define CLSET_RETRY_TIMEOUT    4       /* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT    5       /* get retry timeout (timeval) */
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ *     CLIENT *rh;
+ */
+#define        CLNT_DESTROY(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
+#define        clnt_destroy(rh)        ((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessible on every rpc
+ * transport/port.  It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM                ((u_long)1)
+#define RPCTEST_VERSION                ((u_long)1)
+#define RPCTEST_NULL_PROC      ((u_long)2)
+#define RPCTEST_NULL_BATCH_PROC        ((u_long)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((u_long)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc.  They can return NULL if a
+ * creation failure occurs.
+ */
+
+/*
+ * Memory based rpc (for speed check and testing)
+ * CLIENT *
+ * clntraw_create(prog, vers)
+ *     u_long prog;
+ *     u_long vers;
+ */
+extern CLIENT *clntraw_create (__const u_long __prog, __const u_long __vers)
+     __THROW;
+
+
+/*
+ * Generic client creation routine. Supported protocols are "udp", "tcp" and
+ * "unix"
+ * CLIENT *
+ * clnt_create(host, prog, vers, prot)
+ *     char *host;     -- hostname
+ *     u_long prog;    -- program number
+ *     u_ong vers;     -- version number
+ *     char *prot;     -- protocol
+ */
+extern CLIENT *clnt_create (__const char *__host, __const u_long __prog,
+                           __const u_long __vers, __const char *__prot)
+     __THROW;
+
+
+/*
+ * TCP based rpc
+ * CLIENT *
+ * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ *     struct sockaddr_in *raddr;
+ *     u_long prog;
+ *     u_long version;
+ *     register int *sockp;
+ *     u_int sendsz;
+ *     u_int recvsz;
+ */
+extern CLIENT *clnttcp_create (struct sockaddr_in *__raddr, u_long __prog,
+                              u_long __version, int *__sockp, u_int __sendsz,
+                              u_int __recvsz) __THROW;
+libc_hidden_proto(clnttcp_create)
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ *     struct sockaddr_in *raddr;
+ *     u_long program;
+ *     u_long version;
+ *     struct timeval wait_resend;
+ *     int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ *     struct sockaddr_in *raddr;
+ *     u_long program;
+ *     u_long version;
+ *     struct timeval wait_resend;
+ *     int *sockp;
+ *     u_int sendsz;
+ *     u_int recvsz;
+ */
+extern CLIENT *clntudp_create (struct sockaddr_in *__raddr, u_long __program,
+                              u_long __version, struct timeval __wait_resend,
+                              int *__sockp) __THROW;
+libc_hidden_proto(clntudp_create)
+extern CLIENT *clntudp_bufcreate (struct sockaddr_in *__raddr,
+                                 u_long __program, u_long __version,
+                                 struct timeval __wait_resend, int *__sockp,
+                                 u_int __sendsz, u_int __recvsz) __THROW;
+libc_hidden_proto(clntudp_bufcreate)
+
+
+/*
+ * AF_UNIX based rpc
+ * CLIENT *
+ * clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ *      struct sockaddr_un *raddr;
+ *      u_long prog;
+ *      u_long version;
+ *      register int *sockp;
+ *      u_int sendsz;
+ *      u_int recvsz;
+ */
+extern CLIENT *clntunix_create  (struct sockaddr_un *__raddr, u_long __program,
+                                u_long __version, int *__sockp,
+                                u_int __sendsz, u_int __recvsz) __THROW;
+libc_hidden_proto(clntunix_create)
+
+
+extern 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) __THROW;
+extern int _rpc_dtablesize (void) __THROW;
+libc_hidden_proto(_rpc_dtablesize)
+
+/*
+ * Print why creation failed
+ */
+extern void clnt_pcreateerror (__const char *__msg);   /* stderr */
+extern char *clnt_spcreateerror(__const char *__msg) __THROW;  /* string */
+libc_hidden_proto(clnt_spcreateerror)
+
+/*
+ * Like clnt_perror(), but is more verbose in its output
+ */
+extern void clnt_perrno (enum clnt_stat __num);                /* stderr */
+
+/*
+ * Print an English error message, given the client error code
+ */
+extern void clnt_perror (CLIENT *__clnt, __const char *__msg);
+                                                       /* stderr */
+libc_hidden_proto(clnt_perror)
+extern char *clnt_sperror (CLIENT *__clnt, __const char *__msg) __THROW;
+                                                       /* string */
+libc_hidden_proto(clnt_sperror)
+
+
+/*
+ * If a creation fails, the following allows the user to figure out why.
+ */
+struct rpc_createerr {
+       enum clnt_stat cf_stat;
+       struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
+};
+
+extern struct rpc_createerr rpc_createerr;
+
+
+
+/*
+ * Copy error message to buffer.
+ */
+extern char *clnt_sperrno (enum clnt_stat __num) __THROW;      /* string */
+libc_hidden_proto(clnt_sperrno)
+
+/*
+ * get the port number on the host for the rpc program,version and proto
+ */
+extern int getrpcport (__const char * __host, u_long __prognum,
+                      u_long __versnum, u_int proto) __THROW;
+
+/*
+ * get the local host's IP address without consulting
+ * name service library functions
+ */
+extern void get_myaddress (struct sockaddr_in *) __THROW;
+
+#define UDPMSGSIZE     8800    /* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE        400     /* a more reasonable packet size */
+
+__END_DECLS
+
+#endif /* rpc/clnt.h */
diff --git a/rpc/des_crypt.h b/rpc/des_crypt.h
new file mode 100644 (file)
index 0000000..6a65887
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * @(#)des_crypt.h     2.1 88/08/11 4.0 RPCSRC;        from 1.4 88/02/08 (C) 1986 SMI
+ *
+ * des_crypt.h, des library routine interface
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#ifndef __DES_CRYPT_H__
+#define __DES_CRYPT_H__ 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+#define DES_MAXDATA 8192       /* max bytes encrypted in one call */
+#define DES_DIRMASK (1 << 0)
+#define DES_ENCRYPT (0*DES_DIRMASK)    /* Encrypt */
+#define DES_DECRYPT (1*DES_DIRMASK)    /* Decrypt */
+
+
+#define DES_DEVMASK (1 << 1)
+#define        DES_HW (0*DES_DEVMASK)  /* Use hardware device */
+#define DES_SW (1*DES_DEVMASK) /* Use software device */
+
+
+#define DESERR_NONE 0  /* succeeded */
+#define DESERR_NOHWDEVICE 1    /* succeeded, but hw device not available */
+#define DESERR_HWERROR 2       /* failed, hardware/driver error */
+#define DESERR_BADPARAM 3      /* failed, bad parameter to call */
+
+#define DES_FAILED(err) \
+       ((err) > DESERR_NOHWDEVICE)
+
+/*
+ * cbc_crypt()
+ * ecb_crypt()
+ *
+ * Encrypt (or decrypt) len bytes of a buffer buf.
+ * The length must be a multiple of eight.
+ * The key should have odd parity in the low bit of each byte.
+ * ivec is the input vector, and is updated to the new one (cbc only).
+ * The mode is created by oring together the appropriate parameters.
+ * DESERR_NOHWDEVICE is returned if DES_HW was specified but
+ * there was no hardware to do it on (the data will still be
+ * encrypted though, in software).
+ */
+
+
+/*
+ * Cipher Block Chaining mode
+ */
+extern int cbc_crypt (char *__key, char *__buf, unsigned __len,
+                     unsigned __mode, char *__ivec) __THROW;
+
+/*
+ * Electronic Code Book mode
+ */
+extern int ecb_crypt (char *__key, char *__buf, unsigned __len,
+                     unsigned __mode) __THROW;
+
+/*
+ * Set des parity for a key.
+ * DES parity is odd and in the low bit of each byte
+ */
+extern void des_setparity (char *__key) __THROW;
+
+__END_DECLS
+
+#endif
diff --git a/rpc/key_prot.h b/rpc/key_prot.h
new file mode 100644 (file)
index 0000000..629e249
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _KEY_PROT_H_RPCGEN
+#define _KEY_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+#pragma ident  "@(#)key_prot.x 1.7     94/04/29 SMI"
+#endif
+/* Copyright (c)  1990, 1991 Sun Microsystems, Inc. */
+
+/*
+ * Compiled from key_prot.x using rpcgen.
+ * DO NOT EDIT THIS FILE!
+ * This is NOT source code!
+ */
+#define PROOT 3
+#define HEXMODULUS "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
+#define HEXKEYBYTES 48
+#define KEYSIZE 192
+#define KEYBYTES 24
+#define KEYCHECKSUMSIZE 16
+
+enum keystatus {
+       KEY_SUCCESS = 0,
+       KEY_NOSECRET = 1,
+       KEY_UNKNOWN = 2,
+       KEY_SYSTEMERR = 3,
+};
+typedef enum keystatus keystatus;
+#ifdef __cplusplus
+extern "C" bool_t xdr_keystatus(XDR *, keystatus*);
+#elif __STDC__
+extern  bool_t xdr_keystatus(XDR *, keystatus*);
+#else /* Old Style C */
+bool_t xdr_keystatus();
+#endif /* Old Style C */
+
+
+typedef char keybuf[HEXKEYBYTES];
+#ifdef __cplusplus
+extern "C" bool_t xdr_keybuf(XDR *, keybuf);
+#elif __STDC__
+extern  bool_t xdr_keybuf(XDR *, keybuf);
+#else /* Old Style C */
+bool_t xdr_keybuf();
+#endif /* Old Style C */
+
+
+typedef char *netnamestr;
+#ifdef __cplusplus
+extern "C" bool_t xdr_netnamestr(XDR *, netnamestr*);
+#elif __STDC__
+extern  bool_t xdr_netnamestr(XDR *, netnamestr*);
+#else /* Old Style C */
+bool_t xdr_netnamestr();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg {
+       netnamestr remotename;
+       des_block deskey;
+};
+typedef struct cryptkeyarg cryptkeyarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#elif __STDC__
+extern  bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg2 {
+       netnamestr remotename;
+       netobj remotekey;
+       des_block deskey;
+};
+typedef struct cryptkeyarg2 cryptkeyarg2;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#elif __STDC__
+extern  bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg2();
+#endif /* Old Style C */
+
+
+struct cryptkeyres {
+       keystatus status;
+       union {
+               des_block deskey;
+       } cryptkeyres_u;
+};
+typedef struct cryptkeyres cryptkeyres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#elif __STDC__
+extern  bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyres();
+#endif /* Old Style C */
+
+#define MAXGIDS 16
+
+struct unixcred {
+       u_int uid;
+       u_int gid;
+       struct {
+               u_int gids_len;
+               u_int *gids_val;
+       } gids;
+};
+typedef struct unixcred unixcred;
+#ifdef __cplusplus
+extern "C" bool_t xdr_unixcred(XDR *, unixcred*);
+#elif __STDC__
+extern  bool_t xdr_unixcred(XDR *, unixcred*);
+#else /* Old Style C */
+bool_t xdr_unixcred();
+#endif /* Old Style C */
+
+
+struct getcredres {
+       keystatus status;
+       union {
+               unixcred cred;
+       } getcredres_u;
+};
+typedef struct getcredres getcredres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_getcredres(XDR *, getcredres*);
+#elif __STDC__
+extern  bool_t xdr_getcredres(XDR *, getcredres*);
+#else /* Old Style C */
+bool_t xdr_getcredres();
+#endif /* Old Style C */
+
+
+struct key_netstarg {
+       keybuf st_priv_key;
+       keybuf st_pub_key;
+       netnamestr st_netname;
+};
+typedef struct key_netstarg key_netstarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#elif __STDC__
+extern  bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#else /* Old Style C */
+bool_t xdr_key_netstarg();
+#endif /* Old Style C */
+
+
+struct key_netstres {
+       keystatus status;
+       union {
+               key_netstarg knet;
+       } key_netstres_u;
+};
+typedef struct key_netstres key_netstres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstres(XDR *, key_netstres*);
+#elif __STDC__
+extern  bool_t xdr_key_netstres(XDR *, key_netstres*);
+#else /* Old Style C */
+bool_t xdr_key_netstres();
+#endif /* Old Style C */
+
+
+#ifndef opaque
+#define opaque char
+#endif
+
+
+#define KEY_PROG ((u_long)100029)
+#define KEY_VERS ((u_long)1)
+
+#ifdef __cplusplus
+#define KEY_SET ((u_long)1)
+extern "C" keystatus * key_set_1(opaque *, CLIENT *);
+extern "C" keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern "C" cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern "C" cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern "C" des_block * key_gen_1(void *, CLIENT *);
+extern "C" des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern "C" getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#elif __STDC__
+#define KEY_SET ((u_long)1)
+extern  keystatus * key_set_1(opaque *, CLIENT *);
+extern  keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern  cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern  cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern  des_block * key_gen_1(void *, CLIENT *);
+extern  des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern  getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern  getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#else /* Old Style C */
+#define KEY_SET ((u_long)1)
+extern  keystatus * key_set_1();
+extern  keystatus * key_set_1_svc();
+#define KEY_ENCRYPT ((u_long)2)
+extern  cryptkeyres * key_encrypt_1();
+extern  cryptkeyres * key_encrypt_1_svc();
+#define KEY_DECRYPT ((u_long)3)
+extern  cryptkeyres * key_decrypt_1();
+extern  cryptkeyres * key_decrypt_1_svc();
+#define KEY_GEN ((u_long)4)
+extern  des_block * key_gen_1();
+extern  des_block * key_gen_1_svc();
+#define KEY_GETCRED ((u_long)5)
+extern  getcredres * key_getcred_1();
+extern  getcredres * key_getcred_1_svc();
+#endif /* Old Style C */
+#define KEY_VERS2 ((u_long)2)
+
+#ifdef __cplusplus
+extern "C" keystatus * key_set_2(opaque *, CLIENT *);
+extern "C" keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern "C" cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" des_block * key_gen_2(void *, CLIENT *);
+extern "C" des_block * key_gen_2_svc(void *, struct svc_req *);
+extern "C" getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern "C" cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern "C" cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern "C" keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern "C" keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern "C" key_netstres * key_net_get_2(void *, CLIENT *);
+extern "C" key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern "C" cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern "C" cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#elif __STDC__
+extern  keystatus * key_set_2(opaque *, CLIENT *);
+extern  keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern  cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern  cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern  des_block * key_gen_2(void *, CLIENT *);
+extern  des_block * key_gen_2_svc(void *, struct svc_req *);
+extern  getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern  getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern  cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern  cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern  cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern  cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern  keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern  keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern  key_netstres * key_net_get_2(void *, CLIENT *);
+extern  key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern  cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern  cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#else /* Old Style C */
+extern  keystatus * key_set_2();
+extern  keystatus * key_set_2_svc();
+extern  cryptkeyres * key_encrypt_2();
+extern  cryptkeyres * key_encrypt_2_svc();
+extern  cryptkeyres * key_decrypt_2();
+extern  cryptkeyres * key_decrypt_2_svc();
+extern  des_block * key_gen_2();
+extern  des_block * key_gen_2_svc();
+extern  getcredres * key_getcred_2();
+extern  getcredres * key_getcred_2_svc();
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern  cryptkeyres * key_encrypt_pk_2();
+extern  cryptkeyres * key_encrypt_pk_2_svc();
+#define KEY_DECRYPT_PK ((u_long)7)
+extern  cryptkeyres * key_decrypt_pk_2();
+extern  cryptkeyres * key_decrypt_pk_2_svc();
+#define KEY_NET_PUT ((u_long)8)
+extern  keystatus * key_net_put_2();
+extern  keystatus * key_net_put_2_svc();
+#define KEY_NET_GET ((u_long)9)
+extern  key_netstres * key_net_get_2();
+extern  key_netstres * key_net_get_2_svc();
+#define KEY_GET_CONV ((u_long)10)
+extern  cryptkeyres * key_get_conv_2();
+extern  cryptkeyres * key_get_conv_2_svc();
+#endif /* Old Style C */
+
+#endif /* !_KEY_PROT_H_RPCGEN */
diff --git a/rpc/netdb.h b/rpc/netdb.h
new file mode 100644 (file)
index 0000000..e9a6565
--- /dev/null
@@ -0,0 +1,79 @@
+/* @(#)netdb.h 2.1 88/07/29 3.9 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*     @(#)rpc.h 1.8 87/07/24 SMI      */
+
+/* Cleaned up for GNU C library roland@gnu.ai.mit.edu:
+   added multiple inclusion protection and use of <sys/cdefs.h>.
+   In GNU this file is #include'd by <netdb.h>.  */
+
+#ifndef _RPC_NETDB_H
+#define _RPC_NETDB_H   1
+
+#include <features.h>
+
+#define __need_size_t
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+struct rpcent
+{
+  char *r_name;                /* Name of server for this rpc program.  */
+  char **r_aliases;    /* Alias list.  */
+  int r_number;                /* RPC program number.  */
+};
+
+extern void setrpcent (int __stayopen) __THROW;
+libc_hidden_proto(setrpcent)
+extern void endrpcent (void) __THROW;
+libc_hidden_proto(endrpcent)
+extern struct rpcent *getrpcbyname (__const char *__name) __THROW;
+libc_hidden_proto(getrpcbyname)
+extern struct rpcent *getrpcbynumber (int __number) __THROW;
+libc_hidden_proto(getrpcbynumber)
+extern struct rpcent *getrpcent (void) __THROW;
+libc_hidden_proto(getrpcent)
+
+#if defined __USE_MISC && defined __UCLIBC_HAS_REENTRANT_RPC__
+extern int getrpcbyname_r (__const char *__name, struct rpcent *__result_buf,
+                          char *__buffer, size_t __buflen,
+                          struct rpcent **__result) __THROW;
+
+extern int getrpcbynumber_r (int __number, struct rpcent *__result_buf,
+                            char *__buffer, size_t __buflen,
+                            struct rpcent **__result) __THROW;
+
+extern int getrpcent_r (struct rpcent *__result_buf, char *__buffer,
+                       size_t __buflen, struct rpcent **__result) __THROW;
+#endif
+
+__END_DECLS
+
+#endif /* rpc/netdb.h */
diff --git a/rpc/pmap_clnt.h b/rpc/pmap_clnt.h
new file mode 100644 (file)
index 0000000..f5e825d
--- /dev/null
@@ -0,0 +1,101 @@
+/* @(#)pmap_clnt.h     2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_PMAP_CLNT_H
+#define _RPC_PMAP_CLNT_H       1
+
+#include <features.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/clnt.h>
+
+__BEGIN_DECLS
+
+typedef bool_t (*resultproc_t) (caddr_t resp, struct sockaddr_in *raddr);
+
+/*
+ * Usage:
+ *     success = pmap_set(program, version, protocol, port);
+ *     success = pmap_unset(program, version);
+ *     port = pmap_getport(address, program, version, protocol);
+ *     head = pmap_getmaps(address);
+ *     clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ *             xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ *             (works for udp only.)
+ *     clnt_stat = clnt_broadcast(program, version, procedure,
+ *             xdrargs, argsp, xdrres, resp, eachresult)
+ *             (like pmap_rmtcall, except the call is broadcasted to all
+ *             locally connected nets.  For each valid response received,
+ *             the procedure eachresult is called.  Its form is:
+ *     done = eachresult(resp, raddr)
+ *             bool_t done;
+ *             caddr_t resp;
+ *             struct sockaddr_in raddr;
+ *             where resp points to the results of the call and raddr is the
+ *             address if the responder to the broadcast.
+ */
+
+extern bool_t pmap_set (__const u_long __program, __const u_long __vers,
+                       int __protocol, u_short __port) __THROW;
+libc_hidden_proto(pmap_set)
+extern bool_t pmap_unset (__const u_long __program, __const u_long __vers)
+     __THROW;
+libc_hidden_proto(pmap_unset)
+extern struct pmaplist *pmap_getmaps (struct sockaddr_in *__address) __THROW;
+extern enum clnt_stat pmap_rmtcall (struct sockaddr_in *__addr,
+                                   __const u_long __prog,
+                                   __const u_long __vers,
+                                   __const u_long __proc,
+                                   xdrproc_t __xdrargs,
+                                   caddr_t __argsp, xdrproc_t __xdrres,
+                                   caddr_t __resp, struct timeval __tout,
+                                   u_long *__port_ptr) __THROW;
+extern enum clnt_stat clnt_broadcast (__const u_long __prog,
+                                     __const u_long __vers,
+                                     __const u_long __proc, xdrproc_t __xargs,
+                                     caddr_t __argsp, xdrproc_t __xresults,
+                                     caddr_t __resultsp,
+                                     resultproc_t __eachresult) __THROW;
+extern u_short pmap_getport (struct sockaddr_in *__address,
+                            __const u_long __program,
+                            __const u_long __version, u_int __protocol)
+     __THROW;
+libc_hidden_proto(pmap_getport)
+
+__END_DECLS
+
+#endif /* rpc/pmap_clnt.h */
diff --git a/rpc/pmap_prot.h b/rpc/pmap_prot.h
new file mode 100644 (file)
index 0000000..30b2670
--- /dev/null
@@ -0,0 +1,110 @@
+/* @(#)pmap_prot.h     2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_PMAP_PROT_H
+#define _RPC_PMAP_PROT_H       1
+
+#include <features.h>
+
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+/* The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ *     takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ *     TRUE is success, FALSE is failure.  Registers the tuple
+ *     [prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ *     TRUE is success, FALSE is failure.  Un-registers pair
+ *     [prog, vers].  prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ *     0 is failure.  Otherwise returns the port number where the pair
+ *     [prog, vers] is registered.  It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ *     RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ *     Calls the procedure on the local machine.  If it is not registered,
+ *     this procedure is quite; ie it does not return error information!!!
+ *     This procedure only is supported on rpc/udp and calls via
+ *     rpc/udp.  This routine only passes null authentication parameters.
+ *     This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#define PMAPPORT               ((u_short)111)
+#define PMAPPROG               ((u_long)100000)
+#define PMAPVERS               ((u_long)2)
+#define PMAPVERS_PROTO         ((u_long)2)
+#define PMAPVERS_ORIG          ((u_long)1)
+#define PMAPPROC_NULL          ((u_long)0)
+#define PMAPPROC_SET           ((u_long)1)
+#define PMAPPROC_UNSET         ((u_long)2)
+#define PMAPPROC_GETPORT       ((u_long)3)
+#define PMAPPROC_DUMP          ((u_long)4)
+#define PMAPPROC_CALLIT                ((u_long)5)
+
+struct pmap {
+       long unsigned pm_prog;
+       long unsigned pm_vers;
+       long unsigned pm_prot;
+       long unsigned pm_port;
+};
+
+extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs) __THROW;
+libc_hidden_proto(xdr_pmap)
+
+struct pmaplist {
+       struct pmap     pml_map;
+       struct pmaplist *pml_next;
+};
+
+extern bool_t xdr_pmaplist (XDR *__xdrs, struct pmaplist **__rp) __THROW;
+libc_hidden_proto(xdr_pmaplist)
+
+__END_DECLS
+
+#endif /* rpc/pmap_prot.h */
diff --git a/rpc/pmap_rmt.h b/rpc/pmap_rmt.h
new file mode 100644 (file)
index 0000000..59b4f65
--- /dev/null
@@ -0,0 +1,71 @@
+/* @(#)pmap_rmt.h      2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_PMAP_RMT_H
+#define _RPC_PMAP_RMT_H        1
+
+#include <features.h>
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+struct rmtcallargs {
+       u_long prog, vers, proc, arglen;
+       caddr_t args_ptr;
+       xdrproc_t xdr_args;
+};
+
+extern bool_t xdr_rmtcall_args (XDR *__xdrs, struct rmtcallargs *__crp)
+     __THROW;
+libc_hidden_proto(xdr_rmtcall_args)
+
+
+struct rmtcallres {
+       u_long *port_ptr;
+       u_long resultslen;
+       caddr_t results_ptr;
+       xdrproc_t xdr_results;
+};
+
+extern bool_t xdr_rmtcallres (XDR *__xdrs, struct rmtcallres *__crp) __THROW;
+libc_hidden_proto(xdr_rmtcallres)
+
+__END_DECLS
+
+#endif /* rpc/pmap_rmt.h */
diff --git a/rpc/rpc.h b/rpc/rpc.h
new file mode 100644 (file)
index 0000000..abcab9e
--- /dev/null
+++ b/rpc/rpc.h
@@ -0,0 +1,119 @@
+/* @(#)rpc.h   2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_RPC_H
+#define _RPC_RPC_H 1
+
+#ifdef _LIBC
+/* Some adjustments to make the libc source from glibc
+ * compile more easily with uClibc... */
+#ifndef __FORCE_GLIBC
+#define __FORCE_GLIBC
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#define _(X)   X
+#include <features.h>
+#endif
+
+#include <rpc/types.h>         /* some typedefs */
+#include <netinet/in.h>
+
+/* external data representation interfaces */
+#include <rpc/xdr.h>           /* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h>          /* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h>          /* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h>       /* protocol for rpc messages */
+#include <rpc/auth_unix.h>     /* protocol for unix style cred */
+#include <rpc/auth_des.h>      /* protocol for des style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h>           /* service manager and multiplexer */
+#include <rpc/svc_auth.h>      /* service side authenticator */
+
+/*
+ * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION
+ * OF UNIX BASED ON NFSSRC.  These systems will already have the structures
+ * defined by <rpc/netdb.h> included in <netdb.h>.
+ */
+/* routines for parsing /etc/rpc */
+#include <rpc/netdb.h>         /* structures and routines to parse /etc/rpc */
+
+__BEGIN_DECLS
+
+/* Global variables, protected for multi-threaded applications.  */
+extern fd_set *__rpc_thread_svc_fdset (void) __attribute__ ((__const__));
+libc_hidden_proto(__rpc_thread_svc_fdset)
+#define svc_fdset (*__rpc_thread_svc_fdset ())
+
+extern struct rpc_createerr *__rpc_thread_createerr (void)
+     __attribute__ ((__const__));
+libc_hidden_proto(__rpc_thread_createerr)
+#define get_rpc_createerr() (*__rpc_thread_createerr ())
+/* The people who "engineered" RPC should bee punished for naming the
+   data structure and the variable the same.  We cannot always define the
+   macro 'rpc_createerr' because this would prevent people from defining
+   object of type 'struct rpc_createerr'.  So we leave it up to the user
+   to select transparent replacement also of this variable.  */
+#ifdef _RPC_MT_VARS
+# define rpc_createerr (*__rpc_thread_createerr ())
+#endif
+
+extern struct pollfd **__rpc_thread_svc_pollfd (void)
+     __attribute__ ((__const__));
+libc_hidden_proto(__rpc_thread_svc_pollfd)
+#define svc_pollfd (*__rpc_thread_svc_pollfd ())
+
+extern int *__rpc_thread_svc_max_pollfd (void) __attribute__ ((__const__));
+libc_hidden_proto(__rpc_thread_svc_max_pollfd)
+#define svc_max_pollfd (*__rpc_thread_svc_max_pollfd ())
+
+extern bool_t xdr_accepted_reply (XDR *xdrs, struct accepted_reply *ar);
+libc_hidden_proto(xdr_accepted_reply)
+extern bool_t xdr_rejected_reply (XDR *xdrs, struct rejected_reply *rr);
+libc_hidden_proto(xdr_rejected_reply)
+
+__END_DECLS
+
+#endif /* rpc/rpc.h */
diff --git a/rpc/rpc_des.h b/rpc/rpc_des.h
new file mode 100644 (file)
index 0000000..96e5369
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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
+ */
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 1986 by Sun Microsystems, Inc.
+ */
+
+#ifndef _DES_H
+#define _DES_H
+
+#include <sys/types.h>
+
+#define DES_MAXLEN     65536   /* maximum # of bytes to encrypt  */
+#define DES_QUICKLEN   16      /* maximum # of bytes to encrypt quickly */
+
+enum desdir
+  {
+    ENCRYPT, DECRYPT
+  };
+enum desmode
+  {
+    CBC, ECB
+  };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams
+  {
+    u_char des_key[8];         /* key (with low bit parity) */
+    enum desdir des_dir;       /* direction */
+    enum desmode des_mode;     /* mode */
+    u_char des_ivec[8];                /* input vector */
+    unsigned des_len;          /* number of bytes to crypt */
+    union
+      {
+       u_char UDES_data[DES_QUICKLEN];
+       u_char *UDES_buf;
+      }
+    UDES;
+#define des_data UDES.UDES_data        /* direct data here if quick */
+#define des_buf        UDES.UDES_buf   /* otherwise, pointer to data */
+  };
+
+#endif
diff --git a/rpc/rpc_msg.h b/rpc/rpc_msg.h
new file mode 100644 (file)
index 0000000..c848b39
--- /dev/null
@@ -0,0 +1,206 @@
+/* @(#)rpc_msg.h       2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)rpc_msg.h 1.7 86/07/16 SMI      */
+
+#ifndef _RPC_MSG_H
+#define _RPC_MSG_H 1
+
+#include <sys/cdefs.h>
+
+#include <rpc/xdr.h>
+#include <rpc/clnt.h>
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#define RPC_MSG_VERSION                ((u_long) 2)
+#define RPC_SERVICE_PORT       ((u_short) 2048)
+
+__BEGIN_DECLS
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall struct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+       CALL=0,
+       REPLY=1
+};
+
+enum reply_stat {
+       MSG_ACCEPTED=0,
+       MSG_DENIED=1
+};
+
+enum accept_stat {
+       SUCCESS=0,
+       PROG_UNAVAIL=1,
+       PROG_MISMATCH=2,
+       PROC_UNAVAIL=3,
+       GARBAGE_ARGS=4,
+       SYSTEM_ERR=5
+};
+
+enum reject_stat {
+       RPC_MISMATCH=0,
+       AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+       struct opaque_auth      ar_verf;
+       enum accept_stat        ar_stat;
+       union {
+               struct {
+                       u_long  low;
+                       u_long  high;
+               } AR_versions;
+               struct {
+                       caddr_t where;
+                       xdrproc_t proc;
+               } AR_results;
+               /* and many other null cases */
+       } ru;
+#define        ar_results      ru.AR_results
+#define        ar_vers         ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+       enum reject_stat rj_stat;
+       union {
+               struct {
+                       u_long low;
+                       u_long high;
+               } RJ_versions;
+               enum auth_stat RJ_why;  /* why authentication did not work */
+       } ru;
+#define        rj_vers ru.RJ_versions
+#define        rj_why  ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+       enum reply_stat rp_stat;
+       union {
+               struct accepted_reply RP_ar;
+               struct rejected_reply RP_dr;
+       } ru;
+#define        rp_acpt ru.RP_ar
+#define        rp_rjct ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+       u_long cb_rpcvers;      /* must be equal to two */
+       u_long cb_prog;
+       u_long cb_vers;
+       u_long cb_proc;
+       struct opaque_auth cb_cred;
+       struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+       u_long                  rm_xid;
+       enum msg_type           rm_direction;
+       union {
+               struct call_body RM_cmb;
+               struct reply_body RM_rmb;
+       } ru;
+#define        rm_call         ru.RM_cmb
+#define        rm_reply        ru.RM_rmb
+};
+#define        acpted_rply     ru.RM_rmb.ru.RP_ar
+#define        rjcted_rply     ru.RM_rmb.ru.RP_dr
+
+
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *cmsg;
+ */
+extern bool_t  xdr_callmsg (XDR *__xdrs, struct rpc_msg *__cmsg) __THROW;
+libc_hidden_proto(xdr_callmsg)
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *cmsg;
+ */
+extern bool_t  xdr_callhdr (XDR *__xdrs, struct rpc_msg *__cmsg) __THROW;
+libc_hidden_proto(xdr_callhdr)
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ *     XDR *xdrs;
+ *     struct rpc_msg *rmsg;
+ */
+extern bool_t  xdr_replymsg (XDR *__xdrs, struct rpc_msg *__rmsg) __THROW;
+libc_hidden_proto(xdr_replymsg)
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ *     struct rpc_msg *msg;
+ *     struct rpc_err *error;
+ */
+extern void    _seterr_reply (struct rpc_msg *__msg, struct rpc_err *__error)
+     __THROW;
+libc_hidden_proto(_seterr_reply)
+
+__END_DECLS
+
+#endif /* rpc/rpc_msg.h */
diff --git a/rpc/svc.h b/rpc/svc.h
new file mode 100644 (file)
index 0000000..6898325
--- /dev/null
+++ b/rpc/svc.h
@@ -0,0 +1,330 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVC_H
+#define _RPC_SVC_H 1
+
+#include <features.h>
+#include <rpc/rpc_msg.h>
+
+__BEGIN_DECLS
+
+/*
+ * This interface must manage two items concerning remote procedure calling:
+ *
+ * 1) An arbitrary number of transport connections upon which rpc requests
+ * are received.  The two most notable transports are TCP and UDP;  they are
+ * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
+ * they in turn call xprt_register and xprt_unregister.
+ *
+ * 2) An arbitrary number of locally registered services.  Services are
+ * described by the following four data: program number, version number,
+ * "service dispatch" function, a transport handle, and a boolean that
+ * indicates whether or not the exported program should be registered with a
+ * local binder service;  if true the program's number and version and the
+ * port number from the transport handle are registered with the binder.
+ * These data are registered with the rpc svc system via svc_register.
+ *
+ * A service's dispatch function is called whenever an rpc request comes in
+ * on a transport.  The request's program and version numbers must match
+ * those of the registered service.  The dispatch function is passed two
+ * parameters, struct svc_req * and SVCXPRT *, defined below.
+ */
+
+enum xprt_stat {
+       XPRT_DIED,
+       XPRT_MOREREQS,
+       XPRT_IDLE
+};
+
+/*
+ * Server side transport handle
+ */
+typedef struct SVCXPRT SVCXPRT;
+struct SVCXPRT {
+  int xp_sock;
+  u_short xp_port;             /* associated port number */
+  const struct xp_ops {
+    bool_t     (*xp_recv) (SVCXPRT *__xprt, struct rpc_msg *__msg);
+                               /* receive incoming requests */
+    enum xprt_stat (*xp_stat) (SVCXPRT *__xprt);
+                               /* get transport status */
+    bool_t     (*xp_getargs) (SVCXPRT *__xprt, xdrproc_t __xdr_args,
+                              caddr_t args_ptr); /* get arguments */
+    bool_t     (*xp_reply) (SVCXPRT *__xprt, struct rpc_msg *__msg);
+                               /* send reply */
+    bool_t     (*xp_freeargs) (SVCXPRT *__xprt, xdrproc_t __xdr_args,
+                               caddr_t args_ptr);
+                               /* free mem allocated for args */
+    void       (*xp_destroy) (SVCXPRT *__xprt);
+                               /* destroy this struct */
+  } *xp_ops;
+  int          xp_addrlen;      /* length of remote address */
+  struct sockaddr_in xp_raddr;  /* remote address */
+  struct opaque_auth xp_verf;   /* raw response verifier */
+  caddr_t              xp_p1;           /* private */
+  caddr_t              xp_p2;           /* private */
+  char         xp_pad [256];   /* padding, internal use */
+};
+
+/*
+ *  Approved way of getting address of caller
+ */
+#define svc_getcaller(x) (&(x)->xp_raddr)
+
+/*
+ * Operations defined on an SVCXPRT handle
+ *
+ * SVCXPRT             *xprt;
+ * struct rpc_msg      *msg;
+ * xdrproc_t            xargs;
+ * caddr_t              argsp;
+ */
+#define SVC_RECV(xprt, msg)                            \
+       (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+#define svc_recv(xprt, msg)                            \
+       (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+
+#define SVC_STAT(xprt)                                 \
+       (*(xprt)->xp_ops->xp_stat)(xprt)
+#define svc_stat(xprt)                                 \
+       (*(xprt)->xp_ops->xp_stat)(xprt)
+
+#define SVC_GETARGS(xprt, xargs, argsp)                        \
+       (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+#define svc_getargs(xprt, xargs, argsp)                        \
+       (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+
+#define SVC_REPLY(xprt, msg)                           \
+       (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+#define svc_reply(xprt, msg)                           \
+       (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+
+#define SVC_FREEARGS(xprt, xargs, argsp)               \
+       (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+#define svc_freeargs(xprt, xargs, argsp)               \
+       (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+
+#define SVC_DESTROY(xprt)                              \
+       (*(xprt)->xp_ops->xp_destroy)(xprt)
+#define svc_destroy(xprt)                              \
+       (*(xprt)->xp_ops->xp_destroy)(xprt)
+
+
+/*
+ * Service request
+ */
+struct svc_req {
+  rpcprog_t rq_prog;            /* service program number */
+  rpcvers_t rq_vers;            /* service protocol version */
+  rpcproc_t rq_proc;            /* the desired procedure */
+  struct opaque_auth rq_cred;   /* raw creds from the wire */
+  caddr_t rq_clntcred;          /* read only cooked cred */
+  SVCXPRT *rq_xprt;             /* associated transport */
+};
+
+#ifndef __DISPATCH_FN_T
+#define __DISPATCH_FN_T
+typedef void (*__dispatch_fn_t) (struct svc_req*, SVCXPRT*);
+#endif
+
+/*
+ * Service registration
+ *
+ * svc_register(xprt, prog, vers, dispatch, protocol)
+ *     SVCXPRT *xprt;
+ *     rpcprog_t prog;
+ *     rpcvers_t vers;
+ *     void (*dispatch)(struct svc_req*, SVCXPRT*);
+ *     rpcprot_t protocol;  like TCP or UDP, zero means do not register
+ */
+extern bool_t svc_register (SVCXPRT *__xprt, rpcprog_t __prog,
+                           rpcvers_t __vers, __dispatch_fn_t __dispatch,
+                           rpcprot_t __protocol) __THROW;
+libc_hidden_proto(svc_register)
+
+/*
+ * Service un-registration
+ *
+ * svc_unregister(prog, vers)
+ *     rpcprog_t prog;
+ *     rpcvers_t vers;
+ */
+extern void svc_unregister (rpcprog_t __prog, rpcvers_t __vers) __THROW;
+libc_hidden_proto(svc_unregister)
+
+/*
+ * Transport registration.
+ *
+ * xprt_register(xprt)
+ *     SVCXPRT *xprt;
+ */
+extern void xprt_register (SVCXPRT *__xprt) __THROW;
+libc_hidden_proto(xprt_register)
+
+/*
+ * Transport un-register
+ *
+ * xprt_unregister(xprt)
+ *     SVCXPRT *xprt;
+ */
+extern void xprt_unregister (SVCXPRT *__xprt) __THROW;
+libc_hidden_proto(xprt_unregister)
+
+/*
+ * When the service routine is called, it must first check to see if it
+ * knows about the procedure;  if not, it should call svcerr_noproc
+ * and return.  If so, it should deserialize its arguments via
+ * SVC_GETARGS (defined above).  If the deserialization does not work,
+ * svcerr_decode should be called followed by a return.  Successful
+ * decoding of the arguments should be followed the execution of the
+ * procedure's code and a call to svc_sendreply.
+ *
+ * Also, if the service refuses to execute the procedure due to too-
+ * weak authentication parameters, svcerr_weakauth should be called.
+ * Note: do not confuse access-control failure with weak authentication!
+ *
+ * NB: In pure implementations of rpc, the caller always waits for a reply
+ * msg.  This message is sent when svc_sendreply is called.
+ * Therefore pure service implementations should always call
+ * svc_sendreply even if the function logically returns void;  use
+ * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
+ * for the abuse of pure rpc via batched calling or pipelining.  In the
+ * case of a batched call, svc_sendreply should NOT be called since
+ * this would send a return message, which is what batching tries to avoid.
+ * It is the service/protocol writer's responsibility to know which calls are
+ * batched and which are not.  Warning: responding to batch calls may
+ * deadlock the caller and server processes!
+ */
+
+extern bool_t  svc_sendreply (SVCXPRT *xprt, xdrproc_t __xdr_results,
+                              caddr_t __xdr_location) __THROW;
+libc_hidden_proto(svc_sendreply)
+
+extern void    svcerr_decode (SVCXPRT *__xprt) __THROW;
+libc_hidden_proto(svcerr_decode)
+
+extern void    svcerr_weakauth (SVCXPRT *__xprt) __THROW;
+
+extern void    svcerr_noproc (SVCXPRT *__xprt) __THROW;
+
+extern void    svcerr_progvers (SVCXPRT *__xprt, rpcvers_t __low_vers,
+                                rpcvers_t __high_vers) __THROW;
+libc_hidden_proto(svcerr_progvers)
+
+extern void    svcerr_auth (SVCXPRT *__xprt, enum auth_stat __why) __THROW;
+libc_hidden_proto(svcerr_auth)
+
+extern void    svcerr_noprog (SVCXPRT *__xprt) __THROW;
+libc_hidden_proto(svcerr_noprog)
+
+extern void    svcerr_systemerr (SVCXPRT *__xprt) __THROW;
+
+/*
+ * Lowest level dispatching -OR- who owns this process anyway.
+ * Somebody has to wait for incoming requests and then call the correct
+ * service routine.  The routine svc_run does infinite waiting; i.e.,
+ * svc_run never returns.
+ * Since another (coexistent) package may wish to selectively wait for
+ * incoming calls or other events outside of the rpc architecture, the
+ * routine svc_getreq is provided.  It must be passed readfds, the
+ * "in-place" results of a select system call (see select, section 2).
+ */
+
+/*
+ * Global keeper of rpc service descriptors in use
+ * dynamic; must be inspected before each call to select
+ */
+
+extern struct pollfd *svc_pollfd;
+extern int svc_max_pollfd;
+extern fd_set svc_fdset;
+#define svc_fds svc_fdset.fds_bits[0]  /* compatibility */
+
+/*
+ * a small program implemented by the svc_rpc implementation itself;
+ * also see clnt.h for protocol numbers.
+ */
+extern void svc_getreq (int __rdfds) __THROW;
+libc_hidden_proto(svc_getreq)
+extern void svc_getreq_common (const int __fd) __THROW;
+libc_hidden_proto(svc_getreq_common)
+extern void svc_getreqset (fd_set *__readfds) __THROW;
+libc_hidden_proto(svc_getreqset)
+extern void svc_getreq_poll (struct pollfd *, const int) __THROW;
+libc_hidden_proto(svc_getreq_poll)
+extern void svc_exit (void) __THROW;
+extern void svc_run (void) __THROW;
+
+/*
+ * Socket to use on svcxxx_create call to get default socket
+ */
+#define        RPC_ANYSOCK     -1
+
+/*
+ * These are the existing service side transport implementations
+ */
+
+/*
+ * Memory based rpc for testing and timing.
+ */
+extern SVCXPRT *svcraw_create (void) __THROW;
+
+/*
+ * Udp based rpc.
+ */
+extern SVCXPRT *svcudp_create (int __sock) __THROW;
+libc_hidden_proto(svcudp_create)
+extern SVCXPRT *svcudp_bufcreate (int __sock, u_int __sendsz, u_int __recvsz)
+     __THROW;
+libc_hidden_proto(svcudp_bufcreate)
+
+/*
+ * Tcp based rpc.
+ */
+extern SVCXPRT *svctcp_create (int __sock, u_int __sendsize, u_int __recvsize)
+     __THROW;
+
+
+/*
+ * Unix based rpc.
+ */
+extern SVCXPRT *svcunix_create (int __sock, u_int __sendsize, u_int __recvsize,
+                               char *__path) __THROW;
+
+
+__END_DECLS
+
+#endif /* rpc/svc.h */
diff --git a/rpc/svc_auth.h b/rpc/svc_auth.h
new file mode 100644 (file)
index 0000000..834e3c9
--- /dev/null
@@ -0,0 +1,55 @@
+/* @(#)svc_auth.h      2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)svc_auth.h 1.6 86/07/16 SMI      */
+
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVC_AUTH_H
+#define _RPC_SVC_AUTH_H        1
+
+#include <features.h>
+#include <rpc/svc.h>
+
+__BEGIN_DECLS
+
+/*
+ * Server side authenticator
+ */
+extern enum auth_stat _authenticate (struct svc_req *__rqst,
+                                    struct rpc_msg *__msg) __THROW;
+libc_hidden_proto(_authenticate)
+
+__END_DECLS
+
+#endif /* rpc/svc_auth.h */
diff --git a/rpc/types.h b/rpc/types.h
new file mode 100644 (file)
index 0000000..05f49c3
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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
+ */
+/* fixincludes should not add extern "C" to this file */
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef _RPC_TYPES_H
+#define _RPC_TYPES_H 1
+
+#ifdef _LIBC
+/* Some adjustments to make the libc source from glibc
+ * compile more easily with uClibc... */
+#ifndef __FORCE_GLIBC
+#define __FORCE_GLIBC
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#define _(X)   X
+#endif
+#include <features.h>
+
+typedef int bool_t;
+typedef int enum_t;
+/* This needs to be changed to uint32_t in the future */
+typedef unsigned long rpcprog_t;
+typedef unsigned long rpcvers_t;
+typedef unsigned long rpcproc_t;
+typedef unsigned long rpcprot_t;
+typedef unsigned long rpcport_t;
+
+#define        __dontcare__    -1
+
+#ifndef FALSE
+#      define  FALSE   (0)
+#endif
+
+#ifndef TRUE
+#      define  TRUE    (1)
+#endif
+
+#ifndef NULL
+#      define  NULL 0
+#endif
+
+#include <stdlib.h>            /* For malloc decl.  */
+#define mem_alloc(bsize)       malloc(bsize)
+#define mem_free(ptr, bsize)   free(ptr)
+
+#ifndef makedev /* ie, we haven't already included it */
+#include <sys/types.h>
+#endif
+
+#ifndef __u_char_defined
+typedef __u_char u_char;
+typedef __u_short u_short;
+typedef __u_int u_int;
+typedef __u_long u_long;
+typedef __quad_t quad_t;
+typedef __u_quad_t u_quad_t;
+typedef __fsid_t fsid_t;
+# define __u_char_defined
+#endif
+#ifndef __daddr_t_defined
+typedef __daddr_t daddr_t;
+typedef __caddr_t caddr_t;
+# define __daddr_t_defined
+#endif
+
+#include <sys/time.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+
+#ifndef INADDR_LOOPBACK
+#define       INADDR_LOOPBACK         (u_long)0x7F000001
+#endif
+#ifndef MAXHOSTNAMELEN
+#define        MAXHOSTNAMELEN  64
+#endif
+
+#endif /* rpc/types.h */
diff --git a/rpc/xdr.h b/rpc/xdr.h
new file mode 100644 (file)
index 0000000..9981e3a
--- /dev/null
+++ b/rpc/xdr.h
@@ -0,0 +1,407 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_XDR_H
+#define _RPC_XDR_H 1
+
+#ifdef _LIBC
+/* Some adjustments to make the libc source from glibc
+ * compile more easily with uClibc... */
+# ifndef __FORCE_GLIBC
+#  define __FORCE_GLIBC
+# endif
+# define _(X)  X
+#endif
+#include <features.h>
+#include <sys/types.h>
+#include <rpc/types.h>
+
+/* We need FILE.  */
+#include <stdio.h>
+
+__BEGIN_DECLS
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation.  Library supplied
+ * routines provide for the conversion on built-in C data types.  These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ *      bool_t
+ *      xdrproc(xdrs, argresp)
+ *              XDR *xdrs;
+ *              <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted.  argresp is a pointer to the structure to be
+ * converted.  The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null.  This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
+ * stream.  XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+  XDR_ENCODE = 0,
+  XDR_DECODE = 1,
+  XDR_FREE = 2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT     (4)
+/*
+ * This only works if the above is a power of 2.  But it's defined to be
+ * 4 by the appropriate RFCs.  So it will work.  And it's normally quicker
+ * than the old routine.
+ */
+#if 1
+#define RNDUP(x)  (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1))
+#else /* this is the old routine */
+#define RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+                   * BYTES_PER_XDR_UNIT)
+#endif
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the particular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular implementation.
+ */
+typedef struct XDR XDR;
+struct XDR
+  {
+    enum xdr_op x_op;          /* operation; fast additional param */
+    struct xdr_ops
+      {
+       bool_t (*x_getlong) (XDR *__xdrs, long *__lp);
+       /* get a long from underlying stream */
+       bool_t (*x_putlong) (XDR *__xdrs, __const long *__lp);
+       /* put a long to " */
+       bool_t (*x_getbytes) (XDR *__xdrs, caddr_t __addr, u_int __len);
+       /* get some bytes from " */
+       bool_t (*x_putbytes) (XDR *__xdrs, __const char *__addr, u_int __len);
+       /* put some bytes to " */
+       u_int (*x_getpostn) (__const XDR *__xdrs);
+       /* returns bytes off from beginning */
+       bool_t (*x_setpostn) (XDR *__xdrs, u_int __pos);
+       /* lets you reposition the stream */
+       int32_t *(*x_inline) (XDR *__xdrs, u_int __len);
+       /* buf quick ptr to buffered data */
+       void (*x_destroy) (XDR *__xdrs);
+       /* free privates of this xdr_stream */
+       bool_t (*x_getint32) (XDR *__xdrs, int32_t *__ip);
+       /* get a int from underlying stream */
+       bool_t (*x_putint32) (XDR *__xdrs, __const int32_t *__ip);
+       /* put a int to " */
+      }
+     *x_ops;
+    caddr_t x_public;          /* users' data */
+    caddr_t x_private;         /* pointer to private data */
+    caddr_t x_base;            /* private used for position info */
+    u_int x_handy;             /* extra private word */
+  };
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded.  If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ * bool_t       (*xdrproc_t)(XDR *, caddr_t *);
+ */
+typedef bool_t (*xdrproc_t) (XDR *, void *,...);
+
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR          *xdrs;
+ * int32_t      *int32p;
+ * long         *longp;
+ * caddr_t       addr;
+ * u_int         len;
+ * u_int         pos;
+ */
+#define XDR_GETINT32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
+#define xdr_getint32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
+
+#define XDR_PUTINT32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
+#define xdr_putint32(xdrs, int32p)                      \
+        (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
+
+#define XDR_GETLONG(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp)                       \
+       (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len)                  \
+       (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs)                               \
+       (*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs)                               \
+       (*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos)                          \
+       (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos)                          \
+       (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define        XDR_INLINE(xdrs, len)                           \
+       (*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define        xdr_inline(xdrs, len)                           \
+       (*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define        XDR_DESTROY(xdrs)                                       \
+       do {                                                    \
+               if ((xdrs)->x_ops->x_destroy)                   \
+                       (*(xdrs)->x_ops->x_destroy)(xdrs);      \
+       } while (0)
+#define        xdr_destroy(xdrs)                                       \
+       do {                                                    \
+               if ((xdrs)->x_ops->x_destroy)                   \
+                       (*(xdrs)->x_ops->x_destroy)(xdrs);      \
+       } while (0)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * a entry with a null procedure pointer.  The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value.  If a match is found the associated xdr routine
+ * is called to handle that part of the union.  If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim
+{
+  int value;
+  xdrproc_t proc;
+};
+
+/*
+ * Inline routines for fast encode/decode of primitive data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned.  The standard way to use these
+ * is to say:
+ *      if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ *              return (FALSE);
+ *      <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+
+#define IXDR_GET_INT32(buf)           ((int32_t)ntohl((uint32_t)*(buf)++))
+#define IXDR_PUT_INT32(buf, v)        (*(buf)++ = (int32_t)htonl((uint32_t)(v)))
+#define IXDR_GET_U_INT32(buf)         ((uint32_t)IXDR_GET_INT32(buf))
+#define IXDR_PUT_U_INT32(buf, v)      IXDR_PUT_INT32(buf, (int32_t)(v))
+
+/* WARNING: The IXDR_*_LONG defines are removed by Sun for new platforms
+ * and shouldn't be used any longer. Code which use this defines or longs
+ * in the RPC code will not work on 64bit Solaris platforms !
+ */
+#define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf))
+#define IXDR_PUT_LONG(buf, v) ((long)IXDR_PUT_INT32(buf, (long)(v)))
+#define IXDR_GET_U_LONG(buf)         ((u_long)IXDR_GET_LONG(buf))
+#define IXDR_PUT_U_LONG(buf, v)              IXDR_PUT_LONG(buf, (long)(v))
+
+
+#define IXDR_GET_BOOL(buf)            ((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t)         ((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf)           ((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf)         ((u_short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v)         IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_ENUM(buf, v)         IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_SHORT(buf, v)        IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_U_SHORT(buf, v)      IXDR_PUT_LONG(buf, (long)(v))
+
+/*
+ * These are the "generic" xdr routines.
+ * None of these can have const applied because it's not possible to
+ * know whether the call is a read or a write to the passed parameter
+ * also, the XDR structure is always updated by some of these calls.
+ */
+extern bool_t xdr_void (void) __THROW;
+libc_hidden_proto(xdr_void)
+extern bool_t xdr_short (XDR *__xdrs, short *__sp) __THROW;
+libc_hidden_proto(xdr_short)
+extern bool_t xdr_u_short (XDR *__xdrs, u_short *__usp) __THROW;
+libc_hidden_proto(xdr_u_short)
+extern bool_t xdr_int (XDR *__xdrs, int *__ip) __THROW;
+libc_hidden_proto(xdr_int)
+extern bool_t xdr_u_int (XDR *__xdrs, u_int *__up) __THROW;
+libc_hidden_proto(xdr_u_int)
+extern bool_t xdr_long (XDR *__xdrs, long *__lp) __THROW;
+libc_hidden_proto(xdr_long)
+extern bool_t xdr_u_long (XDR *__xdrs, u_long *__ulp) __THROW;
+libc_hidden_proto(xdr_u_long)
+extern bool_t xdr_hyper (XDR *__xdrs, quad_t *__llp) __THROW;
+libc_hidden_proto(xdr_hyper)
+extern bool_t xdr_u_hyper (XDR *__xdrs, u_quad_t *__ullp) __THROW;
+libc_hidden_proto(xdr_u_hyper)
+extern bool_t xdr_longlong_t (XDR *__xdrs, quad_t *__llp) __THROW;
+extern bool_t xdr_u_longlong_t (XDR *__xdrs, u_quad_t *__ullp) __THROW;
+extern bool_t xdr_int8_t (XDR *__xdrs, int8_t *__ip) __THROW;
+extern bool_t xdr_uint8_t (XDR *__xdrs, uint8_t *__up) __THROW;
+extern bool_t xdr_int16_t (XDR *__xdrs, int16_t *__ip) __THROW;
+extern bool_t xdr_uint16_t (XDR *__xdrs, uint16_t *__up) __THROW;
+extern bool_t xdr_int32_t (XDR *__xdrs, int32_t *__ip) __THROW;
+extern bool_t xdr_uint32_t (XDR *__xdrs, uint32_t *__up) __THROW;
+extern bool_t xdr_int64_t (XDR *__xdrs, int64_t *__ip) __THROW;
+extern bool_t xdr_uint64_t (XDR *__xdrs, uint64_t *__up) __THROW;
+extern bool_t xdr_bool (XDR *__xdrs, bool_t *__bp) __THROW;
+libc_hidden_proto(xdr_bool)
+extern bool_t xdr_enum (XDR *__xdrs, enum_t *__ep) __THROW;
+libc_hidden_proto(xdr_enum)
+extern bool_t xdr_array (XDR * _xdrs, caddr_t *__addrp, u_int *__sizep,
+                        u_int __maxsize, u_int __elsize, xdrproc_t __elproc)
+     __THROW;
+libc_hidden_proto(xdr_array)
+extern bool_t xdr_bytes (XDR *__xdrs, char **__cpp, u_int *__sizep,
+                        u_int __maxsize) __THROW;
+libc_hidden_proto(xdr_bytes)
+extern bool_t xdr_opaque (XDR *__xdrs, caddr_t __cp, u_int __cnt) __THROW;
+libc_hidden_proto(xdr_opaque)
+extern bool_t xdr_string (XDR *__xdrs, char **__cpp, u_int __maxsize) __THROW;
+libc_hidden_proto(xdr_string)
+extern bool_t xdr_union (XDR *__xdrs, enum_t *__dscmp, char *__unp,
+                        __const struct xdr_discrim *__choices,
+                        xdrproc_t dfault) __THROW;
+libc_hidden_proto(xdr_union)
+extern bool_t xdr_char (XDR *__xdrs, char *__cp) __THROW;
+extern bool_t xdr_u_char (XDR *__xdrs, u_char *__cp) __THROW;
+extern bool_t xdr_vector (XDR *__xdrs, char *__basep, u_int __nelem,
+                         u_int __elemsize, xdrproc_t __xdr_elem) __THROW;
+extern bool_t xdr_float (XDR *__xdrs, float *__fp) __THROW;
+extern bool_t xdr_double (XDR *__xdrs, double *__dp) __THROW;
+extern bool_t xdr_reference (XDR *__xdrs, caddr_t *__xpp, u_int __size,
+                            xdrproc_t __proc) __THROW;
+libc_hidden_proto(xdr_reference)
+extern bool_t xdr_pointer (XDR *__xdrs, char **__objpp,
+                          u_int __obj_size, xdrproc_t __xdr_obj) __THROW;
+extern bool_t xdr_wrapstring (XDR *__xdrs, char **__cpp) __THROW;
+extern u_long xdr_sizeof (xdrproc_t, void *) __THROW;
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024
+struct netobj
+{
+  u_int n_len;
+  char *n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t xdr_netobj (XDR *__xdrs, struct netobj *__np) __THROW;
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+
+/* XDR using memory buffers */
+extern void xdrmem_create (XDR *__xdrs, __const caddr_t __addr,
+                          u_int __size, enum xdr_op __xop) __THROW;
+libc_hidden_proto(xdrmem_create)
+
+/* XDR using stdio library */
+extern void xdrstdio_create (XDR *__xdrs, FILE *__file, enum xdr_op __xop)
+     __THROW;
+
+/* XDR pseudo records for tcp */
+extern 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)) __THROW;
+libc_hidden_proto(xdrrec_create)
+
+/* make end of xdr record */
+extern bool_t xdrrec_endofrecord (XDR *__xdrs, bool_t __sendnow) __THROW;
+libc_hidden_proto(xdrrec_endofrecord)
+
+/* move to beginning of next record */
+extern bool_t xdrrec_skiprecord (XDR *__xdrs) __THROW;
+libc_hidden_proto(xdrrec_skiprecord)
+
+/* true if no more input */
+extern bool_t xdrrec_eof (XDR *__xdrs) __THROW;
+libc_hidden_proto(xdrrec_eof)
+
+/* free memory buffers for xdr */
+extern void xdr_free (xdrproc_t __proc, char *__objp) __THROW;
+
+__END_DECLS
+
+#endif /* rpc/xdr.h */
diff --git a/rpc_cmsg.c b/rpc_cmsg.c
new file mode 100644 (file)
index 0000000..a8c2573
--- /dev/null
@@ -0,0 +1,208 @@
+/* @(#)rpc_callmsg.c   2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#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 (XDR *xdrs, struct rpc_msg *cmsg)
+{
+  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 (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);
+               }
+             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));
+                  */
+               }
+           }
+         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;
+}
+libc_hidden_def(xdr_callmsg)
diff --git a/rpc_commondata.c b/rpc_commondata.c
new file mode 100644 (file)
index 0000000..187d915
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#include <rpc/rpc.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+
+#undef svc_fdset
+#undef rpc_createerr
+#undef svc_pollfd
+#undef svc_max_pollfd
+
+
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces
+ */
+struct opaque_auth _null_auth;
+fd_set svc_fdset;
+struct rpc_createerr rpc_createerr;
+struct pollfd *svc_pollfd;
+int svc_max_pollfd;
diff --git a/rpc_dtablesize.c b/rpc_dtablesize.c
new file mode 100644 (file)
index 0000000..692e8fc
--- /dev/null
@@ -0,0 +1,56 @@
+/* @(#)rpc_dtablesize.c        2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+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 <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)
+{
+  static int size;
+
+  if (size == 0)
+    size = getdtablesize ();
+
+  return size;
+}
+libc_hidden_def(_rpc_dtablesize)
diff --git a/rpc_private.h b/rpc_private.h
new file mode 100644 (file)
index 0000000..ede3ddf
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef _RPC_RPC_H
+#include <rpc/rpc.h>
+
+/* Now define the internal interfaces.  */
+extern u_long _create_xid (void) attribute_hidden;
+
+
+/*
+ * Multi-threaded support
+ * Group all global and static variables into a single spot.
+ * This area is allocated on a per-thread basis
+ */
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+struct rpc_thread_variables {
+       fd_set          svc_fdset_s;            /* Global, rpc_common.c */
+       struct rpc_createerr rpc_createerr_s;   /* Global, rpc_common.c */
+       struct pollfd   *svc_pollfd_s;          /* Global, rpc_common.c */
+       int             svc_max_pollfd_s;       /* Global, rpc_common.c */
+
+       void            *authnone_private_s;    /* auth_none.c */
+
+       void            *clnt_perr_buf_s;       /* clnt_perr.c */
+
+       void            *clntraw_private_s;     /* clnt_raw.c */
+
+       void            *callrpc_private_s;     /* clnt_simp.c */
+
+       void            *key_call_private_s;    /* key_call.c */
+
+       void            *authdes_cache_s;       /* svcauth_des.c */
+       void            *authdes_lru_s;         /* svcauth_des.c */
+
+       void            *svc_xports_s;          /* svc.c */
+       void            *svc_head_s;            /* svc.c */
+
+       void            *svcraw_private_s;      /* svc_raw.c */
+
+       void            *svcsimple_proglst_s;   /* svc_simple.c */
+       void            *svcsimple_transp_s;    /* svc_simple.c */
+};
+
+extern struct rpc_thread_variables *__rpc_thread_variables(void)
+     __attribute__ ((const)) attribute_hidden;
+extern void __rpc_thread_svc_cleanup (void) attribute_hidden;
+extern void __rpc_thread_clnt_cleanup (void) attribute_hidden;
+/*extern void __rpc_thread_key_cleanup (void) attribute_hidden;*/
+
+extern void __rpc_thread_destroy (void);
+
+#define RPC_THREAD_VARIABLE(x) (__rpc_thread_variables()->x)
+
+#endif /* __UCLIBC_HAS_THREADS__ */
+
+#endif
diff --git a/rpc_prot.c b/rpc_prot.c
new file mode 100644 (file)
index 0000000..bf55a3c
--- /dev/null
@@ -0,0 +1,285 @@
+/* @(#)rpc_prot.c      2.3 88/08/07 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if 0
+static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+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;
+}
+libc_hidden_def(xdr_opaque_auth)
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block (XDR *xdrs, des_block *blkp)
+{
+  return xdr_opaque (xdrs, (caddr_t) blkp, sizeof (des_block));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+bool_t
+xdr_accepted_reply (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:
+      return TRUE;
+    }
+  return TRUE;         /* TRUE => open ended set of problems */
+}
+libc_hidden_def(xdr_accepted_reply)
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+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));
+    }
+  return FALSE;
+}
+libc_hidden_def(xdr_rejected_reply)
+
+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 (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;
+}
+libc_hidden_def(xdr_replymsg)
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t
+xdr_callhdr (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;
+}
+libc_hidden_def(xdr_callhdr)
+
+/* ************************** Client utility routine ************* */
+
+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;
+    }
+  /* 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 (enum reject_stat rjct_stat,
+         struct rpc_err *error)
+{
+  switch (rjct_stat)
+    {
+    case RPC_MISMATCH:
+      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 (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:
+      break;
+    }
+}
+libc_hidden_def(_seterr_reply)
diff --git a/rpc_thread.c b/rpc_thread.c
new file mode 100644 (file)
index 0000000..71303b2
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include <stdio.h>
+#include <assert.h>
+#include "rpc_private.h"
+
+
+#ifdef __UCLIBC_HAS_THREADS__
+
+#include <bits/libc-tsd.h>
+#include <bits/libc-lock.h>
+
+/* Variable used in non-threaded applications or for the first thread.  */
+static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
+__libc_tsd_define (, RPC_VARS)
+
+/*
+ * Task-variable destructor
+ */
+void
+__rpc_thread_destroy (void)
+{
+       struct rpc_thread_variables *tvp = __libc_tsd_get (RPC_VARS);
+
+       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);
+               __libc_tsd_set (RPC_VARS, NULL);
+       }
+}
+
+/*
+ * 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 attribute_hidden *
+__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_get (RPC_VARS);
+               }
+       }
+       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
+
+#undef svc_fdset
+#undef rpc_createerr
+#undef svc_pollfd
+#undef svc_max_pollfd
+
+extern fd_set svc_fdset;
+fd_set * __rpc_thread_svc_fdset (void)
+{
+    return &(svc_fdset);
+}
+
+extern struct rpc_createerr rpc_createerr;
+struct rpc_createerr * __rpc_thread_createerr (void)
+{
+    return &(rpc_createerr);
+}
+
+extern struct pollfd *svc_pollfd;
+struct pollfd ** __rpc_thread_svc_pollfd (void)
+{
+    return &(svc_pollfd);
+}
+
+extern int svc_max_pollfd;
+int * __rpc_thread_svc_max_pollfd (void)
+{
+    return &(svc_max_pollfd);
+}
+
+#endif /* __UCLIBC_HAS_THREADS__ */
+
+libc_hidden_def(__rpc_thread_svc_fdset)
+libc_hidden_def(__rpc_thread_createerr)
+libc_hidden_def(__rpc_thread_svc_pollfd)
+libc_hidden_def(__rpc_thread_svc_max_pollfd)
diff --git a/rtime.c b/rtime.c
new file mode 100644 (file)
index 0000000..f9f1d9e
--- /dev/null
+++ b/rtime.c
@@ -0,0 +1,153 @@
+#if 0
+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;
+  /* RFC 868 says the time is transmitted as a 32-bit value.  */
+  uint32_t thetime;
+  struct sockaddr_in from;
+  socklen_t 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;
+}
+libc_hidden_def (rtime)
diff --git a/ruserpass.c b/ruserpass.c
new file mode 100644 (file)
index 0000000..0e4b74f
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 1985, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#define _(X)  (X)
+/* #include "ftp_var.h" */
+
+static int token (void);
+static FILE *cfile;
+
+#define        DEFAULT 1
+#define        LOGIN   2
+#define        PASSWD  3
+#define        ACCOUNT 4
+#define MACDEF  5
+#define        ID      10
+#define        MACHINE 11
+
+static&n