1*7f2fe78bSCy Schubert /* @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright (c) 2010, Oracle America, Inc.
4*7f2fe78bSCy Schubert *
5*7f2fe78bSCy Schubert * All rights reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions are met:
9*7f2fe78bSCy Schubert *
10*7f2fe78bSCy Schubert * * Redistributions of source code must retain the above copyright
11*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
12*7f2fe78bSCy Schubert *
13*7f2fe78bSCy Schubert * * Redistributions in binary form must reproduce the above copyright
14*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in
15*7f2fe78bSCy Schubert * the documentation and/or other materials provided with the
16*7f2fe78bSCy Schubert * distribution.
17*7f2fe78bSCy Schubert *
18*7f2fe78bSCy Schubert * * Neither the name of the "Oracle America, Inc." nor the names of
19*7f2fe78bSCy Schubert * its contributors may be used to endorse or promote products
20*7f2fe78bSCy Schubert * derived from this software without specific prior written permission.
21*7f2fe78bSCy Schubert *
22*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23*7f2fe78bSCy Schubert * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*7f2fe78bSCy Schubert * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25*7f2fe78bSCy Schubert * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*7f2fe78bSCy Schubert * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*7f2fe78bSCy Schubert * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28*7f2fe78bSCy Schubert * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*7f2fe78bSCy Schubert * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*7f2fe78bSCy Schubert * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*7f2fe78bSCy Schubert * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*7f2fe78bSCy Schubert * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert */
34*7f2fe78bSCy Schubert #if !defined(lint) && defined(SCCSIDS)
35*7f2fe78bSCy Schubert static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
36*7f2fe78bSCy Schubert #endif
37*7f2fe78bSCy Schubert
38*7f2fe78bSCy Schubert /*
39*7f2fe78bSCy Schubert * clnt_simple.c
40*7f2fe78bSCy Schubert * Simplified front end to rpc.
41*7f2fe78bSCy Schubert */
42*7f2fe78bSCy Schubert
43*7f2fe78bSCy Schubert #include "autoconf.h"
44*7f2fe78bSCy Schubert #include <stdio.h>
45*7f2fe78bSCy Schubert /* for close() */
46*7f2fe78bSCy Schubert #include <unistd.h>
47*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
48*7f2fe78bSCy Schubert #include <sys/socket.h>
49*7f2fe78bSCy Schubert #include <netdb.h>
50*7f2fe78bSCy Schubert #include <string.h>
51*7f2fe78bSCy Schubert #include <port-sockets.h>
52*7f2fe78bSCy Schubert
53*7f2fe78bSCy Schubert static struct callrpc_private {
54*7f2fe78bSCy Schubert CLIENT *client;
55*7f2fe78bSCy Schubert SOCKET socket;
56*7f2fe78bSCy Schubert rpcprog_t oldprognum;
57*7f2fe78bSCy Schubert rpcvers_t oldversnum;
58*7f2fe78bSCy Schubert int valid;
59*7f2fe78bSCy Schubert char *oldhost;
60*7f2fe78bSCy Schubert } *callrpc_private;
61*7f2fe78bSCy Schubert
62*7f2fe78bSCy Schubert int
callrpc(char * host,rpcprog_t prognum,rpcvers_t versnum,rpcproc_t procnum,xdrproc_t inproc,char * in,xdrproc_t outproc,char * out)63*7f2fe78bSCy Schubert callrpc(
64*7f2fe78bSCy Schubert char *host,
65*7f2fe78bSCy Schubert rpcprog_t prognum,
66*7f2fe78bSCy Schubert rpcvers_t versnum,
67*7f2fe78bSCy Schubert rpcproc_t procnum,
68*7f2fe78bSCy Schubert xdrproc_t inproc,
69*7f2fe78bSCy Schubert char *in,
70*7f2fe78bSCy Schubert xdrproc_t outproc,
71*7f2fe78bSCy Schubert char *out)
72*7f2fe78bSCy Schubert {
73*7f2fe78bSCy Schubert struct callrpc_private *crp = callrpc_private;
74*7f2fe78bSCy Schubert struct sockaddr_in server_addr;
75*7f2fe78bSCy Schubert enum clnt_stat clnt_stat;
76*7f2fe78bSCy Schubert struct hostent *hp;
77*7f2fe78bSCy Schubert struct timeval timeout, tottimeout;
78*7f2fe78bSCy Schubert
79*7f2fe78bSCy Schubert if (crp == 0) {
80*7f2fe78bSCy Schubert crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
81*7f2fe78bSCy Schubert if (crp == 0)
82*7f2fe78bSCy Schubert return (0);
83*7f2fe78bSCy Schubert callrpc_private = crp;
84*7f2fe78bSCy Schubert }
85*7f2fe78bSCy Schubert if (crp->oldhost == NULL) {
86*7f2fe78bSCy Schubert crp->oldhost = mem_alloc(256);
87*7f2fe78bSCy Schubert if (crp->oldhost == 0)
88*7f2fe78bSCy Schubert return 0;
89*7f2fe78bSCy Schubert crp->oldhost[0] = 0;
90*7f2fe78bSCy Schubert crp->socket = RPC_ANYSOCK;
91*7f2fe78bSCy Schubert }
92*7f2fe78bSCy Schubert if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
93*7f2fe78bSCy Schubert && strcmp(crp->oldhost, host) == 0) {
94*7f2fe78bSCy Schubert /* reuse old client */
95*7f2fe78bSCy Schubert } else {
96*7f2fe78bSCy Schubert crp->valid = 0;
97*7f2fe78bSCy Schubert (void)closesocket(crp->socket);
98*7f2fe78bSCy Schubert crp->socket = RPC_ANYSOCK;
99*7f2fe78bSCy Schubert if (crp->client) {
100*7f2fe78bSCy Schubert clnt_destroy(crp->client);
101*7f2fe78bSCy Schubert crp->client = NULL;
102*7f2fe78bSCy Schubert }
103*7f2fe78bSCy Schubert if ((hp = gethostbyname(host)) == NULL)
104*7f2fe78bSCy Schubert return ((int) RPC_UNKNOWNHOST);
105*7f2fe78bSCy Schubert timeout.tv_usec = 0;
106*7f2fe78bSCy Schubert timeout.tv_sec = 5;
107*7f2fe78bSCy Schubert memset(&server_addr, 0, sizeof(server_addr));
108*7f2fe78bSCy Schubert memmove((char *)&server_addr.sin_addr, hp->h_addr,
109*7f2fe78bSCy Schubert sizeof(server_addr.sin_addr));
110*7f2fe78bSCy Schubert server_addr.sin_family = AF_INET;
111*7f2fe78bSCy Schubert server_addr.sin_port = 0;
112*7f2fe78bSCy Schubert if ((crp->client = clntudp_create(&server_addr, prognum,
113*7f2fe78bSCy Schubert versnum, timeout, &crp->socket)) == NULL)
114*7f2fe78bSCy Schubert return ((int) rpc_createerr.cf_stat);
115*7f2fe78bSCy Schubert crp->valid = 1;
116*7f2fe78bSCy Schubert crp->oldprognum = prognum;
117*7f2fe78bSCy Schubert crp->oldversnum = versnum;
118*7f2fe78bSCy Schubert (void) strncpy(crp->oldhost, host, 255);
119*7f2fe78bSCy Schubert crp->oldhost[255] = '\0';
120*7f2fe78bSCy Schubert }
121*7f2fe78bSCy Schubert tottimeout.tv_sec = 25;
122*7f2fe78bSCy Schubert tottimeout.tv_usec = 0;
123*7f2fe78bSCy Schubert clnt_stat = clnt_call(crp->client, procnum, inproc, in,
124*7f2fe78bSCy Schubert outproc, out, tottimeout);
125*7f2fe78bSCy Schubert /*
126*7f2fe78bSCy Schubert * if call failed, empty cache
127*7f2fe78bSCy Schubert */
128*7f2fe78bSCy Schubert if (clnt_stat != RPC_SUCCESS)
129*7f2fe78bSCy Schubert crp->valid = 0;
130*7f2fe78bSCy Schubert return ((int) clnt_stat);
131*7f2fe78bSCy Schubert }
132