initial import
[platform/upstream/glibc.git] / sunrpc / clnt_raw.c
1 /* @(#)clnt_raw.c       2.2 88/08/01 4.0 RPCSRC */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  * 
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  * 
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  * 
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  * 
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30 #if !defined(lint) && defined(SCCSIDS)
31 static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
32 #endif
33
34 /*
35  * clnt_raw.c
36  *
37  * Copyright (C) 1984, Sun Microsystems, Inc.
38  *
39  * Memory based rpc for simple testing and timing.
40  * Interface to create an rpc client and server in the same process.
41  * This lets us similate rpc and get round trip overhead, without
42  * any interference from the kernal.
43  */
44
45 #include <rpc/rpc.h>
46
47 #define MCALL_MSG_SIZE 24
48
49 /*
50  * This is the "network" we will be moving stuff over.
51  */
52 static struct clntraw_private {
53         CLIENT  client_object;
54         XDR     xdr_stream;
55         char    _raw_buf[UDPMSGSIZE];
56         char    mashl_callmsg[MCALL_MSG_SIZE];
57         u_int   mcnt;
58 } *clntraw_private;
59
60 static enum clnt_stat   clntraw_call();
61 static void             clntraw_abort();
62 static void             clntraw_geterr();
63 static bool_t           clntraw_freeres();
64 static bool_t           clntraw_control();
65 static void             clntraw_destroy();
66
67 static struct clnt_ops client_ops = {
68         clntraw_call,
69         clntraw_abort,
70         clntraw_geterr,
71         clntraw_freeres,
72         clntraw_destroy,
73         clntraw_control
74 };
75
76 void    svc_getreq();
77
78 /*
79  * Create a client handle for memory based rpc.
80  */
81 CLIENT *
82 clntraw_create(prog, vers)
83         u_long prog;
84         u_long vers;
85 {
86         register struct clntraw_private *clp = clntraw_private;
87         struct rpc_msg call_msg;
88         XDR *xdrs = &clp->xdr_stream;
89         CLIENT  *client = &clp->client_object;
90
91         if (clp == 0) {
92                 clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
93                 if (clp == 0)
94                         return (0);
95                 clntraw_private = clp;
96         }
97         /*
98          * pre-serialize the staic part of the call msg and stash it away
99          */
100         call_msg.rm_direction = CALL;
101         call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
102         call_msg.rm_call.cb_prog = prog;
103         call_msg.rm_call.cb_vers = vers;
104         xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); 
105         if (! xdr_callhdr(xdrs, &call_msg)) {
106                 perror("clnt_raw.c - Fatal header serialization error.");
107         }
108         clp->mcnt = XDR_GETPOS(xdrs);
109         XDR_DESTROY(xdrs);
110
111         /*
112          * Set xdrmem for client/server shared buffer
113          */
114         xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
115
116         /*
117          * create client handle
118          */
119         client->cl_ops = &client_ops;
120         client->cl_auth = authnone_create();
121         return (client);
122 }
123
124 static enum clnt_stat 
125 clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
126         CLIENT *h;
127         u_long proc;
128         xdrproc_t xargs;
129         caddr_t argsp;
130         xdrproc_t xresults;
131         caddr_t resultsp;
132         struct timeval timeout;
133 {
134         register struct clntraw_private *clp = clntraw_private;
135         register XDR *xdrs = &clp->xdr_stream;
136         struct rpc_msg msg;
137         enum clnt_stat status;
138         struct rpc_err error;
139
140         if (clp == 0)
141                 return (RPC_FAILED);
142 call_again:
143         /*
144          * send request
145          */
146         xdrs->x_op = XDR_ENCODE;
147         XDR_SETPOS(xdrs, 0);
148         ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
149         if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
150             (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
151             (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
152             (! (*xargs)(xdrs, argsp))) {
153                 return (RPC_CANTENCODEARGS);
154         }
155         (void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
156
157         /*
158          * We have to call server input routine here because this is
159          * all going on in one process. Yuk.
160          */
161         svc_getreq(1);
162
163         /*
164          * get results
165          */
166         xdrs->x_op = XDR_DECODE;
167         XDR_SETPOS(xdrs, 0);
168         msg.acpted_rply.ar_verf = _null_auth;
169         msg.acpted_rply.ar_results.where = resultsp;
170         msg.acpted_rply.ar_results.proc = xresults;
171         if (! xdr_replymsg(xdrs, &msg))
172                 return (RPC_CANTDECODERES);
173         _seterr_reply(&msg, &error);
174         status = error.re_status;
175
176         if (status == RPC_SUCCESS) {
177                 if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
178                         status = RPC_AUTHERROR;
179                 }
180         }  /* end successful completion */
181         else {
182                 if (AUTH_REFRESH(h->cl_auth))
183                         goto call_again;
184         }  /* end of unsuccessful completion */
185
186         if (status == RPC_SUCCESS) {
187                 if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
188                         status = RPC_AUTHERROR;
189                 }
190                 if (msg.acpted_rply.ar_verf.oa_base != NULL) {
191                         xdrs->x_op = XDR_FREE;
192                         (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
193                 }
194         }
195
196         return (status);
197 }
198
199 static void
200 clntraw_geterr()
201 {
202 }
203
204
205 static bool_t
206 clntraw_freeres(cl, xdr_res, res_ptr)
207         CLIENT *cl;
208         xdrproc_t xdr_res;
209         caddr_t res_ptr;
210 {
211         register struct clntraw_private *clp = clntraw_private;
212         register XDR *xdrs = &clp->xdr_stream;
213         bool_t rval;
214
215         if (clp == 0)
216         {
217                 rval = (bool_t) RPC_FAILED;
218                 return (rval);
219         }
220         xdrs->x_op = XDR_FREE;
221         return ((*xdr_res)(xdrs, res_ptr));
222 }
223
224 static void
225 clntraw_abort()
226 {
227 }
228
229 static bool_t
230 clntraw_control()
231 {
232         return (FALSE);
233 }
234
235 static void
236 clntraw_destroy()
237 {
238 }