home *** CD-ROM | disk | FTP | other *** search
- Date: Wed, 3 Apr 85 00:05:44 pst
- From: decvax!sun!pumpkinseed!blyon (Bob Lyon)
- Subject: Sun RPC part 7 of 10
-
- echo x - auth.h
- sed 's/^X//' >auth.h <<'!Funky!Stuff!'
- /*
- * 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 1.3 85/03/28 SMI */
-
- /*
- * 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".
- */
-
-
- #define MAX_AUTH_BYTES 400
-
-
- /*
- * 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_long high;
- u_long low;
- } key;
- char c[8];
- };
-
-
- /*
- * 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 {
- struct opaque_auth ah_cred;
- struct opaque_auth ah_verf;
- union des_block ah_key;
- struct auth_ops {
- void (*ah_nextverf)();
- int (*ah_marshal)(); /* nextverf & serialize */
- int (*ah_validate)(); /* validate varifier */
- int (*ah_refresh)(); /* refresh credentials */
- void (*ah_destroy)(); /* destroy this structure */
- } *ah_ops;
- caddr_t ah_private;
- } AUTH;
-
-
- /*
- * 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.
- */
-
- /*
- * Null authentication
- */
- extern AUTH *authnone_create(); /* takes no parameters */
- #define AUTH_NULL 0
-
- /*
- * 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();
- extern AUTH *authunix_create_default(); /* takes no parameters */
- #define AUTH_UNIX 1 /* unix style (uid, gids) */
- #define AUTH_SHORT 2 /* short hand unix style */
-
- !Funky!Stuff!
- echo x - auth_none.c
- sed 's/^X//' >auth_none.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)auth_none.c 1.4 85/03/17 Copyr 1984 Sun Micro";
- #endif
-
- /*
- * auth_none.c
- * Creates a client authentication handle for passing "null"
- * credentials and verifiers to remote systems.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
- #include "types.h"
- #include "xdr.h"
- #include "auth.h"
- #define NULL ((caddr_t)0)
- #define MAX_MARSHEL_SIZE 20
-
- /*
- * Authenticator operations routines
- */
- static void authnone_verf();
- static void authnone_destroy();
- static bool_t authnone_marshal();
- static bool_t authnone_validate();
- static bool_t authnone_refresh();
-
- static struct auth_ops ops = {
- authnone_verf,
- authnone_marshal,
- authnone_validate,
- authnone_refresh,
- authnone_destroy
- };
-
- static AUTH no_client;
- static char marshalled_client[MAX_MARSHEL_SIZE];
- static u_int mcnt = 0;
-
- AUTH *
- authnone_create()
- {
- XDR xdr_stream;
- register XDR *xdrs;
-
- if (! mcnt) {
- no_client.ah_cred = no_client.ah_verf = _null_auth;
- no_client.ah_ops = &ops;
- xdrs = &xdr_stream;
- xdrmem_create(xdrs, marshalled_client, (u_int)MAX_MARSHEL_SIZE,
- XDR_ENCODE);
- if ((! xdr_opaque_auth(xdrs, &no_client.ah_cred)) ||
- (! xdr_opaque_auth(xdrs, &no_client.ah_verf))) {
- } else {
- mcnt = XDR_GETPOS(xdrs);
- }
- XDR_DESTROY(xdrs);
- }
- return (&no_client);
- }
-
- static bool_t
- /* ARGSUSED */
- authnone_marshal(client, xdrs)
- AUTH *client;
- XDR *xdrs;
- {
-
- return ((*xdrs->x_ops->x_putbytes)(xdrs, marshalled_client, mcnt));
- }
-
- static void
- authnone_verf()
- {
- }
-
- static bool_t
- authnone_validate()
- {
-
- return (TRUE);
- }
-
- static bool_t
- authnone_refresh()
- {
-
- return (FALSE);
- }
-
- static void
- authnone_destroy()
- {
- }
- !Funky!Stuff!
- echo x - auth_unix.c
- sed 's/^X//' >auth_unix.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)auth_unix.c 1.5 85/03/17 Copyr 1984 Sun Micro";
- #endif
-
- /*
- * auth_unix.c, Implements UNIX style authentication parameters.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- *
- * 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.
- *
- */
-
- #include <stdio.h>
- #include "types.h"
- #include <sys/time.h>
- #include "xdr.h"
- #include "auth.h"
- #include "auth_unix.h"
- char *malloc();
-
- /*
- * Unix authenticator operations vector
- */
- static void authunix_nextverf();
- static bool_t authunix_marshal();
- static bool_t authunix_validate();
- static bool_t authunix_refresh();
- static void authunix_destroy();
-
- static 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();
-
-
- /*
- * Create a unix style authenticator.
- * Returns an auth handle with the given stuff in it.
- */
- AUTH *
- authunix_create(machname, uid, gid, len, aup_gids)
- char *machname;
- int uid;
- int gid;
- register int len;
- int *aup_gids;
- {
- struct authunix_parms aup;
- char mymem[MAX_AUTH_BYTES];
- struct timeval now;
- XDR xdrs;
- register AUTH *auth;
- register struct audata *au;
-
- /*
- * Allocate and set up auth handle
- */
- auth = (AUTH *)mem_alloc(sizeof(*auth));
- if (auth == NULL) {
- fprintf(stderr, "authunix_create: out of memory\n");
- return (NULL);
- }
- au = (struct audata *)mem_alloc(sizeof(*au));
- if (au == NULL) {
- fprintf(stderr, "authunix_create: out of memory\n");
- 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;
- if ((au->au_origcred.oa_base = mem_alloc(len)) == NULL) {
- fprintf(stderr, "authunix_create: out of memory\n");
- return (NULL);
- }
- bcopy(mymem, au->au_origcred.oa_base, (u_int)len);
-
- /*
- * set auth handle to reflect new cred.
- */
- auth->ah_cred = au->au_origcred;
- marshal_new_auth(auth);
- return (auth);
- }
-
- /*
- * Returns an auth handle with parameters determined by doing lots of
- * syscalls.
- */
- AUTH *
- authunix_create_default()
- {
- register int len;
- char machname[MAX_MACHINE_NAME + 1];
- register int uid;
- register int gid;
- int gids[NGRPS];
-
- if (gethostname(machname, MAX_MACHINE_NAME) == -1)
- abort();
- machname[MAX_MACHINE_NAME] = 0;
- uid = geteuid();
- gid = getegid();
- if ((len = getgroups(NGRPS, gids)) < 0)
- abort();
- return (authunix_create(machname, uid, gid, len, gids));
- }
-
- /*
- * authunix operations
- */
-
- static void
- authunix_nextverf(auth)
- AUTH *auth;
- {
- /* no action necessary */
- }
-
- static bool_t
- authunix_marshal(auth, xdrs)
- AUTH *auth;
- XDR *xdrs;
- {
- register struct audata *au = AUTH_PRIVATE(auth);
-
- return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
- }
-
- static bool_t
- authunix_validate(auth, verf)
- register AUTH *auth;
- struct opaque_auth verf;
- {
- register struct audata *au;
- XDR xdrs;
-
- if (verf.oa_flavor == AUTH_SHORT) {
- au = AUTH_PRIVATE(auth);
- xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
-
- if (au->au_shcred.oa_base != NULL) {
- mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
- au->au_shcred.oa_base = NULL;
- }
- if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
- auth->ah_cred = au->au_shcred;
- } else {
- xdrs.x_op = XDR_FREE;
- (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
- au->au_shcred.oa_base = NULL;
- auth->ah_cred = au->au_origcred;
- }
- marshal_new_auth(auth);
- }
- return (TRUE);
- }
-
- static bool_t
- authunix_refresh(auth)
- register AUTH *auth;
- {
- register struct audata *au = AUTH_PRIVATE(auth);
- struct authunix_parms aup;
- struct timeval now;
- XDR xdrs;
- register int stat;
-
- if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
- /* there is no hope. Punt */
- return (FALSE);
- }
- au->au_shfaults ++;
-
- /* first deserialize the creds back into a struct authunix_parms */
- aup.aup_machname = NULL;
- aup.aup_gids = (int *)NULL;
- xdrmem_create(&xdrs, au->au_origcred.oa_base,
- au->au_origcred.oa_length, XDR_DECODE);
- stat = xdr_authunix_parms(&xdrs, &aup);
- if (! stat)
- goto done;
-
- /* update the time and serialize in place */
- (void)gettimeofday(&now, (struct timezone *)0);
- aup.aup_time = now.tv_sec;
- xdrs.x_op = XDR_ENCODE;
- XDR_SETPOS(&xdrs, 0);
- stat = xdr_authunix_parms(&xdrs, &aup);
- if (! stat)
- goto done;
- auth->ah_cred = au->au_origcred;
- marshal_new_auth(auth);
- done:
- /* free the struct authunix_parms created by deserializing */
- xdrs.x_op = XDR_FREE;
- (void)xdr_authunix_parms(&xdrs, &aup);
- XDR_DESTROY(&xdrs);
- return (stat);
- }
-
- static void
- authunix_destroy(auth)
- register AUTH *auth;
- {
- register 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
- marshal_new_auth(auth)
- register AUTH *auth;
- {
- XDR xdr_stream;
- register XDR *xdrs = &xdr_stream;
- register struct audata *au = AUTH_PRIVATE(auth);
-
- xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
- if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
- (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
- } else {
- au->au_mpos = XDR_GETPOS(xdrs);
- }
- XDR_DESTROY(xdrs);
- }
- !Funky!Stuff!
- echo x - auth_unix.h
- sed 's/^X//' >auth_unix.h <<'!Funky!Stuff!'
- /*
- * 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.1 84/12/20 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.
- */
-
- /* 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 10 of them */
- #define NGRPS 8
-
- /*
- * Unix style credentials.
- */
- struct authunix_parms {
- u_long aup_time;
- char *aup_machname;
- int aup_uid;
- int aup_gid;
- u_int aup_len;
- int *aup_gids;
- };
-
- extern bool_t 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;
- };
- !Funky!Stuff!
- echo x - authunix_prot.c
- sed 's/^X//' >authunix_prot.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)authunix_prot.c 1.3 85/03/12 Copyr 1984 Sun Micro";
- #endif
-
- /*
- * authunix_prot.c
- * XDR for UNIX style authentication parameters for RPC
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
- #include "types.h"
- #include "xdr.h"
- #include "auth.h"
- #include "auth_unix.h"
-
- /*
- * XDR for unix authentication parameters.
- */
- bool_t
- xdr_authunix_parms(xdrs, p)
- register XDR *xdrs;
- register struct authunix_parms *p;
- {
- int i;
-
- if (xdr_u_long(xdrs, &(p->aup_time))
- && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
- && xdr_int(xdrs, &(p->aup_uid))
- && xdr_int(xdrs, &(p->aup_gid))
- && xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
- &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) {
- return (TRUE);
- }
- return (FALSE);
- }
-
- !Funky!Stuff!
- echo x - clnt.h
- sed 's/^X//' >clnt.h <<'!Funky!Stuff!'
- /*
- * 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 1.3 85/03/20 SMI */
-
- /*
- * clnt.h - Client side remote procedure call interface.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
- /*
- * 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" */
-
- /*
- * callrpc errors
- */
- RPC_UNKNOWNHOST=13, /* unknown host name */
-
- /*
- * _ create errors
- */
- RPC_PMAPFAILURE=14, /* the pmapper failed in its call */
- RPC_PROGNOTREGISTERED=15, /* remote program is not registered */
- /*
- * unspecified error
- */
- RPC_FAILED=16
- };
-
-
- /*
- * Error info.
- */
- struct rpc_err {
- enum clnt_stat re_status;
- union {
- int RE_errno; /* realated 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 {
- AUTH *cl_auth; /* authenticator */
- struct clnt_ops {
- enum clnt_stat (*cl_call)(); /* call remote procedure */
- void (*cl_abort)(); /* abort a call */
- void (*cl_geterr)(); /* get specific error code */
- bool_t (*cl_freeres)(); /* frees results */
- void (*cl_destroy)();/* destroy this structure */
- } *cl_ops;
- caddr_t cl_private; /* private stuff */
- } CLIENT;
-
-
- /*
- * 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))
-
- /*
- * 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 accessable 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();
-
- /*
- * UDP based rpc.
- * CLIENT *
- * clntudp_create(raddr, program, version, wait, sockp)
- * struct sockaddr_in *raddr;
- * u_long program;
- * u_long version;
- * struct timeval wait;
- * int *sockp;
- */
- extern CLIENT *clntudp_create();
- #define UDPMSGSIZE 8800
-
- /*
- * 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();
-
-
- /*
- * 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;
-
- !Funky!Stuff!
- echo x - clnt_perror.c
- sed 's/^X//' >clnt_perror.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)clnt_perror.c 1.1 85/02/08 Copyr 1984 Sun Micro";
- #endif
-
- /*
- * clnt_perror.c
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- *
- */
- #include "types.h"
- #include "xdr.h"
- #include "auth.h"
- #include "clnt.h"
- #include "rpc_msg.h"
- #include <stdio.h>
- extern char *sys_errlist[];
-
- /*
- * Print reply error info
- */
- void
- clnt_perror(rpch, s)
- CLIENT *rpch;
- char *s;
- {
- struct rpc_err e;
- void clnt_perrno();
-
- CLNT_GETERR(rpch, &e);
- fprintf(stderr, "%s: ", s);
- 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:
- clnt_perrno(e.re_status);
- break;
- case RPC_CANTSEND:
- clnt_perrno(e.re_status);
- fprintf(stderr, "; errno = %s",
- sys_errlist[e.re_errno]);
- break;
-
- case RPC_CANTRECV:
- clnt_perrno(e.re_status);
- fprintf(stderr, "; errno = %s",
- sys_errlist[e.re_errno]);
- break;
-
- case RPC_VERSMISMATCH:
- clnt_perrno(e.re_status);
- fprintf(stderr, "; low version = %lu, high version = %lu", e.re_vers.low, e.re_vers.high);
- break;
-
- case RPC_AUTHERROR:
- clnt_perrno(e.re_status);
- fprintf(stderr, "; why = ");
- switch (e.re_why) {
- case AUTH_OK:
- fprintf(stderr, "AUTH_OK");
- break;
-
- case AUTH_BADCRED:
- fprintf(stderr, "AUTH_BOGUS_CREDENTIAL");
- break;
-
- case AUTH_REJECTEDCRED:
- fprintf(stderr, "AUTH_REJECTED_CREDENTIAL");
- break;
-
- case AUTH_BADVERF:
- fprintf(stderr, "AUTH_BOGUS_VERIFIER");
- break;
-
- case AUTH_REJECTEDVERF:
- fprintf(stderr, "AUTH_REJECTED_VERIFIER");
- break;
-
- case AUTH_TOOWEAK:
- fprintf(stderr, "AUTH_TOO_WEAK (remote error)");
- break;
-
- case AUTH_INVALIDRESP:
- fprintf(stderr, "AUTH_INVALID_RESPONSE");
- break;
-
- default:
- fprintf(stderr, "AUTH_UNKNOWN_FAILURE");
- break;
- }
- break;
-
- case RPC_PROGVERSMISMATCH:
- clnt_perrno(e.re_status);
- fprintf(stderr, "; low version = %lu, high version = %lu", e.re_vers.low, e.re_vers.high);
- break;
-
- default:
- fprintf(stderr, "RPC_UNKNOWN_FAILURE; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2);
- break;
- }
- fprintf(stderr, "\n");
- }
-
- /*
- * This interface for use by clntrpc
- */
- void
- clnt_perrno(num)
- enum clnt_stat num;
- {
- switch (num) {
- case RPC_SUCCESS:
- fprintf(stderr, "RPC_SUCCESS");
- break;
-
- case RPC_CANTENCODEARGS:
- fprintf(stderr, "RPC_CANT_ENCODE_ARGS");
- break;
-
- case RPC_CANTDECODERES:
- fprintf(stderr, "RPC_CANT_DECODE_RESULTS");
- break;
-
- case RPC_CANTSEND:
- fprintf(stderr, "RPC_CANT_SEND");
- break;
-
- case RPC_CANTRECV:
- fprintf(stderr, "RPC_CANT_RECV");
- break;
-
- case RPC_TIMEDOUT:
- fprintf(stderr, "RPC_TIMED_OUT");
- break;
-
- case RPC_VERSMISMATCH:
- fprintf(stderr, "RPC_VERSION_MISMATCH");
- break;
-
- case RPC_AUTHERROR:
- fprintf(stderr, "RPC_AUTH_ERROR");
- break;
-
- case RPC_PROGUNAVAIL:
- fprintf(stderr, "RPC_REMOTE_PROGRAM_UNAVAILABLE");
- break;
-
- case RPC_PROGVERSMISMATCH:
- fprintf(stderr, "RPC_PROGRAM_MISMATCH");
- break;
-
- case RPC_PROCUNAVAIL:
- fprintf(stderr, "RPC_UNKNOWN_PROCEDURE");
- break;
-
- case RPC_CANTDECODEARGS:
- fprintf(stderr, "RPC_CANT_DECODE_ARGS");
- break;
- case RPC_UNKNOWNHOST:
- fprintf(stderr, "RPC_UNKNOWNHOST");
- break;
- case RPC_PMAPFAILURE:
- fprintf(stderr, "RPC_PMAP_FAILURE");
- break;
- case RPC_PROGNOTREGISTERED:
- fprintf(stderr, "RPC_PROG_NOT_REGISTERED");
- break;
- case RPC_SYSTEMERROR:
- fprintf(stderr, "RPC_SYSTEM_ERROR");
- break;
- }
- }
-
- /*
- * A handle on why an rpc creation routine failed (returned NULL.)
- */
- struct rpc_createerr rpc_createerr;
-
- clnt_pcreateerror(s)
- char *s;
- {
-
- fprintf(stderr, "%s: ", s);
- clnt_perrno(rpc_createerr.cf_stat);
- switch (rpc_createerr.cf_stat) {
- case RPC_PMAPFAILURE:
- fprintf(stderr, " - ");
- clnt_perrno(rpc_createerr.cf_error.re_status);
- break;
-
- case RPC_SYSTEMERROR:
- fprintf(stderr, " - %s", sys_errlist[rpc_createerr.cf_error.re_errno]);
- break;
-
- }
- fprintf(stderr, "\n");
- }
- !Funky!Stuff!
- echo x - clnt_raw.c
- sed 's/^X//' >clnt_raw.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)clnt_raw.c 1.4 85/03/17 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 similate rpc and get round trip overhead, without
- * any interference from the kernal.
- */
-
- #include "types.h"
- #include <sys/time.h>
- #include <netinet/in.h>
- #include "xdr.h"
- #include "auth.h"
- #include "clnt.h"
- #include "rpc_msg.h"
-
- #define NULL ((caddr_t)0)
- #define MCALL_MSG_SIZE 24
-
- /*
- * This is the "network" we will be moving stuff over.
- */
- char _raw_buf[UDPMSGSIZE];
-
- static char mashl_callmsg[MCALL_MSG_SIZE];
- static u_int mcnt;
-
- static enum clnt_stat clntraw_call();
- static void clntraw_abort();
- static void clntraw_geterr();
- static bool_t clntraw_freeres();
- static void clntraw_destroy();
-
- static struct clnt_ops client_ops = {
- clntraw_call,
- clntraw_abort,
- clntraw_geterr,
- clntraw_freeres,
- clntraw_destroy
- };
-
- static CLIENT client_object;
- static CLIENT *client = &client_object;
- static XDR xdr_stream;
-
- void svc_getreq();
-
- /*
- * Create a client handle for memory based rpc.
- */
- CLIENT *
- clntraw_create(prog, vers)
- u_long prog;
- u_long vers;
- {
- struct rpc_msg call_msg;
- XDR *xdrs = &xdr_stream;
-
- /*
- * pre-serialize the staic part of the call msg and stash it away
- */
- call_msg.rm_direction = CALL;
- call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
- call_msg.rm_call.cb_prog = prog;
- call_msg.rm_call.cb_vers = vers;
- xdrmem_create(xdrs, mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
- if (! xdr_callhdr(xdrs, &call_msg)) {
- perror("clnt_raw.c - Fatal header serialization error.");
- }
- mcnt = XDR_GETPOS(xdrs);
- XDR_DESTROY(xdrs);
-
- /*
- * Set xdrmem for client/server shared buffer
- */
- xdrmem_create(xdrs, _raw_buf, UDPMSGSIZE, XDR_FREE);
-
- /*
- * create client handle
- */
- client->cl_ops = &client_ops;
- client->cl_auth = authnone_create();
- return (client);
- }
-
- static enum clnt_stat
- clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
- CLIENT *h;
- u_long proc;
- xdrproc_t xargs;
- caddr_t argsp;
- xdrproc_t xresults;
- caddr_t resultsp;
- struct timeval timeout;
- {
- register XDR *xdrs = &xdr_stream;
- struct rpc_msg msg;
- enum clnt_stat status;
- struct rpc_err error;
-
- call_again:
- /*
- * send request
- */
- xdrs->x_op = XDR_ENCODE;
- XDR_SETPOS(xdrs, 0);
- ((struct rpc_msg *)mashl_callmsg)->rm_xid ++ ;
- if ((! XDR_PUTBYTES(xdrs, mashl_callmsg, 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()
- {
- }
-
-
- static bool_t
- clntraw_freeres(cl, xdr_res, res_ptr)
- CLIENT *cl;
- xdrproc_t xdr_res;
- caddr_t res_ptr;
- {
- register XDR *xdrs = &xdr_stream;
-
- xdrs->x_op = XDR_FREE;
- return ((*xdr_res)(xdrs, res_ptr));
- }
-
- static void
- clntraw_abort()
- {
- }
-
- static void
- clntraw_destroy()
- {
- }
- !Funky!Stuff!
- echo x - clnt_simple.c
- sed 's/^X//' >clnt_simple.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)clnt_simple.c 1.1 84/12/20 Copyr 1984 Sun Micro";
- #endif
-
- /*
- * clnt_simple.c
- * Simplified front end to rpc.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
- #include <stdio.h>
- #include <rpc/rpc.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netdb.h>
-
- callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
- char *host;
- xdrproc_t inproc, outproc;
- char *in, *out;
- {
- struct sockaddr_in server_addr;
- enum clnt_stat clnt_stat;
- struct hostent *hp;
- struct timeval timeout, tottimeout;
-
- static CLIENT *client;
- static int socket = RPC_ANYSOCK;
- static int oldprognum, oldversnum, valid;
- static char oldhost[256];
-
- if (valid && oldprognum == prognum && oldversnum == versnum
- && strcmp(oldhost, host) == 0) {
- /* reuse old client */
- }
- else {
- close(socket);
- socket = RPC_ANYSOCK;
- if (client) {
- clnt_destroy(client);
- client = NULL;
- }
- if ((hp = gethostbyname(host)) == NULL)
- return ((int) RPC_UNKNOWNHOST);
- timeout.tv_usec = 0;
- timeout.tv_sec = 10;
- bcopy(hp->h_addr, &server_addr.sin_addr, hp->h_length);
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = 0;
- if ((client = clntudp_create(&server_addr, prognum,
- versnum, timeout, &socket)) == NULL)
- return ((int) rpc_createerr.cf_stat);
- valid = 1;
- oldprognum = prognum;
- oldversnum = versnum;
- strcpy(oldhost, host);
- }
- tottimeout.tv_sec = 25;
- tottimeout.tv_usec = 0;
- clnt_stat = clnt_call(client, procnum, inproc, in,
- outproc, out, tottimeout);
- /*
- * if call failed, empty cache
- */
- if (clnt_stat != RPC_SUCCESS)
- valid = 0;
- return ((int) clnt_stat);
- }
- !Funky!Stuff!
- echo x - clnt_tcp.c
- sed 's/^X//' >clnt_tcp.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)clnt_tcp.c 1.5 85/03/17 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 iff 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.
- */
-
- #include <stdio.h>
- #include "types.h"
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <errno.h>
- #include "xdr.h"
- #include "auth.h"
- #include "clnt.h"
- #include "rpc_msg.h"
- #include "pmap_clnt.h"
-
- #define MCALL_MSG_SIZE 24
-
- char *malloc();
- extern int errno;
- long random();
-
- static int readtcp();
- static int writetcp();
-
- static enum clnt_stat clnttcp_call();
- static void clnttcp_abort();
- static void clnttcp_geterr();
- static bool_t clnttcp_freeres();
- static void clnttcp_destroy();
-
- static struct clnt_ops tcp_ops = {
- clnttcp_call,
- clnttcp_abort,
- clnttcp_geterr,
- clnttcp_freeres,
- clnttcp_destroy
- };
-
- struct ct_data {
- int ct_sock;
- struct timeval ct_wait;
- struct rpc_err ct_error;
- char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
- u_int ct_mpos; /* pos after marshal */
- XDR ct_xdrs;
- };
-
- /*
- * 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(raddr, prog, vers, sockp, sendsz, recvsz)
- struct sockaddr_in *raddr;
- u_long prog;
- u_long vers;
- register int *sockp;
- u_int sendsz;
- u_int recvsz;
- {
- CLIENT *h;
- register struct ct_data *ct;
- struct timeval now;
- struct rpc_msg call_msg;
-
- h = (CLIENT *)mem_alloc(sizeof(*h));
- if (h == NULL) {
- fprintf(stderr, "clnttcp_create: out of memory\n");
- rpc_createerr.cf_stat = RPC_SYSTEMERROR;
- rpc_createerr.cf_error.re_errno = errno;
- goto fooy;
- }
- ct = (struct ct_data *)mem_alloc(sizeof(*ct));
- if (ct == NULL) {
- fprintf(stderr, "clnttcp_create: out of memory\n");
- rpc_createerr.cf_stat = RPC_SYSTEMERROR;
- rpc_createerr.cf_error.re_errno = errno;
- 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) {
- if (((*sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
- || (connect(*sockp, (struct sockaddr *)raddr,
- sizeof(*raddr)) < 0)) {
- rpc_createerr.cf_stat = RPC_SYSTEMERROR;
- rpc_createerr.cf_error.re_errno = errno;
- goto fooy;
- }
- }
-
- /*
- * Set up private data struct
- */
- ct->ct_sock = *sockp;
- ct->ct_wait.tv_usec = 0;
-
- /*
- * Initialize call message
- */
- (void)gettimeofday(&now, (struct timezone *)0);
- call_msg.rm_xid = getpid() ^ (int)random() ^ now.tv_sec ^ now.tv_usec;
- call_msg.rm_direction = CALL;
- call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
- call_msg.rm_call.cb_prog = prog;
- call_msg.rm_call.cb_vers = vers;
-
- /*
- * pre-serialize the staic part of the call msg and stash it away
- */
- xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
- XDR_ENCODE);
- if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
- 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));
- (void)close(*sockp);
- return ((CLIENT *)NULL);
- }
-
- static enum clnt_stat
- clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
- register CLIENT *h;
- u_long proc;
- xdrproc_t xdr_args;
- caddr_t args_ptr;
- xdrproc_t xdr_results;
- caddr_t results_ptr;
- struct timeval timeout;
- {
- register struct ct_data *ct = (struct ct_data *) h->cl_private;
- register XDR *xdrs = &(ct->ct_xdrs);
- struct rpc_msg reply_msg;
- u_long x_id;
- u_long *msg_x_id = (u_long *)(ct->ct_mcall); /* yuk */
- register bool_t shipnow;
-
- ct->ct_wait = timeout;
- shipnow =
- (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
- && timeout.tv_usec == 0) ? FALSE : TRUE;
-
- call_again:
- xdrs->x_op = XDR_ENCODE;
- ct->ct_error.re_status = RPC_SUCCESS;
- x_id = ntohl(--(*msg_x_id));
- if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
- (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
- (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
- (! (*xdr_args)(xdrs, args_ptr))) {
- if (ct->ct_error.re_status == RPC_SUCCESS)
- ct->ct_error.re_status = RPC_CANTENCODEARGS;
- (void)xdrrec_endofrecord(xdrs, TRUE);
- return (ct->ct_error.re_status);
- }
- if (! xdrrec_endofrecord(xdrs, shipnow))
- return (ct->ct_error.re_status = RPC_CANTSEND);
- if (! shipnow)
- return (RPC_SUCCESS);
- xdrs->x_op = XDR_DECODE;
-
- /*
- * Keep receiving until we get a valid transaction id
- */
- 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 = 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 (AUTH_REFRESH(h->cl_auth))
- goto call_again;
- } /* end of unsuccessful completion */
- return (ct->ct_error.re_status);
- }
-
- static void
- clnttcp_geterr(h, errp)
- CLIENT *h;
- struct rpc_err *errp;
- {
- register struct ct_data *ct =
- (struct ct_data *) h->cl_private;
-
- *errp = ct->ct_error;
- }
-
- static bool_t
- clnttcp_freeres(cl, xdr_res, res_ptr)
- CLIENT *cl;
- xdrproc_t xdr_res;
- caddr_t res_ptr;
- {
- register struct ct_data *ct = (struct ct_data *)cl->cl_private;
- register XDR *xdrs = &(ct->ct_xdrs);
-
- xdrs->x_op = XDR_FREE;
- return ((*xdr_res)(xdrs, res_ptr));
- }
-
- static void
- clnttcp_abort()
- {
- }
-
- static void
- clnttcp_destroy(h)
- CLIENT *h;
- {
- register struct ct_data *ct =
- (struct ct_data *) h->cl_private;
-
- 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(ct, buf, len)
- register struct ct_data *ct;
- caddr_t buf;
- register int len;
- {
- register int mask = 1 << (ct->ct_sock);
- int readfds;
-
- while (TRUE) {
- readfds = mask;
- switch (select(32, &readfds, (int*)NULL, (int*)NULL,
- &(ct->ct_wait))) {
-
- case 0:
- ct->ct_error.re_status = RPC_TIMEDOUT;
- return (-1);
-
- case -1:
- if (errno == EINTR)
- continue;
- ct->ct_error.re_status = RPC_CANTRECV;
- ct->ct_error.re_errno = errno;
- return (-1);
- }
- if (readfds == mask)
- break;
- }
- if ((len = read(ct->ct_sock, buf, len)) == -1) {
- ct->ct_error.re_errno = errno;
- ct->ct_error.re_status = RPC_CANTRECV;
- }
- return (len);
- }
-
- static int
- writetcp(ct, buf, len)
- struct ct_data *ct;
- caddr_t buf;
- int len;
- {
- register int i, cnt;
-
- for (cnt = len; cnt > 0; cnt -= i, buf += i) {
- if ((i = write(ct->ct_sock, buf, cnt)) == -1) {
- ct->ct_error.re_errno = errno;
- ct->ct_error.re_status = RPC_CANTSEND;
- return (-1);
- }
- }
- return (len);
- }
- !Funky!Stuff!
- echo x - clnt_udp.c
- sed 's/^X//' >clnt_udp.c <<'!Funky!Stuff!'
- /*
- * 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 lint
- static char sccsid[] = "@(#)clnt_udp.c 1.5 85/03/17 Copyr 1984 Sun Micro";
- #endif
-
- /*
- * clnt_udp.c, Implements a UPD/IP based, client side RPC.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
- #include <stdio.h>
- #include "types.h"
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <errno.h>
- #include "xdr.h"
- #include "auth.h"
- #include "clnt.h"
- #include "rpc_msg.h"
- #include "pmap_clnt.h"
-
- char *malloc();
- extern int errno;
- long random();
-
- /*
- * UDP bases client side rpc operations
- */
- static enum clnt_stat clntudp_call();
- static void clntudp_abort();
- static void clntudp_geterr();
- static bool_t clntudp_freeres();
- static void clntudp_destroy();
-
- static struct clnt_ops udp_ops = {
- clntudp_call,
- clntudp_abort,
- clntudp_geterr,
- clntudp_freeres,
- clntudp_destroy
- };
-
- /*
- * Private data kept per client handle
- */
- struct cu_data {
- int cu_sock;
- struct sockaddr_in cu_raddr;
- int cu_rlen;
- struct timeval cu_wait;
- struct rpc_err cu_error;
- XDR cu_outxdrs;
- u_int cu_xdrpos;
- char cu_outbuf[UDPMSGSIZE];
- char cu_inbuf[UDPMSGSIZE];
- };
-
- /*
- * 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; retransmition occurs until the actual
- * rpc call times out.
- */
- CLIENT *
- clntudp_create(raddr, program, version, wait, sockp)
- struct sockaddr_in *raddr;
- u_long program;
- u_long version;
- struct timeval wait;
- register int *sockp;
- {
- CLIENT *cl;
- register struct cu_data *cu;
- struct timeval now;
- struct rpc_msg call_msg;
-
- cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
- if (cl == NULL) {
- fprintf(stderr, "clntudp_create: out of memory\n");
- rpc_createerr.cf_stat = RPC_SYSTEMERROR;
- rpc_createerr.cf_error.re_errno = errno;
- goto fooy;
- }
- cu = (struct cu_data *)mem_alloc(sizeof(*cu));
- if (cu == NULL) {
- fprintf(stderr, "clntudp_create: out of memory\n");
- rpc_createerr.cf_stat = RPC_SYSTEMERROR;
- rpc_createerr.cf_error.re_errno = errno;
- goto fooy;
- }
-
- (void)gettimeofday(&now, (struct timezone *)0);
- if (raddr->sin_port == 0) {
- u_short port;
- if ((port =
- pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
- goto fooy;
- }
- raddr->sin_port = htons(port);
- }
- cl->cl_ops = &udp_ops;
- cl->cl_private = (caddr_t)cu;
- cu->cu_raddr = *raddr;
- cu->cu_rlen = sizeof (cu->cu_raddr);
- cu->cu_wait = wait;
- call_msg.rm_xid = getpid() ^ (int)random() ^ now.tv_sec ^ now.tv_usec;
- call_msg.rm_direction = CALL;
- call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
- call_msg.rm_call.cb_prog = program;
- call_msg.rm_call.cb_vers = version;
- xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
- UDPMSGSIZE, XDR_ENCODE);
- if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
- goto fooy;
- }
- cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
- cu->cu_sock = (*sockp < 0) ?
- (*sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) :
- *sockp;
- if (cu->cu_sock < 0) {
- rpc_createerr.cf_stat = RPC_SYSTEMERROR;
- rpc_createerr.cf_error.re_errno = errno;
- goto fooy;
- }
- cl->cl_auth = authnone_create();
- return (cl);
- fooy:
- mem_free((caddr_t)cu, sizeof(*cu));
- mem_free((caddr_t)cl, sizeof(CLIENT));
- return ((CLIENT *)NULL);
- }
-
- static enum clnt_stat
- clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, timeout)
- register CLIENT *cl; /* client handle */
- u_long proc; /* procedure number */
- xdrproc_t xargs; /* xdr routine for args */
- caddr_t argsp; /* pointer to args */
- xdrproc_t xresults; /* xdr routine for results */
- caddr_t resultsp; /* pointer to results */
- struct timeval timeout; /* seconds to wait before giving up */
- {
- register struct cu_data *cu = (struct cu_data *)cl->cl_private;
- register XDR *xdrs;
- register int outlen;
- register int inlen;
- int readfds, fromlen;
- register int mask;
- struct sockaddr_in from;
- struct rpc_msg reply_msg;
- XDR reply_xdrs;
- struct timeval time_waited;
- bool_t ok;
-
- call_again:
- time_waited.tv_sec = 0;
- time_waited.tv_usec = 0;
- xdrs = &(cu->cu_outxdrs);
- xdrs->x_op = XDR_ENCODE;
- XDR_SETPOS(xdrs, cu->cu_xdrpos);
- /*
- * the transaction is the first thing in the out buffer
- */
- (*(u_short *)(cu->cu_outbuf))++;
- if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
- (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
- (! (*xargs)(xdrs, argsp)))
- return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
- outlen = (int)XDR_GETPOS(xdrs);
- while (TRUE) {
-
- 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);
- }
- /*
- * sub-optimal code appears inside the loop 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;
- mask = 1 << cu->cu_sock;
- rcv_again:
- readfds = mask;
- switch (select(32, &readfds, (int *)NULL, (int *)NULL,
- &(cu->cu_wait))) {
-
- case 0:
- time_waited.tv_sec += cu->cu_wait.tv_sec;
- time_waited.tv_usec += cu->cu_wait.tv_usec;
- while (time_waited.tv_usec >= 1000000) {
- time_waited.tv_sec++;
- time_waited.tv_usec -= 1000000;
- }
- if ((time_waited.tv_sec < timeout.tv_sec) ||
- ((time_waited.tv_sec == timeout.tv_sec) &&
- (time_waited.tv_usec < timeout.tv_usec)))
- continue;
- return (cu->cu_error.re_status = RPC_TIMEDOUT);
-
- case -1:
- if (errno == EINTR)
- goto rcv_again;
- cu->cu_error.re_errno = errno;
- return (cu->cu_error.re_status = RPC_CANTRECV);
- }
- if ((readfds & mask) == 0)
- goto rcv_again;
- tryagain:
- fromlen = sizeof(struct sockaddr);
- inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, UDPMSGSIZE, 0,
- (struct sockaddr *)&from, &fromlen);
- if (inlen < 0) {
- if (errno == EINTR)
- goto tryagain;
- cu->cu_error.re_errno = errno;
- return (cu->cu_error.re_status = RPC_CANTRECV);
- }
- if (inlen < sizeof(u_long))
- goto rcv_again;
- /* see if reply transaction id matches sent id */
- if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf)))
- goto rcv_again;
- /* 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 (AUTH_REFRESH(cl->cl_auth))
- goto call_again;
- } /* end of unsuccessful completion */
- } /* end of valid reply message */
- else {
- cu->cu_error.re_status = RPC_CANTDECODERES;
- }
- return (cu->cu_error.re_status);
- }
-
- static void
- clntudp_geterr(cl, errp)
- CLIENT *cl;
- struct rpc_err *errp;
- {
- register struct cu_data *cu = (struct cu_data *)cl->cl_private;
-
- *errp = cu->cu_error;
- }
-
-
- static bool_t
- clntudp_freeres(cl, xdr_res, res_ptr)
- CLIENT *cl;
- xdrproc_t xdr_res;
- caddr_t res_ptr;
- {
- register struct cu_data *cu = (struct cu_data *)cl->cl_private;
- register XDR *xdrs = &(cu->cu_outxdrs);
-
- xdrs->x_op = XDR_FREE;
- return ((*xdr_res)(xdrs, res_ptr));
- }
-
- static void
- clntudp_abort(/*h*/)
- /*CLIENT *h;*/
- {
- }
-
- static void
- clntudp_destroy(cl)
- CLIENT *cl;
- {
- register struct cu_data *cu = (struct cu_data *)cl->cl_private;
-
- XDR_DESTROY(&(cu->cu_outxdrs));
- mem_free((caddr_t)cu, sizeof(*cu));
- mem_free((caddr_t)cl, sizeof(CLIENT));
- }
- !Funky!Stuff!
-
- exit
-