/* $NetBSD: clnt_simple.c,v 1.21 2000/07/06 03:10:34 christos Exp $ */12/*-3* SPDX-License-Identifier: BSD-3-Clause4*5* Copyright (c) 2009, Sun Microsystems, Inc.6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions are met:10* - Redistributions of source code must retain the above copyright notice,11* this list of conditions and the following disclaimer.12* - Redistributions in binary form must reproduce the above copyright notice,13* this list of conditions and the following disclaimer in the documentation14* and/or other materials provided with the distribution.15* - Neither the name of Sun Microsystems, Inc. nor the names of its16* contributors may be used to endorse or promote products derived17* from this software without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"20* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE22* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE23* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR24* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF25* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS26* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN27* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE29* POSSIBILITY OF SUCH DAMAGE.30*/31/*32* Copyright (c) 1986-1991 by Sun Microsystems Inc.33*/3435/*36* clnt_simple.c37* Simplified front end to client rpc.38*39*/4041#include "namespace.h"42#include "reentrant.h"43#include <sys/param.h>44#include <stdio.h>45#include <errno.h>46#include <rpc/rpc.h>47#include <string.h>48#include <stdlib.h>49#include <fcntl.h>50#include <unistd.h>51#include "un-namespace.h"52#include "mt_misc.h"5354#ifndef MAXHOSTNAMELEN55#define MAXHOSTNAMELEN 6456#endif5758#ifndef NETIDLEN59#define NETIDLEN 3260#endif6162struct rpc_call_private {63int valid; /* Is this entry valid ? */64CLIENT *client; /* Client handle */65pid_t pid; /* process-id at moment of creation */66rpcprog_t prognum; /* Program */67rpcvers_t versnum; /* Version */68char host[MAXHOSTNAMELEN]; /* Servers host */69char nettype[NETIDLEN]; /* Network type */70};71static struct rpc_call_private *rpc_call_private_main;72static thread_key_t rpc_call_key;73static once_t rpc_call_once = ONCE_INITIALIZER;74static int rpc_call_key_error;7576static void rpc_call_key_init(void);77static void rpc_call_destroy(void *);7879static void80rpc_call_destroy(void *vp)81{82struct rpc_call_private *rcp = (struct rpc_call_private *)vp;8384if (rcp) {85if (rcp->client)86CLNT_DESTROY(rcp->client);87free(rcp);88}89}9091static void92rpc_call_key_init(void)93{9495rpc_call_key_error = thr_keycreate(&rpc_call_key, rpc_call_destroy);96}9798/*99* This is the simplified interface to the client rpc layer.100* The client handle is not destroyed here and is reused for101* the future calls to same prog, vers, host and nettype combination.102*103* The total time available is 25 seconds.104*105* host - host name106* prognum - program number107* versnum - version number108* procnum - procedure number109* inproc, outproc - in/out XDR procedures110* in, out - recv/send data111* nettype - nettype112*/113enum clnt_stat114rpc_call(const char *host, const rpcprog_t prognum, const rpcvers_t versnum,115const rpcproc_t procnum, const xdrproc_t inproc, const char *in,116const xdrproc_t outproc, char *out, const char *nettype)117{118struct rpc_call_private *rcp = (struct rpc_call_private *) 0;119enum clnt_stat clnt_stat;120struct timeval timeout, tottimeout;121int main_thread = 1;122123if ((main_thread = thr_main())) {124rcp = rpc_call_private_main;125} else {126if (thr_once(&rpc_call_once, rpc_call_key_init) != 0 ||127rpc_call_key_error != 0) {128rpc_createerr.cf_stat = RPC_SYSTEMERROR;129rpc_createerr.cf_error.re_errno = rpc_call_key_error;130return (rpc_createerr.cf_stat);131}132rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key);133}134if (rcp == NULL) {135rcp = malloc(sizeof (*rcp));136if (rcp == NULL) {137rpc_createerr.cf_stat = RPC_SYSTEMERROR;138rpc_createerr.cf_error.re_errno = errno;139return (rpc_createerr.cf_stat);140}141if (main_thread)142rpc_call_private_main = rcp;143else144thr_setspecific(rpc_call_key, (void *) rcp);145rcp->valid = 0;146rcp->client = NULL;147}148if ((nettype == NULL) || (nettype[0] == 0))149nettype = "netpath";150if (!(rcp->valid && rcp->pid == getpid() &&151(rcp->prognum == prognum) &&152(rcp->versnum == versnum) &&153(!strcmp(rcp->host, host)) &&154(!strcmp(rcp->nettype, nettype)))) {155int fd;156157rcp->valid = 0;158if (rcp->client)159CLNT_DESTROY(rcp->client);160/*161* Using the first successful transport for that type162*/163rcp->client = clnt_create(host, prognum, versnum, nettype);164rcp->pid = getpid();165if (rcp->client == NULL) {166return (rpc_createerr.cf_stat);167}168/*169* Set time outs for connectionless case. Do it170* unconditionally. Faster than doing a t_getinfo()171* and then doing the right thing.172*/173timeout.tv_usec = 0;174timeout.tv_sec = 5;175(void) CLNT_CONTROL(rcp->client,176CLSET_RETRY_TIMEOUT, (char *)(void *)&timeout);177if (CLNT_CONTROL(rcp->client, CLGET_FD, (char *)(void *)&fd))178_fcntl(fd, F_SETFD, 1); /* make it "close on exec" */179rcp->prognum = prognum;180rcp->versnum = versnum;181if ((strlen(host) < (size_t)MAXHOSTNAMELEN) &&182(strlen(nettype) < (size_t)NETIDLEN)) {183(void) strcpy(rcp->host, host);184(void) strcpy(rcp->nettype, nettype);185rcp->valid = 1;186} else {187rcp->valid = 0;188}189} /* else reuse old client */190tottimeout.tv_sec = 25;191tottimeout.tv_usec = 0;192/*LINTED const castaway*/193clnt_stat = CLNT_CALL(rcp->client, procnum, inproc, (char *) in,194outproc, out, tottimeout);195/*196* if call failed, empty cache197*/198if (clnt_stat != RPC_SUCCESS)199rcp->valid = 0;200return (clnt_stat);201}202203204