--- /dev/null
+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
+)
--- /dev/null
+/*
+ * 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)
+{
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/* @(#)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);
+}
--- /dev/null
+/* @(#)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)
+{
+}
--- /dev/null
+/* @(#)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__ */
--- /dev/null
+/* @(#)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;
+}
--- /dev/null
+/* @(#)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));
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/* @(#)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);
+}
--- /dev/null
+/* @(#)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__ */
--- /dev/null
+/* @(#)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);
+}
--- /dev/null
+/* @(#)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;
+}
--- /dev/null
+/* @(#)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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/* @(#)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, ®s->pm_prog) &&
+ xdr_u_long (xdrs, ®s->pm_vers) &&
+ xdr_u_long (xdrs, ®s->pm_prot))
+ return xdr_u_long (xdrs, ®s->pm_port);
+ return FALSE;
+}
+libc_hidden_def(xdr_pmap)
--- /dev/null
+/* @(#)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)
--- /dev/null
+/* @(#)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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/*
+ * @(#)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
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/* @(#)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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/* @(#)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)
--- /dev/null
+/*
+ * 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;
--- /dev/null
+/* @(#)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)
--- /dev/null
+#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
--- /dev/null
+/* @(#)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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+#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)
--- /dev/null
+/*
+ * 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 &n