home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990, 1991, 1992 Stanford University
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name
- * Stanford may not be used in any advertising or publicity relating to
- * the software without the specific, prior written permission of
- * Stanford.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /* $Header: /Source/Media/drapeau/NetworkProtocol/RCS/rpcModifications.c,v 1.13 92/05/29 12:40:44 drapeau Exp $ */
- /* $Log: rpcModifications.c,v $
- * Revision 1.13 92/05/29 12:40:44 drapeau
- * Changed the name of the "Selection" structure to "MAESelection",
- * to avoid name conflicts with other software packages and toolkits
- * that might also define a "Selection" structure.
- *
- * Revision 1.12 91/06/17 18:17:26 drapeau
- * Added copyright notice.
- *
- * Revision 1.11 1991/02/28 07:19:24 drapeau
- * No code changes; this version uses a new version numbering scheme and a new
- * version of RCS.
- *
- * Revision 1.1 90/10/24 18:31:21 drapeau
- * Initial revision
- * */
-
- static char rpcModificationsRcsid[] = "$Header: /Source/Media/drapeau/NetworkProtocol/RCS/rpcModifications.c,v 1.13 92/05/29 12:40:44 drapeau Exp $";
-
- #include <stdio.h>
- #include <rpc/rpc.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <errno.h>
- #include <rpc/pmap_clnt.h>
-
- #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 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; /* Changed timeout to be a pointer to the timeval ... */
- { /* structure instead of the whole struct. */
- /* George D. Drapeau, 10/15/90 */
- register struct ct_data *ct = (struct ct_data *) h->cl_private;
- register XDR *xdrs = &(ct->ct_xdrs);
- struct rpc_msg reply_msg;
- u_long x_id;
- u_long *msg_x_id = (u_long *)(ct->ct_mcall); /* yuk */
- register bool_t shipnow;
- int refreshes = 2;
-
- if (!ct->ct_waitset)
- {
- ct->ct_wait.tv_sec = timeout->tv_sec;
- ct->ct_wait.tv_usec = timeout->tv_usec;
- }
- 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);
-
- if (timeout->tv_sec == 0 && timeout->tv_usec == 0) /* Hack to provide rpc-based message passing */
- {
- return(ct->ct_error.re_status = RPC_TIMEDOUT);
- }
- 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;
- }
- _seterr_reply(&reply_msg, &(ct->ct_error)); /* process header */
- 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;
- }
- if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) /* free verifier ... */
- {
- xdrs->x_op = XDR_FREE;
- (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
- }
- } /* end successful completion */
- else
- {
- if (refreshes-- && AUTH_REFRESH(h->cl_auth)) /* maybe our credentials need to be refreshed ... */
- goto call_again;
- } /* end of unsuccessful completion */
- return (ct->ct_error.re_status);
- } /* end function clnttcp_call */
-